forked from luck/tmp_suning_uos_patched
gfs2: fix infinite loop when checking ail item count before go_inval
Before this patch, the rgrp_go_inval and inode_go_inval functions each checked if there were any items left on the ail count (by way of a count), and if so, did a withdraw. But the withdraw code now uses glocks when changing the file system to read-only status. So we can not have glock functions withdrawing or a hang will likely result: The glocks can't be serviced by the work_func if the work_func is busy doing its own withdraw. This patch removes the checks from the go_inval functions and adds a centralized check in do_xmote to warn about the problem and not withdraw, but flag the error so it's eventually caught when the logd daemon eventually runs. Signed-off-by: Bob Peterson <rpeterso@redhat.com> Reviewed-by: Andreas Gruenbacher <agruenba@redhat.com>
This commit is contained in:
parent
601ef0d52e
commit
33dbd1e41a
|
@ -604,9 +604,22 @@ __acquires(&gl->gl_lockref.lock)
|
|||
spin_unlock(&gl->gl_lockref.lock);
|
||||
if (glops->go_sync)
|
||||
glops->go_sync(gl);
|
||||
if (test_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags))
|
||||
if (test_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags)) {
|
||||
/*
|
||||
* The call to go_sync should have cleared out the ail list.
|
||||
* If there are still items, we have a problem. We ought to
|
||||
* withdraw, but we can't because the withdraw code also uses
|
||||
* glocks. Warn about the error, dump the glock, then fall
|
||||
* through and wait for logd to do the withdraw for us.
|
||||
*/
|
||||
if ((atomic_read(&gl->gl_ail_count) != 0) &&
|
||||
(!cmpxchg(&sdp->sd_log_error, 0, -EIO))) {
|
||||
gfs2_assert_warn(sdp, !atomic_read(&gl->gl_ail_count));
|
||||
gfs2_dump_glock(NULL, gl, true);
|
||||
}
|
||||
glops->go_inval(gl, target == LM_ST_DEFERRED ? 0 : DIO_METADATA);
|
||||
clear_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags);
|
||||
clear_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags);
|
||||
}
|
||||
|
||||
gfs2_glock_hold(gl);
|
||||
if (sdp->sd_lockstruct.ls_ops->lm_lock) {
|
||||
|
|
|
@ -188,7 +188,6 @@ static void rgrp_go_inval(struct gfs2_glock *gl, int flags)
|
|||
gfs2_rgrp_brelse(rgd);
|
||||
|
||||
WARN_ON_ONCE(!(flags & DIO_METADATA));
|
||||
gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count));
|
||||
truncate_inode_pages_range(mapping, gl->gl_vm.start, gl->gl_vm.end);
|
||||
|
||||
if (rgd)
|
||||
|
@ -288,8 +287,6 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags)
|
|||
{
|
||||
struct gfs2_inode *ip = gfs2_glock2inode(gl);
|
||||
|
||||
gfs2_assert_withdraw(gl->gl_name.ln_sbd, !atomic_read(&gl->gl_ail_count));
|
||||
|
||||
if (flags & DIO_METADATA) {
|
||||
struct address_space *mapping = gfs2_glock2aspace(gl);
|
||||
truncate_inode_pages(mapping, 0);
|
||||
|
|
Loading…
Reference in New Issue
Block a user