xfs: abort consistently on dquot flush failure
The dquot flush handler effectively aborts the dquot flush if the filesystem is already shut down, but doesn't actually shut down if the flush fails. Update xfs_qm_dqflush() to consistently abort the dquot flush and shutdown the fs if the flush fails with an unexpected error. Signed-off-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Allison Collins <allison.henderson@oracle.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
This commit is contained in:
Родитель
629dcb38dc
Коммит
b707fffda6
|
@ -1068,6 +1068,7 @@ xfs_qm_dqflush(
|
|||
struct xfs_buf **bpp)
|
||||
{
|
||||
struct xfs_mount *mp = dqp->q_mount;
|
||||
struct xfs_log_item *lip = &dqp->q_logitem.qli_item;
|
||||
struct xfs_buf *bp;
|
||||
struct xfs_dqblk *dqb;
|
||||
struct xfs_disk_dquot *ddqp;
|
||||
|
@ -1083,32 +1084,16 @@ xfs_qm_dqflush(
|
|||
|
||||
xfs_qm_dqunpin_wait(dqp);
|
||||
|
||||
/*
|
||||
* This may have been unpinned because the filesystem is shutting
|
||||
* down forcibly. If that's the case we must not write this dquot
|
||||
* to disk, because the log record didn't make it to disk.
|
||||
*
|
||||
* We also have to remove the log item from the AIL in this case,
|
||||
* as we wait for an emptry AIL as part of the unmount process.
|
||||
*/
|
||||
if (XFS_FORCED_SHUTDOWN(mp)) {
|
||||
struct xfs_log_item *lip = &dqp->q_logitem.qli_item;
|
||||
dqp->dq_flags &= ~XFS_DQ_DIRTY;
|
||||
|
||||
xfs_trans_ail_remove(lip, SHUTDOWN_CORRUPT_INCORE);
|
||||
|
||||
error = -EIO;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the buffer containing the on-disk dquot
|
||||
*/
|
||||
error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, dqp->q_blkno,
|
||||
mp->m_quotainfo->qi_dqchunklen, XBF_TRYLOCK,
|
||||
&bp, &xfs_dquot_buf_ops);
|
||||
if (error)
|
||||
if (error == -EAGAIN)
|
||||
goto out_unlock;
|
||||
if (error)
|
||||
goto out_abort;
|
||||
|
||||
/*
|
||||
* Calculate the location of the dquot inside the buffer.
|
||||
|
@ -1123,9 +1108,8 @@ xfs_qm_dqflush(
|
|||
xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS",
|
||||
be32_to_cpu(dqp->q_core.d_id), fa);
|
||||
xfs_buf_relse(bp);
|
||||
xfs_dqfunlock(dqp);
|
||||
xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
|
||||
return -EFSCORRUPTED;
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_abort;
|
||||
}
|
||||
|
||||
/* This is the only portion of data that needs to persist */
|
||||
|
@ -1174,6 +1158,10 @@ xfs_qm_dqflush(
|
|||
*bpp = bp;
|
||||
return 0;
|
||||
|
||||
out_abort:
|
||||
dqp->dq_flags &= ~XFS_DQ_DIRTY;
|
||||
xfs_trans_ail_remove(lip, SHUTDOWN_CORRUPT_INCORE);
|
||||
xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
|
||||
out_unlock:
|
||||
xfs_dqfunlock(dqp);
|
||||
return error;
|
||||
|
|
Загрузка…
Ссылка в новой задаче