From 67e0d9e40acc6adcebf89e2a4ac3860f0c4273d2 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Thu, 2 Nov 2023 20:33:50 -0400 Subject: [PATCH] LU-17191 osc: only call xa_insert for new entries The handling of updating the Xarray entry is incorrect. If the Xarray already exist and we call xa_insert() it will return -EBUSY and not continue examining the entry. The correct approach is if xa_load() returns a value never call xa_insert(). With the return value of xa_load() we test if type bit was set and if not set it. We add ll_xa_insert to spelling.txt since the return value changed with kernel versions. This will avoid mistakes in the future for cases we look at the return value of xa_insert(). Test-Parameters: testlist=sanity-quota Test-parameters: clientdistro=ubuntu2204 testlist=sanity-quota Fixes: ac8c28f959 ("LU-8130 osc: convert osc_quota hash to xarray") Change-Id: Icd88f5e47fb24f669bf362c1daec500b743b447b Signed-off-by: James Simmons Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/52713 Reviewed-by: Sergey Cheremencev Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin Tested-by: jenkins Tested-by: Maloo --- contrib/scripts/spelling.txt | 1 + lustre/osc/osc_quota.c | 37 +++++++++++++++++++++++++------------ 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/contrib/scripts/spelling.txt b/contrib/scripts/spelling.txt index bc31253..5dee6180 100644 --- a/contrib/scripts/spelling.txt +++ b/contrib/scripts/spelling.txt @@ -138,3 +138,4 @@ timer_setup||cfs_timer_setup version_code.*2.1[7-9]||version 2.16.x should be used vui_tot_count||vui_tot_bytes wait_queue_t||wait_queue_entry_t +xa_insert||ll_xa_insert diff --git a/lustre/osc/osc_quota.c b/lustre/osc/osc_quota.c index b127361..cee9d68 100644 --- a/lustre/osc/osc_quota.c +++ b/lustre/osc/osc_quota.c @@ -119,17 +119,29 @@ int osc_quota_setdq(struct client_obd *cli, u64 xid, const unsigned int qid[], /* This ID is getting close to its quota limit, let's * switch to sync I/O */ - if (qtypes) { + if (qtypes) { /* ID already cached */ bits = xa_to_value(qtypes); - /* test if already set */ - if (bits & BIT(type)) - continue; + /* test if ID type already set */ + if (!(bits & BIT(type))) { + bits |= BIT(type); + rc = xa_err(xa_store(&cli->cl_quota_exceeded_ids, + qid[type], + xa_mk_value(bits), + GFP_KERNEL)); + if (rc < 0) + GOTO(out_unlock, rc); + } + continue; } + /* Only insert if we see the this ID for the + * very first time. + */ bits |= BIT(type); - rc = xa_insert(&cli->cl_quota_exceeded_ids, qid[type], - xa_mk_value(bits), GFP_KERNEL); - if (rc) + rc = ll_xa_insert(&cli->cl_quota_exceeded_ids, + qid[type], xa_mk_value(bits), + GFP_KERNEL); + if (rc == -ENOMEM) break; CDEBUG(D_QUOTA, "%s: setdq to insert for %s %d: rc = %d\n", @@ -147,11 +159,12 @@ int osc_quota_setdq(struct client_obd *cli, u64 xid, const unsigned int qid[], bits &= ~BIT(type); if (bits) { - if (xa_cmpxchg(&cli->cl_quota_exceeded_ids, - qid[type], qtypes, - xa_mk_value(bits), - GFP_KERNEL) != qtypes) - GOTO(out_unlock, rc = -ENOENT); + rc = xa_err(xa_store(&cli->cl_quota_exceeded_ids, + qid[type], + xa_mk_value(bits), + GFP_KERNEL)); + if (rc < 0) + GOTO(out_unlock, rc); } else { xa_erase(&cli->cl_quota_exceeded_ids, qid[type]); } -- 1.8.3.1