aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_trans_buf.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_trans_buf.c')
-rw-r--r--fs/xfs/xfs_trans_buf.c243
1 files changed, 80 insertions, 163 deletions
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
index 49130628d5ef..fb586360d1c9 100644
--- a/fs/xfs/xfs_trans_buf.c
+++ b/fs/xfs/xfs_trans_buf.c
@@ -46,6 +46,65 @@ STATIC xfs_buf_t *xfs_trans_buf_item_match(xfs_trans_t *, xfs_buftarg_t *,
46STATIC xfs_buf_t *xfs_trans_buf_item_match_all(xfs_trans_t *, xfs_buftarg_t *, 46STATIC xfs_buf_t *xfs_trans_buf_item_match_all(xfs_trans_t *, xfs_buftarg_t *,
47 xfs_daddr_t, int); 47 xfs_daddr_t, int);
48 48
49/*
50 * Add the locked buffer to the transaction.
51 *
52 * The buffer must be locked, and it cannot be associated with any
53 * transaction.
54 *
55 * If the buffer does not yet have a buf log item associated with it,
56 * then allocate one for it. Then add the buf item to the transaction.
57 */
58STATIC void
59_xfs_trans_bjoin(
60 struct xfs_trans *tp,
61 struct xfs_buf *bp,
62 int reset_recur)
63{
64 struct xfs_buf_log_item *bip;
65
66 ASSERT(XFS_BUF_ISBUSY(bp));
67 ASSERT(XFS_BUF_FSPRIVATE2(bp, void *) == NULL);
68
69 /*
70 * The xfs_buf_log_item pointer is stored in b_fsprivate. If
71 * it doesn't have one yet, then allocate one and initialize it.
72 * The checks to see if one is there are in xfs_buf_item_init().
73 */
74 xfs_buf_item_init(bp, tp->t_mountp);
75 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
76 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
77 ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
78 ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
79 if (reset_recur)
80 bip->bli_recur = 0;
81
82 /*
83 * Take a reference for this transaction on the buf item.
84 */
85 atomic_inc(&bip->bli_refcount);
86
87 /*
88 * Get a log_item_desc to point at the new item.
89 */
90 (void) xfs_trans_add_item(tp, (xfs_log_item_t *)bip);
91
92 /*
93 * Initialize b_fsprivate2 so we can find it with incore_match()
94 * in xfs_trans_get_buf() and friends above.
95 */
96 XFS_BUF_SET_FSPRIVATE2(bp, tp);
97
98}
99
100void
101xfs_trans_bjoin(
102 struct xfs_trans *tp,
103 struct xfs_buf *bp)
104{
105 _xfs_trans_bjoin(tp, bp, 0);
106 trace_xfs_trans_bjoin(bp->b_fspriv);
107}
49 108
50/* 109/*
51 * Get and lock the buffer for the caller if it is not already 110 * Get and lock the buffer for the caller if it is not already
@@ -75,13 +134,14 @@ xfs_trans_get_buf(xfs_trans_t *tp,
75 xfs_buf_log_item_t *bip; 134 xfs_buf_log_item_t *bip;
76 135
77 if (flags == 0) 136 if (flags == 0)
78 flags = XFS_BUF_LOCK | XFS_BUF_MAPPED; 137 flags = XBF_LOCK | XBF_MAPPED;
79 138
80 /* 139 /*
81 * Default to a normal get_buf() call if the tp is NULL. 140 * Default to a normal get_buf() call if the tp is NULL.
82 */ 141 */
83 if (tp == NULL) 142 if (tp == NULL)
84 return xfs_buf_get(target_dev, blkno, len, flags | BUF_BUSY); 143 return xfs_buf_get(target_dev, blkno, len,
144 flags | XBF_DONT_BLOCK);
85 145
86 /* 146 /*
87 * If we find the buffer in the cache with this transaction 147 * If we find the buffer in the cache with this transaction
@@ -117,54 +177,22 @@ xfs_trans_get_buf(xfs_trans_t *tp,
117 } 177 }
118 178
119 /* 179 /*
120 * We always specify the BUF_BUSY flag within a transaction so 180 * We always specify the XBF_DONT_BLOCK flag within a transaction
121 * that get_buf does not try to push out a delayed write buffer 181 * so that get_buf does not try to push out a delayed write buffer
122 * which might cause another transaction to take place (if the 182 * which might cause another transaction to take place (if the
123 * buffer was delayed alloc). Such recursive transactions can 183 * buffer was delayed alloc). Such recursive transactions can
124 * easily deadlock with our current transaction as well as cause 184 * easily deadlock with our current transaction as well as cause
125 * us to run out of stack space. 185 * us to run out of stack space.
126 */ 186 */
127 bp = xfs_buf_get(target_dev, blkno, len, flags | BUF_BUSY); 187 bp = xfs_buf_get(target_dev, blkno, len, flags | XBF_DONT_BLOCK);
128 if (bp == NULL) { 188 if (bp == NULL) {
129 return NULL; 189 return NULL;
130 } 190 }
131 191
132 ASSERT(!XFS_BUF_GETERROR(bp)); 192 ASSERT(!XFS_BUF_GETERROR(bp));
133 193
134 /* 194 _xfs_trans_bjoin(tp, bp, 1);
135 * The xfs_buf_log_item pointer is stored in b_fsprivate. If 195 trace_xfs_trans_get_buf(bp->b_fspriv);
136 * it doesn't have one yet, then allocate one and initialize it.
137 * The checks to see if one is there are in xfs_buf_item_init().
138 */
139 xfs_buf_item_init(bp, tp->t_mountp);
140
141 /*
142 * Set the recursion count for the buffer within this transaction
143 * to 0.
144 */
145 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*);
146 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
147 ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
148 ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
149 bip->bli_recur = 0;
150
151 /*
152 * Take a reference for this transaction on the buf item.
153 */
154 atomic_inc(&bip->bli_refcount);
155
156 /*
157 * Get a log_item_desc to point at the new item.
158 */
159 (void) xfs_trans_add_item(tp, (xfs_log_item_t*)bip);
160
161 /*
162 * Initialize b_fsprivate2 so we can find it with incore_match()
163 * above.
164 */
165 XFS_BUF_SET_FSPRIVATE2(bp, tp);
166
167 trace_xfs_trans_get_buf(bip);
168 return (bp); 196 return (bp);
169} 197}
170 198
@@ -209,44 +237,11 @@ xfs_trans_getsb(xfs_trans_t *tp,
209 } 237 }
210 238
211 bp = xfs_getsb(mp, flags); 239 bp = xfs_getsb(mp, flags);
212 if (bp == NULL) { 240 if (bp == NULL)
213 return NULL; 241 return NULL;
214 }
215
216 /*
217 * The xfs_buf_log_item pointer is stored in b_fsprivate. If
218 * it doesn't have one yet, then allocate one and initialize it.
219 * The checks to see if one is there are in xfs_buf_item_init().
220 */
221 xfs_buf_item_init(bp, mp);
222
223 /*
224 * Set the recursion count for the buffer within this transaction
225 * to 0.
226 */
227 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*);
228 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
229 ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
230 ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
231 bip->bli_recur = 0;
232
233 /*
234 * Take a reference for this transaction on the buf item.
235 */
236 atomic_inc(&bip->bli_refcount);
237
238 /*
239 * Get a log_item_desc to point at the new item.
240 */
241 (void) xfs_trans_add_item(tp, (xfs_log_item_t*)bip);
242
243 /*
244 * Initialize b_fsprivate2 so we can find it with incore_match()
245 * above.
246 */
247 XFS_BUF_SET_FSPRIVATE2(bp, tp);
248 242
249 trace_xfs_trans_getsb(bip); 243 _xfs_trans_bjoin(tp, bp, 1);
244 trace_xfs_trans_getsb(bp->b_fspriv);
250 return (bp); 245 return (bp);
251} 246}
252 247
@@ -290,15 +285,15 @@ xfs_trans_read_buf(
290 int error; 285 int error;
291 286
292 if (flags == 0) 287 if (flags == 0)
293 flags = XFS_BUF_LOCK | XFS_BUF_MAPPED; 288 flags = XBF_LOCK | XBF_MAPPED;
294 289
295 /* 290 /*
296 * Default to a normal get_buf() call if the tp is NULL. 291 * Default to a normal get_buf() call if the tp is NULL.
297 */ 292 */
298 if (tp == NULL) { 293 if (tp == NULL) {
299 bp = xfs_buf_read(target, blkno, len, flags | BUF_BUSY); 294 bp = xfs_buf_read(target, blkno, len, flags | XBF_DONT_BLOCK);
300 if (!bp) 295 if (!bp)
301 return (flags & XFS_BUF_TRYLOCK) ? 296 return (flags & XBF_TRYLOCK) ?
302 EAGAIN : XFS_ERROR(ENOMEM); 297 EAGAIN : XFS_ERROR(ENOMEM);
303 298
304 if (XFS_BUF_GETERROR(bp) != 0) { 299 if (XFS_BUF_GETERROR(bp) != 0) {
@@ -385,14 +380,14 @@ xfs_trans_read_buf(
385 } 380 }
386 381
387 /* 382 /*
388 * We always specify the BUF_BUSY flag within a transaction so 383 * We always specify the XBF_DONT_BLOCK flag within a transaction
389 * that get_buf does not try to push out a delayed write buffer 384 * so that get_buf does not try to push out a delayed write buffer
390 * which might cause another transaction to take place (if the 385 * which might cause another transaction to take place (if the
391 * buffer was delayed alloc). Such recursive transactions can 386 * buffer was delayed alloc). Such recursive transactions can
392 * easily deadlock with our current transaction as well as cause 387 * easily deadlock with our current transaction as well as cause
393 * us to run out of stack space. 388 * us to run out of stack space.
394 */ 389 */
395 bp = xfs_buf_read(target, blkno, len, flags | BUF_BUSY); 390 bp = xfs_buf_read(target, blkno, len, flags | XBF_DONT_BLOCK);
396 if (bp == NULL) { 391 if (bp == NULL) {
397 *bpp = NULL; 392 *bpp = NULL;
398 return 0; 393 return 0;
@@ -424,40 +419,9 @@ xfs_trans_read_buf(
424 if (XFS_FORCED_SHUTDOWN(mp)) 419 if (XFS_FORCED_SHUTDOWN(mp))
425 goto shutdown_abort; 420 goto shutdown_abort;
426 421
427 /* 422 _xfs_trans_bjoin(tp, bp, 1);
428 * The xfs_buf_log_item pointer is stored in b_fsprivate. If 423 trace_xfs_trans_read_buf(bp->b_fspriv);
429 * it doesn't have one yet, then allocate one and initialize it.
430 * The checks to see if one is there are in xfs_buf_item_init().
431 */
432 xfs_buf_item_init(bp, tp->t_mountp);
433 424
434 /*
435 * Set the recursion count for the buffer within this transaction
436 * to 0.
437 */
438 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*);
439 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
440 ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
441 ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
442 bip->bli_recur = 0;
443
444 /*
445 * Take a reference for this transaction on the buf item.
446 */
447 atomic_inc(&bip->bli_refcount);
448
449 /*
450 * Get a log_item_desc to point at the new item.
451 */
452 (void) xfs_trans_add_item(tp, (xfs_log_item_t*)bip);
453
454 /*
455 * Initialize b_fsprivate2 so we can find it with incore_match()
456 * above.
457 */
458 XFS_BUF_SET_FSPRIVATE2(bp, tp);
459
460 trace_xfs_trans_read_buf(bip);
461 *bpp = bp; 425 *bpp = bp;
462 return 0; 426 return 0;
463 427
@@ -472,8 +436,8 @@ shutdown_abort:
472 if (XFS_BUF_ISSTALE(bp) && XFS_BUF_ISDELAYWRITE(bp)) 436 if (XFS_BUF_ISSTALE(bp) && XFS_BUF_ISDELAYWRITE(bp))
473 cmn_err(CE_NOTE, "about to pop assert, bp == 0x%p", bp); 437 cmn_err(CE_NOTE, "about to pop assert, bp == 0x%p", bp);
474#endif 438#endif
475 ASSERT((XFS_BUF_BFLAGS(bp) & (XFS_B_STALE|XFS_B_DELWRI)) != 439 ASSERT((XFS_BUF_BFLAGS(bp) & (XBF_STALE|XBF_DELWRI)) !=
476 (XFS_B_STALE|XFS_B_DELWRI)); 440 (XBF_STALE|XBF_DELWRI));
477 441
478 trace_xfs_trans_read_buf_shut(bp, _RET_IP_); 442 trace_xfs_trans_read_buf_shut(bp, _RET_IP_);
479 xfs_buf_relse(bp); 443 xfs_buf_relse(bp);
@@ -622,53 +586,6 @@ xfs_trans_brelse(xfs_trans_t *tp,
622} 586}
623 587
624/* 588/*
625 * Add the locked buffer to the transaction.
626 * The buffer must be locked, and it cannot be associated with any
627 * transaction.
628 *
629 * If the buffer does not yet have a buf log item associated with it,
630 * then allocate one for it. Then add the buf item to the transaction.
631 */
632void
633xfs_trans_bjoin(xfs_trans_t *tp,
634 xfs_buf_t *bp)
635{
636 xfs_buf_log_item_t *bip;
637
638 ASSERT(XFS_BUF_ISBUSY(bp));
639 ASSERT(XFS_BUF_FSPRIVATE2(bp, void *) == NULL);
640
641 /*
642 * The xfs_buf_log_item pointer is stored in b_fsprivate. If
643 * it doesn't have one yet, then allocate one and initialize it.
644 * The checks to see if one is there are in xfs_buf_item_init().
645 */
646 xfs_buf_item_init(bp, tp->t_mountp);
647 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
648 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
649 ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
650 ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
651
652 /*
653 * Take a reference for this transaction on the buf item.
654 */
655 atomic_inc(&bip->bli_refcount);
656
657 /*
658 * Get a log_item_desc to point at the new item.
659 */
660 (void) xfs_trans_add_item(tp, (xfs_log_item_t *)bip);
661
662 /*
663 * Initialize b_fsprivate2 so we can find it with incore_match()
664 * in xfs_trans_get_buf() and friends above.
665 */
666 XFS_BUF_SET_FSPRIVATE2(bp, tp);
667
668 trace_xfs_trans_bjoin(bip);
669}
670
671/*
672 * Mark the buffer as not needing to be unlocked when the buf item's 589 * Mark the buffer as not needing to be unlocked when the buf item's
673 * IOP_UNLOCK() routine is called. The buffer must already be locked 590 * IOP_UNLOCK() routine is called. The buffer must already be locked
674 * and associated with the given transaction. 591 * and associated with the given transaction.