diff options
-rw-r--r-- | fs/gfs2/glock.c | 162 | ||||
-rw-r--r-- | fs/gfs2/incore.h | 1 | ||||
-rw-r--r-- | fs/gfs2/recovery.c | 79 |
3 files changed, 46 insertions, 196 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 32cc400..0f31715 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -450,86 +450,6 @@ void gfs2_holder_put(struct gfs2_holder *gh) } /** - * handle_recurse - put other holder structures (marked recursive) - * into the holders list - * @gh: the holder structure - * - */ - -static void handle_recurse(struct gfs2_holder *gh) -{ - struct gfs2_glock *gl = gh->gh_gl; - struct gfs2_sbd *sdp = gl->gl_sbd; - struct gfs2_holder *tmp_gh, *safe; - int found = 0; - - BUG_ON(!spin_is_locked(&gl->gl_spin)); - - printk(KERN_INFO "recursion %016llx, %u\n", gl->gl_name.ln_number, - gl->gl_name.ln_type); - - if (gfs2_assert_warn(sdp, gh->gh_owner)) - return; - - list_for_each_entry_safe(tmp_gh, safe, &gl->gl_waiters3, gh_list) { - if (tmp_gh->gh_owner != gh->gh_owner) - continue; - - gfs2_assert_warn(sdp, - test_bit(HIF_RECURSE, &tmp_gh->gh_iflags)); - - list_move_tail(&tmp_gh->gh_list, &gl->gl_holders); - tmp_gh->gh_error = 0; - set_bit(HIF_HOLDER, &tmp_gh->gh_iflags); - - complete(&tmp_gh->gh_wait); - - found = 1; - } - - gfs2_assert_warn(sdp, found); -} - -/** - * do_unrecurse - a recursive holder was just dropped of the waiters3 list - * @gh: the holder - * - * If there is only one other recursive holder, clear its HIF_RECURSE bit. - * If there is more than one, leave them alone. - * - */ - -static void do_unrecurse(struct gfs2_holder *gh) -{ - struct gfs2_glock *gl = gh->gh_gl; - struct gfs2_sbd *sdp = gl->gl_sbd; - struct gfs2_holder *tmp_gh, *last_gh = NULL; - int found = 0; - - BUG_ON(!spin_is_locked(&gl->gl_spin)); - - if (gfs2_assert_warn(sdp, gh->gh_owner)) - return; - - list_for_each_entry(tmp_gh, &gl->gl_waiters3, gh_list) { - if (tmp_gh->gh_owner != gh->gh_owner) - continue; - - gfs2_assert_warn(sdp, - test_bit(HIF_RECURSE, &tmp_gh->gh_iflags)); - - if (found) - return; - - found = 1; - last_gh = tmp_gh; - } - - if (!gfs2_assert_warn(sdp, found)) - clear_bit(HIF_RECURSE, &last_gh->gh_iflags); -} - -/** * rq_mutex - process a mutex request in the queue * @gh: the glock holder * @@ -562,7 +482,6 @@ static int rq_promote(struct gfs2_holder *gh) struct gfs2_glock *gl = gh->gh_gl; struct gfs2_sbd *sdp = gl->gl_sbd; struct gfs2_glock_operations *glops = gl->gl_ops; - int recurse; if (!relaxed_state_ok(gl->gl_state, gh->gh_state, gh->gh_flags)) { if (list_empty(&gl->gl_holders)) { @@ -588,7 +507,6 @@ static int rq_promote(struct gfs2_holder *gh) if (list_empty(&gl->gl_holders)) { set_bit(HIF_FIRST, &gh->gh_iflags); set_bit(GLF_LOCK, &gl->gl_flags); - recurse = 0; } else { struct gfs2_holder *next_gh; if (gh->gh_flags & GL_LOCAL_EXCL) @@ -597,16 +515,12 @@ static int rq_promote(struct gfs2_holder *gh) gh_list); if (next_gh->gh_flags & GL_LOCAL_EXCL) return 1; - recurse = test_bit(HIF_RECURSE, &gh->gh_iflags); } list_move_tail(&gh->gh_list, &gl->gl_holders); gh->gh_error = 0; set_bit(HIF_HOLDER, &gh->gh_iflags); - if (recurse) - handle_recurse(gh); - complete(&gh->gh_wait); return 0; @@ -897,8 +811,6 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret) spin_lock(&gl->gl_spin); list_del_init(&gh->gh_list); gh->gh_error = -EIO; - if (test_bit(HIF_RECURSE, &gh->gh_iflags)) - do_unrecurse(gh); spin_unlock(&gl->gl_spin); } else if (test_bit(HIF_DEMOTE, &gh->gh_iflags)) { @@ -922,8 +834,6 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret) spin_lock(&gl->gl_spin); list_del_init(&gh->gh_list); gh->gh_error = GLR_CANCELED; - if (test_bit(HIF_RECURSE, &gh->gh_iflags)) - do_unrecurse(gh); spin_unlock(&gl->gl_spin); } else if (relaxed_state_ok(gl->gl_state, gh->gh_state, gh->gh_flags)) { @@ -941,8 +851,6 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret) spin_lock(&gl->gl_spin); list_del_init(&gh->gh_list); gh->gh_error = GLR_TRYFAILED; - if (test_bit(HIF_RECURSE, &gh->gh_iflags)) - do_unrecurse(gh); spin_unlock(&gl->gl_spin); } else { @@ -1161,8 +1069,6 @@ static int glock_wait_internal(struct gfs2_holder *gh) !list_empty(&gh->gh_list)) { list_del_init(&gh->gh_list); gh->gh_error = GLR_TRYFAILED; - if (test_bit(HIF_RECURSE, &gh->gh_iflags)) - do_unrecurse(gh); run_queue(gl); spin_unlock(&gl->gl_spin); return gh->gh_error; @@ -1191,9 +1097,6 @@ static int glock_wait_internal(struct gfs2_holder *gh) if (gh->gh_error) { spin_lock(&gl->gl_spin); list_del_init(&gh->gh_list); - if (test_and_clear_bit(HIF_RECURSE, - &gh->gh_iflags)) - do_unrecurse(gh); spin_unlock(&gl->gl_spin); } } @@ -1202,8 +1105,6 @@ static int glock_wait_internal(struct gfs2_holder *gh) gl->gl_req_gh = NULL; gl->gl_req_bh = NULL; clear_bit(GLF_LOCK, &gl->gl_flags); - if (test_bit(HIF_RECURSE, &gh->gh_iflags)) - handle_recurse(gh); run_queue(gl); spin_unlock(&gl->gl_spin); } @@ -1225,40 +1126,6 @@ find_holder_by_owner(struct list_head *head, struct task_struct *owner) } /** - * recurse_check - - * - * Make sure the new holder is compatible with the pre-existing one. - * - */ - -static int recurse_check(struct gfs2_holder *existing, struct gfs2_holder *new, - unsigned int state) -{ - struct gfs2_sbd *sdp = existing->gh_gl->gl_sbd; - - if (gfs2_assert_warn(sdp, (new->gh_flags & LM_FLAG_ANY) || - !(existing->gh_flags & LM_FLAG_ANY))) - goto fail; - - if (gfs2_assert_warn(sdp, (existing->gh_flags & GL_LOCAL_EXCL) || - !(new->gh_flags & GL_LOCAL_EXCL))) - goto fail; - - if (gfs2_assert_warn(sdp, relaxed_state_ok(state, new->gh_state, - new->gh_flags))) - goto fail; - - return 0; - -fail: - print_symbol(KERN_WARNING "GFS2: Existing holder from %s\n", - existing->gh_ip); - print_symbol(KERN_WARNING "GFS2: New holder from %s\n", new->gh_ip); - set_bit(HIF_ABORTED, &new->gh_iflags); - return -EINVAL; -} - -/** * add_to_queue - Add a holder to the wait queue (but look for recursion) * @gh: the holder structure to add * @@ -1271,37 +1138,20 @@ static void add_to_queue(struct gfs2_holder *gh) BUG_ON(!gh->gh_owner); - if (!gh->gh_owner) - goto out; - existing = find_holder_by_owner(&gl->gl_holders, gh->gh_owner); if (existing) { - if (recurse_check(existing, gh, gl->gl_state)) - return; - - list_add_tail(&gh->gh_list, &gl->gl_holders); - set_bit(HIF_HOLDER, &gh->gh_iflags); - - gh->gh_error = 0; - complete(&gh->gh_wait); - - return; + print_symbol(KERN_WARNING "original: %s\n", existing->gh_ip); + print_symbol(KERN_WARNING "new: %s\n", gh->gh_ip); + BUG(); } existing = find_holder_by_owner(&gl->gl_waiters3, gh->gh_owner); if (existing) { - if (recurse_check(existing, gh, existing->gh_state)) - return; - - set_bit(HIF_RECURSE, &gh->gh_iflags); - set_bit(HIF_RECURSE, &existing->gh_iflags); - - list_add_tail(&gh->gh_list, &gl->gl_waiters3); - - return; + print_symbol(KERN_WARNING "original: %s\n", existing->gh_ip); + print_symbol(KERN_WARNING "new: %s\n", gh->gh_ip); + BUG(); } - out: if (gh->gh_flags & LM_FLAG_PRIORITY) list_add(&gh->gh_list, &gl->gl_waiters3); else diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 761f001..84dd2f5 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -146,7 +146,6 @@ enum { HIF_DEALLOC = 5, HIF_HOLDER = 6, HIF_FIRST = 7, - HIF_RECURSE = 8, HIF_ABORTED = 9, }; diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c index e91c2bd..7d46796 100644 --- a/fs/gfs2/recovery.c +++ b/fs/gfs2/recovery.c @@ -436,30 +436,35 @@ int gfs2_recover_journal(struct gfs2_jdesc *jd) unsigned int pass; int error; - fs_info(sdp, "jid=%u: Trying to acquire journal lock...\n", jd->jd_jid); - - /* Aquire the journal lock so we can do recovery */ - - error = gfs2_glock_nq_num(sdp, jd->jd_jid, &gfs2_journal_glops, - LM_ST_EXCLUSIVE, - LM_FLAG_NOEXP | LM_FLAG_TRY | GL_NOCACHE, - &j_gh); - switch (error) { - case 0: - break; + if (jd->jd_jid != sdp->sd_lockstruct.ls_jid) { + fs_info(sdp, "jid=%u: Trying to acquire journal lock...\n", + jd->jd_jid); - case GLR_TRYFAILED: - fs_info(sdp, "jid=%u: Busy\n", jd->jd_jid); - error = 0; + /* Aquire the journal lock so we can do recovery */ - default: - goto fail; - }; + error = gfs2_glock_nq_num(sdp, jd->jd_jid, &gfs2_journal_glops, + LM_ST_EXCLUSIVE, + LM_FLAG_NOEXP | LM_FLAG_TRY | GL_NOCACHE, + &j_gh); + switch (error) { + case 0: + break; + + case GLR_TRYFAILED: + fs_info(sdp, "jid=%u: Busy\n", jd->jd_jid); + error = 0; + + default: + goto fail; + }; - error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, - LM_FLAG_NOEXP, &ji_gh); - if (error) - goto fail_gunlock_j; + error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, + LM_FLAG_NOEXP, &ji_gh); + if (error) + goto fail_gunlock_j; + } else { + fs_info(sdp, "jid=%u, already locked for use\n", jd->jd_jid); + } fs_info(sdp, "jid=%u: Looking at journal...\n", jd->jd_jid); @@ -481,10 +486,8 @@ int gfs2_recover_journal(struct gfs2_jdesc *jd) error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, - LM_FLAG_NOEXP | - LM_FLAG_PRIORITY | - GL_NEVER_RECURSE | - GL_NOCANCEL | + LM_FLAG_NOEXP | LM_FLAG_PRIORITY | + GL_NEVER_RECURSE | GL_NOCANCEL | GL_NOCACHE, &t_gh); if (error) @@ -521,37 +524,35 @@ int gfs2_recover_journal(struct gfs2_jdesc *jd) goto fail_gunlock_tr; gfs2_glock_dq_uninit(&t_gh); - t = DIV_ROUND_UP(jiffies - t, HZ); - fs_info(sdp, "jid=%u: Journal replayed in %lus\n", jd->jd_jid, t); } - gfs2_glock_dq_uninit(&ji_gh); + if (jd->jd_jid != sdp->sd_lockstruct.ls_jid) + gfs2_glock_dq_uninit(&ji_gh); gfs2_lm_recovery_done(sdp, jd->jd_jid, LM_RD_SUCCESS); - gfs2_glock_dq_uninit(&j_gh); + if (jd->jd_jid != sdp->sd_lockstruct.ls_jid) + gfs2_glock_dq_uninit(&j_gh); fs_info(sdp, "jid=%u: Done\n", jd->jd_jid); - return 0; - fail_gunlock_tr: +fail_gunlock_tr: gfs2_glock_dq_uninit(&t_gh); - - fail_gunlock_ji: - gfs2_glock_dq_uninit(&ji_gh); - - fail_gunlock_j: - gfs2_glock_dq_uninit(&j_gh); +fail_gunlock_ji: + if (jd->jd_jid != sdp->sd_lockstruct.ls_jid) { + gfs2_glock_dq_uninit(&ji_gh); +fail_gunlock_j: + gfs2_glock_dq_uninit(&j_gh); + } fs_info(sdp, "jid=%u: %s\n", jd->jd_jid, (error) ? "Failed" : "Done"); - fail: +fail: gfs2_lm_recovery_done(sdp, jd->jd_jid, LM_RD_GAVEUP); - return error; } |