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.
Lustre-commit:
07fdba2244e748e1721232abc52617209a544b87
Lustre-change: http://review.whamcloud.com/31721
Change-Id: I21f31647ebc15d34dc2021a2d8c5ad40fe128535
Signed-off-by: Hongchao Zhang <hongchao.zhang@intel.com>
Reviewed-on: https://review.whamcloud.com/32567
Reviewed-by: Wang Shilong <wshilong@ddn.com>
Tested-by: Jenkins
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
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;
+
ENTRY;
+
+ /* 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));
}
}
ret = 1;
- for (; index <= 0xff && ret > 0; index++) {
+ for (; index <= 0xff; index++) {
blk = le32_to_cpu(ref[index]);
if (!blk) /* No reference */
continue;
else
ret = walk_block_dqentry(env, obj, type, blk, 0, it);
+ if (ret <= 0)
+ break;
}
+
it->oiq_blk[depth + 1] = blk;
it->oiq_index[depth] = index;