aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/libxfs/xfs_attr.c1
-rw-r--r--fs/xfs/libxfs/xfs_defer.c58
-rw-r--r--fs/xfs/libxfs/xfs_defer.h1
-rw-r--r--fs/xfs/xfs_dquot.c1
-rw-r--r--fs/xfs/xfs_trans.h1
5 files changed, 26 insertions, 36 deletions
diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index 3deb5cdadf08..227887bee00d 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -320,7 +320,6 @@ xfs_attr_set(
320 * buffer and run into problems with the write verifier. 320 * buffer and run into problems with the write verifier.
321 */ 321 */
322 xfs_trans_bhold(args.trans, leaf_bp); 322 xfs_trans_bhold(args.trans, leaf_bp);
323 xfs_defer_bjoin(args.trans->t_dfops, leaf_bp);
324 xfs_defer_ijoin(args.trans->t_dfops, dp); 323 xfs_defer_ijoin(args.trans->t_dfops, dp);
325 error = xfs_defer_finish(&args.trans); 324 error = xfs_defer_finish(&args.trans);
326 if (error) 325 if (error)
diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c
index 64e1abc60edc..e9b7671d289a 100644
--- a/fs/xfs/libxfs/xfs_defer.c
+++ b/fs/xfs/libxfs/xfs_defer.c
@@ -14,6 +14,7 @@
14#include "xfs_mount.h" 14#include "xfs_mount.h"
15#include "xfs_defer.h" 15#include "xfs_defer.h"
16#include "xfs_trans.h" 16#include "xfs_trans.h"
17#include "xfs_buf_item.h"
17#include "xfs_trace.h" 18#include "xfs_trace.h"
18 19
19/* 20/*
@@ -228,6 +229,10 @@ xfs_defer_trans_roll(
228 struct xfs_trans **tp) 229 struct xfs_trans **tp)
229{ 230{
230 struct xfs_defer_ops *dop = (*tp)->t_dfops; 231 struct xfs_defer_ops *dop = (*tp)->t_dfops;
232 struct xfs_buf_log_item *bli;
233 struct xfs_log_item *lip;
234 struct xfs_buf *bplist[XFS_DEFER_OPS_NR_BUFS];
235 int bpcount = 0;
231 int i; 236 int i;
232 int error; 237 int error;
233 238
@@ -235,9 +240,24 @@ xfs_defer_trans_roll(
235 for (i = 0; i < XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++) 240 for (i = 0; i < XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++)
236 xfs_trans_log_inode(*tp, dop->dop_inodes[i], XFS_ILOG_CORE); 241 xfs_trans_log_inode(*tp, dop->dop_inodes[i], XFS_ILOG_CORE);
237 242
238 /* Hold the (previously bjoin'd) buffer locked across the roll. */ 243 list_for_each_entry(lip, &(*tp)->t_items, li_trans) {
239 for (i = 0; i < XFS_DEFER_OPS_NR_BUFS && dop->dop_bufs[i]; i++) 244 switch (lip->li_type) {
240 xfs_trans_dirty_buf(*tp, dop->dop_bufs[i]); 245 case XFS_LI_BUF:
246 bli = container_of(lip, struct xfs_buf_log_item,
247 bli_item);
248 if (bli->bli_flags & XFS_BLI_HOLD) {
249 if (bpcount >= XFS_DEFER_OPS_NR_BUFS) {
250 ASSERT(0);
251 return -EFSCORRUPTED;
252 }
253 xfs_trans_dirty_buf(*tp, bli->bli_buf);
254 bplist[bpcount++] = bli->bli_buf;
255 }
256 break;
257 default:
258 break;
259 }
260 }
241 261
242 trace_xfs_defer_trans_roll((*tp)->t_mountp, dop, _RET_IP_); 262 trace_xfs_defer_trans_roll((*tp)->t_mountp, dop, _RET_IP_);
243 263
@@ -255,9 +275,9 @@ xfs_defer_trans_roll(
255 xfs_trans_ijoin(*tp, dop->dop_inodes[i], 0); 275 xfs_trans_ijoin(*tp, dop->dop_inodes[i], 0);
256 276
257 /* Rejoin the buffers and dirty them so the log moves forward. */ 277 /* Rejoin the buffers and dirty them so the log moves forward. */
258 for (i = 0; i < XFS_DEFER_OPS_NR_BUFS && dop->dop_bufs[i]; i++) { 278 for (i = 0; i < bpcount; i++) {
259 xfs_trans_bjoin(*tp, dop->dop_bufs[i]); 279 xfs_trans_bjoin(*tp, bplist[i]);
260 xfs_trans_bhold(*tp, dop->dop_bufs[i]); 280 xfs_trans_bhold(*tp, bplist[i]);
261 } 281 }
262 282
263 return error; 283 return error;
@@ -296,30 +316,6 @@ xfs_defer_ijoin(
296} 316}
297 317
298/* 318/*
299 * Add this buffer to the deferred op. Each joined buffer is relogged
300 * each time we roll the transaction.
301 */
302int
303xfs_defer_bjoin(
304 struct xfs_defer_ops *dop,
305 struct xfs_buf *bp)
306{
307 int i;
308
309 for (i = 0; i < XFS_DEFER_OPS_NR_BUFS; i++) {
310 if (dop->dop_bufs[i] == bp)
311 return 0;
312 else if (dop->dop_bufs[i] == NULL) {
313 dop->dop_bufs[i] = bp;
314 return 0;
315 }
316 }
317
318 ASSERT(0);
319 return -EFSCORRUPTED;
320}
321
322/*
323 * Reset an already used dfops after finish. 319 * Reset an already used dfops after finish.
324 */ 320 */
325static void 321static void
@@ -331,7 +327,6 @@ xfs_defer_reset(
331 ASSERT(!xfs_defer_has_unfinished_work(dop)); 327 ASSERT(!xfs_defer_has_unfinished_work(dop));
332 328
333 memset(dop->dop_inodes, 0, sizeof(dop->dop_inodes)); 329 memset(dop->dop_inodes, 0, sizeof(dop->dop_inodes));
334 memset(dop->dop_bufs, 0, sizeof(dop->dop_bufs));
335 330
336 /* 331 /*
337 * Low mode state transfers across transaction rolls to mirror dfops 332 * Low mode state transfers across transaction rolls to mirror dfops
@@ -594,7 +589,6 @@ xfs_defer_move(
594 list_splice_init(&src->dop_pending, &dst->dop_pending); 589 list_splice_init(&src->dop_pending, &dst->dop_pending);
595 590
596 memcpy(dst->dop_inodes, src->dop_inodes, sizeof(dst->dop_inodes)); 591 memcpy(dst->dop_inodes, src->dop_inodes, sizeof(dst->dop_inodes));
597 memcpy(dst->dop_bufs, src->dop_bufs, sizeof(dst->dop_bufs));
598 592
599 /* 593 /*
600 * Low free space mode was historically controlled by a dfops field. 594 * Low free space mode was historically controlled by a dfops field.
diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h
index 8908a2716774..4a8bb838adf2 100644
--- a/fs/xfs/libxfs/xfs_defer.h
+++ b/fs/xfs/libxfs/xfs_defer.h
@@ -43,7 +43,6 @@ void xfs_defer_cancel(struct xfs_trans *);
43void xfs_defer_init(struct xfs_trans *tp, struct xfs_defer_ops *dop); 43void xfs_defer_init(struct xfs_trans *tp, struct xfs_defer_ops *dop);
44bool xfs_defer_has_unfinished_work(struct xfs_defer_ops *dop); 44bool xfs_defer_has_unfinished_work(struct xfs_defer_ops *dop);
45int xfs_defer_ijoin(struct xfs_defer_ops *dop, struct xfs_inode *ip); 45int xfs_defer_ijoin(struct xfs_defer_ops *dop, struct xfs_inode *ip);
46int xfs_defer_bjoin(struct xfs_defer_ops *dop, struct xfs_buf *bp);
47void xfs_defer_move(struct xfs_trans *dtp, struct xfs_trans *stp); 46void xfs_defer_move(struct xfs_trans *dtp, struct xfs_trans *stp);
48 47
49/* Description of a deferred type. */ 48/* Description of a deferred type. */
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index da5c55cec966..e1196854dbcd 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -362,7 +362,6 @@ xfs_dquot_disk_alloc(
362 * manually or by committing the transaction. 362 * manually or by committing the transaction.
363 */ 363 */
364 xfs_trans_bhold(tp, bp); 364 xfs_trans_bhold(tp, bp);
365 error = xfs_defer_bjoin(tp->t_dfops, bp);
366 if (error) { 365 if (error) {
367 xfs_trans_bhold_release(tp, bp); 366 xfs_trans_bhold_release(tp, bp);
368 xfs_trans_brelse(tp, bp); 367 xfs_trans_brelse(tp, bp);
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index 7e493221160e..581456c79197 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -100,7 +100,6 @@ struct xfs_defer_ops {
100 100
101 /* relog these with each roll */ 101 /* relog these with each roll */
102 struct xfs_inode *dop_inodes[XFS_DEFER_OPS_NR_INODES]; 102 struct xfs_inode *dop_inodes[XFS_DEFER_OPS_NR_INODES];
103 struct xfs_buf *dop_bufs[XFS_DEFER_OPS_NR_BUFS];
104}; 103};
105 104
106/* 105/*