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 <fan.yong@intel.com>
Change-Id: Ie555838cd782a9378c6305485dd737b6bc6b2d46
Reviewed-on: https://review.whamcloud.com/25105
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
pos = &ooc->ooc_pos_preload;
count = &ooc->ooc_cached_items;
}
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) {
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;
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);
desc = ldiskfs_get_group_desc(param.sb, param.bg, NULL);
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);
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);
}
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);
param.bitmap = ldiskfs_read_inode_bitmap(param.sb, param.bg);
- if (param.bitmap == NULL) {
CDEBUG(D_LFSCK, "%.16s: fail to read bitmap for %u, "
"scrub will stop, urgent mode\n",
osd_scrub2name(scrub), (__u32)param.bg);
CDEBUG(D_LFSCK, "%.16s: fail to read bitmap for %u, "
"scrub will stop, urgent mode\n",
osd_scrub2name(scrub), (__u32)param.bg);
while (param.offset < LDISKFS_INODES_PER_GROUP(param.sb) &&
*count < max) {
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)) {
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);
goto next_group;
}
rc = next(info, dev, ¶m, &oic, noslot);
switch (rc) {
case SCRUB_NEXT_BREAK:
goto next_group;
}
rc = next(info, dev, ¶m, &oic, noslot);
switch (rc) {
case SCRUB_NEXT_BREAK:
goto next_group;
case SCRUB_NEXT_EXIT:
brelse(param.bitmap);
goto next_group;
case SCRUB_NEXT_EXIT:
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;
+ }