When the LFSCK engine makes checkpoint, it will record the current
position (hash) of the iteration that can be used to resume the
LFSCK scanning from the latest checkpoint. But if someone removed
the target corresponding to the LFSCK checkpoint position, then
the LFSCK will start scanning from the 'next' position when try to
resume from the latest checkpoint. But if the 'next' hits the end
of the iteration, the lower layer (ldiskfs) will return "-ENODATA"
for dt_it_ops::load() call. The LFSCK engine needs to handle such
case properly to avoid reguarding it as failure.
Signed-off-by: Fan Yong <fan.yong@intel.com>
Change-Id: I5a6a46cf3eefbdc680780abcc3402860736d6e0a
Reviewed-on: https://review.whamcloud.com/24056
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Lai Siyao <lai.siyao@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
GOTO(out, rc = PTR_ERR(di));
rc = iops->load(env, di, cookie);
GOTO(out, rc = PTR_ERR(di));
rc = iops->load(env, di, cookie);
- if (rc == 0 || (rc > 0 && cookie > 0))
+ if (rc == -ENODATA)
+ rc = 1;
+ else if (rc == 0 || (rc > 0 && cookie > 0))
rc = iops->next(env, di);
else if (rc > 0)
rc = 0;
rc = iops->next(env, di);
else if (rc > 0)
rc = 0;
/* Init otable-based iterator. */
if (pos == NULL) {
rc = iops->load(env, lfsck->li_di_oit, 0);
/* Init otable-based iterator. */
if (pos == NULL) {
rc = iops->load(env, lfsck->li_di_oit, 0);
+ if (rc > 0 || unlikely(rc == -ENODATA)) {
lfsck->li_oit_over = 1;
rc = 0;
}
lfsck->li_oit_over = 1;
rc = 0;
}
}
rc = iops->load(env, lfsck->li_di_oit, pos->lp_oit_cookie);
}
rc = iops->load(env, lfsck->li_di_oit, pos->lp_oit_cookie);
- if (rc < 0)
- GOTO(out, rc);
- else if (rc > 0)
+ if (rc > 0 || unlikely(rc == -ENODATA))
+ else if (rc < 0)
+ GOTO(out, rc);
if (!lfsck->li_master || fid_is_zero(&pos->lp_dir_parent))
GOTO(out, rc = 0);
if (!lfsck->li_master || fid_is_zero(&pos->lp_dir_parent))
GOTO(out, rc = 0);