diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/xfs_dquot.c | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_iget.c | 18 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.c | 17 | ||||
-rw-r--r-- | fs/xfs/xfs_sync.c | 1 |
4 files changed, 12 insertions, 27 deletions
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index e2f6f7c877db..786a61e1cccd 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c | |||
@@ -915,8 +915,7 @@ xfs_qm_dqflush( | |||
915 | 915 | ||
916 | spin_lock(&mp->m_ail->xa_lock); | 916 | spin_lock(&mp->m_ail->xa_lock); |
917 | if (lip->li_flags & XFS_LI_IN_AIL) | 917 | if (lip->li_flags & XFS_LI_IN_AIL) |
918 | xfs_trans_ail_delete(mp->m_ail, lip, | 918 | xfs_trans_ail_delete(mp->m_ail, lip); |
919 | SHUTDOWN_CORRUPT_INCORE); | ||
920 | else | 919 | else |
921 | spin_unlock(&mp->m_ail->xa_lock); | 920 | spin_unlock(&mp->m_ail->xa_lock); |
922 | 921 | ||
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index bcc6c249b2c7..ab89ca7fdb95 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
@@ -123,23 +123,7 @@ xfs_inode_free( | |||
123 | xfs_idestroy_fork(ip, XFS_ATTR_FORK); | 123 | xfs_idestroy_fork(ip, XFS_ATTR_FORK); |
124 | 124 | ||
125 | if (ip->i_itemp) { | 125 | if (ip->i_itemp) { |
126 | /* | 126 | ASSERT(!(ip->i_itemp->ili_item.li_flags & XFS_LI_IN_AIL)); |
127 | * Only if we are shutting down the fs will we see an | ||
128 | * inode still in the AIL. If it is there, we should remove | ||
129 | * it to prevent a use-after-free from occurring. | ||
130 | */ | ||
131 | xfs_log_item_t *lip = &ip->i_itemp->ili_item; | ||
132 | struct xfs_ail *ailp = lip->li_ailp; | ||
133 | |||
134 | ASSERT(((lip->li_flags & XFS_LI_IN_AIL) == 0) || | ||
135 | XFS_FORCED_SHUTDOWN(ip->i_mount)); | ||
136 | if (lip->li_flags & XFS_LI_IN_AIL) { | ||
137 | spin_lock(&ailp->xa_lock); | ||
138 | if (lip->li_flags & XFS_LI_IN_AIL) | ||
139 | xfs_trans_ail_delete(ailp, lip); | ||
140 | else | ||
141 | spin_unlock(&ailp->xa_lock); | ||
142 | } | ||
143 | xfs_inode_item_destroy(ip); | 127 | xfs_inode_item_destroy(ip); |
144 | ip->i_itemp = NULL; | 128 | ip->i_itemp = NULL; |
145 | } | 129 | } |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index bc46c0a133d3..00f9c2f34e1f 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -2397,7 +2397,6 @@ xfs_iflush( | |||
2397 | xfs_inode_t *ip, | 2397 | xfs_inode_t *ip, |
2398 | uint flags) | 2398 | uint flags) |
2399 | { | 2399 | { |
2400 | xfs_inode_log_item_t *iip; | ||
2401 | xfs_buf_t *bp; | 2400 | xfs_buf_t *bp; |
2402 | xfs_dinode_t *dip; | 2401 | xfs_dinode_t *dip; |
2403 | xfs_mount_t *mp; | 2402 | xfs_mount_t *mp; |
@@ -2410,7 +2409,6 @@ xfs_iflush( | |||
2410 | ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || | 2409 | ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || |
2411 | ip->i_d.di_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); | 2410 | ip->i_d.di_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); |
2412 | 2411 | ||
2413 | iip = ip->i_itemp; | ||
2414 | mp = ip->i_mount; | 2412 | mp = ip->i_mount; |
2415 | 2413 | ||
2416 | /* | 2414 | /* |
@@ -2447,13 +2445,14 @@ xfs_iflush( | |||
2447 | /* | 2445 | /* |
2448 | * This may have been unpinned because the filesystem is shutting | 2446 | * This may have been unpinned because the filesystem is shutting |
2449 | * down forcibly. If that's the case we must not write this inode | 2447 | * down forcibly. If that's the case we must not write this inode |
2450 | * to disk, because the log record didn't make it to disk! | 2448 | * to disk, because the log record didn't make it to disk. |
2449 | * | ||
2450 | * We also have to remove the log item from the AIL in this case, | ||
2451 | * as we wait for an empty AIL as part of the unmount process. | ||
2451 | */ | 2452 | */ |
2452 | if (XFS_FORCED_SHUTDOWN(mp)) { | 2453 | if (XFS_FORCED_SHUTDOWN(mp)) { |
2453 | if (iip) | 2454 | error = XFS_ERROR(EIO); |
2454 | iip->ili_fields = 0; | 2455 | goto abort_out; |
2455 | xfs_ifunlock(ip); | ||
2456 | return XFS_ERROR(EIO); | ||
2457 | } | 2456 | } |
2458 | 2457 | ||
2459 | /* | 2458 | /* |
@@ -2500,11 +2499,13 @@ corrupt_out: | |||
2500 | xfs_buf_relse(bp); | 2499 | xfs_buf_relse(bp); |
2501 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); | 2500 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); |
2502 | cluster_corrupt_out: | 2501 | cluster_corrupt_out: |
2502 | error = XFS_ERROR(EFSCORRUPTED); | ||
2503 | abort_out: | ||
2503 | /* | 2504 | /* |
2504 | * Unlocks the flush lock | 2505 | * Unlocks the flush lock |
2505 | */ | 2506 | */ |
2506 | xfs_iflush_abort(ip); | 2507 | xfs_iflush_abort(ip); |
2507 | return XFS_ERROR(EFSCORRUPTED); | 2508 | return error; |
2508 | } | 2509 | } |
2509 | 2510 | ||
2510 | 2511 | ||
diff --git a/fs/xfs/xfs_sync.c b/fs/xfs/xfs_sync.c index c318d8a4a631..7648776e0a9e 100644 --- a/fs/xfs/xfs_sync.c +++ b/fs/xfs/xfs_sync.c | |||
@@ -782,6 +782,7 @@ restart: | |||
782 | goto reclaim; | 782 | goto reclaim; |
783 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) { | 783 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) { |
784 | xfs_iunpin_wait(ip); | 784 | xfs_iunpin_wait(ip); |
785 | xfs_iflush_abort(ip); | ||
785 | goto reclaim; | 786 | goto reclaim; |
786 | } | 787 | } |
787 | if (xfs_ipincount(ip)) { | 788 | if (xfs_ipincount(ip)) { |