Whamcloud - gitweb
LU-17191 osc: only call xa_insert for new entries 13/52713/9
authorJames Simmons <jsimmons@infradead.org>
Fri, 3 Nov 2023 00:33:50 +0000 (20:33 -0400)
committerOleg Drokin <green@whamcloud.com>
Wed, 8 Nov 2023 22:03:05 +0000 (22:03 +0000)
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 <jsimmons@infradead.org>
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/52713
Reviewed-by: Sergey Cheremencev <scherementsev@ddn.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
contrib/scripts/spelling.txt
lustre/osc/osc_quota.c

index bc31253..5dee618 100644 (file)
@@ -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
index b127361..cee9d68 100644 (file)
@@ -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]);
                        }