aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_inode_item.c14
-rw-r--r--fs/xfs/xfs_trans.c4
2 files changed, 10 insertions, 8 deletions
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index 09983a3344a5..b1e88d56069c 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -681,15 +681,15 @@ xfs_inode_item_unlock(
681 * where the cluster buffer may be unpinned before the inode is inserted into 681 * where the cluster buffer may be unpinned before the inode is inserted into
682 * the AIL during transaction committed processing. If the buffer is unpinned 682 * the AIL during transaction committed processing. If the buffer is unpinned
683 * before the inode item has been committed and inserted, then it is possible 683 * before the inode item has been committed and inserted, then it is possible
684 * for the buffer to be written and IO completions before the inode is inserted 684 * for the buffer to be written and IO completes before the inode is inserted
685 * into the AIL. In that case, we'd be inserting a clean, stale inode into the 685 * into the AIL. In that case, we'd be inserting a clean, stale inode into the
686 * AIL which will never get removed. It will, however, get reclaimed which 686 * AIL which will never get removed. It will, however, get reclaimed which
687 * triggers an assert in xfs_inode_free() complaining about freein an inode 687 * triggers an assert in xfs_inode_free() complaining about freein an inode
688 * still in the AIL. 688 * still in the AIL.
689 * 689 *
690 * To avoid this, return a lower LSN than the one passed in so that the 690 * To avoid this, just unpin the inode directly and return a LSN of -1 so the
691 * transaction committed code will not move the inode forward in the AIL but 691 * transaction committed code knows that it does not need to do any further
692 * will still unpin it properly. 692 * processing on the item.
693 */ 693 */
694STATIC xfs_lsn_t 694STATIC xfs_lsn_t
695xfs_inode_item_committed( 695xfs_inode_item_committed(
@@ -699,8 +699,10 @@ xfs_inode_item_committed(
699 struct xfs_inode_log_item *iip = INODE_ITEM(lip); 699 struct xfs_inode_log_item *iip = INODE_ITEM(lip);
700 struct xfs_inode *ip = iip->ili_inode; 700 struct xfs_inode *ip = iip->ili_inode;
701 701
702 if (xfs_iflags_test(ip, XFS_ISTALE)) 702 if (xfs_iflags_test(ip, XFS_ISTALE)) {
703 return lsn - 1; 703 xfs_inode_item_unpin(lip, 0);
704 return -1;
705 }
704 return lsn; 706 return lsn;
705} 707}
706 708
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 7c7bc2b786bd..c83f63b33aae 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -1361,7 +1361,7 @@ xfs_trans_item_committed(
1361 lip->li_flags |= XFS_LI_ABORTED; 1361 lip->li_flags |= XFS_LI_ABORTED;
1362 item_lsn = IOP_COMMITTED(lip, commit_lsn); 1362 item_lsn = IOP_COMMITTED(lip, commit_lsn);
1363 1363
1364 /* If the committed routine returns -1, item has been freed. */ 1364 /* item_lsn of -1 means the item needs no further processing */
1365 if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0) 1365 if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0)
1366 return; 1366 return;
1367 1367
@@ -1474,7 +1474,7 @@ xfs_trans_committed_bulk(
1474 lip->li_flags |= XFS_LI_ABORTED; 1474 lip->li_flags |= XFS_LI_ABORTED;
1475 item_lsn = IOP_COMMITTED(lip, commit_lsn); 1475 item_lsn = IOP_COMMITTED(lip, commit_lsn);
1476 1476
1477 /* item_lsn of -1 means the item was freed */ 1477 /* item_lsn of -1 means the item needs no further processing */
1478 if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0) 1478 if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0)
1479 continue; 1479 continue;
1480 1480