]> git.neil.brown.name Git - LaFS.git/commitdiff
Various incorporation and truncation fixes.
authorNeilBrown <neilb@suse.de>
Thu, 19 Mar 2009 01:46:24 +0000 (12:46 +1100)
committerNeilBrown <neilb@suse.de>
Thu, 19 Mar 2009 01:46:24 +0000 (12:46 +1100)
inode.c
lafs.h
modify.c

diff --git a/inode.c b/inode.c
index a8463da3c34b4d9a4ff0d0f9c9f9f9f6c19cef12..9c92db65f832dc17eba492bd9ed86f1d4eecad80 100644 (file)
--- a/inode.c
+++ b/inode.c
@@ -563,7 +563,12 @@ static int lafs_inode_handle_orphan(struct datablock *b)
                         */
                        getiref(ib2, MKREF(inode_handle_orphan2));
                        lafs_iolock_block(&ib2->b);
-                       lafs_incorporate_loop(fs, ib2);
+                       /* call lafs_incorporate at least once to ensure
+                        * that lafs_erase_iblock gets called
+                        */
+                       do
+                               lafs_incorporate(fs, ib2);
+                       while (ib2->uninc_table.pending_cnt || ib2->uninc);
                        lafs_iounlock_block(&ib2->b, 0);
                        putiref(ib2, MKREF(inode_handle_orphan2));
                        printk(".");
@@ -612,7 +617,8 @@ static int lafs_inode_handle_orphan(struct datablock *b)
 
        LAFSI(ino)->trunc_next = trunc_next;
        lafs_iolock_block(&ib2->b);
-       lafs_incorporate_loop(fs, ib2);
+       while (ib->uninc_table.pending_cnt || ib->uninc)
+               lafs_incorporate(fs, ib2);
        lafs_iounlock_block(&ib2->b, 0);
        dprintk("Trunc %d\n", (int)LAFSI(ino)->trunc_next);
        lafs_walk_leaf_index(ib2, prune, ib2);
diff --git a/lafs.h b/lafs.h
index a1197cac3b82524ad68d63b0412b38c3a37bd0ee..fc85891b681b54616b42949b20fec15117e12391 100644 (file)
--- a/lafs.h
+++ b/lafs.h
@@ -484,7 +484,6 @@ void lafs_summary_update(struct fs *fs, struct inode *ino,
 int lafs_summary_allocate(struct fs *fs, struct inode *ino, int diff);
 void lafs_qcommit(struct fs *fs, struct inode *ino, int diff, int phase);
 void lafs_incorporate(struct fs *fs, struct indexblock *ib);
-void lafs_incorporate_loop(struct fs *fs, struct indexblock *ib);
 void lafs_walk_leaf_index(struct indexblock *ib,
                          int (*handle)(void*, u32, u64, int),
                          void *data);
index a96f2248c84aad644dbe76810d615223603d0616..dc9dbe029f9b22f0b00ab95dc62b2717b7371adb 100644 (file)
--- a/modify.c
+++ b/modify.c
@@ -1071,6 +1071,7 @@ static int do_incorporate_leaf(struct fs *fs, struct indexblock *ib,
        int choice;
        struct layoutinfo layout;
        u32 next = 0;
+       u32 next2;
        int uinxt, uinum;
        struct block *b, *tmp;
 
@@ -1257,7 +1258,8 @@ static int do_incorporate_leaf(struct fs *fs, struct indexblock *ib,
        }
        layout.data = ibuf;
        layout.size = len;
-       next = walk_extent(next, &sbuf, slen, ui, add_extent, &layout);
+       next2 = walk_extent(next, &sbuf, slen, ui, add_extent, &layout);
+       BUG_ON(next2 != 0);
        if (slen && layout.data > sbuf) {
                printk("slen=%d ld-sb=%d layout.data=%p sbuf=%p buf=%p ibuf=%p len=%d\n",
                       slen, layout.data-sbuf, layout.data, sbuf, buf, ibuf, len);
@@ -1505,6 +1507,7 @@ void lafs_incorporate(struct fs *fs, struct indexblock *ib)
                                memset(buf, 0, blocksize - offset);
                                *(u16*)(buf) = cpu_to_le16(IBLK_EXTENT);
                                LAFSI(ib->b.inode)->depth = 1;
+                               ib->depth = 1;
                        }
                } else
                        offset = 0;
@@ -1582,6 +1585,8 @@ void lafs_incorporate(struct fs *fs, struct indexblock *ib)
        new = lafs_iblock_alloc(fs, GFP_NOFS, 1, MKREF(inc));
        /* FIXME need to preallocate something for a fall-back?? */
 
+       if (ib->depth < 1) printk("small depth %s\n", strblk(&ib->b));
+       BUG_ON(ib->depth < 1);
        if (ib->depth == 1) {
                rv = do_incorporate_leaf(fs, ib, &uit, new);
        } else
@@ -1594,18 +1599,17 @@ void lafs_incorporate(struct fs *fs, struct indexblock *ib)
                 */
                dprintk("incorp to empty off=%d %s\n", (int)offset, strblk(&ib->b));
                lafs_iblock_free(new);
+               buf = map_iblock(ib);
+               memset(buf + offset, 0, blocksize - offset);
+               *(u16*)(buf) = cpu_to_le16(IBLK_INDIRECT);
+               unmap_iblock(ib, buf);
                if (offset) {
-                       buf = map_iblock(ib);
-                       memset(buf + offset, 0, blocksize - offset);
-                       *(u16*)(buf) = cpu_to_le16(IBLK_INDIRECT);
-                       unmap_iblock(ib, buf);
                        LAFSI(ib->b.inode)->depth = 1;
 
                        if (LAFSI(ib->b.inode)->type == 0)
                                /* truncate has finished */
                                lafs_erase_dblock(LAFSI(ib->b.inode)->dblock);
-               } else
-                       lafs_erase_iblock(ib);
+               }
 
                break;
 
@@ -1651,24 +1655,16 @@ void lafs_incorporate(struct fs *fs, struct indexblock *ib)
        lafs_space_return(fs, uit.credits);
 
        /* If this index block is now empty, we need to be sure it
-        * is erased.
+        * is erased.  But if there is anything pending in the next phase
+        * we need to wait for that to complete.
         */
        if (test_bit(B_Valid, &ib->b.flags) &&
-           lafs_leaf_next(ib, ib->b.fileaddr) == 0xFFFFFFFF)
+           lafs_leaf_next(ib, ib->b.fileaddr) == 0xFFFFFFFF &&
+           atomic_read(&ib->pincnt[0]) == 0 &&
+           atomic_read(&ib->pincnt[1]) == 0)
                lafs_erase_iblock(ib);
 }
 
-void lafs_incorporate_loop(struct fs *fs, struct indexblock *ib)
-{
-       /* Repeatedly run lafs_incorporate until
-        * uninc_table is empty.  This is only used during
-        * truncation and we know all the incorporated addresses
-        * are zero, so no splitting or such is needed.
-        */
-       while (ib->uninc_table.pending_cnt || ib->uninc)
-               lafs_incorporate(fs, ib);
-}
-
 /***************************************************************
  * Space pre-allocation
  * We need to make sure that the block and all parents