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:

committed by
Bob Peterson

父節點
f85c10e24a
當前提交
9e1a9ecd13
@@ -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);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user