]> git.neil.brown.name Git - LaFS.git/commitdiff
Hold ref to inode-map inode while allocating inode.
authorNeilBrown <neilb@suse.de>
Sun, 25 Jul 2010 10:25:50 +0000 (20:25 +1000)
committerNeilBrown <neilb@suse.de>
Mon, 9 Aug 2010 01:58:12 +0000 (11:58 +1000)
The block doesn't explicitly reference the inode, so we need
to hold a reference as long as we reference a block in the file.

Signed-off-by: NeilBrown <neilb@suse.de>
inode.c

diff --git a/inode.c b/inode.c
index 89722e480a2ee191d5112cd9b450409b0718cb39..171c1818465c673154d147c2e32d47cb656f52d6 100644 (file)
--- a/inode.c
+++ b/inode.c
@@ -1195,7 +1195,9 @@ choose_free_inum(struct fs *fs, struct inode *filesys, u32 *inump,
        mutex_lock_nested(&im->i_mutex, I_MUTEX_QUOTA);
 retry:
        if (*bp) {
+               struct inode *i = (*bp)->b.inode;
                putdref(*bp, MKREF(cfi_map));
+               iput(i);
                *bp = NULL;
        }
 
@@ -1280,7 +1282,6 @@ retry:
 
        mutex_unlock(&im->i_mutex);
        *inump = bit + (bnum << (im->i_blkbits + 3));
-       iput(im);
        return 0;
 
 abort_unlock:
@@ -1350,6 +1351,8 @@ inode_map_new_commit(struct inode_map_new_info *imni)
        int blksize = imni->ib->b.inode->i_sb->s_blocksize;
        int bit = imni->ib->b.fileaddr & (blksize*8 - 1);
        int hole = 0;
+       struct inode *ino = NULL;
+
        clear_bit(bit, buf);
        if (buf[blksize/sizeof(*buf)-1] == 0 &&
            find_first_bit(buf, blksize*8) == blksize*8)
@@ -1362,12 +1365,17 @@ inode_map_new_commit(struct inode_map_new_info *imni)
        else
                lafs_dirty_dblock(imni->mb);
        putdref(imni->ib, MKREF(cfi_ino));
+       if (imni->mb)
+               ino = imni->mb->b.inode;
        putdref(imni->mb, MKREF(cfi_map));
+       if (ino)
+               iput(ino);
 }
 
 static void
 inode_map_new_abort(struct inode_map_new_info *imni)
 {
+       struct inode *ino = NULL;
        if (imni->ib) {
                clear_bit(B_Claimed, &imni->ib->b.flags);
                clear_bit(B_PinPending, &imni->ib->b.flags);
@@ -1375,7 +1383,11 @@ inode_map_new_abort(struct inode_map_new_info *imni)
                                    imni->ib);
        }
        putdref(imni->ib, MKREF(cfi_ino));
+       if (imni->mb)
+               ino = imni->mb->b.inode;
        putdref(imni->mb, MKREF(cfi_map));
+       if (ino)
+               iput(ino);
 }
 
 struct inode *