]> git.neil.brown.name Git - LaFS.git/commitdiff
update to 2.6.27 and other fixes.
authorNeil Brown <neilb@suse.de>
Wed, 10 Dec 2008 23:11:32 +0000 (10:11 +1100)
committerNeil Brown <neilb@suse.de>
Wed, 10 Dec 2008 23:11:32 +0000 (10:11 +1100)
18 files changed:
Makefile
README
block.c
checkpoint.c
clean.c
cluster.c
file.c
index.c
inode.c
io.c
lafs.h
modify.c
orphan.c
roll.c
snapshot.c
summary.c
test/go
test/runtty

index 753900b43dbea49aa5993a8f88a3ae530f3b168c..db10ffb20b59b575197bba3948c0f85e90df5baa 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,7 @@ ARCH=i386
 ifneq ($(KERNELRELEASE),)
 # kbuild part
 
-CFLAGS += -Werror -DDUMP
+EXTRA_CFLAGS += -Werror -DDUMP
 obj-m += lafs.o
 
 lafs-y := super.o io.o roll.o dir.o inode.o index.o block.o file.o link.o dir-avl.o \
@@ -16,7 +16,7 @@ lafs-y := super.o io.o roll.o dir.o inode.o index.o block.o file.o link.o dir-av
 
 else
 
-KERNELDIR := /home/src/lafs-2.6.23
+KERNELDIR := /home/src/lafs-2.6.27
 all::
        $(MAKE) -C $(KERNELDIR) ARCH=i386 M=`pwd`
        nm lafs.o | grep ' T ' | grep -v lafs_
diff --git a/README b/README
index 3098961aa073a4c5c24503f40e5eec3707bfdadb..d81cf49e53b5eefe090a0db299aeeab3aeaa451d 100644 (file)
--- a/README
+++ b/README
@@ -1623,6 +1623,27 @@ FIXME when I "rm [b-z]*" it waits for writeback on something???
    This is good as it motivates the code to handle block splitting in
    the Btree.   But it shouldn't happen.
 
+  ....
+  Block spliting might work - it doesn't crash at least.
+  But
+  After deleting all files, the tree is full of stuff.
+  Lots of inode data/InoIdx blocks.
+  Many but not all a Pinned.  The others are OnFree
+  The Pinned ones have outstanding references.
+  Others
+
+  ....
+  Problem with the block splitting, when adding an index block.
+  The index block is initially empty - we need to find things by looking
+  at children.  But we don't.  We BUG_ON the iphys==0.
+  In general, when we add a block below and index block and before we incorporate,
+  the block must be found by finding the first indexed block and looking to
+  see if there is a 'next' block that contains the address we need.
+  FIXED
+
+  But if we truncate a file while an index block is pinned and dirty,
+  we spin on trying to incorporate it, which should make it empty.
+
 --------------------------------------------------
 I don't remember what this is about.....
 CLEANABLE: 0/5 y=32777 u=7
diff --git a/block.c b/block.c
index 43b09823c909d18e5bd0204669cdddd1050d56ee..7606850c13ec62d023960f0ea2804da14a3eba5d 100644 (file)
--- a/block.c
+++ b/block.c
@@ -276,6 +276,9 @@ lafs_reserve_block(struct block *b, int alloc_type)
        int err = 0;
        struct fs *fs = fs_from_inode(b->inode);
 
+       if (!test_bit(B_PhysValid, &b->flags))
+               b->physaddr = 0;
+
        if (test_bit(B_Index, &b->flags))
                BUG_ON(b->parent == NULL && !test_bit(B_Root, &b->flags));
        else
@@ -422,7 +425,7 @@ lafs_erase_dblock(struct datablock *b)
        if (!b->b.parent) {
                printk("erase with no parent: %s\n", strblk(&b->b));
        }
-       printk("Eraseblock for %s\n", strblk(&b->b));
+       dprintk("Eraseblock for %s\n", strblk(&b->b));
        if (b->b.physaddr == 0 &&
            b->b.fileaddr == 0 &&
            LAFSI(b->b.inode)->depth == 0) {
index 5d8ea85c31b4151543f520dce6786fde0939a587..b55a0b62f8cc748b5d186306634b67b888afea7b 100644 (file)
@@ -57,7 +57,7 @@ char *strflags(struct block *b)
 {
        static char ans[200];
        ans[0] = 0;
-       if (test_bit(B_Index, &b->flags)) strcat(ans, "Index,");
+       if (test_bit(B_Index, &b->flags)) sprintf(ans, "Index(%d),", iblk(b)->depth);
        if (test_bit(B_Alloc, &b->flags)) strcat(ans, "Alloc,");
        if (test_bit(B_Pinned, &b->flags)) {
                strcat(ans, "Pinned,");
@@ -157,6 +157,7 @@ static int print_tree(struct block *b, int depth)
        int j;
        struct block *b2;
        int credits = 0;
+
        if (depth > 20) { printk("... aborting at %d\n", depth); BUG();return 0;}
 
        printk("%*s", depth, "");
@@ -231,6 +232,7 @@ extern struct freelists {
 
        if (test_bit(B_Index, &b->flags)) {
                list_for_each_entry(b, &ib->children, siblings) {
+                       BUG_ON(b->parent != ib);
                        credits += print_tree(b, depth+2);
                }
        } else if (LAFSI(b->inode)->type == TypeInodeFile &&
@@ -311,7 +313,7 @@ static void do_checkpoint(void *data)
 dprintk("Block %d/%d idx=%d\n", (int)b->inode->i_ino, (int)b->fileaddr,
        test_bit(B_Index, &b->flags));
 
-//printk("(");
+dprintk("(");
                if (!test_bit(B_Pinned, &b->flags))
                        /* Haven't refiled since we cleared that */ ;
                else if (!!test_bit(B_Phase1, &b->flags) == oldphase) {
@@ -347,13 +349,14 @@ dprintk("flip\n");
                        WARN_ON(1);
                        /* FIXME is this possible? */
                }
-//printk(")");
+dprintk(")");
                putref(b);
 //             lafs_dump_tree();
                if (list_empty(&fs->phase_leafs[oldphase])) {
                        void lafs_cluster_wait_all(struct fs *fs);
                        lafs_cluster_flush(fs, 0);
                        lafs_cluster_wait_all(fs);
+       lafs_clusters_done(fs);
                }
                cnt++;
 #if 0
diff --git a/clean.c b/clean.c
index 749969ab4ba6c8bca5982362e592a0ac3b70c452..486998ac9b0380f9807a0ec98d9826e81875364a 100644 (file)
--- a/clean.c
+++ b/clean.c
@@ -392,7 +392,7 @@ static int try_clean(struct fs *fs, struct toclean *tc)
                         */
                        int err = PTR_ERR(ino);
                        ino = NULL;
-               //printk("iget gives error %d\n", err);
+                       dprintk("iget gives error %d\n", err);
                        if (err != -EAGAIN) {
                                /* inode not found */
                                tc->desc++;
index e3bd33c7b0fd62684da1b214e5cf6157d3b37f8c..ebb7e8948fb4dacc0f52f08aef7141f221a3d83f 100644 (file)
--- a/cluster.c
+++ b/cluster.c
@@ -1286,17 +1286,15 @@ void lafs_cluster_wait_all(struct fs *fs)
  * of 4 depending on which in the circular list the
  * block is for.
  */
-static int cluster_end_io(struct bio *bio, unsigned int len, int err,
+static void cluster_end_io(struct bio *bio, int err,
                   int which, int header)
 {
        /* FIXME how to handle errors? */
        struct wc *wc = bio->bi_private;
        int wake = 0;
 
-       dprintk("end_io len=%d err=%d which=%d header=%d\n",
-              len, err, which, header);
-       if (bio->bi_size)
-               return 1;
+       dprintk("end_io err=%d which=%d header=%d\n",
+              err, which, header);
 
        if (atomic_dec_and_test(&wc->pending_cnt[which]))
                wake++;
@@ -1317,40 +1315,39 @@ static int cluster_end_io(struct bio *bio, unsigned int len, int err,
                schedule_work(&fs->done_work);
                wake_up(&wc->pending_wait);
        }
-       return 0;
 }
-static int cluster_endio_data_0(struct bio *bio, unsigned int len, int err)
+static void cluster_endio_data_0(struct bio *bio, int err)
 {
-       return cluster_end_io(bio, len, err, 0, 0);
+       cluster_end_io(bio, err, 0, 0);
 }
-static int cluster_endio_data_1(struct bio *bio, unsigned int len, int err)
+static void cluster_endio_data_1(struct bio *bio, int err)
 {
-       return cluster_end_io(bio, len, err, 1, 0);
+       cluster_end_io(bio, err, 1, 0);
 }
-static int cluster_endio_data_2(struct bio *bio, unsigned int len, int err)
+static void cluster_endio_data_2(struct bio *bio, int err)
 {
-       return cluster_end_io(bio, len, err, 2, 0);
+       cluster_end_io(bio, err, 2, 0);
 }
-static int cluster_endio_data_3(struct bio *bio, unsigned int len, int err)
+static void cluster_endio_data_3(struct bio *bio, int err)
 {
-       return cluster_end_io(bio, len, err, 3, 0);
+       cluster_end_io(bio, err, 3, 0);
 }
 
-static int cluster_endio_header_0(struct bio *bio, unsigned int len, int err)
+static void cluster_endio_header_0(struct bio *bio, int err)
 {
-       return cluster_end_io(bio, len, err, 0, 1);
+        cluster_end_io(bio, err, 0, 1);
 }
-static int cluster_endio_header_1(struct bio *bio, unsigned int len, int err)
+static void cluster_endio_header_1(struct bio *bio, int err)
 {
-       return cluster_end_io(bio, len, err, 1, 1);
+       cluster_end_io(bio, err, 1, 1);
 }
-static int cluster_endio_header_2(struct bio *bio, unsigned int len, int err)
+static void cluster_endio_header_2(struct bio *bio, int err)
 {
-       return cluster_end_io(bio, len, err, 2, 1);
+       cluster_end_io(bio, err, 2, 1);
 }
-static int cluster_endio_header_3(struct bio *bio, unsigned int len, int err)
+static void cluster_endio_header_3(struct bio *bio, int err)
 {
-       return cluster_end_io(bio, len, err, 3, 1);
+       cluster_end_io(bio, err, 3, 1);
 }
 
 bio_end_io_t *lafs_cluster_endio_choose(int which, int header)
diff --git a/file.c b/file.c
index c33ad64f03aea76028d4b14fdcca55299c3993c9..505d615b1186ab8d786778c4169accf13ed7c8c1 100644 (file)
--- a/file.c
+++ b/file.c
@@ -222,11 +222,20 @@ static void lafs_sync_page(struct page *page)
        /* If any block is dirty, flush the cluster so that
         * writeback completes.
         */
-       struct inode *ino = page->mapping->host;
-       struct fs *fs = fs_from_inode(ino);
-       int bits = PAGE_SHIFT - ino->i_blkbits;
-       int i;
+       struct inode *ino;
+       struct address_space *mapping;
+       struct fs *fs;
+       int bits;
+//     int i;
 
+       mapping = page->mapping;
+       if (!mapping)
+               return;
+       ino = mapping->host;
+       fs = fs_from_inode(ino);
+       bits = PAGE_SHIFT - ino->i_blkbits;
+
+#if 0
        for (i=0; i < (1<<bits); i++) {
                struct datablock *b = lafs_get_block(ino, i, page, 
                                                     GFP_KERNEL);
@@ -245,6 +254,10 @@ static void lafs_sync_page(struct page *page)
                }
                putdref(b);
        }
+#else
+       if (!lafs_cluster_empty(fs, 0))
+               lafs_cluster_flush(fs, 0);
+#endif
 }
 
 struct file_operations lafs_file_file_operations = {
diff --git a/index.c b/index.c
index e1ac397c596eb38b44e3b17008e7741bbdc083ad..785c32be1a4eaa72d62ccf46aaec76666fee82a0 100644 (file)
--- a/index.c
+++ b/index.c
@@ -227,6 +227,7 @@ iblock_get(struct inode *ino, faddr_t addr, int depth, paddr_t phys)
        new->b.inode = ino;
        new->depth = depth;
        new->b.physaddr = phys;
+       set_bit(B_PhysValid, &new->b.flags);
 
        ib = ihash_lookup(ino, addr, depth, new);
        if (ib != new)
@@ -750,6 +751,13 @@ void lafs_refile(struct block *b, int dec)
                                b->parent = NULL;
                                spin_lock(&b->inode->i_mapping->private_lock);
                                list_del_init(&b->siblings);
+                               if (test_bit(B_InoIdx, &b->flags) && 0 &&
+                                   !test_bit(B_Root, &b->flags) &&
+                                   LAFSI(b->inode)->iblock == iblk(b)) {
+                                       LAFSI(b->inode)->iblock = NULL;
+                                       BUG_ON(LAFSI(b->inode)->dblock->b.parent != iblk(next));
+                                       next = &LAFSI(b->inode)->dblock->b;
+                               }
                                spin_unlock(&b->inode->i_mapping->private_lock);
                                if (test_bit(B_Index, &b->flags)) {
 //printk("7a");
@@ -769,7 +777,8 @@ void lafs_refile(struct block *b, int dec)
                                if (test_and_clear_bit(B_NICredit, &b->flags))
                                        credits++;
                                lafs_space_return(fs, credits);
-                               if (b->inode->i_ino == 0 && b->fileaddr == 0) printk("E Dropped credit for %s\n", strblk(b));         
+                               if (b->inode->i_ino == 0 && b->fileaddr == 0)
+                                       printk("E Dropped credit for %s\n", strblk(b));       
                        }
                        if (test_bit(B_Index, &b->flags) &&
                            !test_bit(B_Pinned, &b->flags)) {
@@ -798,6 +807,7 @@ void lafs_refile(struct block *b, int dec)
                if (free_me)
                        kfree(b);
                if (next) {
+                       BUG_ON(dnext);
                        b = next;
                        next = NULL;
                } else {
@@ -832,6 +842,8 @@ lafs_make_iblock(struct inode *ino, int adopt, int async)
        struct fs *fs = fs_from_inode(ino);
        int err = 0;
 
+       dprintk("MAKE_IBLOCK %d\n", (int)ino->i_ino);
+
        BUG_ON(lai->dblock == NULL);
        BUG_ON(atomic_read(&lai->dblock->b.refcnt) == 0);
  retry:
@@ -870,6 +882,7 @@ lafs_make_iblock(struct inode *ino, int adopt, int async)
 
        new->b.fileaddr = 0;
        new->b.physaddr = lai->dblock->b.physaddr;
+       set_bit(B_PhysValid, &new->b.flags);
        new->b.inode = ino;
        new->depth = lai->depth;
        /* Note: this doesn't get hashed until the index
@@ -1087,6 +1100,7 @@ lafs_leaf_find(struct inode *inode, u32 addr, int adopt, u32 *next, int async)
         * find the appropriate index, find the relevant index block,
         * load it, and see what's there...
         */
+       dprintk("LEAF FIND %d %d\n", (int)inode->i_ino, (int)li->depth);
        depth = li->depth - 1;
        buf = map_dblock(li->dblock);
        iphys = index_lookup(buf + li->metadata_size,
@@ -1095,20 +1109,23 @@ lafs_leaf_find(struct inode *inode, u32 addr, int adopt, u32 *next, int async)
                             &iaddr, next);
        unmap_dblock(li->dblock, buf);
 
-       /* FIXME if there is corruption, iphys could be zero which will
-        * cause problems soon.
-        * Actually, this could happen during truncate if indexes are
-        * incorporated quickly??? But we should never look for
-        * one of those blocks, should we?
+
+       /* If the index block hasn't been incorporated yet,
+        * then we might have found an iaddr before the one we
+        * really want, or even iaddr and iphys might be 0 if
+        * this is a new index block that is totally unincorporated.
         */
-       BUG_ON(iphys==0);
 
        ib = iblock_get(inode, iaddr, depth, iphys);
        dprintk("lafs_leaf_find: first block at %llu\n",
                (unsigned long long) iphys);
 
-       if (!ib)
-               return ERR_PTR(-ENOMEM);
+       if (!ib) {
+               if (iphys)
+                       return ERR_PTR(-ENOMEM);
+               /* li is empty, but child is no longer around!! */
+               BUG();
+       }
 
        if (! test_bit(B_Linked, &ib->b.flags)) {
                /* need to check for peers */
@@ -1500,6 +1517,7 @@ find_block(struct datablock *b, int adopt, int async)
                b->b.physaddr = leaf_lookup(buf+offset,
                                            b->b.inode->i_sb->s_blocksize - offset,
                                            ib->b.fileaddr, b->b.fileaddr, NULL);
+               set_bit(B_PhysValid, &b->b.flags);
                unmap_iblock(ib, buf);
        }
        dprintk("lafs_find_block: lookup for %lu of %lu at %lu found %llu\n",
@@ -1560,7 +1578,7 @@ int lafs_allocated_block(struct fs *fs, struct block *blk, u64 phys)
               !test_bit(B_Realloc, &blk->flags) &&
                phys != 0)
                printk("something missing %s\n", strblk(blk));
-       BUG_ON(!test_bit(B_UnincCredit, &blk->flags));
+//     BUG_ON(!test_bit(B_UnincCredit, &blk->flags));
        BUG_ON(!test_bit(B_Dirty, &blk->flags) &&
               !test_bit(B_Realloc, &blk->flags) &&
                phys != 0);
@@ -1576,6 +1594,7 @@ int lafs_allocated_block(struct fs *fs, struct block *blk, u64 phys)
                                break;
                BUG_ON(i == fs->maxsnapshot);
                blk->physaddr = phys; /* superblock doesn't get counted in summaries */
+               set_bit(B_PhysValid, &blk->flags);
                fs->ss[i].root_addr = phys;
                lai = LAFSI(blk->inode);
                if (i == 0 && lai->md.fs.usagetable > 1)
@@ -1624,10 +1643,13 @@ int lafs_allocated_block(struct fs *fs, struct block *blk, u64 phys)
        clear_bit(B_Prealloc, &blk->flags);
 
        blk->physaddr = phys;
+       set_bit(B_PhysValid, &blk->flags);
 
        if (test_bit(B_Dirty, &blk->flags) || phys == 0) {
-               if (!test_bit(B_Dirty, &p->b.flags) && !test_bit(B_Credit, &p->b.flags))
+               if (!test_bit(B_Dirty, &p->b.flags) && !test_bit(B_Credit, &p->b.flags)) {
                        printk("Oh dear: %s\n", strblk(blk));
+                       printk(".......: %s\n", strblk(&p->b));
+               }
                lafs_dirty_iblock(p);
        } else {
                if (!test_and_set_bit(B_Realloc, &p->b.flags)) {
@@ -1636,7 +1658,8 @@ int lafs_allocated_block(struct fs *fs, struct block *blk, u64 phys)
                                printk(" for %s\n", strblk(blk));
                                BUG();
                        }
-               else if (p->b.inode->i_ino == 0 && p->b.fileaddr == 0) printk("F Dropped credit for %s\n", strblk(&p->b));            
+                       else if (p->b.inode->i_ino == 0 && p->b.fileaddr == 0)
+                               printk("F Dropped credit for %s\n", strblk(&p->b));           
                }
                if (!test_and_set_bit(B_UnincCredit, &p->b.flags))
                        if (!test_and_clear_bit(B_ICredit, &p->b.flags))
diff --git a/inode.c b/inode.c
index f40763457f96e3c5e117330e16b881d771112dc6..a6b8c3971c2c181bf9420b3e041c393c67ef43c3 100644 (file)
--- a/inode.c
+++ b/inode.c
@@ -405,7 +405,7 @@ void lafs_inode_init(struct datablock *b, int type, int mode, struct inode *dir)
 void lafs_clear_inode(struct inode *ino)
 {
        struct lafs_inode *li = LAFSI(ino);
-       dprintk("CLEAR INODE\n");
+       dprintk("CLEAR INODE %d\n", (int)ino->i_ino);
 
        li->type = 0;
 
@@ -420,7 +420,7 @@ void lafs_delete_inode(struct inode *ino)
 {
        struct fs *fs = fs_from_inode(ino);
        struct datablock *b;
-       dprintk("DELETE INODE\n");
+       dprintk("DELETE INODE %d\n",(int)ino->i_ino);
 
        if (ino->i_mode == 0) {
                /* There never was an inode here,
@@ -542,6 +542,8 @@ static int lafs_inode_handle_orphan(struct datablock *b)
                 * let it.
                 */
 
+               /* FIXME I need some sort of lock to safely walk
+                * down this list */
                while (!list_empty(&ib->children) && !fs->checkpointing) {
                        ib2 = ib;
                        while (ib2->depth > 1 && !list_empty(&ib2->children)) {
@@ -555,8 +557,16 @@ static int lafs_inode_handle_orphan(struct datablock *b)
                         */
                        getiref(ib2);
                        lafs_incorporate_loop(fs, ib2);
+                       /* FIXME should the be implicit in lafs_incorporate_loop,
+                        */
+                       lafs_erase_iblock(ib2);
                        putiref(ib2);
                        printk(".");
+                       if (!list_empty(&ib2->b.siblings)) {
+                               printk("looping on %s %s\n", strblk(&ib2->b),
+                                      list_empty(&ib2->children)?"empty":"Full");
+                               BUG();
+                       }
                }
                if (fs->checkpointing)
                        return 2; /* means "Try again after the checkpoint" */
diff --git a/io.c b/io.c
index f655f20507540a725cfad1c5be137951ba75b4c6..369c49381494bbd243fbc9ede037a19238fe9dc9 100644 (file)
--- a/io.c
+++ b/io.c
@@ -41,14 +41,9 @@ lafs_dev_find(struct fs *fs, u64 virt)
        return -1;
 }
 
-static int
-bi_complete(struct bio *bio, unsigned int bytes_done, int error)
+static void bi_complete(struct bio *bio, int error)
 {
-       if (bio->bi_size)
-               return 1;
-
        complete((struct completion*)bio->bi_private);
-       return 0;
 }
 
 int
@@ -96,12 +91,10 @@ lafs_load_page(struct fs *fs, struct page *p, u64 vaddr, int blocks)
 }
 
 
-static int
-bi_async_complete(struct bio *bio, unsigned int bytes_done, int error)
+static void
+bi_async_complete(struct bio *bio, int error)
 {
        struct async_complete *ac = bio->bi_private;
-       if (bio->bi_size)
-               return 1;
 
        if (test_bit(BIO_UPTODATE, &bio->bi_flags))
                ac->state = 3;  
@@ -109,7 +102,6 @@ bi_async_complete(struct bio *bio, unsigned int bytes_done, int error)
                ac->state = 4;
        bio_put(bio);
        lafs_wake_cleaner(ac->fs);
-       return 0;
 }
 
 static void
@@ -158,17 +150,15 @@ lafs_load_page_async(struct fs *fs, struct page *p, u64 vaddr,
        return -EAGAIN;
 }
 
-static int
-bi_write_done(struct bio *bio, unsigned int bytes_done, int error)
+static void
+bi_write_done(struct bio *bio, int error)
 {
        struct fs *fs = bio->bi_private;
-       if (bio->bi_size)
-               return 1;
+
        if (atomic_dec_and_test(&fs->sb_writes_pending))
                wake_up(&fs->sb_writes_wait);
        bio_put(bio);
        /* FIXME didn't do anything with error */
-       return 0;
 }
 
 void
@@ -297,12 +287,10 @@ lafs_wait_block_async(struct block *b)
 }
 
 
-static int
-block_loaded(struct bio *bio, unsigned int bytes_done, int error)
+static void
+block_loaded(struct bio *bio, int error)
 {
        struct block *b = bio->bi_private;
-       if (bio->bi_size)
-               return 1;
 
        dprintk("loaded %d of %d\n", (int)b->fileaddr, (int)b->inode->i_ino);
        if (test_bit(BIO_UPTODATE, &bio->bi_flags)) {
@@ -313,15 +301,12 @@ block_loaded(struct bio *bio, unsigned int bytes_done, int error)
        } else dprintk("Block with no page!!\n");
 /* FIXME signal error for index block */
        lafs_iounlock_block(b, B_IOLock);
-       return 0;
 }
 
-static int
-block_loaded_nounlock(struct bio *bio, unsigned int bytes_done, int error)
+static void
+block_loaded_nounlock(struct bio *bio, int error)
 {
        struct block *b = bio->bi_private;
-       if (bio->bi_size)
-               return 1;
 
        dprintk("loaded %d of %d\n", (int)b->fileaddr, (int)b->inode->i_ino);
        if (test_bit(BIO_UPTODATE, &bio->bi_flags)) {
@@ -332,7 +317,6 @@ block_loaded_nounlock(struct bio *bio, unsigned int bytes_done, int error)
        } else dprintk("Block with no page!!\n");
 
        lafs_iounlock_block(b, 0);
-       return 0;
 }
 
 int __must_check
@@ -346,6 +330,8 @@ lafs_load_block(struct block *b, int unlock)
        struct page *page;
        int offset;
 
+       if (!test_bit(B_PhysValid, &b->flags))
+               b->physaddr = 0;
        if (test_bit(B_Valid, &b->flags))
                return 0;
        lafs_iolock_block(b);
@@ -356,6 +342,7 @@ lafs_load_block(struct block *b, int unlock)
        if (test_bit(B_Index, &b->flags)) {
                struct indexblock *ib = iblk(b);
                if (b->physaddr == 0) {
+                       BUG();
                        /* I think this is really an error FIXME */
                        memset(ib->data, 0, b->inode->i_sb->s_blocksize);
                        lafs_iounlock_block(b, unlock ? B_IOLock : 0);
diff --git a/lafs.h b/lafs.h
index c8b2094187afa92f956b8e27828a856ccc1282c7..a3f9d22cb570630ef3c0c294fac321a6d6d23249 100644 (file)
--- a/lafs.h
+++ b/lafs.h
@@ -280,6 +280,7 @@ static inline int set_phase(struct block *b, int ph)
  */
 void lafs_refile(struct block *b, int dec);
 
+extern spinlock_t lafs_hash_lock;
 static inline struct block *getref(struct block *b)
 {
        if (atomic_read(&b->refcnt) == 0) {
@@ -287,6 +288,8 @@ static inline struct block *getref(struct block *b)
                if (test_bit(B_Index, &b->flags)) {
                        if (spin_is_locked(&b->inode->i_data.private_lock))
                                ok = 1;
+                       if (spin_is_locked(&lafs_hash_lock))
+                               ok = 1;
                        // FIXME more tests - just when is this allowed?
                } else {
                        struct datablock *db = dblk(b);
index 2accea5ca801047493dd88dd56c2fcf00b4fcb15..469bc78e9267402fa35f6e21c09a2284ded19d65 100644 (file)
--- a/modify.c
+++ b/modify.c
@@ -172,10 +172,11 @@ static int incorporate_index(struct uninc *ui, char *buf, int size)
                phys = decode48(b);
                if (phys != 0)
                        break;
+               icnt--;
        }
        u=0; i=0;
        ncnt = 0;
-       BUG_ON(ucnt == 0 || icnt == 0);
+       BUG_ON(ucnt == 0);
        uaddr = ui->pending_addr[0].fileaddr;
        b = buf + 6;
        iaddr = decode32(b);
@@ -191,7 +192,7 @@ static int incorporate_index(struct uninc *ui, char *buf, int size)
                        iaddr = decode32(b);
                } else
                        iaddr = 0xffffffff;
-                       
+
                if (uaddr == iaddr) {
                        /* replacement */
                        if (ui->pending_addr[u].physaddr)
@@ -1126,7 +1127,7 @@ static int do_incorporate(struct fs *fs, struct indexblock *ib,
 void lafs_incorporate(struct fs *fs, struct indexblock *ib)
 {
        int offset;     /* start of block where indexing is */
-       struct indexblock *new = NULL, *tofree = NULL;
+       struct indexblock *new = NULL;
        int rv;
        char *buf;
        struct uninc uit, *spareui, **uip;
@@ -1218,6 +1219,7 @@ void lafs_incorporate(struct fs *fs, struct indexblock *ib)
                /* There is nothing in this block any more.
                 * If it is an inode, clear it, else punch a hole
                 */
+               printk("incorp to empty off=%d %s\n", (int)offset, strblk(&ib->b));
                lafs_iblock_free(new);
                if (offset) {
                        buf = map_iblock(ib);
@@ -1260,10 +1262,8 @@ void lafs_incorporate(struct fs *fs, struct indexblock *ib)
                set_bit(B_ICredit, &new->b.flags);
 
                lafs_dirty_iblock(new); // or Realloc?? FIXME
-               ib = new;
-               if (tofree)
-                       putiref(tofree);
-               tofree = new;
+               printk("Just Grew %s\n", strblk(&new->b));
+               putiref(new);
 
                goto retry;
        }
@@ -1272,8 +1272,6 @@ void lafs_incorporate(struct fs *fs, struct indexblock *ib)
        //printk("Done Incorp %s\n", strblk(&ib->b));
        lafs_space_return(fs, uit.credits);
        kfree(spareui);
-       if (tofree)
-               putiref(tofree);
 }
 
 void lafs_incorporate_loop(struct fs *fs, struct indexblock *ib)
index 4b8c8f49d9754ed00574e4b87ef669dbb53707c4..e9ebb8ca09c93f06dccfd48686b3ae0a0bbba8c6 100644 (file)
--- a/orphan.c
+++ b/orphan.c
@@ -242,7 +242,7 @@ void lafs_orphan_release(struct fs *fs, struct datablock *b)
        struct datablock *ob1, *ob2;
        int shift = b->b.inode->i_blkbits - 4;
        struct orphan_md *om = &LAFSI(fs->orphans)->md.orphan;
-       struct orphan *or, *lastor;
+       struct orphan *or, *lastor, last;
        int ent, lastent;
        u32 bnum;
 
@@ -279,27 +279,30 @@ void lafs_orphan_release(struct fs *fs, struct datablock *b)
                lastor = map_dblock_2(ob2);
                lastent = (om->nextfree-1) & ((1<<shift)-1);
                dprintk("lastor=%p lastent=%d\n", lastor, lastent);
+               last = lastor[lastent];
+               lastor[lastent].type = 0;
+               unmap_dblock_2(ob2, lastor);
 
                /* FIXME these should not create the block if it doesn't exist */
-               bfs = lafs_get_block(fs->ss[0].root, le32_to_cpu(lastor[lastent].filesys),
+               bfs = lafs_get_block(fs->ss[0].root, le32_to_cpu(last.filesys),
                                     NULL, GFP_KERNEL);
                if (bfs && bfs->my_inode)
                        bi = lafs_get_block(bfs->my_inode,
-                                           le32_to_cpu(lastor[lastent].inum),
+                                           le32_to_cpu(last.inum),
                                            NULL, GFP_KERNEL);
                else bi = NULL;
                putdref(bfs);
                if (bi && bi->my_inode)
                        bbl = lafs_get_block(bi->my_inode,
-                                            le32_to_cpu(lastor[lastent].addr),
+                                            le32_to_cpu(last.addr),
                                             NULL, GFP_KERNEL);
                else bbl = NULL;
                putdref(bi);
                dprintk("O bfs=%p(%p) bi=%p bbl=%p lastent=%d fs=%d in=%d a=%d\n",
                       bfs, bfs->my_inode, bi, bbl, lastent, 
-                      le32_to_cpu(lastor[lastent].filesys),
-                      le32_to_cpu(lastor[lastent].inum),
-                      le32_to_cpu(lastor[lastent].addr)
+                      le32_to_cpu(last.filesys),
+                      le32_to_cpu(last.inum),
+                      le32_to_cpu(last.addr)
                       );
                if (!bbl) {
                        putdref(ob2);
@@ -311,13 +314,11 @@ void lafs_orphan_release(struct fs *fs, struct datablock *b)
                BUG_ON(bbl->orphan_slot != om->nextfree-1);
 
                or = map_dblock(ob1);
-               or[ent] = lastor[lastent];
+               or[ent] = last;
                bbl->orphan_slot = b->orphan_slot;
                putdref(bbl);
-               lastor[lastent].type = 0;
                lafs_dirty_dblock(ob1);
                lafs_dirty_dblock(ob2);
-               unmap_dblock_2(ob2, lastor);
                unmap_dblock(ob1, or);
 
                putdref(ob1); /* no longer hold a reservation reference
diff --git a/roll.c b/roll.c
index f59b9afd43c1490d1568cbfbe85ea9e22461022c..a38c7c64bb01dda8edcc1f8b61a7de64ce7f27de 100644 (file)
--- a/roll.c
+++ b/roll.c
@@ -634,6 +634,7 @@ lafs_mount(struct fs *fs)
                return -ENOMEM;
        set_bit(B_Root, &b->b.flags);
        b->b.physaddr = fs->ss[0].root_addr;
+       set_bit(B_PhysValid, &b->b.flags);
        err = lafs_load_block(&b->b, 0);
 //printk("2 %d\n", err);
        if (err)
index 22fa9b0642ae8f09279daf6ee705c8578996e008..2b7f38d02b0b0f57e8c1c43c210a3166d6847410 100644 (file)
@@ -94,7 +94,7 @@ lafs_snap_get_sb(struct file_system_type *fstype,
                put_page(p);
                return err;
        }
-       sb = nd.dentry->d_sb;
+       sb = nd.path.dentry->d_sb;
        err = -EINVAL;
        if (sb->s_type != &lafs_fs_type)
                goto fail;
@@ -131,6 +131,7 @@ lafs_snap_get_sb(struct file_system_type *fstype,
                fs->ss[s].root = iget_locked(sb, 1);
                b = lafs_get_block(fs->ss[s].root, 0, NULL, GFP_KERNEL);
                b->b.physaddr = fs->ss[s].root_addr;
+               set_bit(B_PhysValid, &b->b.flags);
                BUG_ON(test_bit(B_Valid, &b->b.flags));
                printk("ss root at %llu\n", b->b.physaddr);
                err = lafs_load_block(&b->b, 0);
@@ -155,7 +156,7 @@ lafs_snap_get_sb(struct file_system_type *fstype,
                        goto fail;
                }
                up_write(&fs->prime_sb->s_umount);
-               path_release(&nd);
+               path_put(&nd.path);
                put_page(p);
                simple_set_mnt(mnt, sb);
                return 0;
@@ -164,7 +165,7 @@ lafs_snap_get_sb(struct file_system_type *fstype,
 
  fail:
        put_page(p);
-       path_release(&nd);
+       path_put(&nd.path);
        return err;
 }
 
index 98f65dea8f2933d6554af987703a3b35bbd34903..8a56d7f81efacf544e48e6151a16fe6b5af74cff 100644 (file)
--- a/summary.c
+++ b/summary.c
@@ -80,7 +80,7 @@ int lafs_summary_allocate(struct fs *fs, struct inode *ino, int diff)
        struct lafs_inode *lai = LAFSI(ino);
        lai = LAFSI(lai->filesys);
        spin_lock(&lai->vfs_inode.i_lock);
-       printk("LSA: %d -> ", (int)lai->md.fs.ablocks_used);
+//     printk("LSA: %d -> ", (int)lai->md.fs.ablocks_used);
        if (lai->md.fs.blocks_allowed &&
            diff > 0 &&
            lai->md.fs.cblocks_used +
@@ -91,7 +91,7 @@ int lafs_summary_allocate(struct fs *fs, struct inode *ino, int diff)
        else
                lai->md.fs.ablocks_used += diff;
 
-       printk(" %d\n", (int)lai->md.fs.ablocks_used);
+//     printk(" %d\n", (int)lai->md.fs.ablocks_used);
        spin_unlock(&lai->vfs_inode.i_lock);
        if (err)
                return err;
diff --git a/test/go b/test/go
index 6504d6de21ddc7ab9298ff2c73331ddaf249959e..586aea32bb5b42692f41dace7ed0ebd904f24adb 100644 (file)
--- a/test/go
+++ b/test/go
@@ -138,6 +138,7 @@ ls -li big1
 echo 0 > /sys/module/lafs/parameters/lafs_trace
 echo cleanable > /sys/module/lafs/parameters/dump
 echo usage > /sys/module/lafs/parameters/dump
+echo 1 > /sys/module/lafs/parameters/lafs_trace
 sync
 sleep 3
 ls -fi /mnt/1/adir
index c37331c4122f8b4342f33dccc3aa9636b5bdaffc..8cdf5bc0e460d9133f9def0c343985c701fa11d9 100644 (file)
@@ -14,5 +14,5 @@ ln -s $dir /tmp/tftp
 qemu -hda hda -hdb $dir/../../code2/fred -hdc $dir/../../code2/frog \
   -net nic,model=ne2k_pci -net user \
   -m 256 -serial stdio \
-  -kernel /home/src/lafs-2.6.23/arch/i386/boot/bzImage \
+  -kernel /home/src/lafs-2.6.27/arch/i386/boot/bzImage \
   -append "root=/dev/hda1 console=ttyS0" -tftp /tmp/tftp