|
@@ -309,11 +309,15 @@ xfs_sync_attr(
|
|
|
STATIC int
|
|
|
xfs_commit_dummy_trans(
|
|
|
struct xfs_mount *mp,
|
|
|
- uint log_flags)
|
|
|
+ uint flags)
|
|
|
{
|
|
|
struct xfs_inode *ip = mp->m_rootip;
|
|
|
struct xfs_trans *tp;
|
|
|
int error;
|
|
|
+ int log_flags = XFS_LOG_FORCE;
|
|
|
+
|
|
|
+ if (flags & SYNC_WAIT)
|
|
|
+ log_flags |= XFS_LOG_SYNC;
|
|
|
|
|
|
/*
|
|
|
* Put a dummy transaction in the log to tell recovery
|
|
@@ -331,13 +335,12 @@ xfs_commit_dummy_trans(
|
|
|
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
|
|
|
xfs_trans_ihold(tp, ip);
|
|
|
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
|
|
|
- /* XXX(hch): ignoring the error here.. */
|
|
|
error = xfs_trans_commit(tp, 0);
|
|
|
-
|
|
|
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
|
|
|
|
|
+ /* the log force ensures this transaction is pushed to disk */
|
|
|
xfs_log_force(mp, 0, log_flags);
|
|
|
- return 0;
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
int
|
|
@@ -385,7 +388,20 @@ xfs_sync_fsdata(
|
|
|
else
|
|
|
XFS_BUF_ASYNC(bp);
|
|
|
|
|
|
- return xfs_bwrite(mp, bp);
|
|
|
+ error = xfs_bwrite(mp, bp);
|
|
|
+ if (error)
|
|
|
+ return error;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If this is a data integrity sync make sure all pending buffers
|
|
|
+ * are flushed out for the log coverage check below.
|
|
|
+ */
|
|
|
+ if (flags & SYNC_WAIT)
|
|
|
+ xfs_flush_buftarg(mp->m_ddev_targp, 1);
|
|
|
+
|
|
|
+ if (xfs_log_need_covered(mp))
|
|
|
+ error = xfs_commit_dummy_trans(mp, flags);
|
|
|
+ return error;
|
|
|
|
|
|
out_brelse:
|
|
|
xfs_buf_relse(bp);
|
|
@@ -572,8 +588,6 @@ xfs_sync_worker(
|
|
|
/* dgc: errors ignored here */
|
|
|
error = xfs_qm_sync(mp, SYNC_TRYLOCK);
|
|
|
error = xfs_sync_fsdata(mp, SYNC_TRYLOCK);
|
|
|
- if (xfs_log_need_covered(mp))
|
|
|
- error = xfs_commit_dummy_trans(mp, XFS_LOG_FORCE);
|
|
|
}
|
|
|
mp->m_sync_seq++;
|
|
|
wake_up(&mp->m_wait_single_sync_task);
|