diff options
Diffstat (limited to 'fs/xfs/xfs_inode.c')
| -rw-r--r-- | fs/xfs/xfs_inode.c | 51 |
1 files changed, 36 insertions, 15 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 5fa0adb7e173..c27d7d495aa0 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
| @@ -334,10 +334,9 @@ xfs_itobp( | |||
| 334 | #if !defined(__KERNEL__) | 334 | #if !defined(__KERNEL__) |
| 335 | ni = 0; | 335 | ni = 0; |
| 336 | #elif defined(DEBUG) | 336 | #elif defined(DEBUG) |
| 337 | ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 : | 337 | ni = BBTOB(imap.im_len) >> mp->m_sb.sb_inodelog; |
| 338 | (BBTOB(imap.im_len) >> mp->m_sb.sb_inodelog); | ||
| 339 | #else /* usual case */ | 338 | #else /* usual case */ |
| 340 | ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 : 1; | 339 | ni = 1; |
| 341 | #endif | 340 | #endif |
| 342 | 341 | ||
| 343 | for (i = 0; i < ni; i++) { | 342 | for (i = 0; i < ni; i++) { |
| @@ -348,11 +347,15 @@ xfs_itobp( | |||
| 348 | (i << mp->m_sb.sb_inodelog)); | 347 | (i << mp->m_sb.sb_inodelog)); |
| 349 | di_ok = INT_GET(dip->di_core.di_magic, ARCH_CONVERT) == XFS_DINODE_MAGIC && | 348 | di_ok = INT_GET(dip->di_core.di_magic, ARCH_CONVERT) == XFS_DINODE_MAGIC && |
| 350 | XFS_DINODE_GOOD_VERSION(INT_GET(dip->di_core.di_version, ARCH_CONVERT)); | 349 | XFS_DINODE_GOOD_VERSION(INT_GET(dip->di_core.di_version, ARCH_CONVERT)); |
| 351 | if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP, | 350 | if (unlikely(XFS_TEST_ERROR(!di_ok, mp, |
| 352 | XFS_RANDOM_ITOBP_INOTOBP))) { | 351 | XFS_ERRTAG_ITOBP_INOTOBP, |
| 352 | XFS_RANDOM_ITOBP_INOTOBP))) { | ||
| 353 | if (imap_flags & XFS_IMAP_BULKSTAT) { | ||
| 354 | xfs_trans_brelse(tp, bp); | ||
| 355 | return XFS_ERROR(EINVAL); | ||
| 356 | } | ||
| 353 | #ifdef DEBUG | 357 | #ifdef DEBUG |
| 354 | if (!(imap_flags & XFS_IMAP_BULKSTAT)) | 358 | cmn_err(CE_ALERT, |
| 355 | cmn_err(CE_ALERT, | ||
| 356 | "Device %s - bad inode magic/vsn " | 359 | "Device %s - bad inode magic/vsn " |
| 357 | "daddr %lld #%d (magic=%x)", | 360 | "daddr %lld #%d (magic=%x)", |
| 358 | XFS_BUFTARG_NAME(mp->m_ddev_targp), | 361 | XFS_BUFTARG_NAME(mp->m_ddev_targp), |
| @@ -851,7 +854,8 @@ xfs_iread( | |||
| 851 | xfs_trans_t *tp, | 854 | xfs_trans_t *tp, |
| 852 | xfs_ino_t ino, | 855 | xfs_ino_t ino, |
| 853 | xfs_inode_t **ipp, | 856 | xfs_inode_t **ipp, |
| 854 | xfs_daddr_t bno) | 857 | xfs_daddr_t bno, |
| 858 | uint imap_flags) | ||
| 855 | { | 859 | { |
| 856 | xfs_buf_t *bp; | 860 | xfs_buf_t *bp; |
| 857 | xfs_dinode_t *dip; | 861 | xfs_dinode_t *dip; |
| @@ -863,6 +867,7 @@ xfs_iread( | |||
| 863 | ip = kmem_zone_zalloc(xfs_inode_zone, KM_SLEEP); | 867 | ip = kmem_zone_zalloc(xfs_inode_zone, KM_SLEEP); |
| 864 | ip->i_ino = ino; | 868 | ip->i_ino = ino; |
| 865 | ip->i_mount = mp; | 869 | ip->i_mount = mp; |
| 870 | spin_lock_init(&ip->i_flags_lock); | ||
| 866 | 871 | ||
| 867 | /* | 872 | /* |
| 868 | * 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. |
| @@ -871,7 +876,7 @@ xfs_iread( | |||
| 871 | * 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 |
| 872 | * know that this is a new incore inode. | 877 | * know that this is a new incore inode. |
| 873 | */ | 878 | */ |
| 874 | error = xfs_itobp(mp, tp, ip, &dip, &bp, bno, 0); | 879 | error = xfs_itobp(mp, tp, ip, &dip, &bp, bno, imap_flags); |
| 875 | if (error) { | 880 | if (error) { |
| 876 | kmem_zone_free(xfs_inode_zone, ip); | 881 | kmem_zone_free(xfs_inode_zone, ip); |
| 877 | return error; | 882 | return error; |
| @@ -1110,7 +1115,7 @@ xfs_ialloc( | |||
| 1110 | * to prevent others from looking at until we're done. | 1115 | * to prevent others from looking at until we're done. |
| 1111 | */ | 1116 | */ |
| 1112 | error = xfs_trans_iget(tp->t_mountp, tp, ino, | 1117 | error = xfs_trans_iget(tp->t_mountp, tp, ino, |
| 1113 | IGET_CREATE, XFS_ILOCK_EXCL, &ip); | 1118 | XFS_IGET_CREATE, XFS_ILOCK_EXCL, &ip); |
| 1114 | if (error != 0) { | 1119 | if (error != 0) { |
| 1115 | return error; | 1120 | return error; |
| 1116 | } | 1121 | } |
| @@ -1961,9 +1966,9 @@ xfs_iunlink_remove( | |||
| 1961 | xfs_agino_t agino; | 1966 | xfs_agino_t agino; |
| 1962 | xfs_agino_t next_agino; | 1967 | xfs_agino_t next_agino; |
| 1963 | xfs_buf_t *last_ibp; | 1968 | xfs_buf_t *last_ibp; |
| 1964 | xfs_dinode_t *last_dip; | 1969 | xfs_dinode_t *last_dip = NULL; |
| 1965 | short bucket_index; | 1970 | short bucket_index; |
| 1966 | int offset, last_offset; | 1971 | int offset, last_offset = 0; |
| 1967 | int error; | 1972 | int error; |
| 1968 | int agi_ok; | 1973 | int agi_ok; |
| 1969 | 1974 | ||
| @@ -2210,7 +2215,9 @@ xfs_ifree_cluster( | |||
| 2210 | 2215 | ||
| 2211 | if (ip == free_ip) { | 2216 | if (ip == free_ip) { |
| 2212 | if (xfs_iflock_nowait(ip)) { | 2217 | if (xfs_iflock_nowait(ip)) { |
| 2218 | spin_lock(&ip->i_flags_lock); | ||
| 2213 | ip->i_flags |= XFS_ISTALE; | 2219 | ip->i_flags |= XFS_ISTALE; |
| 2220 | spin_unlock(&ip->i_flags_lock); | ||
| 2214 | 2221 | ||
| 2215 | if (xfs_inode_clean(ip)) { | 2222 | if (xfs_inode_clean(ip)) { |
| 2216 | xfs_ifunlock(ip); | 2223 | xfs_ifunlock(ip); |
| @@ -2224,7 +2231,9 @@ xfs_ifree_cluster( | |||
| 2224 | 2231 | ||
| 2225 | if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) { | 2232 | if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) { |
| 2226 | if (xfs_iflock_nowait(ip)) { | 2233 | if (xfs_iflock_nowait(ip)) { |
| 2234 | spin_lock(&ip->i_flags_lock); | ||
| 2227 | ip->i_flags |= XFS_ISTALE; | 2235 | ip->i_flags |= XFS_ISTALE; |
| 2236 | spin_unlock(&ip->i_flags_lock); | ||
| 2228 | 2237 | ||
| 2229 | if (xfs_inode_clean(ip)) { | 2238 | if (xfs_inode_clean(ip)) { |
| 2230 | xfs_ifunlock(ip); | 2239 | xfs_ifunlock(ip); |
| @@ -2254,7 +2263,9 @@ xfs_ifree_cluster( | |||
| 2254 | AIL_LOCK(mp,s); | 2263 | AIL_LOCK(mp,s); |
| 2255 | iip->ili_flush_lsn = iip->ili_item.li_lsn; | 2264 | iip->ili_flush_lsn = iip->ili_item.li_lsn; |
| 2256 | AIL_UNLOCK(mp, s); | 2265 | AIL_UNLOCK(mp, s); |
| 2266 | spin_lock(&iip->ili_inode->i_flags_lock); | ||
| 2257 | iip->ili_inode->i_flags |= XFS_ISTALE; | 2267 | iip->ili_inode->i_flags |= XFS_ISTALE; |
| 2268 | spin_unlock(&iip->ili_inode->i_flags_lock); | ||
| 2258 | pre_flushed++; | 2269 | pre_flushed++; |
| 2259 | } | 2270 | } |
| 2260 | lip = lip->li_bio_list; | 2271 | lip = lip->li_bio_list; |
| @@ -2750,19 +2761,29 @@ xfs_iunpin( | |||
| 2750 | * call as the inode reclaim may be blocked waiting for | 2761 | * call as the inode reclaim may be blocked waiting for |
| 2751 | * the inode to become unpinned. | 2762 | * the inode to become unpinned. |
| 2752 | */ | 2763 | */ |
| 2764 | struct inode *inode = NULL; | ||
| 2765 | |||
| 2766 | spin_lock(&ip->i_flags_lock); | ||
| 2753 | if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) { | 2767 | if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) { |
| 2754 | bhv_vnode_t *vp = XFS_ITOV_NULL(ip); | 2768 | bhv_vnode_t *vp = XFS_ITOV_NULL(ip); |
| 2755 | 2769 | ||
| 2756 | /* make sync come back and flush this inode */ | 2770 | /* make sync come back and flush this inode */ |
| 2757 | if (vp) { | 2771 | if (vp) { |
| 2758 | struct inode *inode = vn_to_inode(vp); | 2772 | inode = vn_to_inode(vp); |
| 2759 | 2773 | ||
| 2760 | if (!(inode->i_state & | 2774 | if (!(inode->i_state & |
| 2761 | (I_NEW|I_FREEING|I_CLEAR))) | 2775 | (I_NEW|I_FREEING|I_CLEAR))) { |
| 2762 | mark_inode_dirty_sync(inode); | 2776 | inode = igrab(inode); |
| 2777 | if (inode) | ||
| 2778 | mark_inode_dirty_sync(inode); | ||
| 2779 | } else | ||
| 2780 | inode = NULL; | ||
| 2763 | } | 2781 | } |
| 2764 | } | 2782 | } |
| 2783 | spin_unlock(&ip->i_flags_lock); | ||
| 2765 | wake_up(&ip->i_ipin_wait); | 2784 | wake_up(&ip->i_ipin_wait); |
| 2785 | if (inode) | ||
| 2786 | iput(inode); | ||
| 2766 | } | 2787 | } |
| 2767 | } | 2788 | } |
| 2768 | 2789 | ||
