aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_vnodeops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_vnodeops.c')
-rw-r--r--fs/xfs/xfs_vnodeops.c198
1 files changed, 56 insertions, 142 deletions
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 76a1166af822..aa238c8fbd7a 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -83,7 +83,7 @@ xfs_setattr(
83 cred_t *credp) 83 cred_t *credp)
84{ 84{
85 xfs_mount_t *mp = ip->i_mount; 85 xfs_mount_t *mp = ip->i_mount;
86 struct inode *inode = XFS_ITOV(ip); 86 struct inode *inode = VFS_I(ip);
87 int mask = iattr->ia_valid; 87 int mask = iattr->ia_valid;
88 xfs_trans_t *tp; 88 xfs_trans_t *tp;
89 int code; 89 int code;
@@ -182,7 +182,7 @@ xfs_setattr(
182 xfs_ilock(ip, lock_flags); 182 xfs_ilock(ip, lock_flags);
183 183
184 /* boolean: are we the file owner? */ 184 /* boolean: are we the file owner? */
185 file_owner = (current_fsuid(credp) == ip->i_d.di_uid); 185 file_owner = (current_fsuid() == ip->i_d.di_uid);
186 186
187 /* 187 /*
188 * Change various properties of a file. 188 * Change various properties of a file.
@@ -513,7 +513,6 @@ xfs_setattr(
513 ip->i_d.di_atime.t_sec = iattr->ia_atime.tv_sec; 513 ip->i_d.di_atime.t_sec = iattr->ia_atime.tv_sec;
514 ip->i_d.di_atime.t_nsec = iattr->ia_atime.tv_nsec; 514 ip->i_d.di_atime.t_nsec = iattr->ia_atime.tv_nsec;
515 ip->i_update_core = 1; 515 ip->i_update_core = 1;
516 timeflags &= ~XFS_ICHGTIME_ACC;
517 } 516 }
518 if (mask & ATTR_MTIME) { 517 if (mask & ATTR_MTIME) {
519 inode->i_mtime = iattr->ia_mtime; 518 inode->i_mtime = iattr->ia_mtime;
@@ -714,7 +713,7 @@ xfs_fsync(
714 return XFS_ERROR(EIO); 713 return XFS_ERROR(EIO);
715 714
716 /* capture size updates in I/O completion before writing the inode. */ 715 /* capture size updates in I/O completion before writing the inode. */
717 error = filemap_fdatawait(vn_to_inode(XFS_ITOV(ip))->i_mapping); 716 error = filemap_fdatawait(VFS_I(ip)->i_mapping);
718 if (error) 717 if (error)
719 return XFS_ERROR(error); 718 return XFS_ERROR(error);
720 719
@@ -1160,7 +1159,6 @@ int
1160xfs_release( 1159xfs_release(
1161 xfs_inode_t *ip) 1160 xfs_inode_t *ip)
1162{ 1161{
1163 bhv_vnode_t *vp = XFS_ITOV(ip);
1164 xfs_mount_t *mp = ip->i_mount; 1162 xfs_mount_t *mp = ip->i_mount;
1165 int error; 1163 int error;
1166 1164
@@ -1195,13 +1193,13 @@ xfs_release(
1195 * be exposed to that problem. 1193 * be exposed to that problem.
1196 */ 1194 */
1197 truncated = xfs_iflags_test_and_clear(ip, XFS_ITRUNCATED); 1195 truncated = xfs_iflags_test_and_clear(ip, XFS_ITRUNCATED);
1198 if (truncated && VN_DIRTY(vp) && ip->i_delayed_blks > 0) 1196 if (truncated && VN_DIRTY(VFS_I(ip)) && ip->i_delayed_blks > 0)
1199 xfs_flush_pages(ip, 0, -1, XFS_B_ASYNC, FI_NONE); 1197 xfs_flush_pages(ip, 0, -1, XFS_B_ASYNC, FI_NONE);
1200 } 1198 }
1201 1199
1202 if (ip->i_d.di_nlink != 0) { 1200 if (ip->i_d.di_nlink != 0) {
1203 if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) && 1201 if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) &&
1204 ((ip->i_size > 0) || (VN_CACHED(vp) > 0 || 1202 ((ip->i_size > 0) || (VN_CACHED(VFS_I(ip)) > 0 ||
1205 ip->i_delayed_blks > 0)) && 1203 ip->i_delayed_blks > 0)) &&
1206 (ip->i_df.if_flags & XFS_IFEXTENTS)) && 1204 (ip->i_df.if_flags & XFS_IFEXTENTS)) &&
1207 (!(ip->i_d.di_flags & 1205 (!(ip->i_d.di_flags &
@@ -1227,7 +1225,6 @@ int
1227xfs_inactive( 1225xfs_inactive(
1228 xfs_inode_t *ip) 1226 xfs_inode_t *ip)
1229{ 1227{
1230 bhv_vnode_t *vp = XFS_ITOV(ip);
1231 xfs_bmap_free_t free_list; 1228 xfs_bmap_free_t free_list;
1232 xfs_fsblock_t first_block; 1229 xfs_fsblock_t first_block;
1233 int committed; 1230 int committed;
@@ -1242,7 +1239,7 @@ xfs_inactive(
1242 * If the inode is already free, then there can be nothing 1239 * If the inode is already free, then there can be nothing
1243 * to clean up here. 1240 * to clean up here.
1244 */ 1241 */
1245 if (ip->i_d.di_mode == 0 || VN_BAD(vp)) { 1242 if (ip->i_d.di_mode == 0 || VN_BAD(VFS_I(ip))) {
1246 ASSERT(ip->i_df.if_real_bytes == 0); 1243 ASSERT(ip->i_df.if_real_bytes == 0);
1247 ASSERT(ip->i_df.if_broot_bytes == 0); 1244 ASSERT(ip->i_df.if_broot_bytes == 0);
1248 return VN_INACTIVE_CACHE; 1245 return VN_INACTIVE_CACHE;
@@ -1272,7 +1269,7 @@ xfs_inactive(
1272 1269
1273 if (ip->i_d.di_nlink != 0) { 1270 if (ip->i_d.di_nlink != 0) {
1274 if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) && 1271 if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) &&
1275 ((ip->i_size > 0) || (VN_CACHED(vp) > 0 || 1272 ((ip->i_size > 0) || (VN_CACHED(VFS_I(ip)) > 0 ||
1276 ip->i_delayed_blks > 0)) && 1273 ip->i_delayed_blks > 0)) &&
1277 (ip->i_df.if_flags & XFS_IFEXTENTS) && 1274 (ip->i_df.if_flags & XFS_IFEXTENTS) &&
1278 (!(ip->i_d.di_flags & 1275 (!(ip->i_d.di_flags &
@@ -1536,7 +1533,7 @@ xfs_create(
1536 * Make sure that we have allocated dquot(s) on disk. 1533 * Make sure that we have allocated dquot(s) on disk.
1537 */ 1534 */
1538 error = XFS_QM_DQVOPALLOC(mp, dp, 1535 error = XFS_QM_DQVOPALLOC(mp, dp,
1539 current_fsuid(credp), current_fsgid(credp), prid, 1536 current_fsuid(), current_fsgid(), prid,
1540 XFS_QMOPT_QUOTALL|XFS_QMOPT_INHERIT, &udqp, &gdqp); 1537 XFS_QMOPT_QUOTALL|XFS_QMOPT_INHERIT, &udqp, &gdqp);
1541 if (error) 1538 if (error)
1542 goto std_return; 1539 goto std_return;
@@ -1708,111 +1705,6 @@ std_return:
1708} 1705}
1709 1706
1710#ifdef DEBUG 1707#ifdef DEBUG
1711/*
1712 * Some counters to see if (and how often) we are hitting some deadlock
1713 * prevention code paths.
1714 */
1715
1716int xfs_rm_locks;
1717int xfs_rm_lock_delays;
1718int xfs_rm_attempts;
1719#endif
1720
1721/*
1722 * The following routine will lock the inodes associated with the
1723 * directory and the named entry in the directory. The locks are
1724 * acquired in increasing inode number.
1725 *
1726 * If the entry is "..", then only the directory is locked. The
1727 * vnode ref count will still include that from the .. entry in
1728 * this case.
1729 *
1730 * There is a deadlock we need to worry about. If the locked directory is
1731 * in the AIL, it might be blocking up the log. The next inode we lock
1732 * could be already locked by another thread waiting for log space (e.g
1733 * a permanent log reservation with a long running transaction (see
1734 * xfs_itruncate_finish)). To solve this, we must check if the directory
1735 * is in the ail and use lock_nowait. If we can't lock, we need to
1736 * drop the inode lock on the directory and try again. xfs_iunlock will
1737 * potentially push the tail if we were holding up the log.
1738 */
1739STATIC int
1740xfs_lock_dir_and_entry(
1741 xfs_inode_t *dp,
1742 xfs_inode_t *ip) /* inode of entry 'name' */
1743{
1744 int attempts;
1745 xfs_ino_t e_inum;
1746 xfs_inode_t *ips[2];
1747 xfs_log_item_t *lp;
1748
1749#ifdef DEBUG
1750 xfs_rm_locks++;
1751#endif
1752 attempts = 0;
1753
1754again:
1755 xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
1756
1757 e_inum = ip->i_ino;
1758
1759 xfs_itrace_ref(ip);
1760
1761 /*
1762 * We want to lock in increasing inum. Since we've already
1763 * acquired the lock on the directory, we may need to release
1764 * if if the inum of the entry turns out to be less.
1765 */
1766 if (e_inum > dp->i_ino) {
1767 /*
1768 * We are already in the right order, so just
1769 * lock on the inode of the entry.
1770 * We need to use nowait if dp is in the AIL.
1771 */
1772
1773 lp = (xfs_log_item_t *)dp->i_itemp;
1774 if (lp && (lp->li_flags & XFS_LI_IN_AIL)) {
1775 if (!xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) {
1776 attempts++;
1777#ifdef DEBUG
1778 xfs_rm_attempts++;
1779#endif
1780
1781 /*
1782 * Unlock dp and try again.
1783 * xfs_iunlock will try to push the tail
1784 * if the inode is in the AIL.
1785 */
1786
1787 xfs_iunlock(dp, XFS_ILOCK_EXCL);
1788
1789 if ((attempts % 5) == 0) {
1790 delay(1); /* Don't just spin the CPU */
1791#ifdef DEBUG
1792 xfs_rm_lock_delays++;
1793#endif
1794 }
1795 goto again;
1796 }
1797 } else {
1798 xfs_ilock(ip, XFS_ILOCK_EXCL);
1799 }
1800 } else if (e_inum < dp->i_ino) {
1801 xfs_iunlock(dp, XFS_ILOCK_EXCL);
1802
1803 ips[0] = ip;
1804 ips[1] = dp;
1805 xfs_lock_inodes(ips, 2, XFS_ILOCK_EXCL);
1806 }
1807 /* else e_inum == dp->i_ino */
1808 /* This can happen if we're asked to lock /x/..
1809 * the entry is "..", which is also the parent directory.
1810 */
1811
1812 return 0;
1813}
1814
1815#ifdef DEBUG
1816int xfs_locked_n; 1708int xfs_locked_n;
1817int xfs_small_retries; 1709int xfs_small_retries;
1818int xfs_middle_retries; 1710int xfs_middle_retries;
@@ -1946,6 +1838,45 @@ again:
1946#endif 1838#endif
1947} 1839}
1948 1840
1841void
1842xfs_lock_two_inodes(
1843 xfs_inode_t *ip0,
1844 xfs_inode_t *ip1,
1845 uint lock_mode)
1846{
1847 xfs_inode_t *temp;
1848 int attempts = 0;
1849 xfs_log_item_t *lp;
1850
1851 ASSERT(ip0->i_ino != ip1->i_ino);
1852
1853 if (ip0->i_ino > ip1->i_ino) {
1854 temp = ip0;
1855 ip0 = ip1;
1856 ip1 = temp;
1857 }
1858
1859 again:
1860 xfs_ilock(ip0, xfs_lock_inumorder(lock_mode, 0));
1861
1862 /*
1863 * If the first lock we have locked is in the AIL, we must TRY to get
1864 * the second lock. If we can't get it, we must release the first one
1865 * and try again.
1866 */
1867 lp = (xfs_log_item_t *)ip0->i_itemp;
1868 if (lp && (lp->li_flags & XFS_LI_IN_AIL)) {
1869 if (!xfs_ilock_nowait(ip1, xfs_lock_inumorder(lock_mode, 1))) {
1870 xfs_iunlock(ip0, lock_mode);
1871 if ((++attempts % 5) == 0)
1872 delay(1); /* Don't just spin the CPU */
1873 goto again;
1874 }
1875 } else {
1876 xfs_ilock(ip1, xfs_lock_inumorder(lock_mode, 1));
1877 }
1878}
1879
1949int 1880int
1950xfs_remove( 1881xfs_remove(
1951 xfs_inode_t *dp, 1882 xfs_inode_t *dp,
@@ -2018,9 +1949,7 @@ xfs_remove(
2018 goto out_trans_cancel; 1949 goto out_trans_cancel;
2019 } 1950 }
2020 1951
2021 error = xfs_lock_dir_and_entry(dp, ip); 1952 xfs_lock_two_inodes(dp, ip, XFS_ILOCK_EXCL);
2022 if (error)
2023 goto out_trans_cancel;
2024 1953
2025 /* 1954 /*
2026 * At this point, we've gotten both the directory and the entry 1955 * At this point, we've gotten both the directory and the entry
@@ -2047,9 +1976,6 @@ xfs_remove(
2047 } 1976 }
2048 } 1977 }
2049 1978
2050 /*
2051 * Entry must exist since we did a lookup in xfs_lock_dir_and_entry.
2052 */
2053 XFS_BMAP_INIT(&free_list, &first_block); 1979 XFS_BMAP_INIT(&free_list, &first_block);
2054 error = xfs_dir_removename(tp, dp, name, ip->i_ino, 1980 error = xfs_dir_removename(tp, dp, name, ip->i_ino,
2055 &first_block, &free_list, resblks); 1981 &first_block, &free_list, resblks);
@@ -2155,7 +2081,6 @@ xfs_link(
2155{ 2081{
2156 xfs_mount_t *mp = tdp->i_mount; 2082 xfs_mount_t *mp = tdp->i_mount;
2157 xfs_trans_t *tp; 2083 xfs_trans_t *tp;
2158 xfs_inode_t *ips[2];
2159 int error; 2084 int error;
2160 xfs_bmap_free_t free_list; 2085 xfs_bmap_free_t free_list;
2161 xfs_fsblock_t first_block; 2086 xfs_fsblock_t first_block;
@@ -2203,15 +2128,7 @@ xfs_link(
2203 goto error_return; 2128 goto error_return;
2204 } 2129 }
2205 2130
2206 if (sip->i_ino < tdp->i_ino) { 2131 xfs_lock_two_inodes(sip, tdp, XFS_ILOCK_EXCL);
2207 ips[0] = sip;
2208 ips[1] = tdp;
2209 } else {
2210 ips[0] = tdp;
2211 ips[1] = sip;
2212 }
2213
2214 xfs_lock_inodes(ips, 2, XFS_ILOCK_EXCL);
2215 2132
2216 /* 2133 /*
2217 * Increment vnode ref counts since xfs_trans_commit & 2134 * Increment vnode ref counts since xfs_trans_commit &
@@ -2352,7 +2269,7 @@ xfs_mkdir(
2352 * Make sure that we have allocated dquot(s) on disk. 2269 * Make sure that we have allocated dquot(s) on disk.
2353 */ 2270 */
2354 error = XFS_QM_DQVOPALLOC(mp, dp, 2271 error = XFS_QM_DQVOPALLOC(mp, dp,
2355 current_fsuid(credp), current_fsgid(credp), prid, 2272 current_fsuid(), current_fsgid(), prid,
2356 XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); 2273 XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
2357 if (error) 2274 if (error)
2358 goto std_return; 2275 goto std_return;
@@ -2578,7 +2495,7 @@ xfs_symlink(
2578 * Make sure that we have allocated dquot(s) on disk. 2495 * Make sure that we have allocated dquot(s) on disk.
2579 */ 2496 */
2580 error = XFS_QM_DQVOPALLOC(mp, dp, 2497 error = XFS_QM_DQVOPALLOC(mp, dp,
2581 current_fsuid(credp), current_fsgid(credp), prid, 2498 current_fsuid(), current_fsgid(), prid,
2582 XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); 2499 XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
2583 if (error) 2500 if (error)
2584 goto std_return; 2501 goto std_return;
@@ -2873,14 +2790,13 @@ int
2873xfs_reclaim( 2790xfs_reclaim(
2874 xfs_inode_t *ip) 2791 xfs_inode_t *ip)
2875{ 2792{
2876 bhv_vnode_t *vp = XFS_ITOV(ip);
2877 2793
2878 xfs_itrace_entry(ip); 2794 xfs_itrace_entry(ip);
2879 2795
2880 ASSERT(!VN_MAPPED(vp)); 2796 ASSERT(!VN_MAPPED(VFS_I(ip)));
2881 2797
2882 /* bad inode, get out here ASAP */ 2798 /* bad inode, get out here ASAP */
2883 if (VN_BAD(vp)) { 2799 if (VN_BAD(VFS_I(ip))) {
2884 xfs_ireclaim(ip); 2800 xfs_ireclaim(ip);
2885 return 0; 2801 return 0;
2886 } 2802 }
@@ -2917,7 +2833,7 @@ xfs_reclaim(
2917 XFS_MOUNT_ILOCK(mp); 2833 XFS_MOUNT_ILOCK(mp);
2918 spin_lock(&ip->i_flags_lock); 2834 spin_lock(&ip->i_flags_lock);
2919 __xfs_iflags_set(ip, XFS_IRECLAIMABLE); 2835 __xfs_iflags_set(ip, XFS_IRECLAIMABLE);
2920 vn_to_inode(vp)->i_private = NULL; 2836 VFS_I(ip)->i_private = NULL;
2921 ip->i_vnode = NULL; 2837 ip->i_vnode = NULL;
2922 spin_unlock(&ip->i_flags_lock); 2838 spin_unlock(&ip->i_flags_lock);
2923 list_add_tail(&ip->i_reclaim, &mp->m_del_inodes); 2839 list_add_tail(&ip->i_reclaim, &mp->m_del_inodes);
@@ -2933,7 +2849,7 @@ xfs_finish_reclaim(
2933 int sync_mode) 2849 int sync_mode)
2934{ 2850{
2935 xfs_perag_t *pag = xfs_get_perag(ip->i_mount, ip->i_ino); 2851 xfs_perag_t *pag = xfs_get_perag(ip->i_mount, ip->i_ino);
2936 bhv_vnode_t *vp = XFS_ITOV_NULL(ip); 2852 struct inode *vp = VFS_I(ip);
2937 2853
2938 if (vp && VN_BAD(vp)) 2854 if (vp && VN_BAD(vp))
2939 goto reclaim; 2855 goto reclaim;
@@ -3321,7 +3237,6 @@ xfs_free_file_space(
3321 xfs_off_t len, 3237 xfs_off_t len,
3322 int attr_flags) 3238 int attr_flags)
3323{ 3239{
3324 bhv_vnode_t *vp;
3325 int committed; 3240 int committed;
3326 int done; 3241 int done;
3327 xfs_off_t end_dmi_offset; 3242 xfs_off_t end_dmi_offset;
@@ -3341,7 +3256,6 @@ xfs_free_file_space(
3341 xfs_trans_t *tp; 3256 xfs_trans_t *tp;
3342 int need_iolock = 1; 3257 int need_iolock = 1;
3343 3258
3344 vp = XFS_ITOV(ip);
3345 mp = ip->i_mount; 3259 mp = ip->i_mount;
3346 3260
3347 xfs_itrace_entry(ip); 3261 xfs_itrace_entry(ip);
@@ -3378,7 +3292,7 @@ xfs_free_file_space(
3378 rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE); 3292 rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE);
3379 ioffset = offset & ~(rounding - 1); 3293 ioffset = offset & ~(rounding - 1);
3380 3294
3381 if (VN_CACHED(vp) != 0) { 3295 if (VN_CACHED(VFS_I(ip)) != 0) {
3382 xfs_inval_cached_trace(ip, ioffset, -1, ioffset, -1); 3296 xfs_inval_cached_trace(ip, ioffset, -1, ioffset, -1);
3383 error = xfs_flushinval_pages(ip, ioffset, -1, FI_REMAPF_LOCKED); 3297 error = xfs_flushinval_pages(ip, ioffset, -1, FI_REMAPF_LOCKED);
3384 if (error) 3298 if (error)