]> Pileus Git - ~andy/linux/commitdiff
GFS2: Protect quota sync generation
authorSteven Whitehouse <swhiteho@redhat.com>
Fri, 4 Oct 2013 11:29:34 +0000 (12:29 +0100)
committerSteven Whitehouse <swhiteho@redhat.com>
Fri, 4 Oct 2013 11:29:34 +0000 (12:29 +0100)
Now that gfs2_quota_sync can be potentially called from multiple
threads, we should protect this bit of code, and the sync generation
number in particular in order to ensure that there are no races
when syncing quotas.

Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Cc: Abhijith Das <adas@redhat.com>
fs/gfs2/incore.h
fs/gfs2/ops_fstype.c
fs/gfs2/quota.c

index 37b3cd795d6cf0609139695f2cba22781a00c632..2ab4f8d8f4c4b092a92f636eafece065dd7957f6 100644 (file)
@@ -714,6 +714,7 @@ 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;
        struct list_head sd_trunc_list;
        spinlock_t sd_trunc_lock;
index 8e40fda985d62bab14f1e5e46e0cdf7dcf3fb410..82303b4749582cd3c00d402a9f42b9972b1de677 100644 (file)
@@ -93,6 +93,7 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
 
        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);
        INIT_LIST_HEAD(&sdp->sd_trunc_list);
        spin_lock_init(&sdp->sd_trunc_lock);
index cfb4cdeddacbd568ee2797c16f1b304f13b70a89..4a9726aa191f59d1a01a7cff7241ad4a2285d687 100644 (file)
@@ -1132,12 +1132,13 @@ int gfs2_quota_sync(struct super_block *sb, int type)
        unsigned int x;
        int error = 0;
 
-       sdp->sd_quota_sync_gen++;
-
        qda = kcalloc(max_qd, sizeof(struct gfs2_quota_data *), GFP_KERNEL);
        if (!qda)
                return -ENOMEM;
 
+       mutex_lock(&sdp->sd_quota_sync_mutex);
+       sdp->sd_quota_sync_gen++;
+
        do {
                num_qd = 0;
 
@@ -1162,6 +1163,7 @@ int gfs2_quota_sync(struct super_block *sb, int type)
                }
        } while (!error && num_qd == max_qd);
 
+       mutex_unlock(&sdp->sd_quota_sync_mutex);
        kfree(qda);
 
        return error;