aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorBrian Foster <bfoster@redhat.com>2018-09-28 23:45:02 -0400
committerDave Chinner <david@fromorbit.com>2018-09-28 23:45:02 -0400
commit23420d05e67d23728e116321c4afe084ebfa6427 (patch)
treec6db7f7cbbfa20a23027f39dc604d5d37f09abad /fs/xfs
parentd9183105caa926522a4bc8a40e162de7019f1a21 (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.c110
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 */
339void 336void
340xfs_trans_brelse( 337xfs_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;