From: NeilBrown Date: Sat, 14 Aug 2010 10:34:45 +0000 (+1000) Subject: Refactor try_clean X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=e67be93c91a17879b45aee7a7a67a95355d93a0d;p=LaFS.git Refactor try_clean It is a very big function - change it to 3 moderate sized functions. Signed-off-by: NeilBrown --- diff --git a/clean.c b/clean.c index 7cff7c3..f2a8a7f 100644 --- a/clean.c +++ b/clean.c @@ -133,63 +133,61 @@ static void cleaner_flush(struct fs *fs) lafs_cluster_flush(fs, 1); } -static int try_clean(struct fs *fs, struct toclean *tc) +static void cleaner_load(struct fs *fs, struct toclean *tc) +{ + /* Need to read in the cluster header */ + int err; + err = lafs_load_page_async(fs, tc->chead, + tc->haddr, + (PAGE_SIZE / + fs->blocksize), + &tc->ac); + + BUG_ON(err && err != -EAGAIN && err != -EIO); + + if (err == -EAGAIN) + return; + if (err) + //printk("CLEANER got IO error !!\n"); + // FIXME adjust youth to so as not to touch this again + goto bad_header; + + tc->ch = page_address(tc->chead); + if (memcmp(tc->ch->idtag, "LaFSHead", 8) != 0) + goto bad_header; + if (memcmp(tc->ch->uuid, fs->state->uuid, 16) != 0) + goto bad_header; + if (tc->seq == 0) + tc->seq = le64_to_cpu(tc->ch->seq); + else { + tc->seq++; + if (tc->seq != le64_to_cpu(tc->ch->seq)) { + printk("Bad seq number\n"); + goto bad_header; + } + } + tc->gh = tc->ch->groups; + tc->desc = tc->gh->u.desc; + if (lafs_calc_cluster_csum(tc->ch) != tc->ch->checksum) { + //printk("Cluster header checksum is wrong!!\n"); + goto bad_header; + } + dprintk("try_clean: got header %d\n", (int)tc->haddr); + return; + +bad_header: + tc->ac.state = 0; + tc->have_addr = 0; +} + +static void cleaner_parse(struct fs *fs, struct toclean *tc) { - /* return 1 if everything has been found, -ve if we need to flush */ - int again = 0; u32 bnum; int bcnt; u32 inum, fsnum; struct inode *ino = NULL; - struct datablock *b, *tmp; - int rv = 0; - mutex_lock(&fs->cleaner.lock); - dprintk("try_clean: state = %d\n", tc->ac.state); - if (tc->ch == NULL && tc->have_addr) { - /* Need to read in the cluster header */ - int err; - err = lafs_load_page_async(fs, tc->chead, - tc->haddr, - (PAGE_SIZE / - fs->blocksize), - &tc->ac); - - rv = 0; - if (err == -EAGAIN) - goto out; - if (err == -EIO) { - //printk("CLEANER got IO error !!\n"); - // FIXME adjust youth to so as not to touch this again - bad_header: - tc->ac.state = 0; - tc->have_addr = 0; - rv = 0; - goto out; - } - BUG_ON(err); - tc->ch = page_address(tc->chead); - if (memcmp(tc->ch->idtag, "LaFSHead", 8) != 0) - goto bad_header; - if (memcmp(tc->ch->uuid, fs->state->uuid, 16) != 0) - goto bad_header; - if (tc->seq == 0) - tc->seq = le64_to_cpu(tc->ch->seq); - else { - tc->seq++; - if (tc->seq != le64_to_cpu(tc->ch->seq)) { - printk("Bad seq number\n"); - goto bad_header; - } - } - tc->gh = tc->ch->groups; - tc->desc = tc->gh->u.desc; - if (lafs_calc_cluster_csum(tc->ch) != tc->ch->checksum) { - //printk("Cluster header checksum is wrong!!\n"); - goto bad_header; - } - dprintk("try_clean: got header %d\n", (int)tc->haddr); - } + int again = 0; while (tc->ch && again < 16) { /* Load the index block for each described data or index block. * For data blocks, get the address and possibly load the @@ -283,6 +281,7 @@ static int try_clean(struct fs *fs, struct toclean *tc) } break; } else { + struct datablock *b; dprintk("got the inode\n"); /* Minor optimisation for files that have shrunk */ /* Actually this is critical for handling truncation @@ -341,6 +340,14 @@ static int try_clean(struct fs *fs, struct toclean *tc) } if (ino) iput(ino); +} + +static int cleaner_process(struct fs *fs, struct toclean *tc) +{ + struct datablock *b, *tmp; + int rv = 0; + struct inode *ino; + dprintk("start processing list\n"); list_for_each_entry_safe(b, tmp, &tc->cleaning, cleaning) { struct block *cb = NULL; @@ -400,11 +407,29 @@ static int try_clean(struct fs *fs, struct toclean *tc) iput(ino); putref(cb, MKREF(clean2)); if (rv) - goto out; + break; } - rv = tc->ch == NULL && !tc->have_addr && - list_empty(&tc->cleaning); -out: + return rv; +} + +static int try_clean(struct fs *fs, struct toclean *tc) +{ + /* return 1 if everything has been found, -ve if we need to flush */ + int rv = 0; + + mutex_lock(&fs->cleaner.lock); + dprintk("try_clean: state = %d\n", tc->ac.state); + if (tc->ch == NULL && tc->have_addr) + cleaner_load(fs, tc); + + if (tc->ch) + cleaner_parse(fs, tc); + + if (!list_empty(&tc->cleaning)) + rv = cleaner_process(fs, tc); + if (!rv) + rv = (tc->ch == NULL && !tc->have_addr && + list_empty(&tc->cleaning)); mutex_unlock(&fs->cleaner.lock); return rv; }