.. | .. |
---|
10 | 10 | #include "xfs_log_format.h" |
---|
11 | 11 | #include "xfs_trans_resv.h" |
---|
12 | 12 | #include "xfs_mount.h" |
---|
13 | | -#include "xfs_inode.h" |
---|
14 | 13 | #include "xfs_trans.h" |
---|
15 | 14 | #include "xfs_buf_item.h" |
---|
16 | 15 | #include "xfs_trans_priv.h" |
---|
17 | | -#include "xfs_error.h" |
---|
18 | 16 | #include "xfs_trace.h" |
---|
19 | 17 | |
---|
20 | 18 | /* |
---|
.. | .. |
---|
114 | 112 | * If the transaction pointer is NULL, make this just a normal |
---|
115 | 113 | * get_buf() call. |
---|
116 | 114 | */ |
---|
117 | | -struct xfs_buf * |
---|
| 115 | +int |
---|
118 | 116 | xfs_trans_get_buf_map( |
---|
119 | 117 | struct xfs_trans *tp, |
---|
120 | 118 | struct xfs_buftarg *target, |
---|
121 | 119 | struct xfs_buf_map *map, |
---|
122 | 120 | int nmaps, |
---|
123 | | - xfs_buf_flags_t flags) |
---|
| 121 | + xfs_buf_flags_t flags, |
---|
| 122 | + struct xfs_buf **bpp) |
---|
124 | 123 | { |
---|
125 | 124 | xfs_buf_t *bp; |
---|
126 | 125 | struct xfs_buf_log_item *bip; |
---|
| 126 | + int error; |
---|
127 | 127 | |
---|
| 128 | + *bpp = NULL; |
---|
128 | 129 | if (!tp) |
---|
129 | | - return xfs_buf_get_map(target, map, nmaps, flags); |
---|
| 130 | + return xfs_buf_get_map(target, map, nmaps, flags, bpp); |
---|
130 | 131 | |
---|
131 | 132 | /* |
---|
132 | 133 | * If we find the buffer in the cache with this transaction |
---|
.. | .. |
---|
148 | 149 | ASSERT(atomic_read(&bip->bli_refcount) > 0); |
---|
149 | 150 | bip->bli_recur++; |
---|
150 | 151 | trace_xfs_trans_get_buf_recur(bip); |
---|
151 | | - return bp; |
---|
| 152 | + *bpp = bp; |
---|
| 153 | + return 0; |
---|
152 | 154 | } |
---|
153 | 155 | |
---|
154 | | - bp = xfs_buf_get_map(target, map, nmaps, flags); |
---|
155 | | - if (bp == NULL) { |
---|
156 | | - return NULL; |
---|
157 | | - } |
---|
| 156 | + error = xfs_buf_get_map(target, map, nmaps, flags, &bp); |
---|
| 157 | + if (error) |
---|
| 158 | + return error; |
---|
158 | 159 | |
---|
159 | 160 | ASSERT(!bp->b_error); |
---|
160 | 161 | |
---|
161 | 162 | _xfs_trans_bjoin(tp, bp, 1); |
---|
162 | 163 | trace_xfs_trans_get_buf(bp->b_log_item); |
---|
163 | | - return bp; |
---|
| 164 | + *bpp = bp; |
---|
| 165 | + return 0; |
---|
164 | 166 | } |
---|
165 | 167 | |
---|
166 | 168 | /* |
---|
167 | | - * Get and lock the superblock buffer of this file system for the |
---|
168 | | - * given transaction. |
---|
169 | | - * |
---|
170 | | - * We don't need to use incore_match() here, because the superblock |
---|
171 | | - * buffer is a private buffer which we keep a pointer to in the |
---|
172 | | - * mount structure. |
---|
| 169 | + * Get and lock the superblock buffer for the given transaction. |
---|
173 | 170 | */ |
---|
174 | | -xfs_buf_t * |
---|
| 171 | +struct xfs_buf * |
---|
175 | 172 | xfs_trans_getsb( |
---|
176 | | - xfs_trans_t *tp, |
---|
177 | | - struct xfs_mount *mp, |
---|
178 | | - int flags) |
---|
| 173 | + struct xfs_trans *tp) |
---|
179 | 174 | { |
---|
180 | | - xfs_buf_t *bp; |
---|
181 | | - struct xfs_buf_log_item *bip; |
---|
| 175 | + struct xfs_buf *bp = tp->t_mountp->m_sb_bp; |
---|
182 | 176 | |
---|
183 | 177 | /* |
---|
184 | | - * Default to just trying to lock the superblock buffer |
---|
185 | | - * if tp is NULL. |
---|
| 178 | + * Just increment the lock recursion count if the buffer is already |
---|
| 179 | + * attached to this transaction. |
---|
186 | 180 | */ |
---|
187 | | - if (tp == NULL) |
---|
188 | | - return xfs_getsb(mp, flags); |
---|
189 | | - |
---|
190 | | - /* |
---|
191 | | - * If the superblock buffer already has this transaction |
---|
192 | | - * pointer in its b_fsprivate2 field, then we know we already |
---|
193 | | - * have it locked. In this case we just increment the lock |
---|
194 | | - * recursion count and return the buffer to the caller. |
---|
195 | | - */ |
---|
196 | | - bp = mp->m_sb_bp; |
---|
197 | 181 | if (bp->b_transp == tp) { |
---|
198 | | - bip = bp->b_log_item; |
---|
| 182 | + struct xfs_buf_log_item *bip = bp->b_log_item; |
---|
| 183 | + |
---|
199 | 184 | ASSERT(bip != NULL); |
---|
200 | 185 | ASSERT(atomic_read(&bip->bli_refcount) > 0); |
---|
201 | 186 | bip->bli_recur++; |
---|
| 187 | + |
---|
202 | 188 | trace_xfs_trans_getsb_recur(bip); |
---|
203 | | - return bp; |
---|
| 189 | + } else { |
---|
| 190 | + xfs_buf_lock(bp); |
---|
| 191 | + xfs_buf_hold(bp); |
---|
| 192 | + _xfs_trans_bjoin(tp, bp, 1); |
---|
| 193 | + |
---|
| 194 | + trace_xfs_trans_getsb(bp->b_log_item); |
---|
204 | 195 | } |
---|
205 | 196 | |
---|
206 | | - bp = xfs_getsb(mp, flags); |
---|
207 | | - if (bp == NULL) |
---|
208 | | - return NULL; |
---|
209 | | - |
---|
210 | | - _xfs_trans_bjoin(tp, bp, 1); |
---|
211 | | - trace_xfs_trans_getsb(bp->b_log_item); |
---|
212 | 197 | return bp; |
---|
213 | 198 | } |
---|
214 | 199 | |
---|
.. | .. |
---|
264 | 249 | return -EIO; |
---|
265 | 250 | } |
---|
266 | 251 | |
---|
| 252 | + /* |
---|
| 253 | + * Check if the caller is trying to read a buffer that is |
---|
| 254 | + * already attached to the transaction yet has no buffer ops |
---|
| 255 | + * assigned. Ops are usually attached when the buffer is |
---|
| 256 | + * attached to the transaction, or by the read caller if |
---|
| 257 | + * special circumstances. That didn't happen, which is not |
---|
| 258 | + * how this is supposed to go. |
---|
| 259 | + * |
---|
| 260 | + * If the buffer passes verification we'll let this go, but if |
---|
| 261 | + * not we have to shut down. Let the transaction cleanup code |
---|
| 262 | + * release this buffer when it kills the tranaction. |
---|
| 263 | + */ |
---|
| 264 | + ASSERT(bp->b_ops != NULL); |
---|
| 265 | + error = xfs_buf_reverify(bp, ops); |
---|
| 266 | + if (error) { |
---|
| 267 | + xfs_buf_ioerror_alert(bp, __return_address); |
---|
| 268 | + |
---|
| 269 | + if (tp->t_flags & XFS_TRANS_DIRTY) |
---|
| 270 | + xfs_force_shutdown(tp->t_mountp, |
---|
| 271 | + SHUTDOWN_META_IO_ERROR); |
---|
| 272 | + |
---|
| 273 | + /* bad CRC means corrupted metadata */ |
---|
| 274 | + if (error == -EFSBADCRC) |
---|
| 275 | + error = -EFSCORRUPTED; |
---|
| 276 | + return error; |
---|
| 277 | + } |
---|
| 278 | + |
---|
267 | 279 | bip = bp->b_log_item; |
---|
268 | 280 | bip->bli_recur++; |
---|
269 | 281 | |
---|
270 | 282 | ASSERT(atomic_read(&bip->bli_refcount) > 0); |
---|
271 | 283 | trace_xfs_trans_read_buf_recur(bip); |
---|
| 284 | + ASSERT(bp->b_ops != NULL || ops == NULL); |
---|
272 | 285 | *bpp = bp; |
---|
273 | 286 | return 0; |
---|
274 | 287 | } |
---|
275 | 288 | |
---|
276 | | - bp = xfs_buf_read_map(target, map, nmaps, flags, ops); |
---|
277 | | - if (!bp) { |
---|
278 | | - if (!(flags & XBF_TRYLOCK)) |
---|
279 | | - return -ENOMEM; |
---|
280 | | - return tp ? 0 : -EAGAIN; |
---|
281 | | - } |
---|
282 | | - |
---|
283 | | - /* |
---|
284 | | - * If we've had a read error, then the contents of the buffer are |
---|
285 | | - * invalid and should not be used. To ensure that a followup read tries |
---|
286 | | - * to pull the buffer from disk again, we clear the XBF_DONE flag and |
---|
287 | | - * mark the buffer stale. This ensures that anyone who has a current |
---|
288 | | - * reference to the buffer will interpret it's contents correctly and |
---|
289 | | - * future cache lookups will also treat it as an empty, uninitialised |
---|
290 | | - * buffer. |
---|
291 | | - */ |
---|
292 | | - if (bp->b_error) { |
---|
293 | | - error = bp->b_error; |
---|
294 | | - if (!XFS_FORCED_SHUTDOWN(mp)) |
---|
295 | | - xfs_buf_ioerror_alert(bp, __func__); |
---|
296 | | - bp->b_flags &= ~XBF_DONE; |
---|
297 | | - xfs_buf_stale(bp); |
---|
298 | | - |
---|
| 289 | + error = xfs_buf_read_map(target, map, nmaps, flags, &bp, ops, |
---|
| 290 | + __return_address); |
---|
| 291 | + switch (error) { |
---|
| 292 | + case 0: |
---|
| 293 | + break; |
---|
| 294 | + default: |
---|
299 | 295 | if (tp && (tp->t_flags & XFS_TRANS_DIRTY)) |
---|
300 | 296 | xfs_force_shutdown(tp->t_mountp, SHUTDOWN_META_IO_ERROR); |
---|
301 | | - xfs_buf_relse(bp); |
---|
302 | | - |
---|
303 | | - /* bad CRC means corrupted metadata */ |
---|
304 | | - if (error == -EFSBADCRC) |
---|
305 | | - error = -EFSCORRUPTED; |
---|
| 297 | + /* fall through */ |
---|
| 298 | + case -ENOMEM: |
---|
| 299 | + case -EAGAIN: |
---|
306 | 300 | return error; |
---|
307 | 301 | } |
---|
308 | 302 | |
---|
.. | .. |
---|
316 | 310 | _xfs_trans_bjoin(tp, bp, 1); |
---|
317 | 311 | trace_xfs_trans_read_buf(bp->b_log_item); |
---|
318 | 312 | } |
---|
| 313 | + ASSERT(bp->b_ops != NULL || ops == NULL); |
---|
319 | 314 | *bpp = bp; |
---|
320 | 315 | return 0; |
---|
321 | 316 | |
---|
| 317 | +} |
---|
| 318 | + |
---|
| 319 | +/* Has this buffer been dirtied by anyone? */ |
---|
| 320 | +bool |
---|
| 321 | +xfs_trans_buf_is_dirty( |
---|
| 322 | + struct xfs_buf *bp) |
---|
| 323 | +{ |
---|
| 324 | + struct xfs_buf_log_item *bip = bp->b_log_item; |
---|
| 325 | + |
---|
| 326 | + if (!bip) |
---|
| 327 | + return false; |
---|
| 328 | + ASSERT(bip->bli_item.li_type == XFS_LI_BUF); |
---|
| 329 | + return test_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags); |
---|
322 | 330 | } |
---|
323 | 331 | |
---|
324 | 332 | /* |
---|
.. | .. |
---|
386 | 394 | |
---|
387 | 395 | /* |
---|
388 | 396 | * Mark the buffer as not needing to be unlocked when the buf item's |
---|
389 | | - * iop_unlock() routine is called. The buffer must already be locked |
---|
| 397 | + * iop_committing() routine is called. The buffer must already be locked |
---|
390 | 398 | * and associated with the given transaction. |
---|
391 | 399 | */ |
---|
392 | 400 | /* ARGSUSED */ |
---|
.. | .. |
---|
441 | 449 | |
---|
442 | 450 | ASSERT(bp->b_transp == tp); |
---|
443 | 451 | ASSERT(bip != NULL); |
---|
444 | | - ASSERT(bp->b_iodone == NULL || |
---|
445 | | - bp->b_iodone == xfs_buf_iodone_callbacks); |
---|
446 | 452 | |
---|
447 | 453 | /* |
---|
448 | 454 | * Mark the buffer as needing to be written out eventually, |
---|
449 | 455 | * and set its iodone function to remove the buffer's buf log |
---|
450 | 456 | * item from the AIL and free it when the buffer is flushed |
---|
451 | | - * to disk. See xfs_buf_attach_iodone() for more details |
---|
452 | | - * on li_cb and xfs_buf_iodone_callbacks(). |
---|
453 | | - * If we end up aborting this transaction, we trap this buffer |
---|
454 | | - * inside the b_bdstrat callback so that this won't get written to |
---|
455 | | - * disk. |
---|
| 457 | + * to disk. |
---|
456 | 458 | */ |
---|
457 | 459 | bp->b_flags |= XBF_DONE; |
---|
458 | 460 | |
---|
459 | 461 | ASSERT(atomic_read(&bip->bli_refcount) > 0); |
---|
460 | | - bp->b_iodone = xfs_buf_iodone_callbacks; |
---|
461 | | - bip->bli_item.li_cb = xfs_buf_iodone; |
---|
462 | 462 | |
---|
463 | 463 | /* |
---|
464 | 464 | * If we invalidated the buffer within this transaction, then |
---|
.. | .. |
---|
602 | 602 | ASSERT(atomic_read(&bip->bli_refcount) > 0); |
---|
603 | 603 | |
---|
604 | 604 | bip->bli_flags |= XFS_BLI_INODE_BUF; |
---|
| 605 | + bp->b_flags |= _XBF_INODES; |
---|
605 | 606 | xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DINO_BUF); |
---|
606 | 607 | } |
---|
607 | 608 | |
---|
.. | .. |
---|
626 | 627 | ASSERT(atomic_read(&bip->bli_refcount) > 0); |
---|
627 | 628 | |
---|
628 | 629 | bip->bli_flags |= XFS_BLI_STALE_INODE; |
---|
629 | | - bip->bli_item.li_cb = xfs_buf_iodone; |
---|
| 630 | + bp->b_flags |= _XBF_INODES; |
---|
630 | 631 | xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DINO_BUF); |
---|
631 | 632 | } |
---|
632 | 633 | |
---|
.. | .. |
---|
651 | 652 | ASSERT(atomic_read(&bip->bli_refcount) > 0); |
---|
652 | 653 | |
---|
653 | 654 | bip->bli_flags |= XFS_BLI_INODE_ALLOC_BUF; |
---|
| 655 | + bp->b_flags |= _XBF_INODES; |
---|
654 | 656 | xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DINO_BUF); |
---|
655 | 657 | } |
---|
656 | 658 | |
---|
.. | .. |
---|
761 | 763 | break; |
---|
762 | 764 | } |
---|
763 | 765 | |
---|
| 766 | + bp->b_flags |= _XBF_DQUOTS; |
---|
764 | 767 | xfs_trans_buf_set_type(tp, bp, type); |
---|
765 | 768 | } |
---|