diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2007-09-03 06:01:33 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2007-10-10 03:56:12 -0400 |
commit | 1ad38c437fa33f85ba4b6a85ea8c5478ee72d5bd (patch) | |
tree | 11a5fc7993ba9ae343fc72f03f9a11f312fd6128 | |
parent | 0820ab517e1b100ee3f9584ec27f93309689ebe7 (diff) |
[GFS2] Clean up gfs2_trans_add_revoke()
The following alters gfs2_trans_add_revoke() to take a struct
gfs2_bufdata as an argument. This eliminates the memory allocation which
was previously required by making use of the already existing struct
gfs2_bufdata. It makes some sanity checks to ensure that the
gfs2_bufdata has been removed from all the lists before its recycled as
a revoke structure. This saves one memory allocation and one free per
revoke structure.
Also as a result, and to simplify the locking, since there is no longer
any blocking code in gfs2_trans_add_revoke() we must hold the log lock
whenever this function is called. This reduces the amount of times we
take and unlock the log lock.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
-rw-r--r-- | fs/gfs2/glops.c | 14 | ||||
-rw-r--r-- | fs/gfs2/log.c | 4 | ||||
-rw-r--r-- | fs/gfs2/lops.c | 3 | ||||
-rw-r--r-- | fs/gfs2/meta_io.c | 35 | ||||
-rw-r--r-- | fs/gfs2/trans.c | 10 | ||||
-rw-r--r-- | fs/gfs2/trans.h | 2 |
6 files changed, 25 insertions, 43 deletions
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index b17346a355bf..4670dcb2a877 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
@@ -41,7 +41,6 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl) | |||
41 | struct list_head *head = &gl->gl_ail_list; | 41 | struct list_head *head = &gl->gl_ail_list; |
42 | struct gfs2_bufdata *bd; | 42 | struct gfs2_bufdata *bd; |
43 | struct buffer_head *bh; | 43 | struct buffer_head *bh; |
44 | u64 blkno; | ||
45 | int error; | 44 | int error; |
46 | 45 | ||
47 | blocks = atomic_read(&gl->gl_ail_count); | 46 | blocks = atomic_read(&gl->gl_ail_count); |
@@ -57,15 +56,12 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl) | |||
57 | bd = list_entry(head->next, struct gfs2_bufdata, | 56 | bd = list_entry(head->next, struct gfs2_bufdata, |
58 | bd_ail_gl_list); | 57 | bd_ail_gl_list); |
59 | bh = bd->bd_bh; | 58 | bh = bd->bd_bh; |
60 | blkno = bh->b_blocknr; | ||
61 | gfs2_assert_withdraw(sdp, !buffer_busy(bh)); | ||
62 | |||
63 | gfs2_remove_from_ail(NULL, bd); | 59 | gfs2_remove_from_ail(NULL, bd); |
64 | gfs2_log_unlock(sdp); | 60 | bd->bd_bh = NULL; |
65 | 61 | bh->b_private = NULL; | |
66 | gfs2_trans_add_revoke(sdp, blkno); | 62 | bd->bd_blkno = bh->b_blocknr; |
67 | 63 | gfs2_assert_withdraw(sdp, !buffer_busy(bh)); | |
68 | gfs2_log_lock(sdp); | 64 | gfs2_trans_add_revoke(sdp, bd); |
69 | } | 65 | } |
70 | gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count)); | 66 | gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count)); |
71 | gfs2_log_unlock(sdp); | 67 | gfs2_log_unlock(sdp); |
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 20fa528d457d..4d04e6f19706 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
@@ -71,8 +71,8 @@ unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, | |||
71 | void gfs2_remove_from_ail(struct address_space *mapping, struct gfs2_bufdata *bd) | 71 | void gfs2_remove_from_ail(struct address_space *mapping, struct gfs2_bufdata *bd) |
72 | { | 72 | { |
73 | bd->bd_ail = NULL; | 73 | bd->bd_ail = NULL; |
74 | list_del(&bd->bd_ail_st_list); | 74 | list_del_init(&bd->bd_ail_st_list); |
75 | list_del(&bd->bd_ail_gl_list); | 75 | list_del_init(&bd->bd_ail_gl_list); |
76 | atomic_dec(&bd->bd_gl->gl_ail_count); | 76 | atomic_dec(&bd->bd_gl->gl_ail_count); |
77 | if (mapping) | 77 | if (mapping) |
78 | gfs2_meta_cache_flush(GFS2_I(mapping->host)); | 78 | gfs2_meta_cache_flush(GFS2_I(mapping->host)); |
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index 4cbef4c23a6b..342c10e12af2 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c | |||
@@ -343,11 +343,8 @@ static void revoke_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le) | |||
343 | tr = current->journal_info; | 343 | tr = current->journal_info; |
344 | tr->tr_touched = 1; | 344 | tr->tr_touched = 1; |
345 | tr->tr_num_revoke++; | 345 | tr->tr_num_revoke++; |
346 | |||
347 | gfs2_log_lock(sdp); | ||
348 | sdp->sd_log_num_revoke++; | 346 | sdp->sd_log_num_revoke++; |
349 | list_add(&le->le_list, &sdp->sd_log_le_revoke); | 347 | list_add(&le->le_list, &sdp->sd_log_le_revoke); |
350 | gfs2_log_unlock(sdp); | ||
351 | } | 348 | } |
352 | 349 | ||
353 | static void revoke_lo_before_commit(struct gfs2_sbd *sdp) | 350 | static void revoke_lo_before_commit(struct gfs2_sbd *sdp) |
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index d762e4f7044e..19097bc7c81d 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c | |||
@@ -313,42 +313,31 @@ void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen) | |||
313 | while (blen) { | 313 | while (blen) { |
314 | bh = getbuf(ip->i_gl, bstart, NO_CREATE); | 314 | bh = getbuf(ip->i_gl, bstart, NO_CREATE); |
315 | if (bh) { | 315 | if (bh) { |
316 | struct gfs2_bufdata *bd = bh->b_private; | 316 | struct gfs2_bufdata *bd; |
317 | 317 | ||
318 | lock_buffer(bh); | ||
319 | gfs2_log_lock(sdp); | ||
320 | bd = bh->b_private; | ||
318 | if (test_clear_buffer_pinned(bh)) { | 321 | if (test_clear_buffer_pinned(bh)) { |
319 | struct gfs2_trans *tr = current->journal_info; | 322 | struct gfs2_trans *tr = current->journal_info; |
320 | struct gfs2_inode *bh_ip = | ||
321 | GFS2_I(bh->b_page->mapping->host); | ||
322 | |||
323 | gfs2_log_lock(sdp); | ||
324 | list_del_init(&bd->bd_le.le_list); | 323 | list_del_init(&bd->bd_le.le_list); |
325 | gfs2_assert_warn(sdp, sdp->sd_log_num_buf); | 324 | gfs2_assert_warn(sdp, sdp->sd_log_num_buf); |
326 | sdp->sd_log_num_buf--; | 325 | sdp->sd_log_num_buf--; |
327 | gfs2_log_unlock(sdp); | 326 | tr->tr_num_buf_rm++; |
328 | if (bh_ip->i_inode.i_private != NULL) | ||
329 | tr->tr_num_databuf_rm++; | ||
330 | else | ||
331 | tr->tr_num_buf_rm++; | ||
332 | brelse(bh); | 327 | brelse(bh); |
333 | } | 328 | } |
334 | if (bd) { | 329 | if (bd) { |
335 | gfs2_log_lock(sdp); | ||
336 | if (bd->bd_ail) { | 330 | if (bd->bd_ail) { |
337 | u64 blkno = bh->b_blocknr; | 331 | gfs2_remove_from_ail(NULL, bd); |
338 | bd->bd_ail = NULL; | 332 | bh->b_private = NULL; |
339 | list_del(&bd->bd_ail_st_list); | 333 | bd->bd_bh = NULL; |
340 | list_del(&bd->bd_ail_gl_list); | 334 | bd->bd_blkno = bh->b_blocknr; |
341 | atomic_dec(&bd->bd_gl->gl_ail_count); | 335 | gfs2_trans_add_revoke(sdp, bd); |
342 | brelse(bh); | 336 | } |
343 | gfs2_log_unlock(sdp); | ||
344 | gfs2_trans_add_revoke(sdp, blkno); | ||
345 | } else | ||
346 | gfs2_log_unlock(sdp); | ||
347 | } | 337 | } |
348 | |||
349 | lock_buffer(bh); | ||
350 | clear_buffer_dirty(bh); | 338 | clear_buffer_dirty(bh); |
351 | clear_buffer_uptodate(bh); | 339 | clear_buffer_uptodate(bh); |
340 | gfs2_log_unlock(sdp); | ||
352 | unlock_buffer(bh); | 341 | unlock_buffer(bh); |
353 | 342 | ||
354 | brelse(bh); | 343 | brelse(bh); |
diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c index 01cc27fefd84..717983e2c2ae 100644 --- a/fs/gfs2/trans.c +++ b/fs/gfs2/trans.c | |||
@@ -142,12 +142,12 @@ void gfs2_trans_add_bh(struct gfs2_glock *gl, struct buffer_head *bh, int meta) | |||
142 | lops_add(sdp, &bd->bd_le); | 142 | lops_add(sdp, &bd->bd_le); |
143 | } | 143 | } |
144 | 144 | ||
145 | void gfs2_trans_add_revoke(struct gfs2_sbd *sdp, u64 blkno) | 145 | void gfs2_trans_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) |
146 | { | 146 | { |
147 | struct gfs2_bufdata *bd = kmem_cache_alloc(gfs2_bufdata_cachep, | 147 | BUG_ON(!list_empty(&bd->bd_le.le_list)); |
148 | GFP_NOFS | __GFP_NOFAIL); | 148 | BUG_ON(!list_empty(&bd->bd_ail_st_list)); |
149 | BUG_ON(!list_empty(&bd->bd_ail_gl_list)); | ||
149 | lops_init_le(&bd->bd_le, &gfs2_revoke_lops); | 150 | lops_init_le(&bd->bd_le, &gfs2_revoke_lops); |
150 | bd->bd_blkno = blkno; | ||
151 | lops_add(sdp, &bd->bd_le); | 151 | lops_add(sdp, &bd->bd_le); |
152 | } | 152 | } |
153 | 153 | ||
@@ -160,7 +160,7 @@ void gfs2_trans_add_unrevoke(struct gfs2_sbd *sdp, u64 blkno) | |||
160 | 160 | ||
161 | list_for_each_entry(bd, &sdp->sd_log_le_revoke, bd_le.le_list) { | 161 | list_for_each_entry(bd, &sdp->sd_log_le_revoke, bd_le.le_list) { |
162 | if (bd->bd_blkno == blkno) { | 162 | if (bd->bd_blkno == blkno) { |
163 | list_del(&bd->bd_le.le_list); | 163 | list_del_init(&bd->bd_le.le_list); |
164 | gfs2_assert_withdraw(sdp, sdp->sd_log_num_revoke); | 164 | gfs2_assert_withdraw(sdp, sdp->sd_log_num_revoke); |
165 | sdp->sd_log_num_revoke--; | 165 | sdp->sd_log_num_revoke--; |
166 | found = 1; | 166 | found = 1; |
diff --git a/fs/gfs2/trans.h b/fs/gfs2/trans.h index 23d4cbe1de5b..043d5f4b9c4c 100644 --- a/fs/gfs2/trans.h +++ b/fs/gfs2/trans.h | |||
@@ -32,7 +32,7 @@ void gfs2_trans_end(struct gfs2_sbd *sdp); | |||
32 | 32 | ||
33 | void gfs2_trans_add_gl(struct gfs2_glock *gl); | 33 | void gfs2_trans_add_gl(struct gfs2_glock *gl); |
34 | void gfs2_trans_add_bh(struct gfs2_glock *gl, struct buffer_head *bh, int meta); | 34 | void gfs2_trans_add_bh(struct gfs2_glock *gl, struct buffer_head *bh, int meta); |
35 | void gfs2_trans_add_revoke(struct gfs2_sbd *sdp, u64 blkno); | 35 | void gfs2_trans_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd); |
36 | void gfs2_trans_add_unrevoke(struct gfs2_sbd *sdp, u64 blkno); | 36 | void gfs2_trans_add_unrevoke(struct gfs2_sbd *sdp, u64 blkno); |
37 | void gfs2_trans_add_rg(struct gfs2_rgrpd *rgd); | 37 | void gfs2_trans_add_rg(struct gfs2_rgrpd *rgd); |
38 | 38 | ||