]> git.neil.brown.name Git - LaFS.git/commitdiff
Use igrab_fs to hod refcounts on the inodes of orphans.
authorNeilBrown <neilb@suse.de>
Sun, 10 Oct 2010 22:58:36 +0000 (09:58 +1100)
committerNeilBrown <neilb@suse.de>
Sun, 10 Oct 2010 23:33:56 +0000 (10:33 +1100)
We currently hold a refcount on the inodes of dir orphans.
We need the filesystem (super_block) as well.

Also, while we don't really need a similar refcount for inode orphans,
it doesn't hurt.

So simplify the tracking of whether we need to take such a refcount,
use iget_fs to grab the super_block as well, and also take a ref in
lafs_add_orphans, which was missing.

Signed-off-by: NeilBrown <neilb@suse.de>
dir.c
inode.c
lafs.h
orphan.c

diff --git a/dir.c b/dir.c
index e1555f63e192b951ef9e3288f22e6865e5d2b93e..bb8b3d1c58b67b7233ce186d1eeaa86087ee8231 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -432,7 +432,7 @@ dir_delete_prepare(struct fs *fs, struct inode *dir,
                unmap_dblock(dirblk, buf);
        }
        if (orphan)
-               return lafs_make_orphan(fs, doh->dirent_block, dir);
+               return lafs_make_orphan(fs, doh->dirent_block);
        return 0;
 }
 
@@ -768,7 +768,7 @@ lafs_unlink(struct inode *dir, struct dentry *de)
        if (IS_ERR(inodb))
                err = PTR_ERR(inodb);
        if (last && !err)
-               err = lafs_make_orphan(fs, inodb, NULL);
+               err = lafs_make_orphan(fs, inodb);
        if (err)
                goto abort;
        lafs_iolock_block(&inodb->b);
@@ -861,7 +861,7 @@ lafs_rmdir(struct inode *dir, struct dentry *de)
        if (IS_ERR(inodb))
                err = PTR_ERR(inodb);
        if (!err)
-               err = lafs_make_orphan(fs, inodb, NULL);
+               err = lafs_make_orphan(fs, inodb);
        if (err)
                goto abort;
        lafs_iolock_block(&inodb->b);
@@ -1188,7 +1188,7 @@ lafs_rename(struct inode *old_dir, struct dentry *old_dentry,
                if (IS_ERR(newdb))
                        err = PTR_ERR(newdb);
                if (last && !err)
-                       err = lafs_make_orphan(fs, newdb, NULL);
+                       err = lafs_make_orphan(fs, newdb);
                lafs_iolock_block(&newdb->b);
                set_bit(B_PinPending, &newdb->b.flags);
                lafs_iounlock_block(&newdb->b);
@@ -1342,7 +1342,7 @@ int lafs_dir_handle_orphan(struct datablock *b)
                 * space being tight.
                 * just try again
                 */
-               lafs_orphan_release(fs, b, dir);
+               lafs_orphan_release(fs, b);
                err = 0;
                goto abort;
        }
@@ -1423,7 +1423,7 @@ int lafs_dir_handle_orphan(struct datablock *b)
                if (lafs_dir_find(buf2, bits, seed, (hash-1) & MaxDirHash,
                                  &piece) &&
                    lafs_dir_extract(buf2, bits, &de, piece, NULL)->target == 0)
-                       err = lafs_make_orphan_nb(fs, b2, dir);
+                       err = lafs_make_orphan_nb(fs, b2);
                unmap_dblock(b2, buf2);
                putdref(b2, MKREF(dir_orphan));
                b2 = NULL;
@@ -1474,7 +1474,7 @@ int lafs_dir_handle_orphan(struct datablock *b)
        } else
                unmap_dblock(b, buf);
 
-       lafs_orphan_release(fs, b, dir);
+       lafs_orphan_release(fs, b);
        err = 0;
 
 abort:
diff --git a/inode.c b/inode.c
index 857ea60bcd1f1cdeff38252c162b7f35ed6bed4c..8b13b4a88970abda05b87c3cc201a58781bb583e 100644 (file)
--- a/inode.c
+++ b/inode.c
@@ -815,9 +815,9 @@ int lafs_inode_handle_orphan(struct datablock *b)
                               LAFSI(ino)->ciblocks +
                               LAFSI(ino)->piblocks);
                        if (lafs_erase_dblock_async(b))
-                               lafs_orphan_release(fs, b, NULL);
+                               lafs_orphan_release(fs, b);
                } else if (ino->i_nlink || LAFSI(ino)->type == 0)
-                       lafs_orphan_release(fs, b, NULL);
+                       lafs_orphan_release(fs, b);
                else
                        lafs_orphan_forget(fs, b);
                return 0;
@@ -1535,7 +1535,7 @@ inode_map_new_abort(struct inode_map_new_info *imni)
                clear_bit(B_Claimed, &imni->ib->b.flags);
                clear_bit(B_PinPending, &imni->ib->b.flags);
                lafs_orphan_release(fs_from_inode(imni->ib->b.inode),
-                                   imni->ib, NULL);
+                                   imni->ib);
        }
        putdref(imni->ib, MKREF(cfi_ino));
        if (imni->mb) {
@@ -1568,7 +1568,7 @@ lafs_new_inode(struct fs *fs, struct super_block *sb, struct inode *dir,
        err = lafs_cluster_update_prepare(&ui, fs, sizeof(struct la_inode))
                ?: err;
        if (err == 0)
-               err = lafs_make_orphan(fs, imni.ib, NULL);
+               err = lafs_make_orphan(fs, imni.ib);
        if (err)
                goto abort;
 retry:
@@ -1745,7 +1745,7 @@ void lafs_truncate(struct inode *ino)
         * If this doesn't get registered as an orphan .... maybe
         * it will have to wait until something else truncates it.
         */
-       lafs_make_orphan(fs, db, NULL);
+       lafs_make_orphan(fs, db);
 
        if (!test_and_set_bit(I_Trunc, &LAFSI(ino)->iflags))
                igrab(ino);
diff --git a/lafs.h b/lafs.h
index e52a1680d02d9b645ecb447ba6ae1d8f8a35de8d..c6c0bb205499cc8643e98fcdbba2cc67a656442b 100644 (file)
--- a/lafs.h
+++ b/lafs.h
@@ -706,9 +706,9 @@ unsigned long long lafs_checkpoint_start(struct fs *fs);
 unsigned long lafs_do_checkpoint(struct fs *fs);
 struct block *lafs_get_flushable(struct fs *fs, int phase);
 
-int lafs_make_orphan(struct fs *fs, struct datablock *db, struct inode *ino);
-int lafs_make_orphan_nb(struct fs *fs, struct datablock *db, struct inode *ino);
-void lafs_orphan_release(struct fs *fs, struct datablock *b, struct inode *ino);
+int lafs_make_orphan(struct fs *fs, struct datablock *db);
+int lafs_make_orphan_nb(struct fs *fs, struct datablock *db);
+void lafs_orphan_release(struct fs *fs, struct datablock *db);
 long lafs_run_orphans(struct fs *fs);
 void lafs_add_orphan(struct fs *fs, struct datablock *db);
 void lafs_orphan_forget(struct fs *fs, struct datablock *db);
index 9e93676dabe1ce763602449bedecacbd557c35e1..8a09b090db8a525ea40410f45a358085f78ea058 100644 (file)
--- a/orphan.c
+++ b/orphan.c
@@ -170,6 +170,7 @@ static void orphan_commit(struct fs *fs, struct datablock *b, struct datablock *
        b->orphan_slot = om->nextfree++;
        set_bit(B_Orphan, &b->b.flags);
        getdref(b, MKREF(orphan_flag));
+       lafs_igrab_fs(b->b.inode);
        lafs_add_orphan(fs, b);
 
        dprintk("%p->orphan_slot=%d (%lu,%lu,%lu) %s\n", b, b->orphan_slot,
@@ -238,7 +239,7 @@ static void orphan_abort(struct fs *fs)
  * For directories, i_mutex is used for this.
  * For inodes, B_IOLock is used.
  */
-int lafs_make_orphan(struct fs *fs, struct datablock *db, struct inode *ino)
+int lafs_make_orphan(struct fs *fs, struct datablock *db)
 {
        int err;
        struct datablock *ob;
@@ -261,18 +262,16 @@ retry:
        if (IS_ERR(ob)) {
                orphan_abort(fs);
                err = PTR_ERR(ob);
-       } else {
+       } else
                orphan_commit(fs, db, ob);
-               if (ino)
-                       igrab(ino);
-       }
+
        mutex_unlock(&fs->orphans->i_mutex);
        lafs_checkpoint_unlock(fs);
        return err;
 }
 
 /* non-blocking version of make_orphan */
-int lafs_make_orphan_nb(struct fs *fs, struct datablock *db, struct inode *ino)
+int lafs_make_orphan_nb(struct fs *fs, struct datablock *db)
 {
        int err;
        struct datablock *ob;
@@ -293,11 +292,9 @@ int lafs_make_orphan_nb(struct fs *fs, struct datablock *db, struct inode *ino)
        if (IS_ERR(ob)) {
                orphan_abort(fs);
                err = PTR_ERR(ob);
-       } else {
+       } else
                orphan_commit(fs, db, ob);
-               if (ino)
-                       igrab(ino);
-       }
+
        mutex_unlock(&fs->orphans->i_mutex);
        lafs_checkpoint_unlock(fs);
        return err;
@@ -320,7 +317,7 @@ static void lafs_drop_orphan(struct fs *fs, struct datablock *db);
  * like a spinlock, and erase_dblock should not block as the block
  * should be PinPending;
  */
-void lafs_orphan_release(struct fs *fs, struct datablock *b, struct inode *ino)
+void lafs_orphan_release(struct fs *fs, struct datablock *b)
 {
        struct datablock *ob1, *ob2;
        int shift = b->b.inode->i_blkbits - 4;
@@ -434,7 +431,7 @@ again:
        om->nextfree--;
        om->reserved++;
        clear_bit(B_Orphan, &b->b.flags);
-       iput(ino);
+       lafs_iput_fs(b->b.inode);
        lafs_drop_orphan(fs, b);
        putdref(b, MKREF(orphan_flag));
 
@@ -713,6 +710,7 @@ void lafs_add_orphans(struct fs *fs, struct inode *ino, int count)
                                        getdref(ob, MKREF(orphan_flag));
                                        getdref(db, MKREF(orphan));
                                        ob->orphan_slot = bslot + slot;
+                                       lafs_igrab_fs(ob->b.inode);
                                        lafs_add_orphan(fs, ob);
                                } else
                                        or[slot].type = 0;