From: NeilBrown Date: Sat, 14 Aug 2010 10:52:11 +0000 (+1000) Subject: Allow cleaner_parse to request multiple inodes at once. X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=675395c9f03984e9bfe1cee45fcb200243d06f76;p=LaFS.git Allow cleaner_parse to request multiple inodes at once. Currently cleaner_parse stops when it hits an inode that it cannot load immediately. This reduced the opportunities for parallelism. Instream allow up to 16 -EAGAINs from inode lookups. This requires that we mark headers for inodes which failed, and always start again from the beginning of the cluster head. We already reduce the bcnt to 0, so for inodes that can be found, we won't lookup the blocks twice. Signed-off-by: NeilBrown --- diff --git a/clean.c b/clean.c index f2a8a7f..f5f48bd 100644 --- a/clean.c +++ b/clean.c @@ -166,8 +166,6 @@ static void cleaner_load(struct fs *fs, struct toclean *tc) 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; @@ -186,9 +184,15 @@ static void cleaner_parse(struct fs *fs, struct toclean *tc) int bcnt; u32 inum, fsnum; struct inode *ino = NULL; - int again = 0; - while (tc->ch && again < 16) { + + /* Always start at the beginning - we invalidate entries + * that we have finished with + */ + tc->gh = tc->ch->groups; + tc->desc = tc->gh->u.desc; + + while (again < 16) { /* Load the index block for each described data or index block. * For data blocks, get the address and possibly load the * data block too. @@ -200,6 +204,9 @@ static void cleaner_parse(struct fs *fs, struct toclean *tc) >= le16_to_cpu(tc->ch->Hlength)) { /* Finished with that cluster, try another. */ u64 next; + if (again) + /* Need to come back later */ + break; next = le64_to_cpu(tc->ch->next_addr); if (next > tc->haddr && in_seg(fs, tc->dev, tc->seg, next)) { @@ -251,6 +258,11 @@ static void cleaner_parse(struct fs *fs, struct toclean *tc) inum = le32_to_cpu(tc->gh->inum); fsnum = le32_to_cpu(tc->gh->fsnum); + if (inum == 0xFFFFFFFF && + fsnum == 0xFFFFFFFF) { + tc->desc++; + continue; + } dprintk("Cleaner looking at %d/%d %d+%d (%d)\n", (int)fsnum, (int)inum, (int)bnum, (int)bcnt, (int)le16_to_cpu(tc->desc->block_bytes)); @@ -265,22 +277,7 @@ static void cleaner_parse(struct fs *fs, struct toclean *tc) iput(ino); ino = lafs_iget_fs(fs, fsnum, inum, ASYNC); } - if (IS_ERR(ino)) { - /* FIXME check that this is -EAGAIN - * FIXME should have lafs_iget_fs return the - * ino anyway, but lafs_find_block_async, - * doesn't try until ino is uptodate. - */ - int err = PTR_ERR(ino); - ino = NULL; - dprintk("iget gives error %d\n", err); - if (err != -EAGAIN) { - /* inode not found */ - tc->desc++; - continue; - } - break; - } else { + if (!IS_ERR(ino)) { struct datablock *b; dprintk("got the inode\n"); /* Minor optimisation for files that have shrunk */ @@ -329,6 +326,22 @@ static void cleaner_parse(struct fs *fs, struct toclean *tc) } } putdref(b, MKREF(cleaning)); + } else { + int err = PTR_ERR(ino); + ino = NULL; + dprintk("iget gives error %d\n", err); + if (err == -EAGAIN) { + again++; + tc->desc++; + continue; + } + /* inode not found, make sure we never + * look for it again + */ + tc->gh->inum = 0xFFFFFFFF; + tc->gh->fsnum = 0xFFFFFFFF; + tc->desc++; + continue; } skip: /* We modify the descriptor in-place to track where