From cf796725fd39f0c807f60a86d2ddaa22e88c3a8c Mon Sep 17 00:00:00 2001 From: Hongchao Zhang Date: Thu, 24 May 2018 16:33:55 -0400 Subject: [PATCH] LU-8999 quota: fix issue of multiple call of seq start 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 Reviewed-on: https://review.whamcloud.com/32567 Reviewed-by: Wang Shilong Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/osd-ldiskfs/osd_quota.c | 10 ++++++++++ lustre/osd-ldiskfs/osd_quota_fmt.c | 5 ++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lustre/osd-ldiskfs/osd_quota.c b/lustre/osd-ldiskfs/osd_quota.c index 9ed4d5e..3edea2d 100644 --- a/lustre/osd-ldiskfs/osd_quota.c +++ b/lustre/osd-ldiskfs/osd_quota.c @@ -441,7 +441,17 @@ static __u64 osd_it_acct_store(const struct lu_env *env, 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)); } diff --git a/lustre/osd-ldiskfs/osd_quota_fmt.c b/lustre/osd-ldiskfs/osd_quota_fmt.c index 1fb6529..7952d3d 100644 --- a/lustre/osd-ldiskfs/osd_quota_fmt.c +++ b/lustre/osd-ldiskfs/osd_quota_fmt.c @@ -277,7 +277,7 @@ int walk_tree_dqentry(const struct lu_env *env, struct osd_object *obj, } ret = 1; - for (; index <= 0xff && ret > 0; index++) { + for (; index <= 0xff; index++) { blk = le32_to_cpu(ref[index]); if (!blk) /* No reference */ continue; @@ -288,7 +288,10 @@ int walk_tree_dqentry(const struct lu_env *env, struct osd_object *obj, 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; -- 1.8.3.1