Multiple call of lprocfs_quota_seq_start could change the block
orders in the lower level of the quota tree, which will cause
quota entries to be skipped.
This patch also fix a problem in walk_tree_dqentry, which some
entries could be skipped for the "index" can be added even if
a valid quota entry has been found.
Change-Id: I44936c70d4060bd83db22aba0e3f665981cfa50a
Signed-off-by: Hongchao Zhang <hongchao.zhang@intel.com>
Reviewed-on: https://review.whamcloud.com/31721
Reviewed-by: Fan Yong <fan.yong@intel.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
static int osd_it_acct_load(const struct lu_env *env,
const struct dt_it *di, __u64 hash)
{
static int osd_it_acct_load(const struct lu_env *env,
const struct dt_it *di, __u64 hash)
{
+ struct osd_it_quota *it = (struct osd_it_quota *)di;
+
+
+ /* LU-8999 - If it is called to resume the iteration, calling
+ * osd_it_acct_get could change the block orders in the lower level
+ * of the quota tree, which are saved in osd_it_quota->oiq_blk.
+ * */
+ if (it->oiq_id != 0 && it->oiq_id == hash)
+ RETURN(1);
+
RETURN(osd_it_acct_get(env, (struct dt_it *)di,
(const struct dt_key *)&hash));
}
RETURN(osd_it_acct_get(env, (struct dt_it *)di,
(const struct dt_key *)&hash));
}
- for (; index <= 0xff && ret > 0; index++) {
+ for (; index <= 0xff; index++) {
blk = le32_to_cpu(ref[index]);
if (!blk) /* No reference */
continue;
blk = le32_to_cpu(ref[index]);
if (!blk) /* No reference */
continue;
else
ret = walk_block_dqentry(env, obj, type, blk, 0, it);
else
ret = walk_block_dqentry(env, obj, type, blk, 0, it);
it->oiq_blk[depth + 1] = blk;
it->oiq_index[depth] = index;
it->oiq_blk[depth + 1] = blk;
it->oiq_index[depth] = index;