|
@@ -249,6 +249,10 @@ xfs_defer_trans_roll(
|
|
|
for (i = 0; i < XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++)
|
|
|
xfs_trans_log_inode(*tp, dop->dop_inodes[i], XFS_ILOG_CORE);
|
|
|
|
|
|
+ /* Hold the (previously bjoin'd) buffer locked across the roll. */
|
|
|
+ for (i = 0; i < XFS_DEFER_OPS_NR_BUFS && dop->dop_bufs[i]; i++)
|
|
|
+ xfs_trans_dirty_buf(*tp, dop->dop_bufs[i]);
|
|
|
+
|
|
|
trace_xfs_defer_trans_roll((*tp)->t_mountp, dop);
|
|
|
|
|
|
/* Roll the transaction. */
|
|
@@ -264,6 +268,12 @@ xfs_defer_trans_roll(
|
|
|
for (i = 0; i < XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++)
|
|
|
xfs_trans_ijoin(*tp, dop->dop_inodes[i], 0);
|
|
|
|
|
|
+ /* Rejoin the buffers and dirty them so the log moves forward. */
|
|
|
+ for (i = 0; i < XFS_DEFER_OPS_NR_BUFS && dop->dop_bufs[i]; i++) {
|
|
|
+ xfs_trans_bjoin(*tp, dop->dop_bufs[i]);
|
|
|
+ xfs_trans_bhold(*tp, dop->dop_bufs[i]);
|
|
|
+ }
|
|
|
+
|
|
|
return error;
|
|
|
}
|
|
|
|
|
@@ -295,6 +305,31 @@ xfs_defer_ijoin(
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ ASSERT(0);
|
|
|
+ return -EFSCORRUPTED;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Add this buffer to the deferred op. Each joined buffer is relogged
|
|
|
+ * each time we roll the transaction.
|
|
|
+ */
|
|
|
+int
|
|
|
+xfs_defer_bjoin(
|
|
|
+ struct xfs_defer_ops *dop,
|
|
|
+ struct xfs_buf *bp)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+
|
|
|
+ for (i = 0; i < XFS_DEFER_OPS_NR_BUFS; i++) {
|
|
|
+ if (dop->dop_bufs[i] == bp)
|
|
|
+ return 0;
|
|
|
+ else if (dop->dop_bufs[i] == NULL) {
|
|
|
+ dop->dop_bufs[i] = bp;
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ASSERT(0);
|
|
|
return -EFSCORRUPTED;
|
|
|
}
|
|
|
|
|
@@ -493,9 +528,7 @@ xfs_defer_init(
|
|
|
struct xfs_defer_ops *dop,
|
|
|
xfs_fsblock_t *fbp)
|
|
|
{
|
|
|
- dop->dop_committed = false;
|
|
|
- dop->dop_low = false;
|
|
|
- memset(&dop->dop_inodes, 0, sizeof(dop->dop_inodes));
|
|
|
+ memset(dop, 0, sizeof(struct xfs_defer_ops));
|
|
|
*fbp = NULLFSBLOCK;
|
|
|
INIT_LIST_HEAD(&dop->dop_intake);
|
|
|
INIT_LIST_HEAD(&dop->dop_pending);
|