diff options
author | Brian Foster <bfoster@redhat.com> | 2018-09-28 23:45:02 -0400 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2018-09-28 23:45:02 -0400 |
commit | 23420d05e67d23728e116321c4afe084ebfa6427 (patch) | |
tree | c6db7f7cbbfa20a23027f39dc604d5d37f09abad /fs/xfs | |
parent | d9183105caa926522a4bc8a40e162de7019f1a21 (diff) |
xfs: clean up xfs_trans_brelse()
xfs_trans_brelse() is a bit of a historical mess, similar to
xfs_buf_item_unlock(). It is unnecessarily verbose, has snippets of
commented out code, inconsistency with regard to stale items, etc.
Clean up xfs_trans_brelse() to use similar logic and flow as
xfs_buf_item_unlock() with regard to bli reference count handling.
This patch makes no functional changes, but facilitates further
refactoring of the common bli reference count handling code.
Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_trans_buf.c | 110 |
1 files changed, 39 insertions, 71 deletions
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c index 15919f67a88f..7498f87ceed3 100644 --- a/fs/xfs/xfs_trans_buf.c +++ b/fs/xfs/xfs_trans_buf.c | |||
@@ -322,49 +322,40 @@ xfs_trans_read_buf_map( | |||
322 | } | 322 | } |
323 | 323 | ||
324 | /* | 324 | /* |
325 | * Release the buffer bp which was previously acquired with one of the | 325 | * Release a buffer previously joined to the transaction. If the buffer is |
326 | * xfs_trans_... buffer allocation routines if the buffer has not | 326 | * modified within this transaction, decrement the recursion count but do not |
327 | * been modified within this transaction. If the buffer is modified | 327 | * release the buffer even if the count goes to 0. If the buffer is not modified |
328 | * within this transaction, do decrement the recursion count but do | 328 | * within the transaction, decrement the recursion count and release the buffer |
329 | * not release the buffer even if the count goes to 0. If the buffer is not | 329 | * if the recursion count goes to 0. |
330 | * modified within the transaction, decrement the recursion count and | ||
331 | * release the buffer if the recursion count goes to 0. | ||
332 | * | 330 | * |
333 | * If the buffer is to be released and it was not modified before | 331 | * If the buffer is to be released and it was not already dirty before this |
334 | * this transaction began, then free the buf_log_item associated with it. | 332 | * transaction began, then also free the buf_log_item associated with it. |
335 | * | 333 | * |
336 | * If the transaction pointer is NULL, make this just a normal | 334 | * If the transaction pointer is NULL, this is a normal xfs_buf_relse() call. |
337 | * brelse() call. | ||
338 | */ | 335 | */ |
339 | void | 336 | void |
340 | xfs_trans_brelse( | 337 | xfs_trans_brelse( |
341 | xfs_trans_t *tp, | 338 | struct xfs_trans *tp, |
342 | xfs_buf_t *bp) | 339 | struct xfs_buf *bp) |
343 | { | 340 | { |
344 | struct xfs_buf_log_item *bip; | 341 | struct xfs_buf_log_item *bip = bp->b_log_item; |
345 | int freed; | 342 | bool freed; |
343 | bool dirty; | ||
346 | 344 | ||
347 | /* | 345 | ASSERT(bp->b_transp == tp); |
348 | * Default to a normal brelse() call if the tp is NULL. | 346 | |
349 | */ | 347 | if (!tp) { |
350 | if (tp == NULL) { | ||
351 | ASSERT(bp->b_transp == NULL); | ||
352 | xfs_buf_relse(bp); | 348 | xfs_buf_relse(bp); |
353 | return; | 349 | return; |
354 | } | 350 | } |
355 | 351 | ||
356 | ASSERT(bp->b_transp == tp); | 352 | trace_xfs_trans_brelse(bip); |
357 | bip = bp->b_log_item; | ||
358 | ASSERT(bip->bli_item.li_type == XFS_LI_BUF); | 353 | ASSERT(bip->bli_item.li_type == XFS_LI_BUF); |
359 | ASSERT(!(bip->bli_flags & XFS_BLI_STALE)); | ||
360 | ASSERT(!(bip->__bli_format.blf_flags & XFS_BLF_CANCEL)); | ||
361 | ASSERT(atomic_read(&bip->bli_refcount) > 0); | 354 | ASSERT(atomic_read(&bip->bli_refcount) > 0); |
362 | 355 | ||
363 | trace_xfs_trans_brelse(bip); | ||
364 | |||
365 | /* | 356 | /* |
366 | * If the release is just for a recursive lock, | 357 | * If the release is for a recursive lookup, then decrement the count |
367 | * then decrement the count and return. | 358 | * and return. |
368 | */ | 359 | */ |
369 | if (bip->bli_recur > 0) { | 360 | if (bip->bli_recur > 0) { |
370 | bip->bli_recur--; | 361 | bip->bli_recur--; |
@@ -372,63 +363,40 @@ xfs_trans_brelse( | |||
372 | } | 363 | } |
373 | 364 | ||
374 | /* | 365 | /* |
375 | * If the buffer is dirty within this transaction, we can't | 366 | * If the buffer is invalidated or dirty in this transaction, we can't |
376 | * release it until we commit. | 367 | * release it until we commit. |
377 | */ | 368 | */ |
378 | if (test_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags)) | 369 | if (test_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags)) |
379 | return; | 370 | return; |
380 | |||
381 | /* | ||
382 | * If the buffer has been invalidated, then we can't release | ||
383 | * it until the transaction commits to disk unless it is re-dirtied | ||
384 | * as part of this transaction. This prevents us from pulling | ||
385 | * the item from the AIL before we should. | ||
386 | */ | ||
387 | if (bip->bli_flags & XFS_BLI_STALE) | 371 | if (bip->bli_flags & XFS_BLI_STALE) |
388 | return; | 372 | return; |
389 | 373 | ||
390 | ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED)); | ||
391 | |||
392 | /* | 374 | /* |
393 | * Free up the log item descriptor tracking the released item. | 375 | * Unlink the log item from the transaction and clear the hold flag, if |
376 | * set. We wouldn't want the next user of the buffer to get confused. | ||
394 | */ | 377 | */ |
378 | ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED)); | ||
395 | xfs_trans_del_item(&bip->bli_item); | 379 | xfs_trans_del_item(&bip->bli_item); |
380 | bip->bli_flags &= ~XFS_BLI_HOLD; | ||
396 | 381 | ||
397 | /* | 382 | /* |
398 | * Clear the hold flag in the buf log item if it is set. | 383 | * Drop the reference to the bli. At this point, the bli must be either |
399 | * We wouldn't want the next user of the buffer to | 384 | * freed or dirty (or both). If freed, there are a couple cases where we |
400 | * get confused. | 385 | * are responsible to free the item. If the bli is clean, we're the last |
401 | */ | 386 | * user of it. If the fs has shut down, the bli may be dirty and AIL |
402 | if (bip->bli_flags & XFS_BLI_HOLD) { | 387 | * resident, but won't ever be written back. We therefore may also need |
403 | bip->bli_flags &= ~XFS_BLI_HOLD; | 388 | * to remove it from the AIL before freeing it. |
404 | } | ||
405 | |||
406 | /* | ||
407 | * Drop our reference to the buf log item. | ||
408 | */ | 389 | */ |
409 | freed = atomic_dec_and_test(&bip->bli_refcount); | 390 | freed = atomic_dec_and_test(&bip->bli_refcount); |
410 | 391 | dirty = bip->bli_flags & XFS_BLI_DIRTY; | |
411 | /* | 392 | ASSERT(freed || dirty); |
412 | * If the buf item is not tracking data in the log, then we must free it | 393 | if (freed) { |
413 | * before releasing the buffer back to the free pool. | 394 | bool abort = XFS_FORCED_SHUTDOWN(tp->t_mountp); |
414 | * | 395 | ASSERT(abort || !test_bit(XFS_LI_IN_AIL, &bip->bli_item.li_flags)); |
415 | * If the fs has shutdown and we dropped the last reference, it may fall | 396 | if (abort) |
416 | * on us to release a (possibly dirty) bli if it never made it to the | 397 | xfs_trans_ail_remove(&bip->bli_item, SHUTDOWN_LOG_IO_ERROR); |
417 | * AIL (e.g., the aborted unpin already happened and didn't release it | 398 | if (!dirty || abort) |
418 | * due to our reference). Since we're already shutdown and need | 399 | xfs_buf_item_relse(bp); |
419 | * ail_lock, just force remove from the AIL and release the bli here. | ||
420 | */ | ||
421 | if (XFS_FORCED_SHUTDOWN(tp->t_mountp) && freed) { | ||
422 | xfs_trans_ail_remove(&bip->bli_item, SHUTDOWN_LOG_IO_ERROR); | ||
423 | xfs_buf_item_relse(bp); | ||
424 | } else if (!(bip->bli_flags & XFS_BLI_DIRTY)) { | ||
425 | /*** | ||
426 | ASSERT(bp->b_pincount == 0); | ||
427 | ***/ | ||
428 | ASSERT(atomic_read(&bip->bli_refcount) == 0); | ||
429 | ASSERT(!test_bit(XFS_LI_IN_AIL, &bip->bli_item.li_flags)); | ||
430 | ASSERT(!(bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF)); | ||
431 | xfs_buf_item_relse(bp); | ||
432 | } | 400 | } |
433 | 401 | ||
434 | bp->b_transp = NULL; | 402 | bp->b_transp = NULL; |