]> git.neil.brown.name Git - LaFS.git/commitdiff
walk_leaf_index - use kmap, not kmap_atomic
authorNeilBrown <neilb@suse.de>
Mon, 13 Apr 2009 01:50:31 +0000 (11:50 +1000)
committerNeilBrown <neilb@suse.de>
Mon, 13 Apr 2009 01:50:31 +0000 (11:50 +1000)
When truncating a file, we need to update the segusage counts
for all relevant segments.  This can require reading segusage blocks
while walking a leaf index.  So we cannot use kmap_atomic in
lafs_walk_leaf_index.  So use kmap instead.

modify.c

index e01b8eb9da2d85afbe38b5b28291735a94b922fd..dc947395ff3f1dcf3132988607ad4e2177da14a5 100644 (file)
--- a/modify.c
+++ b/modify.c
@@ -938,7 +938,14 @@ void lafs_walk_leaf_index(struct indexblock *ib,
        struct uninc ui;
        ui.pending_cnt = 0;
 
-       ibuf = map_iblock(ib);
+       /* Cannot use kmap_atomic as handle might sleep when
+        * looking up segusage blocks
+        */
+       if (test_bit(B_InoIdx, &ib->b.flags)) {
+               ibuf = kmap(LAFSI(ib->b.inode)->dblock->page);
+               ibuf += dblock_offset(LAFSI(ib->b.inode)->dblock);
+       } else
+               ibuf = map_iblock(ib);
        if (test_bit(B_InoIdx, &ib->b.flags))
                offset = LAFSI(ib->b.inode)->metadata_size;
        else
@@ -964,7 +971,9 @@ void lafs_walk_leaf_index(struct indexblock *ib,
                printk("X: %s\n", strblk(&ib->b));
                BUG(); // FIXME should be IO error ??
        }
-       unmap_iblock(ib, ibuf);
+       if (test_bit(B_InoIdx, &ib->b.flags))
+               kunmap(LAFSI(ib->b.inode)->dblock->page);
+
 }
 
 static void share_list(struct block **ibp, struct block **newp, u32 next)