Fixes icache_put on creation and KFS refcounting
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 16 Sep 2010 00:55:10 +0000 (17:55 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:54 +0000 (17:35 -0700)
KFS decrefs its pinned-path on rmdir/unlink, and doesn't drop a ref when
parsing the cpio.

kern/src/kfs.c
kern/src/vfs.c

index f40149d..208c438 100644 (file)
@@ -364,6 +364,7 @@ int kfs_unlink(struct inode *dir, struct dentry *dentry)
        /* Stop tracking our child */
        TAILQ_REMOVE(&((struct kfs_i_info*)dir->i_fs_info)->children, dentry,
                     d_subdirs_link);
+       kref_put(&dentry->d_kref);                              /* unpin the dentry, KFS-style */
        return 0;
 }
 
@@ -422,6 +423,8 @@ int kfs_rmdir(struct inode *dir, struct dentry *dentry)
        }
        if (!empty)
                return -ENOTEMPTY;
+       kref_put(&dentry->d_kref);                              /* unpin the dentry, KFS-style */
+       printk("DENTRY %s REFCNT %d\n", dentry->d_name.name, kref_refcnt(&dentry->d_kref));
        return 0;
 }
 
@@ -777,7 +780,7 @@ static int __add_kfs_entry(struct dentry *parent, char *path,
        size_t dirname_sz;                              /* not counting the \0 */
        struct dentry *dentry = 0;
        struct inode *inode;
-       int err;
+       int err, retval;
        char *symname, old_end;                 /* for symlink manipulation */
 
        if (first_slash) {
@@ -799,7 +802,9 @@ static int __add_kfs_entry(struct dentry *parent, char *path,
                        printk("Missing dir in CPIO archive or something, aborting.\n");
                        return -1;
                }
-               return __add_kfs_entry(dentry, first_slash + 1, c_bhdr);
+               retval = __add_kfs_entry(dentry, first_slash + 1, c_bhdr);
+               kref_put(&dentry->d_kref);
+               return retval;
        } else {
                /* no directories left in the path.  add the 'file' to the dentry */
                printd("Adding file/dir %s to dentry %s (start: %p, size %d)\n", path,
@@ -837,6 +842,7 @@ static int __add_kfs_entry(struct dentry *parent, char *path,
                        default:
                                printk("Unknown file type %d in the CPIO!",
                                       c_bhdr->c_mode & CPIO_FILE_MASK);
+                               kref_put(&dentry->d_kref);
                                return -1;
                }
                inode = dentry->d_inode;
@@ -851,6 +857,7 @@ static int __add_kfs_entry(struct dentry *parent, char *path,
                inode->i_bdev = 0;                                              /* assuming blockdev? */
                inode->i_socket = FALSE;
                inode->i_blocks = c_bhdr->c_filesize;   /* blocksize == 1 */
+               kref_put(&dentry->d_kref);
        }
        return 0;
 }
index 0606c37..4a188a6 100644 (file)
@@ -979,6 +979,7 @@ int create_file(struct inode *dir, struct dentry *dentry, int mode)
        if (!new_file)
                return -1;
        dir->i_op->create(dir, dentry, mode, 0);
+       icache_put(new_file->i_sb, new_file);
        kref_put(&new_file->i_kref);
        return 0;
 }
@@ -998,6 +999,7 @@ int create_dir(struct inode *dir, struct dentry *dentry, int mode)
        assert(parent && parent == TAILQ_LAST(&dir->i_dentry, dentry_tailq));
        /* parent dentry tracks dentry as a subdir, weak reference */
        TAILQ_INSERT_TAIL(&parent->d_subdirs, dentry, d_subdirs_link);
+       icache_put(new_dir->i_sb, new_dir);
        kref_put(&new_dir->i_kref);
        return 0;
 }
@@ -1011,6 +1013,7 @@ int create_symlink(struct inode *dir, struct dentry *dentry,
        if (!new_sym)
                return -1;
        dir->i_op->symlink(dir, dentry, symname);
+       icache_put(new_sym->i_sb, new_sym);
        kref_put(&new_sym->i_kref);
        return 0;
 }