diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-16 11:58:43 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-16 11:58:43 -0400 |
commit | 3ae2a1ce2e7b70254e5c9e465adefac9cba191d6 (patch) | |
tree | 388da81c97a92861b84b408eb12a494d859cca7a /fs/gfs2/log.c | |
parent | 26a992dbc24e34cbdd03621d1c97ce571ad74e65 (diff) | |
parent | 7e32d02613a72a39ba01638337c609a9a866c653 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw
* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw:
GFS2: Don't use _raw version of RCU dereference
GFS2: Adding missing unlock_page()
GFS2: Update to AIL list locking
GFS2: introduce AIL lock
GFS2: fix block allocation check for fallocate
GFS2: Optimize glock multiple-dequeue code
GFS2: Remove potential race in flock code
GFS2: Fix glock deallocation race
GFS2: quota allows exceeding hard limit
GFS2: deallocation performance patch
GFS2: panics on quotacheck update
GFS2: Improve cluster mmap scalability
GFS2: Fix glock queue trace point
GFS2: Post-VFS scale update for RCU path walk
GFS2: Use RCU for glock hash table
Diffstat (limited to 'fs/gfs2/log.c')
-rw-r--r-- | fs/gfs2/log.c | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index eb01f3575e10..e7ed31f858dd 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
@@ -67,7 +67,7 @@ unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, | |||
67 | * @mapping: The associated mapping (maybe NULL) | 67 | * @mapping: The associated mapping (maybe NULL) |
68 | * @bd: The gfs2_bufdata to remove | 68 | * @bd: The gfs2_bufdata to remove |
69 | * | 69 | * |
70 | * The log lock _must_ be held when calling this function | 70 | * The ail lock _must_ be held when calling this function |
71 | * | 71 | * |
72 | */ | 72 | */ |
73 | 73 | ||
@@ -88,8 +88,8 @@ void gfs2_remove_from_ail(struct gfs2_bufdata *bd) | |||
88 | */ | 88 | */ |
89 | 89 | ||
90 | static void gfs2_ail1_start_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai) | 90 | static void gfs2_ail1_start_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai) |
91 | __releases(&sdp->sd_log_lock) | 91 | __releases(&sdp->sd_ail_lock) |
92 | __acquires(&sdp->sd_log_lock) | 92 | __acquires(&sdp->sd_ail_lock) |
93 | { | 93 | { |
94 | struct gfs2_bufdata *bd, *s; | 94 | struct gfs2_bufdata *bd, *s; |
95 | struct buffer_head *bh; | 95 | struct buffer_head *bh; |
@@ -117,7 +117,7 @@ __acquires(&sdp->sd_log_lock) | |||
117 | list_move(&bd->bd_ail_st_list, &ai->ai_ail1_list); | 117 | list_move(&bd->bd_ail_st_list, &ai->ai_ail1_list); |
118 | 118 | ||
119 | get_bh(bh); | 119 | get_bh(bh); |
120 | gfs2_log_unlock(sdp); | 120 | spin_unlock(&sdp->sd_ail_lock); |
121 | lock_buffer(bh); | 121 | lock_buffer(bh); |
122 | if (test_clear_buffer_dirty(bh)) { | 122 | if (test_clear_buffer_dirty(bh)) { |
123 | bh->b_end_io = end_buffer_write_sync; | 123 | bh->b_end_io = end_buffer_write_sync; |
@@ -126,7 +126,7 @@ __acquires(&sdp->sd_log_lock) | |||
126 | unlock_buffer(bh); | 126 | unlock_buffer(bh); |
127 | brelse(bh); | 127 | brelse(bh); |
128 | } | 128 | } |
129 | gfs2_log_lock(sdp); | 129 | spin_lock(&sdp->sd_ail_lock); |
130 | 130 | ||
131 | retry = 1; | 131 | retry = 1; |
132 | break; | 132 | break; |
@@ -175,10 +175,10 @@ static void gfs2_ail1_start(struct gfs2_sbd *sdp) | |||
175 | struct gfs2_ail *ai; | 175 | struct gfs2_ail *ai; |
176 | int done = 0; | 176 | int done = 0; |
177 | 177 | ||
178 | gfs2_log_lock(sdp); | 178 | spin_lock(&sdp->sd_ail_lock); |
179 | head = &sdp->sd_ail1_list; | 179 | head = &sdp->sd_ail1_list; |
180 | if (list_empty(head)) { | 180 | if (list_empty(head)) { |
181 | gfs2_log_unlock(sdp); | 181 | spin_unlock(&sdp->sd_ail_lock); |
182 | return; | 182 | return; |
183 | } | 183 | } |
184 | sync_gen = sdp->sd_ail_sync_gen++; | 184 | sync_gen = sdp->sd_ail_sync_gen++; |
@@ -189,13 +189,13 @@ static void gfs2_ail1_start(struct gfs2_sbd *sdp) | |||
189 | if (ai->ai_sync_gen >= sync_gen) | 189 | if (ai->ai_sync_gen >= sync_gen) |
190 | continue; | 190 | continue; |
191 | ai->ai_sync_gen = sync_gen; | 191 | ai->ai_sync_gen = sync_gen; |
192 | gfs2_ail1_start_one(sdp, ai); /* This may drop log lock */ | 192 | gfs2_ail1_start_one(sdp, ai); /* This may drop ail lock */ |
193 | done = 0; | 193 | done = 0; |
194 | break; | 194 | break; |
195 | } | 195 | } |
196 | } | 196 | } |
197 | 197 | ||
198 | gfs2_log_unlock(sdp); | 198 | spin_unlock(&sdp->sd_ail_lock); |
199 | } | 199 | } |
200 | 200 | ||
201 | static int gfs2_ail1_empty(struct gfs2_sbd *sdp, int flags) | 201 | static int gfs2_ail1_empty(struct gfs2_sbd *sdp, int flags) |
@@ -203,7 +203,7 @@ static int gfs2_ail1_empty(struct gfs2_sbd *sdp, int flags) | |||
203 | struct gfs2_ail *ai, *s; | 203 | struct gfs2_ail *ai, *s; |
204 | int ret; | 204 | int ret; |
205 | 205 | ||
206 | gfs2_log_lock(sdp); | 206 | spin_lock(&sdp->sd_ail_lock); |
207 | 207 | ||
208 | list_for_each_entry_safe_reverse(ai, s, &sdp->sd_ail1_list, ai_list) { | 208 | list_for_each_entry_safe_reverse(ai, s, &sdp->sd_ail1_list, ai_list) { |
209 | if (gfs2_ail1_empty_one(sdp, ai, flags)) | 209 | if (gfs2_ail1_empty_one(sdp, ai, flags)) |
@@ -214,7 +214,7 @@ static int gfs2_ail1_empty(struct gfs2_sbd *sdp, int flags) | |||
214 | 214 | ||
215 | ret = list_empty(&sdp->sd_ail1_list); | 215 | ret = list_empty(&sdp->sd_ail1_list); |
216 | 216 | ||
217 | gfs2_log_unlock(sdp); | 217 | spin_unlock(&sdp->sd_ail_lock); |
218 | 218 | ||
219 | return ret; | 219 | return ret; |
220 | } | 220 | } |
@@ -247,7 +247,7 @@ static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail) | |||
247 | int wrap = (new_tail < old_tail); | 247 | int wrap = (new_tail < old_tail); |
248 | int a, b, rm; | 248 | int a, b, rm; |
249 | 249 | ||
250 | gfs2_log_lock(sdp); | 250 | spin_lock(&sdp->sd_ail_lock); |
251 | 251 | ||
252 | list_for_each_entry_safe(ai, safe, &sdp->sd_ail2_list, ai_list) { | 252 | list_for_each_entry_safe(ai, safe, &sdp->sd_ail2_list, ai_list) { |
253 | a = (old_tail <= ai->ai_first); | 253 | a = (old_tail <= ai->ai_first); |
@@ -263,7 +263,7 @@ static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail) | |||
263 | kfree(ai); | 263 | kfree(ai); |
264 | } | 264 | } |
265 | 265 | ||
266 | gfs2_log_unlock(sdp); | 266 | spin_unlock(&sdp->sd_ail_lock); |
267 | } | 267 | } |
268 | 268 | ||
269 | /** | 269 | /** |
@@ -421,7 +421,7 @@ static unsigned int current_tail(struct gfs2_sbd *sdp) | |||
421 | struct gfs2_ail *ai; | 421 | struct gfs2_ail *ai; |
422 | unsigned int tail; | 422 | unsigned int tail; |
423 | 423 | ||
424 | gfs2_log_lock(sdp); | 424 | spin_lock(&sdp->sd_ail_lock); |
425 | 425 | ||
426 | if (list_empty(&sdp->sd_ail1_list)) { | 426 | if (list_empty(&sdp->sd_ail1_list)) { |
427 | tail = sdp->sd_log_head; | 427 | tail = sdp->sd_log_head; |
@@ -430,7 +430,7 @@ static unsigned int current_tail(struct gfs2_sbd *sdp) | |||
430 | tail = ai->ai_first; | 430 | tail = ai->ai_first; |
431 | } | 431 | } |
432 | 432 | ||
433 | gfs2_log_unlock(sdp); | 433 | spin_unlock(&sdp->sd_ail_lock); |
434 | 434 | ||
435 | return tail; | 435 | return tail; |
436 | } | 436 | } |
@@ -743,10 +743,12 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) | |||
743 | sdp->sd_log_commited_databuf = 0; | 743 | sdp->sd_log_commited_databuf = 0; |
744 | sdp->sd_log_commited_revoke = 0; | 744 | sdp->sd_log_commited_revoke = 0; |
745 | 745 | ||
746 | spin_lock(&sdp->sd_ail_lock); | ||
746 | if (!list_empty(&ai->ai_ail1_list)) { | 747 | if (!list_empty(&ai->ai_ail1_list)) { |
747 | list_add(&ai->ai_list, &sdp->sd_ail1_list); | 748 | list_add(&ai->ai_list, &sdp->sd_ail1_list); |
748 | ai = NULL; | 749 | ai = NULL; |
749 | } | 750 | } |
751 | spin_unlock(&sdp->sd_ail_lock); | ||
750 | gfs2_log_unlock(sdp); | 752 | gfs2_log_unlock(sdp); |
751 | trace_gfs2_log_flush(sdp, 0); | 753 | trace_gfs2_log_flush(sdp, 0); |
752 | up_write(&sdp->sd_log_flush_lock); | 754 | up_write(&sdp->sd_log_flush_lock); |