From 07fdba2244e748e1721232abc52617209a544b87 Mon Sep 17 00:00:00 2001 From: Hongchao Zhang Date: Wed, 21 Mar 2018 23:17:03 +0800 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. Change-Id: I44936c70d4060bd83db22aba0e3f665981cfa50a Signed-off-by: Hongchao Zhang Reviewed-on: https://review.whamcloud.com/31721 Reviewed-by: Fan Yong Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger 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 3c250ba..8cf39a3 100644 --- a/lustre/osd-ldiskfs/osd_quota.c +++ b/lustre/osd-ldiskfs/osd_quota.c @@ -437,7 +437,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 9cc5c7c..1883cd8 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