Skip to content

Commit 471de20

Browse files
lrumancikChandan Babu R
authored andcommitted
xfs: up(ic_sema) if flushing data device fails
We flush the data device cache before we issue external log IO. If the flush fails, we shut down the log immediately and return. However, the iclog->ic_sema is left in a decremented state so let's add an up(). Prior to this patch, xfs/438 would fail consistently when running with an external log device: sync -> xfs_log_force -> xlog_write_iclog -> down(&iclog->ic_sema) -> blkdev_issue_flush (fail causes us to intiate shutdown) -> xlog_force_shutdown -> return unmount -> xfs_log_umount -> xlog_wait_iclog_completion -> down(&iclog->ic_sema) --------> HANG There is a second early return / shutdown. Make sure the up() happens for it as well. Also make sure we cleanup the iclog state, xlog_state_done_syncing, before dropping the iclog lock. Fixes: b5d721e ("xfs: external logs need to flush data device") Fixes: 842a42d ("xfs: shutdown on failure to add page to log bio") Fixes: 7d839e3 ("xfs: check return codes when flushing block devices") Signed-off-by: Leah Rumancik <[email protected]> Reviewed-by: "Darrick J. Wong" <[email protected]> Signed-off-by: Chandan Babu R <[email protected]>
1 parent 55f669f commit 471de20

File tree

1 file changed

+12
-11
lines changed

1 file changed

+12
-11
lines changed

fs/xfs/xfs_log.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1893,9 +1893,7 @@ xlog_write_iclog(
18931893
* the buffer manually, the code needs to be kept in sync
18941894
* with the I/O completion path.
18951895
*/
1896-
xlog_state_done_syncing(iclog);
1897-
up(&iclog->ic_sema);
1898-
return;
1896+
goto sync;
18991897
}
19001898

19011899
/*
@@ -1925,20 +1923,17 @@ xlog_write_iclog(
19251923
* avoid shutdown re-entering this path and erroring out again.
19261924
*/
19271925
if (log->l_targ != log->l_mp->m_ddev_targp &&
1928-
blkdev_issue_flush(log->l_mp->m_ddev_targp->bt_bdev)) {
1929-
xlog_force_shutdown(log, SHUTDOWN_LOG_IO_ERROR);
1930-
return;
1931-
}
1926+
blkdev_issue_flush(log->l_mp->m_ddev_targp->bt_bdev))
1927+
goto shutdown;
19321928
}
19331929
if (iclog->ic_flags & XLOG_ICL_NEED_FUA)
19341930
iclog->ic_bio.bi_opf |= REQ_FUA;
19351931

19361932
iclog->ic_flags &= ~(XLOG_ICL_NEED_FLUSH | XLOG_ICL_NEED_FUA);
19371933

1938-
if (xlog_map_iclog_data(&iclog->ic_bio, iclog->ic_data, count)) {
1939-
xlog_force_shutdown(log, SHUTDOWN_LOG_IO_ERROR);
1940-
return;
1941-
}
1934+
if (xlog_map_iclog_data(&iclog->ic_bio, iclog->ic_data, count))
1935+
goto shutdown;
1936+
19421937
if (is_vmalloc_addr(iclog->ic_data))
19431938
flush_kernel_vmap_range(iclog->ic_data, count);
19441939

@@ -1959,6 +1954,12 @@ xlog_write_iclog(
19591954
}
19601955

19611956
submit_bio(&iclog->ic_bio);
1957+
return;
1958+
shutdown:
1959+
xlog_force_shutdown(log, SHUTDOWN_LOG_IO_ERROR);
1960+
sync:
1961+
xlog_state_done_syncing(iclog);
1962+
up(&iclog->ic_sema);
19621963
}
19631964

19641965
/*

0 commit comments

Comments
 (0)