aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/lops.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2011-04-14 11:50:31 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2011-04-20 04:01:17 -0400
commitf42ab0852946c1fb5103682c5897eb3da908e4b0 (patch)
tree3847b23d2cac6bab422e6e001e0c6d6c66a81f1e /fs/gfs2/lops.c
parent627c10b7e471b5dcfb7101d6cc74d219619c9bc4 (diff)
GFS2: Optimise glock lru and end of life inodes
The GLF_LRU flag introduced in the previous patch can be used to check if a glock is on the lru list when a new holder is queued and if so remove it, without having first to get the lru_lock. The main purpose of this patch however is to optimise the glocks left over when an inode at end of life is being evicted. Previously such glocks were left with the GLF_LFLUSH flag set, so that when reclaimed, each one required a log flush. This patch resets the GLF_LFLUSH flag when there is nothing left to flush thus preventing later log flushes as glocks are reused or demoted. In order to do this, we need to keep track of the number of revokes which are outstanding, and also to clear the GLF_LFLUSH bit after a log commit when only revokes have been processed. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/lops.c')
-rw-r--r--fs/gfs2/lops.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 611a51d476b2..05bbb124699f 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -320,12 +320,16 @@ static void buf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
320 320
321static void revoke_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le) 321static void revoke_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
322{ 322{
323 struct gfs2_bufdata *bd = container_of(le, struct gfs2_bufdata, bd_le);
324 struct gfs2_glock *gl = bd->bd_gl;
323 struct gfs2_trans *tr; 325 struct gfs2_trans *tr;
324 326
325 tr = current->journal_info; 327 tr = current->journal_info;
326 tr->tr_touched = 1; 328 tr->tr_touched = 1;
327 tr->tr_num_revoke++; 329 tr->tr_num_revoke++;
328 sdp->sd_log_num_revoke++; 330 sdp->sd_log_num_revoke++;
331 atomic_inc(&gl->gl_revokes);
332 set_bit(GLF_LFLUSH, &gl->gl_flags);
329 list_add(&le->le_list, &sdp->sd_log_le_revoke); 333 list_add(&le->le_list, &sdp->sd_log_le_revoke);
330} 334}
331 335
@@ -348,9 +352,7 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp)
348 ld->ld_data1 = cpu_to_be32(sdp->sd_log_num_revoke); 352 ld->ld_data1 = cpu_to_be32(sdp->sd_log_num_revoke);
349 offset = sizeof(struct gfs2_log_descriptor); 353 offset = sizeof(struct gfs2_log_descriptor);
350 354
351 while (!list_empty(head)) { 355 list_for_each_entry(bd, head, bd_le.le_list) {
352 bd = list_entry(head->next, struct gfs2_bufdata, bd_le.le_list);
353 list_del_init(&bd->bd_le.le_list);
354 sdp->sd_log_num_revoke--; 356 sdp->sd_log_num_revoke--;
355 357
356 if (offset + sizeof(u64) > sdp->sd_sb.sb_bsize) { 358 if (offset + sizeof(u64) > sdp->sd_sb.sb_bsize) {
@@ -365,8 +367,6 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp)
365 } 367 }
366 368
367 *(__be64 *)(bh->b_data + offset) = cpu_to_be64(bd->bd_blkno); 369 *(__be64 *)(bh->b_data + offset) = cpu_to_be64(bd->bd_blkno);
368 kmem_cache_free(gfs2_bufdata_cachep, bd);
369
370 offset += sizeof(u64); 370 offset += sizeof(u64);
371 } 371 }
372 gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); 372 gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke);
@@ -374,6 +374,22 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp)
374 submit_bh(WRITE_SYNC, bh); 374 submit_bh(WRITE_SYNC, bh);
375} 375}
376 376
377static void revoke_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
378{
379 struct list_head *head = &sdp->sd_log_le_revoke;
380 struct gfs2_bufdata *bd;
381 struct gfs2_glock *gl;
382
383 while (!list_empty(head)) {
384 bd = list_entry(head->next, struct gfs2_bufdata, bd_le.le_list);
385 list_del_init(&bd->bd_le.le_list);
386 gl = bd->bd_gl;
387 atomic_dec(&gl->gl_revokes);
388 clear_bit(GLF_LFLUSH, &gl->gl_flags);
389 kmem_cache_free(gfs2_bufdata_cachep, bd);
390 }
391}
392
377static void revoke_lo_before_scan(struct gfs2_jdesc *jd, 393static void revoke_lo_before_scan(struct gfs2_jdesc *jd,
378 struct gfs2_log_header_host *head, int pass) 394 struct gfs2_log_header_host *head, int pass)
379{ 395{
@@ -747,6 +763,7 @@ const struct gfs2_log_operations gfs2_buf_lops = {
747const struct gfs2_log_operations gfs2_revoke_lops = { 763const struct gfs2_log_operations gfs2_revoke_lops = {
748 .lo_add = revoke_lo_add, 764 .lo_add = revoke_lo_add,
749 .lo_before_commit = revoke_lo_before_commit, 765 .lo_before_commit = revoke_lo_before_commit,
766 .lo_after_commit = revoke_lo_after_commit,
750 .lo_before_scan = revoke_lo_before_scan, 767 .lo_before_scan = revoke_lo_before_scan,
751 .lo_scan_elements = revoke_lo_scan_elements, 768 .lo_scan_elements = revoke_lo_scan_elements,
752 .lo_after_scan = revoke_lo_after_scan, 769 .lo_after_scan = revoke_lo_after_scan,