aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r--fs/xfs/xfs_inode.c51
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