diff options
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/glock.c | 4 | ||||
-rw-r--r-- | fs/gfs2/incore.h | 2 | ||||
-rw-r--r-- | fs/gfs2/log.c | 4 | ||||
-rw-r--r-- | fs/gfs2/lops.c | 33 | ||||
-rw-r--r-- | fs/gfs2/main.c | 1 | ||||
-rw-r--r-- | fs/gfs2/super.c | 2 |
6 files changed, 15 insertions, 31 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index f0857c056df1..f1ebcb42cbf5 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -137,7 +137,7 @@ void gfs2_glock_free(struct gfs2_glock *gl) { struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; - BUG_ON(test_bit(GLF_REVOKES, &gl->gl_flags)); + BUG_ON(atomic_read(&gl->gl_revokes)); rhashtable_remove_fast(&gl_hash_table, &gl->gl_node, ht_parms); smp_mb(); wake_up_glock(gl); @@ -1798,7 +1798,7 @@ void gfs2_dump_glock(struct seq_file *seq, struct gfs2_glock *gl) state2str(gl->gl_target), state2str(gl->gl_demote_state), dtime, atomic_read(&gl->gl_ail_count), - test_bit(GLF_REVOKES, &gl->gl_flags) ? 1 : 0, + atomic_read(&gl->gl_revokes), (int)gl->gl_lockref.count, gl->gl_hold_time); list_for_each_entry(gh, &gl->gl_holders, gh_list) diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 8c4b334d1be4..c9af93ac6c73 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -342,7 +342,6 @@ enum { GLF_OBJECT = 14, /* Used only for tracing */ GLF_BLOCKING = 15, GLF_INODE_CREATING = 16, /* Inode creation occurring */ - GLF_REVOKES = 17, /* Glock has revokes in queue */ }; struct gfs2_glock { @@ -372,6 +371,7 @@ struct gfs2_glock { struct list_head gl_lru; struct list_head gl_ail_list; atomic_t gl_ail_count; + atomic_t gl_revokes; struct delayed_work gl_work; union { /* For inode and iopen glocks only */ diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 1360008c4ee9..c4c9700c366e 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -603,10 +603,8 @@ void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) gfs2_remove_from_ail(bd); /* drops ref on bh */ bd->bd_bh = NULL; sdp->sd_log_num_revoke++; - if (!test_bit(GLF_REVOKES, &gl->gl_flags)) { - set_bit(GLF_REVOKES, &gl->gl_flags); + if (atomic_inc_return(&gl->gl_revokes) == 1) gfs2_glock_hold(gl); - } set_bit(GLF_LFLUSH, &gl->gl_flags); list_add(&bd->bd_list, &sdp->sd_log_revokes); } diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index badb27ffc874..1921cda034fd 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c @@ -857,34 +857,19 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) static void revoke_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) { struct list_head *head = &sdp->sd_log_revokes; - struct gfs2_bufdata *bd, *tmp; - - /* - * Glocks can be referenced repeatedly on the revoke list, but the list - * only holds one reference. All glocks on the list will have the - * GLF_REVOKES flag set initially. - */ - - list_for_each_entry_safe(bd, tmp, head, bd_list) { - struct gfs2_glock *gl = bd->bd_gl; + struct gfs2_bufdata *bd; + struct gfs2_glock *gl; - if (test_bit(GLF_REVOKES, &gl->gl_flags)) { - /* Keep each glock on the list exactly once. */ - clear_bit(GLF_REVOKES, &gl->gl_flags); - continue; + while (!list_empty(head)) { + bd = list_entry(head->next, struct gfs2_bufdata, bd_list); + list_del_init(&bd->bd_list); + gl = bd->bd_gl; + if (atomic_dec_return(&gl->gl_revokes) == 0) { + clear_bit(GLF_LFLUSH, &gl->gl_flags); + gfs2_glock_queue_put(gl); } - list_del(&bd->bd_list); - kmem_cache_free(gfs2_bufdata_cachep, bd); - } - list_for_each_entry_safe(bd, tmp, head, bd_list) { - struct gfs2_glock *gl = bd->bd_gl; - - list_del(&bd->bd_list); kmem_cache_free(gfs2_bufdata_cachep, bd); - clear_bit(GLF_LFLUSH, &gl->gl_flags); - gfs2_glock_queue_put(gl); } - /* the list is empty now */ } static void revoke_lo_before_scan(struct gfs2_jdesc *jd, diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index 57761731be4f..a1a295b739fb 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c @@ -56,6 +56,7 @@ static void gfs2_init_glock_once(void *foo) INIT_LIST_HEAD(&gl->gl_lru); INIT_LIST_HEAD(&gl->gl_ail_list); atomic_set(&gl->gl_ail_count, 0); + atomic_set(&gl->gl_revokes, 0); } static void gfs2_init_gl_aspace_once(void *foo) diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 2bac687d0ed9..b70cea5c8c59 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -1474,7 +1474,7 @@ static void gfs2_final_release_pages(struct gfs2_inode *ip) truncate_inode_pages(gfs2_glock2aspace(ip->i_gl), 0); truncate_inode_pages(&inode->i_data, 0); - if (!test_bit(GLF_REVOKES, &gl->gl_flags)) { + if (atomic_read(&gl->gl_revokes) == 0) { clear_bit(GLF_LFLUSH, &gl->gl_flags); clear_bit(GLF_DIRTY, &gl->gl_flags); } |