summaryrefslogtreecommitdiff
path: root/fs/gfs2
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruenba@redhat.com>2024-06-07 11:47:47 +0200
committerAndreas Gruenbacher <agruenba@redhat.com>2024-06-08 02:35:16 +0200
commit614abc11870ee7ec5a32c81b7ecf4232ede48ecb (patch)
treec9d71955cba1697b7a6cd2367e3713b3c3daa2a7 /fs/gfs2
parentb510af07aaa4d8a7095bc0368020d8bdba5af942 (diff)
gfs2: Fold qd_fish into gfs2_quota_sync
The split between qd_fish() and gfs2_quota_sync() is rather unfortunate as qd_fish() is repeatedly called to scan sdp->sd_quota_list only to find the next object to that needs syncing; if there are multiple objects on the list that need syncing, it makes more sense to grab them all in one go. This is relatively easy to do when qd_fish() is folded into gfs2_quota_sync(). Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/quota.c77
1 files changed, 29 insertions, 48 deletions
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 11bd16d8f81c..ae02403407aa 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -484,40 +484,6 @@ static void qd_ungrab_sync(struct gfs2_quota_data *qd)
qd_put(qd);
}
-static int qd_fish(struct gfs2_sbd *sdp, struct gfs2_quota_data **qdp)
-{
- struct gfs2_quota_data *qd = NULL, *iter;
- int error;
-
- *qdp = NULL;
-
- if (sb_rdonly(sdp->sd_vfs))
- return 0;
-
- spin_lock(&qd_lock);
-
- list_for_each_entry(iter, &sdp->sd_quota_list, qd_list) {
- if (qd_grab_sync(sdp, iter, sdp->sd_quota_sync_gen)) {
- qd = iter;
- break;
- }
- }
-
- spin_unlock(&qd_lock);
-
- if (qd) {
- error = bh_get(qd);
- if (error) {
- qd_ungrab_sync(qd);
- return error;
- }
- }
-
- *qdp = qd;
-
- return 0;
-}
-
static void qdsb_put(struct gfs2_quota_data *qd)
{
bh_put(qd);
@@ -1332,10 +1298,10 @@ int gfs2_quota_sync(struct super_block *sb, int type)
struct gfs2_sbd *sdp = sb->s_fs_info;
struct gfs2_quota_data **qda;
unsigned int max_qd = PAGE_SIZE / sizeof(struct gfs2_holder);
- unsigned int num_qd;
- unsigned int x;
int error = 0;
+ if (sb_rdonly(sdp->sd_vfs))
+ return 0;
if (!qd_changed(sdp))
return 0;
@@ -1347,24 +1313,39 @@ int gfs2_quota_sync(struct super_block *sb, int type)
sdp->sd_quota_sync_gen++;
do {
- num_qd = 0;
+ struct gfs2_quota_data *iter;
+ unsigned int num_qd = 0;
+ unsigned int x;
- for (;;) {
- error = qd_fish(sdp, qda + num_qd);
- if (error || !qda[num_qd])
- break;
- if (++num_qd == max_qd)
- break;
+ spin_lock(&qd_lock);
+ list_for_each_entry(iter, &sdp->sd_quota_list, qd_list) {
+ if (qd_grab_sync(sdp, iter, sdp->sd_quota_sync_gen)) {
+ qda[num_qd++] = iter;
+ if (num_qd == max_qd)
+ break;
+ }
}
+ spin_unlock(&qd_lock);
- if (num_qd) {
+ if (!num_qd)
+ break;
+
+ for (x = 0; x < num_qd; x++) {
+ error = bh_get(qda[x]);
if (!error)
- error = do_sync(num_qd, qda);
+ continue;
- for (x = 0; x < num_qd; x++)
- qd_unlock(qda[x]);
+ while (x < num_qd)
+ qd_ungrab_sync(qda[--num_qd]);
+ break;
}
- } while (!error && num_qd == max_qd);
+
+ if (!error)
+ error = do_sync(num_qd, qda);
+
+ for (x = 0; x < num_qd; x++)
+ qd_unlock(qda[x]);
+ } while (!error);
mutex_unlock(&sdp->sd_quota_sync_mutex);
kfree(qda);