From 1e42682aeadb0f80dd6e9bfd45abe17221b698bf Mon Sep 17 00:00:00 2001 From: Fan Yong Date: Thu, 6 Oct 2016 17:06:05 +0800 Subject: [PATCH] LU-9040 scrub: handle group boundary properly If the last bit in current inode bitmap is set, then the osd_iit_param::offset will be set as the inode count of per group (LDISKFS_INODES_PER_GROUP). Unfortunately, the orignal logic for osd_inode_iteration() did not handle such boundary value properly, as to the iteration will scan current group again and again. Signed-off-by: Fan Yong Change-Id: Ie555838cd782a9378c6305485dd737b6bc6b2d46 Reviewed-on: https://review.whamcloud.com/25105 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Alex Zhuravlev Reviewed-by: Oleg Drokin --- lustre/osd-ldiskfs/osd_scrub.c | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/lustre/osd-ldiskfs/osd_scrub.c b/lustre/osd-ldiskfs/osd_scrub.c index b686063..0302222 100644 --- a/lustre/osd-ldiskfs/osd_scrub.c +++ b/lustre/osd-ldiskfs/osd_scrub.c @@ -1384,30 +1384,30 @@ full: pos = &ooc->ooc_pos_preload; count = &ooc->ooc_cached_items; } + + param.bg = (*pos - 1) / LDISKFS_INODES_PER_GROUP(param.sb); + param.offset = (*pos - 1) % LDISKFS_INODES_PER_GROUP(param.sb); + param.gbase = 1 + param.bg * LDISKFS_INODES_PER_GROUP(param.sb); limit = le32_to_cpu(LDISKFS_SB(param.sb)->s_es->s_inodes_count); while (*pos <= limit && *count < max) { - struct osd_idmap_cache *oic = NULL; struct ldiskfs_group_desc *desc; + bool next_group = false; - param.bg = (*pos - 1) / LDISKFS_INODES_PER_GROUP(param.sb); desc = ldiskfs_get_group_desc(param.sb, param.bg, NULL); - if (desc == NULL) + if (!desc) RETURN(-EIO); ldiskfs_lock_group(param.sb, param.bg); if (desc->bg_flags & cpu_to_le16(LDISKFS_BG_INODE_UNINIT)) { ldiskfs_unlock_group(param.sb, param.bg); - *pos = 1 + (param.bg + 1) * - LDISKFS_INODES_PER_GROUP(param.sb); - continue; + next_group = true; + goto next_group; } ldiskfs_unlock_group(param.sb, param.bg); - param.offset = (*pos - 1) % LDISKFS_INODES_PER_GROUP(param.sb); - param.gbase = 1 + param.bg * LDISKFS_INODES_PER_GROUP(param.sb); param.bitmap = ldiskfs_read_inode_bitmap(param.sb, param.bg); - if (param.bitmap == NULL) { + if (!param.bitmap) { CDEBUG(D_LFSCK, "%.16s: fail to read bitmap for %u, " "scrub will stop, urgent mode\n", osd_scrub2name(scrub), (__u32)param.bg); @@ -1416,17 +1416,19 @@ full: while (param.offset < LDISKFS_INODES_PER_GROUP(param.sb) && *count < max) { + struct osd_idmap_cache *oic = NULL; + if (param.offset + ldiskfs_itable_unused_count(param.sb, desc) > LDISKFS_INODES_PER_GROUP(param.sb)) { - *pos = 1 + (param.bg + 1) * - LDISKFS_INODES_PER_GROUP(param.sb); + next_group = true; goto next_group; } rc = next(info, dev, ¶m, &oic, noslot); switch (rc) { case SCRUB_NEXT_BREAK: + next_group = true; goto next_group; case SCRUB_NEXT_EXIT: brelse(param.bitmap); @@ -1447,7 +1449,18 @@ full: } next_group: - brelse(param.bitmap); + if (param.bitmap) { + brelse(param.bitmap); + param.bitmap = NULL; + } + + if (next_group) { + param.bg++; + param.offset = 0; + param.gbase = 1 + + param.bg * LDISKFS_INODES_PER_GROUP(param.sb); + *pos = param.gbase; + } } if (*pos > limit) -- 1.8.3.1