aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2007-08-27 08:54:05 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2007-10-10 03:56:00 -0400
commit9b9107a5a8b190e6cf09bbdf893869c6a9c482cc (patch)
tree77016dd5476f6ba72605ac0cdcbccec3ce794057
parenteaf965270ffff3086ef929e660ace45e862cfd2d (diff)
[GFS2] Move pin/unpin into lops.c, clean up locking
gfs2_pin and gfs2_unpin are only used in lops.c, despite being defined in meta_io.c, so this patch moves them into lops.c and makes them static. At the same time, its possible to clean up the locking in the buf and databuf _lo_add() functions so that we only need to grab the spinlock once. Also we have to move lock_buffer() around the _lo_add() functions since we can't do that in gfs2_pin() any more since we hold the spinlock for the duration of that function. As a result, the code shrinks by 12 lines and we do far fewer operations when adding buffers to the log. It also makes the code somewhat easier to read & understand. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
-rw-r--r--fs/gfs2/lops.c117
-rw-r--r--fs/gfs2/meta_io.c70
-rw-r--r--fs/gfs2/meta_io.h3
3 files changed, 89 insertions, 101 deletions
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 7ef335623373..3ec587135d46 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -27,7 +27,71 @@
27#include "trans.h" 27#include "trans.h"
28#include "util.h" 28#include "util.h"
29 29
30static void glock_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le) 30/**
31 * gfs2_pin - Pin a buffer in memory
32 * @sdp: The superblock
33 * @bh: The buffer to be pinned
34 *
35 * The log lock must be held when calling this function
36 */
37static void gfs2_pin(struct gfs2_sbd *sdp, struct buffer_head *bh)
38{
39 struct gfs2_bufdata *bd;
40
41 gfs2_assert_withdraw(sdp, test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags));
42
43 clear_buffer_dirty(bh);
44 if (test_set_buffer_pinned(bh))
45 gfs2_assert_withdraw(sdp, 0);
46 if (!buffer_uptodate(bh))
47 gfs2_io_error_bh(sdp, bh);
48 bd = bh->b_private;
49 /* If this buffer is in the AIL and it has already been written
50 * to in-place disk block, remove it from the AIL.
51 */
52 if (bd->bd_ail)
53 list_move(&bd->bd_ail_st_list, &bd->bd_ail->ai_ail2_list);
54 get_bh(bh);
55}
56
57/**
58 * gfs2_unpin - Unpin a buffer
59 * @sdp: the filesystem the buffer belongs to
60 * @bh: The buffer to unpin
61 * @ai:
62 *
63 */
64
65static void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh,
66 struct gfs2_ail *ai)
67{
68 struct gfs2_bufdata *bd = bh->b_private;
69
70 gfs2_assert_withdraw(sdp, buffer_uptodate(bh));
71
72 if (!buffer_pinned(bh))
73 gfs2_assert_withdraw(sdp, 0);
74
75 lock_buffer(bh);
76 mark_buffer_dirty(bh);
77 clear_buffer_pinned(bh);
78
79 gfs2_log_lock(sdp);
80 if (bd->bd_ail) {
81 list_del(&bd->bd_ail_st_list);
82 brelse(bh);
83 } else {
84 struct gfs2_glock *gl = bd->bd_gl;
85 list_add(&bd->bd_ail_gl_list, &gl->gl_ail_list);
86 atomic_inc(&gl->gl_ail_count);
87 }
88 bd->bd_ail = ai;
89 list_add(&bd->bd_ail_st_list, &ai->ai_ail1_list);
90 gfs2_log_unlock(sdp);
91 unlock_buffer(bh);
92}
93
94static void __glock_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
31{ 95{
32 struct gfs2_glock *gl; 96 struct gfs2_glock *gl;
33 struct gfs2_trans *tr = current->journal_info; 97 struct gfs2_trans *tr = current->journal_info;
@@ -38,15 +102,19 @@ static void glock_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
38 if (gfs2_assert_withdraw(sdp, gfs2_glock_is_held_excl(gl))) 102 if (gfs2_assert_withdraw(sdp, gfs2_glock_is_held_excl(gl)))
39 return; 103 return;
40 104
41 gfs2_log_lock(sdp); 105 if (!list_empty(&le->le_list))
42 if (!list_empty(&le->le_list)){
43 gfs2_log_unlock(sdp);
44 return; 106 return;
45 } 107
46 gfs2_glock_hold(gl); 108 gfs2_glock_hold(gl);
47 set_bit(GLF_DIRTY, &gl->gl_flags); 109 set_bit(GLF_DIRTY, &gl->gl_flags);
48 sdp->sd_log_num_gl++; 110 sdp->sd_log_num_gl++;
49 list_add(&le->le_list, &sdp->sd_log_le_gl); 111 list_add(&le->le_list, &sdp->sd_log_le_gl);
112}
113
114static void glock_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
115{
116 gfs2_log_lock(sdp);
117 __glock_lo_add(sdp, le);
50 gfs2_log_unlock(sdp); 118 gfs2_log_unlock(sdp);
51} 119}
52 120
@@ -71,30 +139,25 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
71 struct gfs2_bufdata *bd = container_of(le, struct gfs2_bufdata, bd_le); 139 struct gfs2_bufdata *bd = container_of(le, struct gfs2_bufdata, bd_le);
72 struct gfs2_trans *tr; 140 struct gfs2_trans *tr;
73 141
142 lock_buffer(bd->bd_bh);
74 gfs2_log_lock(sdp); 143 gfs2_log_lock(sdp);
75 if (!list_empty(&bd->bd_list_tr)) { 144 if (!list_empty(&bd->bd_list_tr))
76 gfs2_log_unlock(sdp); 145 goto out;
77 return;
78 }
79 tr = current->journal_info; 146 tr = current->journal_info;
80 tr->tr_touched = 1; 147 tr->tr_touched = 1;
81 tr->tr_num_buf++; 148 tr->tr_num_buf++;
82 list_add(&bd->bd_list_tr, &tr->tr_list_buf); 149 list_add(&bd->bd_list_tr, &tr->tr_list_buf);
83 gfs2_log_unlock(sdp);
84
85 if (!list_empty(&le->le_list)) 150 if (!list_empty(&le->le_list))
86 return; 151 goto out;
87 152 __glock_lo_add(sdp, &bd->bd_gl->gl_le);
88 gfs2_trans_add_gl(bd->bd_gl);
89
90 gfs2_meta_check(sdp, bd->bd_bh); 153 gfs2_meta_check(sdp, bd->bd_bh);
91 gfs2_pin(sdp, bd->bd_bh); 154 gfs2_pin(sdp, bd->bd_bh);
92 gfs2_log_lock(sdp);
93 sdp->sd_log_num_buf++; 155 sdp->sd_log_num_buf++;
94 list_add(&le->le_list, &sdp->sd_log_le_buf); 156 list_add(&le->le_list, &sdp->sd_log_le_buf);
95 gfs2_log_unlock(sdp);
96
97 tr->tr_num_buf_new++; 157 tr->tr_num_buf_new++;
158out:
159 gfs2_log_unlock(sdp);
160 unlock_buffer(bd->bd_bh);
98} 161}
99 162
100static void buf_lo_incore_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) 163static void buf_lo_incore_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
@@ -476,31 +539,29 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
476 struct address_space *mapping = bd->bd_bh->b_page->mapping; 539 struct address_space *mapping = bd->bd_bh->b_page->mapping;
477 struct gfs2_inode *ip = GFS2_I(mapping->host); 540 struct gfs2_inode *ip = GFS2_I(mapping->host);
478 541
542 lock_buffer(bd->bd_bh);
479 gfs2_log_lock(sdp); 543 gfs2_log_lock(sdp);
480 if (!list_empty(&bd->bd_list_tr)) { 544 if (!list_empty(&bd->bd_list_tr))
481 gfs2_log_unlock(sdp); 545 goto out;
482 return;
483 }
484 tr->tr_touched = 1; 546 tr->tr_touched = 1;
485 if (gfs2_is_jdata(ip)) { 547 if (gfs2_is_jdata(ip)) {
486 tr->tr_num_buf++; 548 tr->tr_num_buf++;
487 list_add(&bd->bd_list_tr, &tr->tr_list_buf); 549 list_add(&bd->bd_list_tr, &tr->tr_list_buf);
488 } 550 }
489 gfs2_log_unlock(sdp);
490 if (!list_empty(&le->le_list)) 551 if (!list_empty(&le->le_list))
491 return; 552 goto out;
492 553
493 gfs2_trans_add_gl(bd->bd_gl); 554 __glock_lo_add(sdp, &bd->bd_gl->gl_le);
494 if (gfs2_is_jdata(ip)) { 555 if (gfs2_is_jdata(ip)) {
495 gfs2_pin(sdp, bd->bd_bh); 556 gfs2_pin(sdp, bd->bd_bh);
496 tr->tr_num_databuf_new++; 557 tr->tr_num_databuf_new++;
497 }
498 gfs2_log_lock(sdp);
499 if (gfs2_is_jdata(ip))
500 sdp->sd_log_num_jdata++; 558 sdp->sd_log_num_jdata++;
559 }
501 sdp->sd_log_num_databuf++; 560 sdp->sd_log_num_databuf++;
502 list_add(&le->le_list, &sdp->sd_log_le_databuf); 561 list_add(&le->le_list, &sdp->sd_log_le_databuf);
562out:
503 gfs2_log_unlock(sdp); 563 gfs2_log_unlock(sdp);
564 unlock_buffer(bd->bd_bh);
504} 565}
505 566
506static int gfs2_check_magic(struct buffer_head *bh) 567static int gfs2_check_magic(struct buffer_head *bh)
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c
index 8da343b34ae7..d762e4f7044e 100644
--- a/fs/gfs2/meta_io.c
+++ b/fs/gfs2/meta_io.c
@@ -298,76 +298,6 @@ void gfs2_attach_bufdata(struct gfs2_glock *gl, struct buffer_head *bh,
298} 298}
299 299
300/** 300/**
301 * gfs2_pin - Pin a buffer in memory
302 * @sdp: the filesystem the buffer belongs to
303 * @bh: The buffer to be pinned
304 *
305 */
306
307void gfs2_pin(struct gfs2_sbd *sdp, struct buffer_head *bh)
308{
309 struct gfs2_bufdata *bd = bh->b_private;
310
311 gfs2_assert_withdraw(sdp, test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags));
312
313 if (test_set_buffer_pinned(bh))
314 gfs2_assert_withdraw(sdp, 0);
315
316 wait_on_buffer(bh);
317
318 /* If this buffer is in the AIL and it has already been written
319 to in-place disk block, remove it from the AIL. */
320
321 gfs2_log_lock(sdp);
322 if (bd->bd_ail && !buffer_in_io(bh))
323 list_move(&bd->bd_ail_st_list, &bd->bd_ail->ai_ail2_list);
324 gfs2_log_unlock(sdp);
325
326 clear_buffer_dirty(bh);
327 wait_on_buffer(bh);
328
329 if (!buffer_uptodate(bh))
330 gfs2_io_error_bh(sdp, bh);
331
332 get_bh(bh);
333}
334
335/**
336 * gfs2_unpin - Unpin a buffer
337 * @sdp: the filesystem the buffer belongs to
338 * @bh: The buffer to unpin
339 * @ai:
340 *
341 */
342
343void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh,
344 struct gfs2_ail *ai)
345{
346 struct gfs2_bufdata *bd = bh->b_private;
347
348 gfs2_assert_withdraw(sdp, buffer_uptodate(bh));
349
350 if (!buffer_pinned(bh))
351 gfs2_assert_withdraw(sdp, 0);
352
353 mark_buffer_dirty(bh);
354 clear_buffer_pinned(bh);
355
356 gfs2_log_lock(sdp);
357 if (bd->bd_ail) {
358 list_del(&bd->bd_ail_st_list);
359 brelse(bh);
360 } else {
361 struct gfs2_glock *gl = bd->bd_gl;
362 list_add(&bd->bd_ail_gl_list, &gl->gl_ail_list);
363 atomic_inc(&gl->gl_ail_count);
364 }
365 bd->bd_ail = ai;
366 list_add(&bd->bd_ail_st_list, &ai->ai_ail1_list);
367 gfs2_log_unlock(sdp);
368}
369
370/**
371 * gfs2_meta_wipe - make inode's buffers so they aren't dirty/pinned anymore 301 * gfs2_meta_wipe - make inode's buffers so they aren't dirty/pinned anymore
372 * @ip: the inode who owns the buffers 302 * @ip: the inode who owns the buffers
373 * @bstart: the first buffer in the run 303 * @bstart: the first buffer in the run
diff --git a/fs/gfs2/meta_io.h b/fs/gfs2/meta_io.h
index 527bf19d9690..fd67f07cd60e 100644
--- a/fs/gfs2/meta_io.h
+++ b/fs/gfs2/meta_io.h
@@ -50,9 +50,6 @@ int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh);
50 50
51void gfs2_attach_bufdata(struct gfs2_glock *gl, struct buffer_head *bh, 51void gfs2_attach_bufdata(struct gfs2_glock *gl, struct buffer_head *bh,
52 int meta); 52 int meta);
53void gfs2_pin(struct gfs2_sbd *sdp, struct buffer_head *bh);
54void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh,
55 struct gfs2_ail *ai);
56 53
57void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen); 54void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen);
58 55