]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
gfs2: Get rid of some unnecessary quota locking
authorAndreas Gruenbacher <agruenba@redhat.com>
Mon, 10 Jun 2024 14:31:22 +0000 (16:31 +0200)
committerAndreas Gruenbacher <agruenba@redhat.com>
Thu, 20 Jun 2024 14:38:13 +0000 (16:38 +0200)
With the locking the previous patch has introduced for each struct
gfs2_quota_data object, sd_quota_mutex has become largely irrelevant.
By waiting on the buffer head instead of waiting on the mutex in
get_bh(), it becomes completely irrelevant and can be removed.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
fs/gfs2/incore.h
fs/gfs2/ops_fstype.c
fs/gfs2/quota.c

index 90fd2584357ad8abedf0b590c9aa3bc629393371..aa4ef67a34e0374e35b8e3f5461e67acab5e67b4 100644 (file)
@@ -782,7 +782,6 @@ struct gfs2_sbd {
 
        struct list_head sd_quota_list;
        atomic_t sd_quota_count;
-       struct mutex sd_quota_mutex;
        struct mutex sd_quota_sync_mutex;
        wait_queue_head_t sd_quota_wait;
 
index 0561edd6cc868e839fd16a6ea662dad4e2aa5e54..ff1f3e3dc65c9db08728fee9ef707a3b911d1302 100644 (file)
@@ -103,7 +103,6 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
        init_completion(&sdp->sd_journal_ready);
 
        INIT_LIST_HEAD(&sdp->sd_quota_list);
-       mutex_init(&sdp->sd_quota_mutex);
        mutex_init(&sdp->sd_quota_sync_mutex);
        init_waitqueue_head(&sdp->sd_quota_wait);
        spin_lock_init(&sdp->sd_bitmap_lock);
index 283c6ff21911d1dac7e9a973df502ecb72cf62ab..931a133a5f9697a2d32458b0053e9dfa5498d182 100644 (file)
@@ -397,16 +397,17 @@ static int bh_get(struct gfs2_quota_data *qd)
        struct inode *inode = sdp->sd_qc_inode;
        struct gfs2_inode *ip = GFS2_I(inode);
        unsigned int block, offset;
-       struct buffer_head *bh;
+       struct buffer_head *bh = NULL;
        struct iomap iomap = { };
        int error;
 
-       mutex_lock(&sdp->sd_quota_mutex);
-
-       if (qd->qd_bh_count++) {
-               mutex_unlock(&sdp->sd_quota_mutex);
+       spin_lock(&qd->qd_lockref.lock);
+       if (qd->qd_bh_count) {
+               qd->qd_bh_count++;
+               spin_unlock(&qd->qd_lockref.lock);
                return 0;
        }
+       spin_unlock(&qd->qd_lockref.lock);
 
        block = qd->qd_slot / sdp->sd_qc_per_block;
        offset = qd->qd_slot % sdp->sd_qc_per_block;
@@ -415,48 +416,50 @@ static int bh_get(struct gfs2_quota_data *qd)
                               (loff_t)block << inode->i_blkbits,
                               i_blocksize(inode), &iomap);
        if (error)
-               goto fail;
+               return error;
        error = -ENOENT;
        if (iomap.type != IOMAP_MAPPED)
-               goto fail;
+               return error;
 
        error = gfs2_meta_read(ip->i_gl, iomap.addr >> inode->i_blkbits,
                               DIO_WAIT, 0, &bh);
        if (error)
-               goto fail;
+               return error;
        error = -EIO;
        if (gfs2_metatype_check(sdp, bh, GFS2_METATYPE_QC))
-               goto fail_brelse;
-
-       qd->qd_bh = bh;
-       qd->qd_bh_qc = (struct gfs2_quota_change *)
-               (bh->b_data + sizeof(struct gfs2_meta_header) +
-                offset * sizeof(struct gfs2_quota_change));
-
-       mutex_unlock(&sdp->sd_quota_mutex);
+               goto out;
 
-       return 0;
+       spin_lock(&qd->qd_lockref.lock);
+       if (qd->qd_bh == NULL) {
+               qd->qd_bh = bh;
+               qd->qd_bh_qc = (struct gfs2_quota_change *)
+                       (bh->b_data + sizeof(struct gfs2_meta_header) +
+                        offset * sizeof(struct gfs2_quota_change));
+               bh = NULL;
+       }
+       qd->qd_bh_count++;
+       spin_unlock(&qd->qd_lockref.lock);
+       error = 0;
 
-fail_brelse:
+out:
        brelse(bh);
-fail:
-       qd->qd_bh_count--;
-       mutex_unlock(&sdp->sd_quota_mutex);
        return error;
 }
 
 static void bh_put(struct gfs2_quota_data *qd)
 {
        struct gfs2_sbd *sdp = qd->qd_sbd;
+       struct buffer_head *bh = NULL;
 
-       mutex_lock(&sdp->sd_quota_mutex);
+       spin_lock(&qd->qd_lockref.lock);
        gfs2_assert(sdp, qd->qd_bh_count);
        if (!--qd->qd_bh_count) {
-               brelse(qd->qd_bh);
+               bh = qd->qd_bh;
                qd->qd_bh = NULL;
                qd->qd_bh_qc = NULL;
        }
-       mutex_unlock(&sdp->sd_quota_mutex);
+       spin_unlock(&qd->qd_lockref.lock);
+       brelse(bh);
 }
 
 static bool qd_grab_sync(struct gfs2_sbd *sdp, struct gfs2_quota_data *qd,
@@ -676,7 +679,6 @@ static void do_qc(struct gfs2_quota_data *qd, s64 change)
        bool needs_put = false;
        s64 x;
 
-       mutex_lock(&sdp->sd_quota_mutex);
        gfs2_trans_add_meta(ip->i_gl, qd->qd_bh);
 
        /*
@@ -720,7 +722,6 @@ static void do_qc(struct gfs2_quota_data *qd, s64 change)
        }
        if (change < 0) /* Reset quiet flag if we freed some blocks */
                clear_bit(QDF_QMSG_QUIET, &qd->qd_flags);
-       mutex_unlock(&sdp->sd_quota_mutex);
 }
 
 static int gfs2_write_buf_to_page(struct gfs2_sbd *sdp, unsigned long index,