gfs2: Don't withdraw under a spin lock

In two places, the gfs2_io_error_bh macro is called while holding the
sd_ail_lock spin lock.  This isn't allowed because gfs2_io_error_bh
withdraws the filesystem, which can sleep because it issues a uevent.
To fix that, add a gfs2_io_error_bh_wd macro that does withdraw the
filesystem and change gfs2_io_error_bh to not withdraw the filesystem.
In those places where the new gfs2_io_error_bh is used, withdraw the
filesystem after releasing sd_ail_lock.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Reviewed-by: Andrew Price <anprice@redhat.com>
This commit is contained in:
Andreas Gruenbacher
2018-06-07 11:56:46 +01:00
committed by Bob Peterson
父節點 f85c10e24a
當前提交 9e1a9ecd13
共有 5 個文件被更改,包括 49 次插入31 次删除

查看文件

@@ -46,14 +46,16 @@ int gfs2_lm_withdraw(struct gfs2_sbd *sdp, const char *fmt, ...)
test_and_set_bit(SDF_SHUTDOWN, &sdp->sd_flags))
return 0;
va_start(args, fmt);
if (fmt) {
va_start(args, fmt);
vaf.fmt = fmt;
vaf.va = &args;
vaf.fmt = fmt;
vaf.va = &args;
fs_err(sdp, "%pV", &vaf);
fs_err(sdp, "%pV", &vaf);
va_end(args);
va_end(args);
}
if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW) {
fs_err(sdp, "about to withdraw this file system\n");
@@ -246,21 +248,21 @@ int gfs2_io_error_i(struct gfs2_sbd *sdp, const char *function, char *file,
}
/**
* gfs2_io_error_bh_i - Flag a buffer I/O error and withdraw
* Returns: -1 if this call withdrew the machine,
* 0 if it was already withdrawn
* gfs2_io_error_bh_i - Flag a buffer I/O error
* @withdraw: withdraw the filesystem
*/
int gfs2_io_error_bh_i(struct gfs2_sbd *sdp, struct buffer_head *bh,
const char *function, char *file, unsigned int line)
void gfs2_io_error_bh_i(struct gfs2_sbd *sdp, struct buffer_head *bh,
const char *function, char *file, unsigned int line,
bool withdraw)
{
int rv;
rv = gfs2_lm_withdraw(sdp,
"fatal: I/O error\n"
" block = %llu\n"
" function = %s, file = %s, line = %u\n",
(unsigned long long)bh->b_blocknr,
function, file, line);
return rv;
fs_err(sdp,
"fatal: I/O error\n"
" block = %llu\n"
" function = %s, file = %s, line = %u\n",
(unsigned long long)bh->b_blocknr,
function, file, line);
if (withdraw)
gfs2_lm_withdraw(sdp, NULL);
}