Commit 22077f57 authored by Steven Whitehouse's avatar Steven Whitehouse Committed by Steven Whitehouse

GFS2: Remove "double" locking in quota

We only really need a single spin lock for the quota data, so
lets just use the lru lock for now.
Signed-off-by: default avatarSteven Whitehouse <swhiteho@redhat.com>
Cc: Abhijith Das <adas@redhat.com>
parent 0a7ab79c
...@@ -540,7 +540,6 @@ struct gfs2_sbd { ...@@ -540,7 +540,6 @@ struct gfs2_sbd {
struct list_head sd_quota_list; struct list_head sd_quota_list;
atomic_t sd_quota_count; atomic_t sd_quota_count;
spinlock_t sd_quota_spin;
struct mutex sd_quota_mutex; struct mutex sd_quota_mutex;
wait_queue_head_t sd_quota_wait; wait_queue_head_t sd_quota_wait;
struct list_head sd_trunc_list; struct list_head sd_trunc_list;
......
...@@ -98,7 +98,6 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) ...@@ -98,7 +98,6 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
mutex_init(&sdp->sd_jindex_mutex); mutex_init(&sdp->sd_jindex_mutex);
INIT_LIST_HEAD(&sdp->sd_quota_list); INIT_LIST_HEAD(&sdp->sd_quota_list);
spin_lock_init(&sdp->sd_quota_spin);
mutex_init(&sdp->sd_quota_mutex); mutex_init(&sdp->sd_quota_mutex);
init_waitqueue_head(&sdp->sd_quota_wait); init_waitqueue_head(&sdp->sd_quota_wait);
INIT_LIST_HEAD(&sdp->sd_trunc_list); INIT_LIST_HEAD(&sdp->sd_trunc_list);
......
...@@ -104,13 +104,11 @@ int gfs2_shrink_qd_memory(int nr, gfp_t gfp_mask) ...@@ -104,13 +104,11 @@ int gfs2_shrink_qd_memory(int nr, gfp_t gfp_mask)
/* Free from the filesystem-specific list */ /* Free from the filesystem-specific list */
list_del(&qd->qd_list); list_del(&qd->qd_list);
spin_lock(&sdp->sd_quota_spin);
gfs2_assert_warn(sdp, !qd->qd_change); gfs2_assert_warn(sdp, !qd->qd_change);
gfs2_assert_warn(sdp, !qd->qd_slot_count); gfs2_assert_warn(sdp, !qd->qd_slot_count);
gfs2_assert_warn(sdp, !qd->qd_bh_count); gfs2_assert_warn(sdp, !qd->qd_bh_count);
gfs2_lvb_unhold(qd->qd_gl); gfs2_lvb_unhold(qd->qd_gl);
spin_unlock(&sdp->sd_quota_spin);
atomic_dec(&sdp->sd_quota_count); atomic_dec(&sdp->sd_quota_count);
/* Delete it from the common reclaim list */ /* Delete it from the common reclaim list */
...@@ -249,10 +247,10 @@ static int slot_get(struct gfs2_quota_data *qd) ...@@ -249,10 +247,10 @@ static int slot_get(struct gfs2_quota_data *qd)
unsigned int c, o = 0, b; unsigned int c, o = 0, b;
unsigned char byte = 0; unsigned char byte = 0;
spin_lock(&sdp->sd_quota_spin); spin_lock(&qd_lru_lock);
if (qd->qd_slot_count++) { if (qd->qd_slot_count++) {
spin_unlock(&sdp->sd_quota_spin); spin_unlock(&qd_lru_lock);
return 0; return 0;
} }
...@@ -276,13 +274,13 @@ static int slot_get(struct gfs2_quota_data *qd) ...@@ -276,13 +274,13 @@ static int slot_get(struct gfs2_quota_data *qd)
sdp->sd_quota_bitmap[c][o] |= 1 << b; sdp->sd_quota_bitmap[c][o] |= 1 << b;
spin_unlock(&sdp->sd_quota_spin); spin_unlock(&qd_lru_lock);
return 0; return 0;
fail: fail:
qd->qd_slot_count--; qd->qd_slot_count--;
spin_unlock(&sdp->sd_quota_spin); spin_unlock(&qd_lru_lock);
return -ENOSPC; return -ENOSPC;
} }
...@@ -290,23 +288,23 @@ static void slot_hold(struct gfs2_quota_data *qd) ...@@ -290,23 +288,23 @@ static void slot_hold(struct gfs2_quota_data *qd)
{ {
struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd; struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd;
spin_lock(&sdp->sd_quota_spin); spin_lock(&qd_lru_lock);
gfs2_assert(sdp, qd->qd_slot_count); gfs2_assert(sdp, qd->qd_slot_count);
qd->qd_slot_count++; qd->qd_slot_count++;
spin_unlock(&sdp->sd_quota_spin); spin_unlock(&qd_lru_lock);
} }
static void slot_put(struct gfs2_quota_data *qd) static void slot_put(struct gfs2_quota_data *qd)
{ {
struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd; struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd;
spin_lock(&sdp->sd_quota_spin); spin_lock(&qd_lru_lock);
gfs2_assert(sdp, qd->qd_slot_count); gfs2_assert(sdp, qd->qd_slot_count);
if (!--qd->qd_slot_count) { if (!--qd->qd_slot_count) {
gfs2_icbit_munge(sdp, sdp->sd_quota_bitmap, qd->qd_slot, 0); gfs2_icbit_munge(sdp, sdp->sd_quota_bitmap, qd->qd_slot, 0);
qd->qd_slot = -1; qd->qd_slot = -1;
} }
spin_unlock(&sdp->sd_quota_spin); spin_unlock(&qd_lru_lock);
} }
static int bh_get(struct gfs2_quota_data *qd) static int bh_get(struct gfs2_quota_data *qd)
...@@ -382,7 +380,6 @@ static int qd_fish(struct gfs2_sbd *sdp, struct gfs2_quota_data **qdp) ...@@ -382,7 +380,6 @@ static int qd_fish(struct gfs2_sbd *sdp, struct gfs2_quota_data **qdp)
return 0; return 0;
spin_lock(&qd_lru_lock); spin_lock(&qd_lru_lock);
spin_lock(&sdp->sd_quota_spin);
list_for_each_entry(qd, &sdp->sd_quota_list, qd_list) { list_for_each_entry(qd, &sdp->sd_quota_list, qd_list) {
if (test_bit(QDF_LOCKED, &qd->qd_flags) || if (test_bit(QDF_LOCKED, &qd->qd_flags) ||
...@@ -406,7 +403,6 @@ static int qd_fish(struct gfs2_sbd *sdp, struct gfs2_quota_data **qdp) ...@@ -406,7 +403,6 @@ static int qd_fish(struct gfs2_sbd *sdp, struct gfs2_quota_data **qdp)
if (!found) if (!found)
qd = NULL; qd = NULL;
spin_unlock(&sdp->sd_quota_spin);
spin_unlock(&qd_lru_lock); spin_unlock(&qd_lru_lock);
if (qd) { if (qd) {
...@@ -433,11 +429,9 @@ static int qd_trylock(struct gfs2_quota_data *qd) ...@@ -433,11 +429,9 @@ static int qd_trylock(struct gfs2_quota_data *qd)
return 0; return 0;
spin_lock(&qd_lru_lock); spin_lock(&qd_lru_lock);
spin_lock(&sdp->sd_quota_spin);
if (test_bit(QDF_LOCKED, &qd->qd_flags) || if (test_bit(QDF_LOCKED, &qd->qd_flags) ||
!test_bit(QDF_CHANGE, &qd->qd_flags)) { !test_bit(QDF_CHANGE, &qd->qd_flags)) {
spin_unlock(&sdp->sd_quota_spin);
spin_unlock(&qd_lru_lock); spin_unlock(&qd_lru_lock);
return 0; return 0;
} }
...@@ -451,7 +445,6 @@ static int qd_trylock(struct gfs2_quota_data *qd) ...@@ -451,7 +445,6 @@ static int qd_trylock(struct gfs2_quota_data *qd)
gfs2_assert_warn(sdp, qd->qd_slot_count); gfs2_assert_warn(sdp, qd->qd_slot_count);
qd->qd_slot_count++; qd->qd_slot_count++;
spin_unlock(&sdp->sd_quota_spin);
spin_unlock(&qd_lru_lock); spin_unlock(&qd_lru_lock);
gfs2_assert_warn(sdp, qd->qd_change_sync); gfs2_assert_warn(sdp, qd->qd_change_sync);
...@@ -612,9 +605,9 @@ static void do_qc(struct gfs2_quota_data *qd, s64 change) ...@@ -612,9 +605,9 @@ static void do_qc(struct gfs2_quota_data *qd, s64 change)
x = be64_to_cpu(qc->qc_change) + change; x = be64_to_cpu(qc->qc_change) + change;
qc->qc_change = cpu_to_be64(x); qc->qc_change = cpu_to_be64(x);
spin_lock(&sdp->sd_quota_spin); spin_lock(&qd_lru_lock);
qd->qd_change = x; qd->qd_change = x;
spin_unlock(&sdp->sd_quota_spin); spin_unlock(&qd_lru_lock);
if (!x) { if (!x) {
gfs2_assert_warn(sdp, test_bit(QDF_CHANGE, &qd->qd_flags)); gfs2_assert_warn(sdp, test_bit(QDF_CHANGE, &qd->qd_flags));
...@@ -945,9 +938,9 @@ static int need_sync(struct gfs2_quota_data *qd) ...@@ -945,9 +938,9 @@ static int need_sync(struct gfs2_quota_data *qd)
if (!qd->qd_qb.qb_limit) if (!qd->qd_qb.qb_limit)
return 0; return 0;
spin_lock(&sdp->sd_quota_spin); spin_lock(&qd_lru_lock);
value = qd->qd_change; value = qd->qd_change;
spin_unlock(&sdp->sd_quota_spin); spin_unlock(&qd_lru_lock);
spin_lock(&gt->gt_spin); spin_lock(&gt->gt_spin);
num = gt->gt_quota_scale_num; num = gt->gt_quota_scale_num;
...@@ -1040,9 +1033,9 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid) ...@@ -1040,9 +1033,9 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid)
continue; continue;
value = (s64)be64_to_cpu(qd->qd_qb.qb_value); value = (s64)be64_to_cpu(qd->qd_qb.qb_value);
spin_lock(&sdp->sd_quota_spin); spin_lock(&qd_lru_lock);
value += qd->qd_change; value += qd->qd_change;
spin_unlock(&sdp->sd_quota_spin); spin_unlock(&qd_lru_lock);
if (be64_to_cpu(qd->qd_qb.qb_limit) && (s64)be64_to_cpu(qd->qd_qb.qb_limit) < value) { if (be64_to_cpu(qd->qd_qb.qb_limit) && (s64)be64_to_cpu(qd->qd_qb.qb_limit) < value) {
print_message(qd, "exceeded"); print_message(qd, "exceeded");
...@@ -1228,9 +1221,7 @@ int gfs2_quota_init(struct gfs2_sbd *sdp) ...@@ -1228,9 +1221,7 @@ int gfs2_quota_init(struct gfs2_sbd *sdp)
qd->qd_slot_count = 1; qd->qd_slot_count = 1;
spin_lock(&qd_lru_lock); spin_lock(&qd_lru_lock);
spin_lock(&sdp->sd_quota_spin);
gfs2_icbit_munge(sdp, sdp->sd_quota_bitmap, slot, 1); gfs2_icbit_munge(sdp, sdp->sd_quota_bitmap, slot, 1);
spin_unlock(&sdp->sd_quota_spin);
list_add(&qd->qd_list, &sdp->sd_quota_list); list_add(&qd->qd_list, &sdp->sd_quota_list);
atomic_inc(&sdp->sd_quota_count); atomic_inc(&sdp->sd_quota_count);
spin_unlock(&qd_lru_lock); spin_unlock(&qd_lru_lock);
...@@ -1263,18 +1254,15 @@ void gfs2_quota_cleanup(struct gfs2_sbd *sdp) ...@@ -1263,18 +1254,15 @@ void gfs2_quota_cleanup(struct gfs2_sbd *sdp)
while (!list_empty(head)) { while (!list_empty(head)) {
qd = list_entry(head->prev, struct gfs2_quota_data, qd_list); qd = list_entry(head->prev, struct gfs2_quota_data, qd_list);
spin_lock(&sdp->sd_quota_spin);
if (atomic_read(&qd->qd_count) > 1 || if (atomic_read(&qd->qd_count) > 1 ||
(atomic_read(&qd->qd_count) && (atomic_read(&qd->qd_count) &&
!test_bit(QDF_CHANGE, &qd->qd_flags))) { !test_bit(QDF_CHANGE, &qd->qd_flags))) {
spin_unlock(&sdp->sd_quota_spin);
list_move(&qd->qd_list, head); list_move(&qd->qd_list, head);
spin_unlock(&qd_lru_lock); spin_unlock(&qd_lru_lock);
schedule(); schedule();
spin_lock(&qd_lru_lock); spin_lock(&qd_lru_lock);
continue; continue;
} }
spin_unlock(&sdp->sd_quota_spin);
list_del(&qd->qd_list); list_del(&qd->qd_list);
/* Also remove if this qd exists in the reclaim list */ /* Also remove if this qd exists in the reclaim list */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment