diff options
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 1f8ecff8553a..c27d7d495aa0 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -854,7 +854,8 @@ xfs_iread( | |||
854 | xfs_trans_t *tp, | 854 | xfs_trans_t *tp, |
855 | xfs_ino_t ino, | 855 | xfs_ino_t ino, |
856 | xfs_inode_t **ipp, | 856 | xfs_inode_t **ipp, |
857 | xfs_daddr_t bno) | 857 | xfs_daddr_t bno, |
858 | uint imap_flags) | ||
858 | { | 859 | { |
859 | xfs_buf_t *bp; | 860 | xfs_buf_t *bp; |
860 | xfs_dinode_t *dip; | 861 | xfs_dinode_t *dip; |
@@ -866,6 +867,7 @@ xfs_iread( | |||
866 | ip = kmem_zone_zalloc(xfs_inode_zone, KM_SLEEP); | 867 | ip = kmem_zone_zalloc(xfs_inode_zone, KM_SLEEP); |
867 | ip->i_ino = ino; | 868 | ip->i_ino = ino; |
868 | ip->i_mount = mp; | 869 | ip->i_mount = mp; |
870 | spin_lock_init(&ip->i_flags_lock); | ||
869 | 871 | ||
870 | /* | 872 | /* |
871 | * Get pointer's to the on-disk inode and the buffer containing it. | 873 | * Get pointer's to the on-disk inode and the buffer containing it. |
@@ -874,7 +876,7 @@ xfs_iread( | |||
874 | * return NULL as well. Set i_blkno to 0 so that xfs_itobp() will | 876 | * return NULL as well. Set i_blkno to 0 so that xfs_itobp() will |
875 | * know that this is a new incore inode. | 877 | * know that this is a new incore inode. |
876 | */ | 878 | */ |
877 | error = xfs_itobp(mp, tp, ip, &dip, &bp, bno, 0); | 879 | error = xfs_itobp(mp, tp, ip, &dip, &bp, bno, imap_flags); |
878 | if (error) { | 880 | if (error) { |
879 | kmem_zone_free(xfs_inode_zone, ip); | 881 | kmem_zone_free(xfs_inode_zone, ip); |
880 | return error; | 882 | return error; |
@@ -1113,7 +1115,7 @@ xfs_ialloc( | |||
1113 | * to prevent others from looking at until we're done. | 1115 | * to prevent others from looking at until we're done. |
1114 | */ | 1116 | */ |
1115 | error = xfs_trans_iget(tp->t_mountp, tp, ino, | 1117 | error = xfs_trans_iget(tp->t_mountp, tp, ino, |
1116 | IGET_CREATE, XFS_ILOCK_EXCL, &ip); | 1118 | XFS_IGET_CREATE, XFS_ILOCK_EXCL, &ip); |
1117 | if (error != 0) { | 1119 | if (error != 0) { |
1118 | return error; | 1120 | return error; |
1119 | } | 1121 | } |
@@ -2213,7 +2215,9 @@ xfs_ifree_cluster( | |||
2213 | 2215 | ||
2214 | if (ip == free_ip) { | 2216 | if (ip == free_ip) { |
2215 | if (xfs_iflock_nowait(ip)) { | 2217 | if (xfs_iflock_nowait(ip)) { |
2218 | spin_lock(&ip->i_flags_lock); | ||
2216 | ip->i_flags |= XFS_ISTALE; | 2219 | ip->i_flags |= XFS_ISTALE; |
2220 | spin_unlock(&ip->i_flags_lock); | ||
2217 | 2221 | ||
2218 | if (xfs_inode_clean(ip)) { | 2222 | if (xfs_inode_clean(ip)) { |
2219 | xfs_ifunlock(ip); | 2223 | xfs_ifunlock(ip); |
@@ -2227,7 +2231,9 @@ xfs_ifree_cluster( | |||
2227 | 2231 | ||
2228 | if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) { | 2232 | if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) { |
2229 | if (xfs_iflock_nowait(ip)) { | 2233 | if (xfs_iflock_nowait(ip)) { |
2234 | spin_lock(&ip->i_flags_lock); | ||
2230 | ip->i_flags |= XFS_ISTALE; | 2235 | ip->i_flags |= XFS_ISTALE; |
2236 | spin_unlock(&ip->i_flags_lock); | ||
2231 | 2237 | ||
2232 | if (xfs_inode_clean(ip)) { | 2238 | if (xfs_inode_clean(ip)) { |
2233 | xfs_ifunlock(ip); | 2239 | xfs_ifunlock(ip); |
@@ -2257,7 +2263,9 @@ xfs_ifree_cluster( | |||
2257 | AIL_LOCK(mp,s); | 2263 | AIL_LOCK(mp,s); |
2258 | iip->ili_flush_lsn = iip->ili_item.li_lsn; | 2264 | iip->ili_flush_lsn = iip->ili_item.li_lsn; |
2259 | AIL_UNLOCK(mp, s); | 2265 | AIL_UNLOCK(mp, s); |
2266 | spin_lock(&iip->ili_inode->i_flags_lock); | ||
2260 | iip->ili_inode->i_flags |= XFS_ISTALE; | 2267 | iip->ili_inode->i_flags |= XFS_ISTALE; |
2268 | spin_unlock(&iip->ili_inode->i_flags_lock); | ||
2261 | pre_flushed++; | 2269 | pre_flushed++; |
2262 | } | 2270 | } |
2263 | lip = lip->li_bio_list; | 2271 | lip = lip->li_bio_list; |
@@ -2753,19 +2761,29 @@ xfs_iunpin( | |||
2753 | * call as the inode reclaim may be blocked waiting for | 2761 | * call as the inode reclaim may be blocked waiting for |
2754 | * the inode to become unpinned. | 2762 | * the inode to become unpinned. |
2755 | */ | 2763 | */ |
2764 | struct inode *inode = NULL; | ||
2765 | |||
2766 | spin_lock(&ip->i_flags_lock); | ||
2756 | if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) { | 2767 | if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) { |
2757 | bhv_vnode_t *vp = XFS_ITOV_NULL(ip); | 2768 | bhv_vnode_t *vp = XFS_ITOV_NULL(ip); |
2758 | 2769 | ||
2759 | /* make sync come back and flush this inode */ | 2770 | /* make sync come back and flush this inode */ |
2760 | if (vp) { | 2771 | if (vp) { |
2761 | struct inode *inode = vn_to_inode(vp); | 2772 | inode = vn_to_inode(vp); |
2762 | 2773 | ||
2763 | if (!(inode->i_state & | 2774 | if (!(inode->i_state & |
2764 | (I_NEW|I_FREEING|I_CLEAR))) | 2775 | (I_NEW|I_FREEING|I_CLEAR))) { |
2765 | mark_inode_dirty_sync(inode); | 2776 | inode = igrab(inode); |
2777 | if (inode) | ||
2778 | mark_inode_dirty_sync(inode); | ||
2779 | } else | ||
2780 | inode = NULL; | ||
2766 | } | 2781 | } |
2767 | } | 2782 | } |
2783 | spin_unlock(&ip->i_flags_lock); | ||
2768 | wake_up(&ip->i_ipin_wait); | 2784 | wake_up(&ip->i_ipin_wait); |
2785 | if (inode) | ||
2786 | iput(inode); | ||
2769 | } | 2787 | } |
2770 | } | 2788 | } |
2771 | 2789 | ||