diff options
Diffstat (limited to 'fs/xfs/xfs_vnodeops.c')
| -rw-r--r-- | fs/xfs/xfs_vnodeops.c | 274 |
1 files changed, 35 insertions, 239 deletions
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 6650601c64f7..70702a60b4bb 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
| @@ -76,132 +76,6 @@ xfs_open( | |||
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | /* | 78 | /* |
| 79 | * xfs_getattr | ||
| 80 | */ | ||
| 81 | int | ||
| 82 | xfs_getattr( | ||
| 83 | xfs_inode_t *ip, | ||
| 84 | bhv_vattr_t *vap, | ||
| 85 | int flags) | ||
| 86 | { | ||
| 87 | bhv_vnode_t *vp = XFS_ITOV(ip); | ||
| 88 | xfs_mount_t *mp = ip->i_mount; | ||
| 89 | |||
| 90 | xfs_itrace_entry(ip); | ||
| 91 | |||
| 92 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
| 93 | return XFS_ERROR(EIO); | ||
| 94 | |||
| 95 | if (!(flags & ATTR_LAZY)) | ||
| 96 | xfs_ilock(ip, XFS_ILOCK_SHARED); | ||
| 97 | |||
| 98 | vap->va_size = XFS_ISIZE(ip); | ||
| 99 | if (vap->va_mask == XFS_AT_SIZE) | ||
| 100 | goto all_done; | ||
| 101 | |||
| 102 | vap->va_nblocks = | ||
| 103 | XFS_FSB_TO_BB(mp, ip->i_d.di_nblocks + ip->i_delayed_blks); | ||
| 104 | vap->va_nodeid = ip->i_ino; | ||
| 105 | #if XFS_BIG_INUMS | ||
| 106 | vap->va_nodeid += mp->m_inoadd; | ||
| 107 | #endif | ||
| 108 | vap->va_nlink = ip->i_d.di_nlink; | ||
| 109 | |||
| 110 | /* | ||
| 111 | * Quick exit for non-stat callers | ||
| 112 | */ | ||
| 113 | if ((vap->va_mask & | ||
| 114 | ~(XFS_AT_SIZE|XFS_AT_FSID|XFS_AT_NODEID| | ||
| 115 | XFS_AT_NLINK|XFS_AT_BLKSIZE)) == 0) | ||
| 116 | goto all_done; | ||
| 117 | |||
| 118 | /* | ||
| 119 | * Copy from in-core inode. | ||
| 120 | */ | ||
| 121 | vap->va_mode = ip->i_d.di_mode; | ||
| 122 | vap->va_uid = ip->i_d.di_uid; | ||
| 123 | vap->va_gid = ip->i_d.di_gid; | ||
| 124 | vap->va_projid = ip->i_d.di_projid; | ||
| 125 | |||
| 126 | /* | ||
| 127 | * Check vnode type block/char vs. everything else. | ||
| 128 | */ | ||
| 129 | switch (ip->i_d.di_mode & S_IFMT) { | ||
| 130 | case S_IFBLK: | ||
| 131 | case S_IFCHR: | ||
| 132 | vap->va_rdev = ip->i_df.if_u2.if_rdev; | ||
| 133 | vap->va_blocksize = BLKDEV_IOSIZE; | ||
| 134 | break; | ||
| 135 | default: | ||
| 136 | vap->va_rdev = 0; | ||
| 137 | |||
| 138 | if (!(XFS_IS_REALTIME_INODE(ip))) { | ||
| 139 | vap->va_blocksize = xfs_preferred_iosize(mp); | ||
| 140 | } else { | ||
| 141 | |||
| 142 | /* | ||
| 143 | * If the file blocks are being allocated from a | ||
| 144 | * realtime partition, then return the inode's | ||
| 145 | * realtime extent size or the realtime volume's | ||
| 146 | * extent size. | ||
| 147 | */ | ||
| 148 | vap->va_blocksize = | ||
| 149 | xfs_get_extsz_hint(ip) << mp->m_sb.sb_blocklog; | ||
| 150 | } | ||
| 151 | break; | ||
| 152 | } | ||
| 153 | |||
| 154 | vn_atime_to_timespec(vp, &vap->va_atime); | ||
| 155 | vap->va_mtime.tv_sec = ip->i_d.di_mtime.t_sec; | ||
| 156 | vap->va_mtime.tv_nsec = ip->i_d.di_mtime.t_nsec; | ||
| 157 | vap->va_ctime.tv_sec = ip->i_d.di_ctime.t_sec; | ||
| 158 | vap->va_ctime.tv_nsec = ip->i_d.di_ctime.t_nsec; | ||
| 159 | |||
| 160 | /* | ||
| 161 | * Exit for stat callers. See if any of the rest of the fields | ||
| 162 | * to be filled in are needed. | ||
| 163 | */ | ||
| 164 | if ((vap->va_mask & | ||
| 165 | (XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS| | ||
| 166 | XFS_AT_GENCOUNT|XFS_AT_VCODE)) == 0) | ||
| 167 | goto all_done; | ||
| 168 | |||
| 169 | /* | ||
| 170 | * Convert di_flags to xflags. | ||
| 171 | */ | ||
| 172 | vap->va_xflags = xfs_ip2xflags(ip); | ||
| 173 | |||
| 174 | /* | ||
| 175 | * Exit for inode revalidate. See if any of the rest of | ||
| 176 | * the fields to be filled in are needed. | ||
| 177 | */ | ||
| 178 | if ((vap->va_mask & | ||
| 179 | (XFS_AT_EXTSIZE|XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS| | ||
| 180 | XFS_AT_GENCOUNT|XFS_AT_VCODE)) == 0) | ||
| 181 | goto all_done; | ||
| 182 | |||
| 183 | vap->va_extsize = ip->i_d.di_extsize << mp->m_sb.sb_blocklog; | ||
| 184 | vap->va_nextents = | ||
| 185 | (ip->i_df.if_flags & XFS_IFEXTENTS) ? | ||
| 186 | ip->i_df.if_bytes / sizeof(xfs_bmbt_rec_t) : | ||
| 187 | ip->i_d.di_nextents; | ||
| 188 | if (ip->i_afp) | ||
| 189 | vap->va_anextents = | ||
| 190 | (ip->i_afp->if_flags & XFS_IFEXTENTS) ? | ||
| 191 | ip->i_afp->if_bytes / sizeof(xfs_bmbt_rec_t) : | ||
| 192 | ip->i_d.di_anextents; | ||
| 193 | else | ||
| 194 | vap->va_anextents = 0; | ||
| 195 | vap->va_gen = ip->i_d.di_gen; | ||
| 196 | |||
| 197 | all_done: | ||
| 198 | if (!(flags & ATTR_LAZY)) | ||
| 199 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | ||
| 200 | return 0; | ||
| 201 | } | ||
| 202 | |||
| 203 | |||
| 204 | /* | ||
| 205 | * xfs_setattr | 79 | * xfs_setattr |
| 206 | */ | 80 | */ |
| 207 | int | 81 | int |
| @@ -211,7 +85,6 @@ xfs_setattr( | |||
| 211 | int flags, | 85 | int flags, |
| 212 | cred_t *credp) | 86 | cred_t *credp) |
| 213 | { | 87 | { |
| 214 | bhv_vnode_t *vp = XFS_ITOV(ip); | ||
| 215 | xfs_mount_t *mp = ip->i_mount; | 88 | xfs_mount_t *mp = ip->i_mount; |
| 216 | xfs_trans_t *tp; | 89 | xfs_trans_t *tp; |
| 217 | int mask; | 90 | int mask; |
| @@ -222,7 +95,6 @@ xfs_setattr( | |||
| 222 | gid_t gid=0, igid=0; | 95 | gid_t gid=0, igid=0; |
| 223 | int timeflags = 0; | 96 | int timeflags = 0; |
| 224 | xfs_prid_t projid=0, iprojid=0; | 97 | xfs_prid_t projid=0, iprojid=0; |
| 225 | int mandlock_before, mandlock_after; | ||
| 226 | struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2; | 98 | struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2; |
| 227 | int file_owner; | 99 | int file_owner; |
| 228 | int need_iolock = 1; | 100 | int need_iolock = 1; |
| @@ -383,7 +255,7 @@ xfs_setattr( | |||
| 383 | m |= S_ISGID; | 255 | m |= S_ISGID; |
| 384 | #if 0 | 256 | #if 0 |
| 385 | /* Linux allows this, Irix doesn't. */ | 257 | /* Linux allows this, Irix doesn't. */ |
| 386 | if ((vap->va_mode & S_ISVTX) && !VN_ISDIR(vp)) | 258 | if ((vap->va_mode & S_ISVTX) && !S_ISDIR(ip->i_d.di_mode)) |
| 387 | m |= S_ISVTX; | 259 | m |= S_ISVTX; |
| 388 | #endif | 260 | #endif |
| 389 | if (m && !capable(CAP_FSETID)) | 261 | if (m && !capable(CAP_FSETID)) |
| @@ -461,10 +333,10 @@ xfs_setattr( | |||
| 461 | goto error_return; | 333 | goto error_return; |
| 462 | } | 334 | } |
| 463 | 335 | ||
| 464 | if (VN_ISDIR(vp)) { | 336 | if (S_ISDIR(ip->i_d.di_mode)) { |
| 465 | code = XFS_ERROR(EISDIR); | 337 | code = XFS_ERROR(EISDIR); |
| 466 | goto error_return; | 338 | goto error_return; |
| 467 | } else if (!VN_ISREG(vp)) { | 339 | } else if (!S_ISREG(ip->i_d.di_mode)) { |
| 468 | code = XFS_ERROR(EINVAL); | 340 | code = XFS_ERROR(EINVAL); |
| 469 | goto error_return; | 341 | goto error_return; |
| 470 | } | 342 | } |
| @@ -626,9 +498,6 @@ xfs_setattr( | |||
| 626 | xfs_trans_ihold(tp, ip); | 498 | xfs_trans_ihold(tp, ip); |
| 627 | } | 499 | } |
| 628 | 500 | ||
| 629 | /* determine whether mandatory locking mode changes */ | ||
| 630 | mandlock_before = MANDLOCK(vp, ip->i_d.di_mode); | ||
| 631 | |||
| 632 | /* | 501 | /* |
| 633 | * Truncate file. Must have write permission and not be a directory. | 502 | * Truncate file. Must have write permission and not be a directory. |
| 634 | */ | 503 | */ |
| @@ -858,13 +727,6 @@ xfs_setattr( | |||
| 858 | code = xfs_trans_commit(tp, commit_flags); | 727 | code = xfs_trans_commit(tp, commit_flags); |
| 859 | } | 728 | } |
| 860 | 729 | ||
| 861 | /* | ||
| 862 | * If the (regular) file's mandatory locking mode changed, then | ||
| 863 | * notify the vnode. We do this under the inode lock to prevent | ||
| 864 | * racing calls to vop_vnode_change. | ||
| 865 | */ | ||
| 866 | mandlock_after = MANDLOCK(vp, ip->i_d.di_mode); | ||
| 867 | |||
| 868 | xfs_iunlock(ip, lock_flags); | 730 | xfs_iunlock(ip, lock_flags); |
| 869 | 731 | ||
| 870 | /* | 732 | /* |
| @@ -1443,7 +1305,7 @@ xfs_inactive_attrs( | |||
| 1443 | int error; | 1305 | int error; |
| 1444 | xfs_mount_t *mp; | 1306 | xfs_mount_t *mp; |
| 1445 | 1307 | ||
| 1446 | ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE)); | 1308 | ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); |
| 1447 | tp = *tpp; | 1309 | tp = *tpp; |
| 1448 | mp = ip->i_mount; | 1310 | mp = ip->i_mount; |
| 1449 | ASSERT(ip->i_d.di_forkoff != 0); | 1311 | ASSERT(ip->i_d.di_forkoff != 0); |
| @@ -1491,7 +1353,7 @@ xfs_release( | |||
| 1491 | xfs_mount_t *mp = ip->i_mount; | 1353 | xfs_mount_t *mp = ip->i_mount; |
| 1492 | int error; | 1354 | int error; |
| 1493 | 1355 | ||
| 1494 | if (!VN_ISREG(vp) || (ip->i_d.di_mode == 0)) | 1356 | if (!S_ISREG(ip->i_d.di_mode) || (ip->i_d.di_mode == 0)) |
| 1495 | return 0; | 1357 | return 0; |
| 1496 | 1358 | ||
| 1497 | /* If this is a read-only mount, don't do this (would generate I/O) */ | 1359 | /* If this is a read-only mount, don't do this (would generate I/O) */ |
| @@ -1774,8 +1636,7 @@ xfs_lookup( | |||
| 1774 | struct xfs_name *name, | 1636 | struct xfs_name *name, |
| 1775 | xfs_inode_t **ipp) | 1637 | xfs_inode_t **ipp) |
| 1776 | { | 1638 | { |
| 1777 | xfs_inode_t *ip; | 1639 | xfs_ino_t inum; |
| 1778 | xfs_ino_t e_inum; | ||
| 1779 | int error; | 1640 | int error; |
| 1780 | uint lock_mode; | 1641 | uint lock_mode; |
| 1781 | 1642 | ||
| @@ -1785,12 +1646,21 @@ xfs_lookup( | |||
| 1785 | return XFS_ERROR(EIO); | 1646 | return XFS_ERROR(EIO); |
| 1786 | 1647 | ||
| 1787 | lock_mode = xfs_ilock_map_shared(dp); | 1648 | lock_mode = xfs_ilock_map_shared(dp); |
| 1788 | error = xfs_dir_lookup_int(dp, lock_mode, name, &e_inum, &ip); | 1649 | error = xfs_dir_lookup(NULL, dp, name, &inum); |
| 1789 | if (!error) { | ||
| 1790 | *ipp = ip; | ||
| 1791 | xfs_itrace_ref(ip); | ||
| 1792 | } | ||
| 1793 | xfs_iunlock_map_shared(dp, lock_mode); | 1650 | xfs_iunlock_map_shared(dp, lock_mode); |
| 1651 | |||
| 1652 | if (error) | ||
| 1653 | goto out; | ||
| 1654 | |||
| 1655 | error = xfs_iget(dp->i_mount, NULL, inum, 0, 0, ipp, 0); | ||
| 1656 | if (error) | ||
| 1657 | goto out; | ||
| 1658 | |||
| 1659 | xfs_itrace_ref(*ipp); | ||
| 1660 | return 0; | ||
| 1661 | |||
| 1662 | out: | ||
| 1663 | *ipp = NULL; | ||
| 1794 | return error; | 1664 | return error; |
| 1795 | } | 1665 | } |
| 1796 | 1666 | ||
| @@ -1906,7 +1776,7 @@ xfs_create( | |||
| 1906 | * It is locked (and joined to the transaction). | 1776 | * It is locked (and joined to the transaction). |
| 1907 | */ | 1777 | */ |
| 1908 | 1778 | ||
| 1909 | ASSERT(ismrlocked (&ip->i_lock, MR_UPDATE)); | 1779 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
| 1910 | 1780 | ||
| 1911 | /* | 1781 | /* |
| 1912 | * Now we join the directory inode to the transaction. We do not do it | 1782 | * Now we join the directory inode to the transaction. We do not do it |
| @@ -2112,7 +1982,7 @@ again: | |||
| 2112 | 1982 | ||
| 2113 | ips[0] = ip; | 1983 | ips[0] = ip; |
| 2114 | ips[1] = dp; | 1984 | ips[1] = dp; |
| 2115 | xfs_lock_inodes(ips, 2, 0, XFS_ILOCK_EXCL); | 1985 | xfs_lock_inodes(ips, 2, XFS_ILOCK_EXCL); |
| 2116 | } | 1986 | } |
| 2117 | /* else e_inum == dp->i_ino */ | 1987 | /* else e_inum == dp->i_ino */ |
| 2118 | /* This can happen if we're asked to lock /x/.. | 1988 | /* This can happen if we're asked to lock /x/.. |
| @@ -2160,7 +2030,6 @@ void | |||
| 2160 | xfs_lock_inodes( | 2030 | xfs_lock_inodes( |
| 2161 | xfs_inode_t **ips, | 2031 | xfs_inode_t **ips, |
| 2162 | int inodes, | 2032 | int inodes, |
| 2163 | int first_locked, | ||
| 2164 | uint lock_mode) | 2033 | uint lock_mode) |
| 2165 | { | 2034 | { |
| 2166 | int attempts = 0, i, j, try_lock; | 2035 | int attempts = 0, i, j, try_lock; |
| @@ -2168,13 +2037,8 @@ xfs_lock_inodes( | |||
| 2168 | 2037 | ||
| 2169 | ASSERT(ips && (inodes >= 2)); /* we need at least two */ | 2038 | ASSERT(ips && (inodes >= 2)); /* we need at least two */ |
| 2170 | 2039 | ||
| 2171 | if (first_locked) { | 2040 | try_lock = 0; |
| 2172 | try_lock = 1; | 2041 | i = 0; |
| 2173 | i = 1; | ||
| 2174 | } else { | ||
| 2175 | try_lock = 0; | ||
| 2176 | i = 0; | ||
| 2177 | } | ||
| 2178 | 2042 | ||
| 2179 | again: | 2043 | again: |
| 2180 | for (; i < inodes; i++) { | 2044 | for (; i < inodes; i++) { |
| @@ -2298,29 +2162,14 @@ xfs_remove( | |||
| 2298 | return error; | 2162 | return error; |
| 2299 | } | 2163 | } |
| 2300 | 2164 | ||
| 2301 | /* | ||
| 2302 | * We need to get a reference to ip before we get our log | ||
| 2303 | * reservation. The reason for this is that we cannot call | ||
| 2304 | * xfs_iget for an inode for which we do not have a reference | ||
| 2305 | * once we've acquired a log reservation. This is because the | ||
| 2306 | * inode we are trying to get might be in xfs_inactive going | ||
| 2307 | * for a log reservation. Since we'll have to wait for the | ||
| 2308 | * inactive code to complete before returning from xfs_iget, | ||
| 2309 | * we need to make sure that we don't have log space reserved | ||
| 2310 | * when we call xfs_iget. Instead we get an unlocked reference | ||
| 2311 | * to the inode before getting our log reservation. | ||
| 2312 | */ | ||
| 2313 | IHOLD(ip); | ||
| 2314 | |||
| 2315 | xfs_itrace_entry(ip); | 2165 | xfs_itrace_entry(ip); |
| 2316 | xfs_itrace_ref(ip); | 2166 | xfs_itrace_ref(ip); |
| 2317 | 2167 | ||
| 2318 | error = XFS_QM_DQATTACH(mp, dp, 0); | 2168 | error = XFS_QM_DQATTACH(mp, dp, 0); |
| 2319 | if (!error && dp != ip) | 2169 | if (!error) |
| 2320 | error = XFS_QM_DQATTACH(mp, ip, 0); | 2170 | error = XFS_QM_DQATTACH(mp, ip, 0); |
| 2321 | if (error) { | 2171 | if (error) { |
| 2322 | REMOVE_DEBUG_TRACE(__LINE__); | 2172 | REMOVE_DEBUG_TRACE(__LINE__); |
| 2323 | IRELE(ip); | ||
| 2324 | goto std_return; | 2173 | goto std_return; |
| 2325 | } | 2174 | } |
| 2326 | 2175 | ||
| @@ -2347,7 +2196,6 @@ xfs_remove( | |||
| 2347 | ASSERT(error != ENOSPC); | 2196 | ASSERT(error != ENOSPC); |
| 2348 | REMOVE_DEBUG_TRACE(__LINE__); | 2197 | REMOVE_DEBUG_TRACE(__LINE__); |
| 2349 | xfs_trans_cancel(tp, 0); | 2198 | xfs_trans_cancel(tp, 0); |
| 2350 | IRELE(ip); | ||
| 2351 | return error; | 2199 | return error; |
| 2352 | } | 2200 | } |
| 2353 | 2201 | ||
| @@ -2355,7 +2203,6 @@ xfs_remove( | |||
| 2355 | if (error) { | 2203 | if (error) { |
| 2356 | REMOVE_DEBUG_TRACE(__LINE__); | 2204 | REMOVE_DEBUG_TRACE(__LINE__); |
| 2357 | xfs_trans_cancel(tp, cancel_flags); | 2205 | xfs_trans_cancel(tp, cancel_flags); |
| 2358 | IRELE(ip); | ||
| 2359 | goto std_return; | 2206 | goto std_return; |
| 2360 | } | 2207 | } |
| 2361 | 2208 | ||
| @@ -2363,23 +2210,18 @@ xfs_remove( | |||
| 2363 | * At this point, we've gotten both the directory and the entry | 2210 | * At this point, we've gotten both the directory and the entry |
| 2364 | * inodes locked. | 2211 | * inodes locked. |
| 2365 | */ | 2212 | */ |
| 2213 | IHOLD(ip); | ||
| 2366 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); | 2214 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); |
| 2367 | if (dp != ip) { | 2215 | |
| 2368 | /* | 2216 | IHOLD(dp); |
| 2369 | * Increment vnode ref count only in this case since | 2217 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); |
| 2370 | * there's an extra vnode reference in the case where | ||
| 2371 | * dp == ip. | ||
| 2372 | */ | ||
| 2373 | IHOLD(dp); | ||
| 2374 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | ||
| 2375 | } | ||
| 2376 | 2218 | ||
| 2377 | /* | 2219 | /* |
| 2378 | * Entry must exist since we did a lookup in xfs_lock_dir_and_entry. | 2220 | * Entry must exist since we did a lookup in xfs_lock_dir_and_entry. |
| 2379 | */ | 2221 | */ |
| 2380 | XFS_BMAP_INIT(&free_list, &first_block); | 2222 | XFS_BMAP_INIT(&free_list, &first_block); |
| 2381 | error = xfs_dir_removename(tp, dp, name, ip->i_ino, | 2223 | error = xfs_dir_removename(tp, dp, name, ip->i_ino, |
| 2382 | &first_block, &free_list, 0); | 2224 | &first_block, &free_list, resblks); |
| 2383 | if (error) { | 2225 | if (error) { |
| 2384 | ASSERT(error != ENOENT); | 2226 | ASSERT(error != ENOENT); |
| 2385 | REMOVE_DEBUG_TRACE(__LINE__); | 2227 | REMOVE_DEBUG_TRACE(__LINE__); |
| @@ -2402,12 +2244,6 @@ xfs_remove( | |||
| 2402 | link_zero = (ip)->i_d.di_nlink==0; | 2244 | link_zero = (ip)->i_d.di_nlink==0; |
| 2403 | 2245 | ||
| 2404 | /* | 2246 | /* |
| 2405 | * Take an extra ref on the inode so that it doesn't | ||
| 2406 | * go to xfs_inactive() from within the commit. | ||
| 2407 | */ | ||
| 2408 | IHOLD(ip); | ||
| 2409 | |||
| 2410 | /* | ||
| 2411 | * If this is a synchronous mount, make sure that the | 2247 | * If this is a synchronous mount, make sure that the |
| 2412 | * remove transaction goes to disk before returning to | 2248 | * remove transaction goes to disk before returning to |
| 2413 | * the user. | 2249 | * the user. |
| @@ -2423,10 +2259,8 @@ xfs_remove( | |||
| 2423 | } | 2259 | } |
| 2424 | 2260 | ||
| 2425 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | 2261 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); |
| 2426 | if (error) { | 2262 | if (error) |
| 2427 | IRELE(ip); | ||
| 2428 | goto std_return; | 2263 | goto std_return; |
| 2429 | } | ||
| 2430 | 2264 | ||
| 2431 | /* | 2265 | /* |
| 2432 | * If we are using filestreams, kill the stream association. | 2266 | * If we are using filestreams, kill the stream association. |
| @@ -2438,7 +2272,6 @@ xfs_remove( | |||
| 2438 | xfs_filestream_deassociate(ip); | 2272 | xfs_filestream_deassociate(ip); |
| 2439 | 2273 | ||
| 2440 | xfs_itrace_exit(ip); | 2274 | xfs_itrace_exit(ip); |
| 2441 | IRELE(ip); | ||
| 2442 | 2275 | ||
| 2443 | /* Fall through to std_return with error = 0 */ | 2276 | /* Fall through to std_return with error = 0 */ |
| 2444 | std_return: | 2277 | std_return: |
| @@ -2467,8 +2300,6 @@ xfs_remove( | |||
| 2467 | cancel_flags |= XFS_TRANS_ABORT; | 2300 | cancel_flags |= XFS_TRANS_ABORT; |
| 2468 | xfs_trans_cancel(tp, cancel_flags); | 2301 | xfs_trans_cancel(tp, cancel_flags); |
| 2469 | 2302 | ||
| 2470 | IRELE(ip); | ||
| 2471 | |||
| 2472 | goto std_return; | 2303 | goto std_return; |
| 2473 | } | 2304 | } |
| 2474 | 2305 | ||
| @@ -2536,7 +2367,7 @@ xfs_link( | |||
| 2536 | ips[1] = sip; | 2367 | ips[1] = sip; |
| 2537 | } | 2368 | } |
| 2538 | 2369 | ||
| 2539 | xfs_lock_inodes(ips, 2, 0, XFS_ILOCK_EXCL); | 2370 | xfs_lock_inodes(ips, 2, XFS_ILOCK_EXCL); |
| 2540 | 2371 | ||
| 2541 | /* | 2372 | /* |
| 2542 | * Increment vnode ref counts since xfs_trans_commit & | 2373 | * Increment vnode ref counts since xfs_trans_commit & |
| @@ -2840,7 +2671,6 @@ xfs_rmdir( | |||
| 2840 | struct xfs_name *name, | 2671 | struct xfs_name *name, |
| 2841 | xfs_inode_t *cdp) | 2672 | xfs_inode_t *cdp) |
| 2842 | { | 2673 | { |
| 2843 | bhv_vnode_t *dir_vp = XFS_ITOV(dp); | ||
| 2844 | xfs_mount_t *mp = dp->i_mount; | 2674 | xfs_mount_t *mp = dp->i_mount; |
| 2845 | xfs_trans_t *tp; | 2675 | xfs_trans_t *tp; |
| 2846 | int error; | 2676 | int error; |
| @@ -2866,27 +2696,12 @@ xfs_rmdir( | |||
| 2866 | } | 2696 | } |
| 2867 | 2697 | ||
| 2868 | /* | 2698 | /* |
| 2869 | * We need to get a reference to cdp before we get our log | ||
| 2870 | * reservation. The reason for this is that we cannot call | ||
| 2871 | * xfs_iget for an inode for which we do not have a reference | ||
| 2872 | * once we've acquired a log reservation. This is because the | ||
| 2873 | * inode we are trying to get might be in xfs_inactive going | ||
| 2874 | * for a log reservation. Since we'll have to wait for the | ||
| 2875 | * inactive code to complete before returning from xfs_iget, | ||
| 2876 | * we need to make sure that we don't have log space reserved | ||
| 2877 | * when we call xfs_iget. Instead we get an unlocked reference | ||
| 2878 | * to the inode before getting our log reservation. | ||
| 2879 | */ | ||
| 2880 | IHOLD(cdp); | ||
| 2881 | |||
| 2882 | /* | ||
| 2883 | * Get the dquots for the inodes. | 2699 | * Get the dquots for the inodes. |
| 2884 | */ | 2700 | */ |
| 2885 | error = XFS_QM_DQATTACH(mp, dp, 0); | 2701 | error = XFS_QM_DQATTACH(mp, dp, 0); |
| 2886 | if (!error && dp != cdp) | 2702 | if (!error) |
| 2887 | error = XFS_QM_DQATTACH(mp, cdp, 0); | 2703 | error = XFS_QM_DQATTACH(mp, cdp, 0); |
| 2888 | if (error) { | 2704 | if (error) { |
| 2889 | IRELE(cdp); | ||
| 2890 | REMOVE_DEBUG_TRACE(__LINE__); | 2705 | REMOVE_DEBUG_TRACE(__LINE__); |
| 2891 | goto std_return; | 2706 | goto std_return; |
| 2892 | } | 2707 | } |
| @@ -2913,7 +2728,6 @@ xfs_rmdir( | |||
| 2913 | if (error) { | 2728 | if (error) { |
| 2914 | ASSERT(error != ENOSPC); | 2729 | ASSERT(error != ENOSPC); |
| 2915 | cancel_flags = 0; | 2730 | cancel_flags = 0; |
| 2916 | IRELE(cdp); | ||
| 2917 | goto error_return; | 2731 | goto error_return; |
| 2918 | } | 2732 | } |
| 2919 | XFS_BMAP_INIT(&free_list, &first_block); | 2733 | XFS_BMAP_INIT(&free_list, &first_block); |
| @@ -2927,21 +2741,13 @@ xfs_rmdir( | |||
| 2927 | error = xfs_lock_dir_and_entry(dp, cdp); | 2741 | error = xfs_lock_dir_and_entry(dp, cdp); |
| 2928 | if (error) { | 2742 | if (error) { |
| 2929 | xfs_trans_cancel(tp, cancel_flags); | 2743 | xfs_trans_cancel(tp, cancel_flags); |
| 2930 | IRELE(cdp); | ||
| 2931 | goto std_return; | 2744 | goto std_return; |
| 2932 | } | 2745 | } |
| 2933 | 2746 | ||
| 2747 | IHOLD(dp); | ||
| 2934 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); | 2748 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); |
| 2935 | if (dp != cdp) { | ||
| 2936 | /* | ||
| 2937 | * Only increment the parent directory vnode count if | ||
| 2938 | * we didn't bump it in looking up cdp. The only time | ||
| 2939 | * we don't bump it is when we're looking up ".". | ||
| 2940 | */ | ||
| 2941 | VN_HOLD(dir_vp); | ||
| 2942 | } | ||
| 2943 | 2749 | ||
| 2944 | xfs_itrace_ref(cdp); | 2750 | IHOLD(cdp); |
| 2945 | xfs_trans_ijoin(tp, cdp, XFS_ILOCK_EXCL); | 2751 | xfs_trans_ijoin(tp, cdp, XFS_ILOCK_EXCL); |
| 2946 | 2752 | ||
| 2947 | ASSERT(cdp->i_d.di_nlink >= 2); | 2753 | ASSERT(cdp->i_d.di_nlink >= 2); |
| @@ -2995,12 +2801,6 @@ xfs_rmdir( | |||
| 2995 | last_cdp_link = (cdp)->i_d.di_nlink==0; | 2801 | last_cdp_link = (cdp)->i_d.di_nlink==0; |
| 2996 | 2802 | ||
| 2997 | /* | 2803 | /* |
| 2998 | * Take an extra ref on the child vnode so that it | ||
| 2999 | * does not go to xfs_inactive() from within the commit. | ||
| 3000 | */ | ||
| 3001 | IHOLD(cdp); | ||
| 3002 | |||
| 3003 | /* | ||
| 3004 | * If this is a synchronous mount, make sure that the | 2804 | * If this is a synchronous mount, make sure that the |
| 3005 | * rmdir transaction goes to disk before returning to | 2805 | * rmdir transaction goes to disk before returning to |
| 3006 | * the user. | 2806 | * the user. |
| @@ -3014,19 +2814,15 @@ xfs_rmdir( | |||
| 3014 | xfs_bmap_cancel(&free_list); | 2814 | xfs_bmap_cancel(&free_list); |
| 3015 | xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | | 2815 | xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | |
| 3016 | XFS_TRANS_ABORT)); | 2816 | XFS_TRANS_ABORT)); |
| 3017 | IRELE(cdp); | ||
| 3018 | goto std_return; | 2817 | goto std_return; |
| 3019 | } | 2818 | } |
| 3020 | 2819 | ||
| 3021 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | 2820 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); |
| 3022 | if (error) { | 2821 | if (error) { |
| 3023 | IRELE(cdp); | ||
| 3024 | goto std_return; | 2822 | goto std_return; |
| 3025 | } | 2823 | } |
| 3026 | 2824 | ||
| 3027 | 2825 | ||
| 3028 | IRELE(cdp); | ||
| 3029 | |||
| 3030 | /* Fall through to std_return with error = 0 or the errno | 2826 | /* Fall through to std_return with error = 0 or the errno |
| 3031 | * from xfs_trans_commit. */ | 2827 | * from xfs_trans_commit. */ |
| 3032 | std_return: | 2828 | std_return: |
