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.c505
1 files changed, 159 insertions, 346 deletions
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 64c5953feca4..6650601c64f7 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -48,7 +48,6 @@
48#include "xfs_quota.h" 48#include "xfs_quota.h"
49#include "xfs_utils.h" 49#include "xfs_utils.h"
50#include "xfs_rtalloc.h" 50#include "xfs_rtalloc.h"
51#include "xfs_refcache.h"
52#include "xfs_trans_space.h" 51#include "xfs_trans_space.h"
53#include "xfs_log_priv.h" 52#include "xfs_log_priv.h"
54#include "xfs_filestream.h" 53#include "xfs_filestream.h"
@@ -327,7 +326,7 @@ xfs_setattr(
327 if (DM_EVENT_ENABLED(ip, DM_EVENT_TRUNCATE) && 326 if (DM_EVENT_ENABLED(ip, DM_EVENT_TRUNCATE) &&
328 !(flags & ATTR_DMI)) { 327 !(flags & ATTR_DMI)) {
329 int dmflags = AT_DELAY_FLAG(flags) | DM_SEM_FLAG_WR; 328 int dmflags = AT_DELAY_FLAG(flags) | DM_SEM_FLAG_WR;
330 code = XFS_SEND_DATA(mp, DM_EVENT_TRUNCATE, vp, 329 code = XFS_SEND_DATA(mp, DM_EVENT_TRUNCATE, ip,
331 vap->va_size, 0, dmflags, NULL); 330 vap->va_size, 0, dmflags, NULL);
332 if (code) { 331 if (code) {
333 lock_flags = 0; 332 lock_flags = 0;
@@ -634,6 +633,15 @@ xfs_setattr(
634 * Truncate file. Must have write permission and not be a directory. 633 * Truncate file. Must have write permission and not be a directory.
635 */ 634 */
636 if (mask & XFS_AT_SIZE) { 635 if (mask & XFS_AT_SIZE) {
636 /*
637 * Only change the c/mtime if we are changing the size
638 * or we are explicitly asked to change it. This handles
639 * the semantic difference between truncate() and ftruncate()
640 * as implemented in the VFS.
641 */
642 if (vap->va_size != ip->i_size || (mask & XFS_AT_CTIME))
643 timeflags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG;
644
637 if (vap->va_size > ip->i_size) { 645 if (vap->va_size > ip->i_size) {
638 xfs_igrow_finish(tp, ip, vap->va_size, 646 xfs_igrow_finish(tp, ip, vap->va_size,
639 !(flags & ATTR_DMI)); 647 !(flags & ATTR_DMI));
@@ -662,10 +670,6 @@ xfs_setattr(
662 */ 670 */
663 xfs_iflags_set(ip, XFS_ITRUNCATED); 671 xfs_iflags_set(ip, XFS_ITRUNCATED);
664 } 672 }
665 /*
666 * Have to do this even if the file's size doesn't change.
667 */
668 timeflags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG;
669 } 673 }
670 674
671 /* 675 /*
@@ -877,7 +881,7 @@ xfs_setattr(
877 881
878 if (DM_EVENT_ENABLED(ip, DM_EVENT_ATTRIBUTE) && 882 if (DM_EVENT_ENABLED(ip, DM_EVENT_ATTRIBUTE) &&
879 !(flags & ATTR_DMI)) { 883 !(flags & ATTR_DMI)) {
880 (void) XFS_SEND_NAMESP(mp, DM_EVENT_ATTRIBUTE, vp, DM_RIGHT_NULL, 884 (void) XFS_SEND_NAMESP(mp, DM_EVENT_ATTRIBUTE, ip, DM_RIGHT_NULL,
881 NULL, DM_RIGHT_NULL, NULL, NULL, 885 NULL, DM_RIGHT_NULL, NULL, NULL,
882 0, 0, AT_DELAY_FLAG(flags)); 886 0, 0, AT_DELAY_FLAG(flags));
883 } 887 }
@@ -1443,28 +1447,22 @@ xfs_inactive_attrs(
1443 tp = *tpp; 1447 tp = *tpp;
1444 mp = ip->i_mount; 1448 mp = ip->i_mount;
1445 ASSERT(ip->i_d.di_forkoff != 0); 1449 ASSERT(ip->i_d.di_forkoff != 0);
1446 xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); 1450 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
1447 xfs_iunlock(ip, XFS_ILOCK_EXCL); 1451 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1452 if (error)
1453 goto error_unlock;
1448 1454
1449 error = xfs_attr_inactive(ip); 1455 error = xfs_attr_inactive(ip);
1450 if (error) { 1456 if (error)
1451 *tpp = NULL; 1457 goto error_unlock;
1452 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
1453 return error; /* goto out */
1454 }
1455 1458
1456 tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); 1459 tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
1457 error = xfs_trans_reserve(tp, 0, 1460 error = xfs_trans_reserve(tp, 0,
1458 XFS_IFREE_LOG_RES(mp), 1461 XFS_IFREE_LOG_RES(mp),
1459 0, XFS_TRANS_PERM_LOG_RES, 1462 0, XFS_TRANS_PERM_LOG_RES,
1460 XFS_INACTIVE_LOG_COUNT); 1463 XFS_INACTIVE_LOG_COUNT);
1461 if (error) { 1464 if (error)
1462 ASSERT(XFS_FORCED_SHUTDOWN(mp)); 1465 goto error_cancel;
1463 xfs_trans_cancel(tp, 0);
1464 *tpp = NULL;
1465 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
1466 return error;
1467 }
1468 1466
1469 xfs_ilock(ip, XFS_ILOCK_EXCL); 1467 xfs_ilock(ip, XFS_ILOCK_EXCL);
1470 xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); 1468 xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
@@ -1475,6 +1473,14 @@ xfs_inactive_attrs(
1475 1473
1476 *tpp = tp; 1474 *tpp = tp;
1477 return 0; 1475 return 0;
1476
1477error_cancel:
1478 ASSERT(XFS_FORCED_SHUTDOWN(mp));
1479 xfs_trans_cancel(tp, 0);
1480error_unlock:
1481 *tpp = NULL;
1482 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
1483 return error;
1478} 1484}
1479 1485
1480int 1486int
@@ -1520,12 +1526,6 @@ xfs_release(
1520 xfs_flush_pages(ip, 0, -1, XFS_B_ASYNC, FI_NONE); 1526 xfs_flush_pages(ip, 0, -1, XFS_B_ASYNC, FI_NONE);
1521 } 1527 }
1522 1528
1523#ifdef HAVE_REFCACHE
1524 /* If we are in the NFS reference cache then don't do this now */
1525 if (ip->i_refcache)
1526 return 0;
1527#endif
1528
1529 if (ip->i_d.di_nlink != 0) { 1529 if (ip->i_d.di_nlink != 0) {
1530 if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) && 1530 if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) &&
1531 ((ip->i_size > 0) || (VN_CACHED(vp) > 0 || 1531 ((ip->i_size > 0) || (VN_CACHED(vp) > 0 ||
@@ -1588,9 +1588,8 @@ xfs_inactive(
1588 1588
1589 mp = ip->i_mount; 1589 mp = ip->i_mount;
1590 1590
1591 if (ip->i_d.di_nlink == 0 && DM_EVENT_ENABLED(ip, DM_EVENT_DESTROY)) { 1591 if (ip->i_d.di_nlink == 0 && DM_EVENT_ENABLED(ip, DM_EVENT_DESTROY))
1592 (void) XFS_SEND_DESTROY(mp, vp, DM_RIGHT_NULL); 1592 XFS_SEND_DESTROY(mp, ip, DM_RIGHT_NULL);
1593 }
1594 1593
1595 error = 0; 1594 error = 0;
1596 1595
@@ -1744,11 +1743,18 @@ xfs_inactive(
1744 XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, XFS_TRANS_DQ_ICOUNT, -1); 1743 XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, XFS_TRANS_DQ_ICOUNT, -1);
1745 1744
1746 /* 1745 /*
1747 * Just ignore errors at this point. There is 1746 * Just ignore errors at this point. There is nothing we can
1748 * nothing we can do except to try to keep going. 1747 * do except to try to keep going. Make sure it's not a silent
1748 * error.
1749 */ 1749 */
1750 (void) xfs_bmap_finish(&tp, &free_list, &committed); 1750 error = xfs_bmap_finish(&tp, &free_list, &committed);
1751 (void) xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); 1751 if (error)
1752 xfs_fs_cmn_err(CE_NOTE, mp, "xfs_inactive: "
1753 "xfs_bmap_finish() returned error %d", error);
1754 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
1755 if (error)
1756 xfs_fs_cmn_err(CE_NOTE, mp, "xfs_inactive: "
1757 "xfs_trans_commit() returned error %d", error);
1752 } 1758 }
1753 /* 1759 /*
1754 * Release the dquots held by inode, if any. 1760 * Release the dquots held by inode, if any.
@@ -1765,8 +1771,8 @@ xfs_inactive(
1765int 1771int
1766xfs_lookup( 1772xfs_lookup(
1767 xfs_inode_t *dp, 1773 xfs_inode_t *dp,
1768 bhv_vname_t *dentry, 1774 struct xfs_name *name,
1769 bhv_vnode_t **vpp) 1775 xfs_inode_t **ipp)
1770{ 1776{
1771 xfs_inode_t *ip; 1777 xfs_inode_t *ip;
1772 xfs_ino_t e_inum; 1778 xfs_ino_t e_inum;
@@ -1779,9 +1785,9 @@ xfs_lookup(
1779 return XFS_ERROR(EIO); 1785 return XFS_ERROR(EIO);
1780 1786
1781 lock_mode = xfs_ilock_map_shared(dp); 1787 lock_mode = xfs_ilock_map_shared(dp);
1782 error = xfs_dir_lookup_int(dp, lock_mode, dentry, &e_inum, &ip); 1788 error = xfs_dir_lookup_int(dp, lock_mode, name, &e_inum, &ip);
1783 if (!error) { 1789 if (!error) {
1784 *vpp = XFS_ITOV(ip); 1790 *ipp = ip;
1785 xfs_itrace_ref(ip); 1791 xfs_itrace_ref(ip);
1786 } 1792 }
1787 xfs_iunlock_map_shared(dp, lock_mode); 1793 xfs_iunlock_map_shared(dp, lock_mode);
@@ -1791,19 +1797,16 @@ xfs_lookup(
1791int 1797int
1792xfs_create( 1798xfs_create(
1793 xfs_inode_t *dp, 1799 xfs_inode_t *dp,
1794 bhv_vname_t *dentry, 1800 struct xfs_name *name,
1795 mode_t mode, 1801 mode_t mode,
1796 xfs_dev_t rdev, 1802 xfs_dev_t rdev,
1797 bhv_vnode_t **vpp, 1803 xfs_inode_t **ipp,
1798 cred_t *credp) 1804 cred_t *credp)
1799{ 1805{
1800 char *name = VNAME(dentry); 1806 xfs_mount_t *mp = dp->i_mount;
1801 xfs_mount_t *mp = dp->i_mount;
1802 bhv_vnode_t *dir_vp = XFS_ITOV(dp);
1803 xfs_inode_t *ip; 1807 xfs_inode_t *ip;
1804 bhv_vnode_t *vp = NULL;
1805 xfs_trans_t *tp; 1808 xfs_trans_t *tp;
1806 int error; 1809 int error;
1807 xfs_bmap_free_t free_list; 1810 xfs_bmap_free_t free_list;
1808 xfs_fsblock_t first_block; 1811 xfs_fsblock_t first_block;
1809 boolean_t unlock_dp_on_error = B_FALSE; 1812 boolean_t unlock_dp_on_error = B_FALSE;
@@ -1813,17 +1816,14 @@ xfs_create(
1813 xfs_prid_t prid; 1816 xfs_prid_t prid;
1814 struct xfs_dquot *udqp, *gdqp; 1817 struct xfs_dquot *udqp, *gdqp;
1815 uint resblks; 1818 uint resblks;
1816 int namelen;
1817 1819
1818 ASSERT(!*vpp); 1820 ASSERT(!*ipp);
1819 xfs_itrace_entry(dp); 1821 xfs_itrace_entry(dp);
1820 1822
1821 namelen = VNAMELEN(dentry);
1822
1823 if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) { 1823 if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) {
1824 error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE, 1824 error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE,
1825 dir_vp, DM_RIGHT_NULL, NULL, 1825 dp, DM_RIGHT_NULL, NULL,
1826 DM_RIGHT_NULL, name, NULL, 1826 DM_RIGHT_NULL, name->name, NULL,
1827 mode, 0, 0); 1827 mode, 0, 0);
1828 1828
1829 if (error) 1829 if (error)
@@ -1855,7 +1855,7 @@ xfs_create(
1855 1855
1856 tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE); 1856 tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE);
1857 cancel_flags = XFS_TRANS_RELEASE_LOG_RES; 1857 cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
1858 resblks = XFS_CREATE_SPACE_RES(mp, namelen); 1858 resblks = XFS_CREATE_SPACE_RES(mp, name->len);
1859 /* 1859 /*
1860 * Initially assume that the file does not exist and 1860 * Initially assume that the file does not exist and
1861 * reserve the resources for that case. If that is not 1861 * reserve the resources for that case. If that is not
@@ -1888,7 +1888,8 @@ xfs_create(
1888 if (error) 1888 if (error)
1889 goto error_return; 1889 goto error_return;
1890 1890
1891 if (resblks == 0 && (error = xfs_dir_canenter(tp, dp, name, namelen))) 1891 error = xfs_dir_canenter(tp, dp, name, resblks);
1892 if (error)
1892 goto error_return; 1893 goto error_return;
1893 error = xfs_dir_ialloc(&tp, dp, mode, 1, 1894 error = xfs_dir_ialloc(&tp, dp, mode, 1,
1894 rdev, credp, prid, resblks > 0, 1895 rdev, credp, prid, resblks > 0,
@@ -1914,11 +1915,11 @@ xfs_create(
1914 * the transaction cancel unlocking dp so don't do it explicitly in the 1915 * the transaction cancel unlocking dp so don't do it explicitly in the
1915 * error path. 1916 * error path.
1916 */ 1917 */
1917 VN_HOLD(dir_vp); 1918 IHOLD(dp);
1918 xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); 1919 xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
1919 unlock_dp_on_error = B_FALSE; 1920 unlock_dp_on_error = B_FALSE;
1920 1921
1921 error = xfs_dir_createname(tp, dp, name, namelen, ip->i_ino, 1922 error = xfs_dir_createname(tp, dp, name, ip->i_ino,
1922 &first_block, &free_list, resblks ? 1923 &first_block, &free_list, resblks ?
1923 resblks - XFS_IALLOC_SPACE_RES(mp) : 0); 1924 resblks - XFS_IALLOC_SPACE_RES(mp) : 0);
1924 if (error) { 1925 if (error) {
@@ -1952,7 +1953,6 @@ xfs_create(
1952 * vnode to the caller, we bump the vnode ref count now. 1953 * vnode to the caller, we bump the vnode ref count now.
1953 */ 1954 */
1954 IHOLD(ip); 1955 IHOLD(ip);
1955 vp = XFS_ITOV(ip);
1956 1956
1957 error = xfs_bmap_finish(&tp, &free_list, &committed); 1957 error = xfs_bmap_finish(&tp, &free_list, &committed);
1958 if (error) { 1958 if (error) {
@@ -1970,17 +1970,17 @@ xfs_create(
1970 XFS_QM_DQRELE(mp, udqp); 1970 XFS_QM_DQRELE(mp, udqp);
1971 XFS_QM_DQRELE(mp, gdqp); 1971 XFS_QM_DQRELE(mp, gdqp);
1972 1972
1973 *vpp = vp; 1973 *ipp = ip;
1974 1974
1975 /* Fallthrough to std_return with error = 0 */ 1975 /* Fallthrough to std_return with error = 0 */
1976 1976
1977std_return: 1977std_return:
1978 if ((*vpp || (error != 0 && dm_event_sent != 0)) && 1978 if ((*ipp || (error != 0 && dm_event_sent != 0)) &&
1979 DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) { 1979 DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) {
1980 (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, 1980 (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE,
1981 dir_vp, DM_RIGHT_NULL, 1981 dp, DM_RIGHT_NULL,
1982 *vpp ? vp:NULL, 1982 *ipp ? ip : NULL,
1983 DM_RIGHT_NULL, name, NULL, 1983 DM_RIGHT_NULL, name->name, NULL,
1984 mode, error, 0); 1984 mode, error, 0);
1985 } 1985 }
1986 return error; 1986 return error;
@@ -2272,46 +2272,32 @@ int remove_which_error_return = 0;
2272int 2272int
2273xfs_remove( 2273xfs_remove(
2274 xfs_inode_t *dp, 2274 xfs_inode_t *dp,
2275 bhv_vname_t *dentry) 2275 struct xfs_name *name,
2276 xfs_inode_t *ip)
2276{ 2277{
2277 bhv_vnode_t *dir_vp = XFS_ITOV(dp);
2278 char *name = VNAME(dentry);
2279 xfs_mount_t *mp = dp->i_mount; 2278 xfs_mount_t *mp = dp->i_mount;
2280 xfs_inode_t *ip;
2281 xfs_trans_t *tp = NULL; 2279 xfs_trans_t *tp = NULL;
2282 int error = 0; 2280 int error = 0;
2283 xfs_bmap_free_t free_list; 2281 xfs_bmap_free_t free_list;
2284 xfs_fsblock_t first_block; 2282 xfs_fsblock_t first_block;
2285 int cancel_flags; 2283 int cancel_flags;
2286 int committed; 2284 int committed;
2287 int dm_di_mode = 0;
2288 int link_zero; 2285 int link_zero;
2289 uint resblks; 2286 uint resblks;
2290 int namelen;
2291 2287
2292 xfs_itrace_entry(dp); 2288 xfs_itrace_entry(dp);
2293 2289
2294 if (XFS_FORCED_SHUTDOWN(mp)) 2290 if (XFS_FORCED_SHUTDOWN(mp))
2295 return XFS_ERROR(EIO); 2291 return XFS_ERROR(EIO);
2296 2292
2297 namelen = VNAMELEN(dentry);
2298
2299 if (!xfs_get_dir_entry(dentry, &ip)) {
2300 dm_di_mode = ip->i_d.di_mode;
2301 IRELE(ip);
2302 }
2303
2304 if (DM_EVENT_ENABLED(dp, DM_EVENT_REMOVE)) { 2293 if (DM_EVENT_ENABLED(dp, DM_EVENT_REMOVE)) {
2305 error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_vp, 2294 error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dp, DM_RIGHT_NULL,
2306 DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, 2295 NULL, DM_RIGHT_NULL, name->name, NULL,
2307 name, NULL, dm_di_mode, 0, 0); 2296 ip->i_d.di_mode, 0, 0);
2308 if (error) 2297 if (error)
2309 return error; 2298 return error;
2310 } 2299 }
2311 2300
2312 /* From this point on, return through std_return */
2313 ip = NULL;
2314
2315 /* 2301 /*
2316 * We need to get a reference to ip before we get our log 2302 * We need to get a reference to ip before we get our log
2317 * reservation. The reason for this is that we cannot call 2303 * reservation. The reason for this is that we cannot call
@@ -2324,13 +2310,7 @@ xfs_remove(
2324 * when we call xfs_iget. Instead we get an unlocked reference 2310 * when we call xfs_iget. Instead we get an unlocked reference
2325 * to the inode before getting our log reservation. 2311 * to the inode before getting our log reservation.
2326 */ 2312 */
2327 error = xfs_get_dir_entry(dentry, &ip); 2313 IHOLD(ip);
2328 if (error) {
2329 REMOVE_DEBUG_TRACE(__LINE__);
2330 goto std_return;
2331 }
2332
2333 dm_di_mode = ip->i_d.di_mode;
2334 2314
2335 xfs_itrace_entry(ip); 2315 xfs_itrace_entry(ip);
2336 xfs_itrace_ref(ip); 2316 xfs_itrace_ref(ip);
@@ -2398,7 +2378,7 @@ xfs_remove(
2398 * Entry must exist since we did a lookup in xfs_lock_dir_and_entry. 2378 * Entry must exist since we did a lookup in xfs_lock_dir_and_entry.
2399 */ 2379 */
2400 XFS_BMAP_INIT(&free_list, &first_block); 2380 XFS_BMAP_INIT(&free_list, &first_block);
2401 error = xfs_dir_removename(tp, dp, name, namelen, ip->i_ino, 2381 error = xfs_dir_removename(tp, dp, name, ip->i_ino,
2402 &first_block, &free_list, 0); 2382 &first_block, &free_list, 0);
2403 if (error) { 2383 if (error) {
2404 ASSERT(error != ENOENT); 2384 ASSERT(error != ENOENT);
@@ -2449,14 +2429,6 @@ xfs_remove(
2449 } 2429 }
2450 2430
2451 /* 2431 /*
2452 * Before we drop our extra reference to the inode, purge it
2453 * from the refcache if it is there. By waiting until afterwards
2454 * to do the IRELE, we ensure that we won't go inactive in the
2455 * xfs_refcache_purge_ip routine (although that would be OK).
2456 */
2457 xfs_refcache_purge_ip(ip);
2458
2459 /*
2460 * If we are using filestreams, kill the stream association. 2432 * If we are using filestreams, kill the stream association.
2461 * If the file is still open it may get a new one but that 2433 * If the file is still open it may get a new one but that
2462 * will get killed on last close in xfs_close() so we don't 2434 * will get killed on last close in xfs_close() so we don't
@@ -2472,9 +2444,9 @@ xfs_remove(
2472 std_return: 2444 std_return:
2473 if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTREMOVE)) { 2445 if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTREMOVE)) {
2474 (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE, 2446 (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE,
2475 dir_vp, DM_RIGHT_NULL, 2447 dp, DM_RIGHT_NULL,
2476 NULL, DM_RIGHT_NULL, 2448 NULL, DM_RIGHT_NULL,
2477 name, NULL, dm_di_mode, error, 0); 2449 name->name, NULL, ip->i_d.di_mode, error, 0);
2478 } 2450 }
2479 return error; 2451 return error;
2480 2452
@@ -2495,14 +2467,6 @@ xfs_remove(
2495 cancel_flags |= XFS_TRANS_ABORT; 2467 cancel_flags |= XFS_TRANS_ABORT;
2496 xfs_trans_cancel(tp, cancel_flags); 2468 xfs_trans_cancel(tp, cancel_flags);
2497 2469
2498 /*
2499 * Before we drop our extra reference to the inode, purge it
2500 * from the refcache if it is there. By waiting until afterwards
2501 * to do the IRELE, we ensure that we won't go inactive in the
2502 * xfs_refcache_purge_ip routine (although that would be OK).
2503 */
2504 xfs_refcache_purge_ip(ip);
2505
2506 IRELE(ip); 2470 IRELE(ip);
2507 2471
2508 goto std_return; 2472 goto std_return;
@@ -2511,12 +2475,10 @@ xfs_remove(
2511int 2475int
2512xfs_link( 2476xfs_link(
2513 xfs_inode_t *tdp, 2477 xfs_inode_t *tdp,
2514 bhv_vnode_t *src_vp, 2478 xfs_inode_t *sip,
2515 bhv_vname_t *dentry) 2479 struct xfs_name *target_name)
2516{ 2480{
2517 bhv_vnode_t *target_dir_vp = XFS_ITOV(tdp);
2518 xfs_mount_t *mp = tdp->i_mount; 2481 xfs_mount_t *mp = tdp->i_mount;
2519 xfs_inode_t *sip = xfs_vtoi(src_vp);
2520 xfs_trans_t *tp; 2482 xfs_trans_t *tp;
2521 xfs_inode_t *ips[2]; 2483 xfs_inode_t *ips[2];
2522 int error; 2484 int error;
@@ -2525,23 +2487,20 @@ xfs_link(
2525 int cancel_flags; 2487 int cancel_flags;
2526 int committed; 2488 int committed;
2527 int resblks; 2489 int resblks;
2528 char *target_name = VNAME(dentry);
2529 int target_namelen;
2530 2490
2531 xfs_itrace_entry(tdp); 2491 xfs_itrace_entry(tdp);
2532 xfs_itrace_entry(xfs_vtoi(src_vp)); 2492 xfs_itrace_entry(sip);
2533 2493
2534 target_namelen = VNAMELEN(dentry); 2494 ASSERT(!S_ISDIR(sip->i_d.di_mode));
2535 ASSERT(!VN_ISDIR(src_vp));
2536 2495
2537 if (XFS_FORCED_SHUTDOWN(mp)) 2496 if (XFS_FORCED_SHUTDOWN(mp))
2538 return XFS_ERROR(EIO); 2497 return XFS_ERROR(EIO);
2539 2498
2540 if (DM_EVENT_ENABLED(tdp, DM_EVENT_LINK)) { 2499 if (DM_EVENT_ENABLED(tdp, DM_EVENT_LINK)) {
2541 error = XFS_SEND_NAMESP(mp, DM_EVENT_LINK, 2500 error = XFS_SEND_NAMESP(mp, DM_EVENT_LINK,
2542 target_dir_vp, DM_RIGHT_NULL, 2501 tdp, DM_RIGHT_NULL,
2543 src_vp, DM_RIGHT_NULL, 2502 sip, DM_RIGHT_NULL,
2544 target_name, NULL, 0, 0, 0); 2503 target_name->name, NULL, 0, 0, 0);
2545 if (error) 2504 if (error)
2546 return error; 2505 return error;
2547 } 2506 }
@@ -2556,7 +2515,7 @@ xfs_link(
2556 2515
2557 tp = xfs_trans_alloc(mp, XFS_TRANS_LINK); 2516 tp = xfs_trans_alloc(mp, XFS_TRANS_LINK);
2558 cancel_flags = XFS_TRANS_RELEASE_LOG_RES; 2517 cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
2559 resblks = XFS_LINK_SPACE_RES(mp, target_namelen); 2518 resblks = XFS_LINK_SPACE_RES(mp, target_name->len);
2560 error = xfs_trans_reserve(tp, resblks, XFS_LINK_LOG_RES(mp), 0, 2519 error = xfs_trans_reserve(tp, resblks, XFS_LINK_LOG_RES(mp), 0,
2561 XFS_TRANS_PERM_LOG_RES, XFS_LINK_LOG_COUNT); 2520 XFS_TRANS_PERM_LOG_RES, XFS_LINK_LOG_COUNT);
2562 if (error == ENOSPC) { 2521 if (error == ENOSPC) {
@@ -2584,8 +2543,8 @@ xfs_link(
2584 * xfs_trans_cancel will both unlock the inodes and 2543 * xfs_trans_cancel will both unlock the inodes and
2585 * decrement the associated ref counts. 2544 * decrement the associated ref counts.
2586 */ 2545 */
2587 VN_HOLD(src_vp); 2546 IHOLD(sip);
2588 VN_HOLD(target_dir_vp); 2547 IHOLD(tdp);
2589 xfs_trans_ijoin(tp, sip, XFS_ILOCK_EXCL); 2548 xfs_trans_ijoin(tp, sip, XFS_ILOCK_EXCL);
2590 xfs_trans_ijoin(tp, tdp, XFS_ILOCK_EXCL); 2549 xfs_trans_ijoin(tp, tdp, XFS_ILOCK_EXCL);
2591 2550
@@ -2608,15 +2567,14 @@ xfs_link(
2608 goto error_return; 2567 goto error_return;
2609 } 2568 }
2610 2569
2611 if (resblks == 0 && 2570 error = xfs_dir_canenter(tp, tdp, target_name, resblks);
2612 (error = xfs_dir_canenter(tp, tdp, target_name, target_namelen))) 2571 if (error)
2613 goto error_return; 2572 goto error_return;
2614 2573
2615 XFS_BMAP_INIT(&free_list, &first_block); 2574 XFS_BMAP_INIT(&free_list, &first_block);
2616 2575
2617 error = xfs_dir_createname(tp, tdp, target_name, target_namelen, 2576 error = xfs_dir_createname(tp, tdp, target_name, sip->i_ino,
2618 sip->i_ino, &first_block, &free_list, 2577 &first_block, &free_list, resblks);
2619 resblks);
2620 if (error) 2578 if (error)
2621 goto abort_return; 2579 goto abort_return;
2622 xfs_ichgtime(tdp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 2580 xfs_ichgtime(tdp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
@@ -2650,9 +2608,9 @@ xfs_link(
2650std_return: 2608std_return:
2651 if (DM_EVENT_ENABLED(sip, DM_EVENT_POSTLINK)) { 2609 if (DM_EVENT_ENABLED(sip, DM_EVENT_POSTLINK)) {
2652 (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTLINK, 2610 (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTLINK,
2653 target_dir_vp, DM_RIGHT_NULL, 2611 tdp, DM_RIGHT_NULL,
2654 src_vp, DM_RIGHT_NULL, 2612 sip, DM_RIGHT_NULL,
2655 target_name, NULL, 0, error, 0); 2613 target_name->name, NULL, 0, error, 0);
2656 } 2614 }
2657 return error; 2615 return error;
2658 2616
@@ -2669,17 +2627,13 @@ std_return:
2669int 2627int
2670xfs_mkdir( 2628xfs_mkdir(
2671 xfs_inode_t *dp, 2629 xfs_inode_t *dp,
2672 bhv_vname_t *dentry, 2630 struct xfs_name *dir_name,
2673 mode_t mode, 2631 mode_t mode,
2674 bhv_vnode_t **vpp, 2632 xfs_inode_t **ipp,
2675 cred_t *credp) 2633 cred_t *credp)
2676{ 2634{
2677 bhv_vnode_t *dir_vp = XFS_ITOV(dp);
2678 char *dir_name = VNAME(dentry);
2679 int dir_namelen = VNAMELEN(dentry);
2680 xfs_mount_t *mp = dp->i_mount; 2635 xfs_mount_t *mp = dp->i_mount;
2681 xfs_inode_t *cdp; /* inode of created dir */ 2636 xfs_inode_t *cdp; /* inode of created dir */
2682 bhv_vnode_t *cvp; /* vnode of created dir */
2683 xfs_trans_t *tp; 2637 xfs_trans_t *tp;
2684 int cancel_flags; 2638 int cancel_flags;
2685 int error; 2639 int error;
@@ -2700,8 +2654,8 @@ xfs_mkdir(
2700 2654
2701 if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) { 2655 if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) {
2702 error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE, 2656 error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE,
2703 dir_vp, DM_RIGHT_NULL, NULL, 2657 dp, DM_RIGHT_NULL, NULL,
2704 DM_RIGHT_NULL, dir_name, NULL, 2658 DM_RIGHT_NULL, dir_name->name, NULL,
2705 mode, 0, 0); 2659 mode, 0, 0);
2706 if (error) 2660 if (error)
2707 return error; 2661 return error;
@@ -2730,7 +2684,7 @@ xfs_mkdir(
2730 2684
2731 tp = xfs_trans_alloc(mp, XFS_TRANS_MKDIR); 2685 tp = xfs_trans_alloc(mp, XFS_TRANS_MKDIR);
2732 cancel_flags = XFS_TRANS_RELEASE_LOG_RES; 2686 cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
2733 resblks = XFS_MKDIR_SPACE_RES(mp, dir_namelen); 2687 resblks = XFS_MKDIR_SPACE_RES(mp, dir_name->len);
2734 error = xfs_trans_reserve(tp, resblks, XFS_MKDIR_LOG_RES(mp), 0, 2688 error = xfs_trans_reserve(tp, resblks, XFS_MKDIR_LOG_RES(mp), 0,
2735 XFS_TRANS_PERM_LOG_RES, XFS_MKDIR_LOG_COUNT); 2689 XFS_TRANS_PERM_LOG_RES, XFS_MKDIR_LOG_COUNT);
2736 if (error == ENOSPC) { 2690 if (error == ENOSPC) {
@@ -2762,8 +2716,8 @@ xfs_mkdir(
2762 if (error) 2716 if (error)
2763 goto error_return; 2717 goto error_return;
2764 2718
2765 if (resblks == 0 && 2719 error = xfs_dir_canenter(tp, dp, dir_name, resblks);
2766 (error = xfs_dir_canenter(tp, dp, dir_name, dir_namelen))) 2720 if (error)
2767 goto error_return; 2721 goto error_return;
2768 /* 2722 /*
2769 * create the directory inode. 2723 * create the directory inode.
@@ -2786,15 +2740,15 @@ xfs_mkdir(
2786 * from here on will result in the transaction cancel 2740 * from here on will result in the transaction cancel
2787 * unlocking dp so don't do it explicitly in the error path. 2741 * unlocking dp so don't do it explicitly in the error path.
2788 */ 2742 */
2789 VN_HOLD(dir_vp); 2743 IHOLD(dp);
2790 xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); 2744 xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
2791 unlock_dp_on_error = B_FALSE; 2745 unlock_dp_on_error = B_FALSE;
2792 2746
2793 XFS_BMAP_INIT(&free_list, &first_block); 2747 XFS_BMAP_INIT(&free_list, &first_block);
2794 2748
2795 error = xfs_dir_createname(tp, dp, dir_name, dir_namelen, cdp->i_ino, 2749 error = xfs_dir_createname(tp, dp, dir_name, cdp->i_ino,
2796 &first_block, &free_list, resblks ? 2750 &first_block, &free_list, resblks ?
2797 resblks - XFS_IALLOC_SPACE_RES(mp) : 0); 2751 resblks - XFS_IALLOC_SPACE_RES(mp) : 0);
2798 if (error) { 2752 if (error) {
2799 ASSERT(error != ENOSPC); 2753 ASSERT(error != ENOSPC);
2800 goto error1; 2754 goto error1;
@@ -2817,11 +2771,9 @@ xfs_mkdir(
2817 if (error) 2771 if (error)
2818 goto error2; 2772 goto error2;
2819 2773
2820 cvp = XFS_ITOV(cdp);
2821
2822 created = B_TRUE; 2774 created = B_TRUE;
2823 2775
2824 *vpp = cvp; 2776 *ipp = cdp;
2825 IHOLD(cdp); 2777 IHOLD(cdp);
2826 2778
2827 /* 2779 /*
@@ -2858,10 +2810,10 @@ std_return:
2858 if ((created || (error != 0 && dm_event_sent != 0)) && 2810 if ((created || (error != 0 && dm_event_sent != 0)) &&
2859 DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) { 2811 DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) {
2860 (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, 2812 (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE,
2861 dir_vp, DM_RIGHT_NULL, 2813 dp, DM_RIGHT_NULL,
2862 created ? XFS_ITOV(cdp):NULL, 2814 created ? cdp : NULL,
2863 DM_RIGHT_NULL, 2815 DM_RIGHT_NULL,
2864 dir_name, NULL, 2816 dir_name->name, NULL,
2865 mode, error, 0); 2817 mode, error, 0);
2866 } 2818 }
2867 return error; 2819 return error;
@@ -2885,20 +2837,17 @@ std_return:
2885int 2837int
2886xfs_rmdir( 2838xfs_rmdir(
2887 xfs_inode_t *dp, 2839 xfs_inode_t *dp,
2888 bhv_vname_t *dentry) 2840 struct xfs_name *name,
2841 xfs_inode_t *cdp)
2889{ 2842{
2890 bhv_vnode_t *dir_vp = XFS_ITOV(dp); 2843 bhv_vnode_t *dir_vp = XFS_ITOV(dp);
2891 char *name = VNAME(dentry);
2892 int namelen = VNAMELEN(dentry);
2893 xfs_mount_t *mp = dp->i_mount; 2844 xfs_mount_t *mp = dp->i_mount;
2894 xfs_inode_t *cdp; /* child directory */
2895 xfs_trans_t *tp; 2845 xfs_trans_t *tp;
2896 int error; 2846 int error;
2897 xfs_bmap_free_t free_list; 2847 xfs_bmap_free_t free_list;
2898 xfs_fsblock_t first_block; 2848 xfs_fsblock_t first_block;
2899 int cancel_flags; 2849 int cancel_flags;
2900 int committed; 2850 int committed;
2901 int dm_di_mode = S_IFDIR;
2902 int last_cdp_link; 2851 int last_cdp_link;
2903 uint resblks; 2852 uint resblks;
2904 2853
@@ -2907,24 +2856,15 @@ xfs_rmdir(
2907 if (XFS_FORCED_SHUTDOWN(mp)) 2856 if (XFS_FORCED_SHUTDOWN(mp))
2908 return XFS_ERROR(EIO); 2857 return XFS_ERROR(EIO);
2909 2858
2910 if (!xfs_get_dir_entry(dentry, &cdp)) {
2911 dm_di_mode = cdp->i_d.di_mode;
2912 IRELE(cdp);
2913 }
2914
2915 if (DM_EVENT_ENABLED(dp, DM_EVENT_REMOVE)) { 2859 if (DM_EVENT_ENABLED(dp, DM_EVENT_REMOVE)) {
2916 error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, 2860 error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE,
2917 dir_vp, DM_RIGHT_NULL, 2861 dp, DM_RIGHT_NULL,
2918 NULL, DM_RIGHT_NULL, 2862 NULL, DM_RIGHT_NULL, name->name,
2919 name, NULL, dm_di_mode, 0, 0); 2863 NULL, cdp->i_d.di_mode, 0, 0);
2920 if (error) 2864 if (error)
2921 return XFS_ERROR(error); 2865 return XFS_ERROR(error);
2922 } 2866 }
2923 2867
2924 /* Return through std_return after this point. */
2925
2926 cdp = NULL;
2927
2928 /* 2868 /*
2929 * We need to get a reference to cdp before we get our log 2869 * We need to get a reference to cdp before we get our log
2930 * reservation. The reason for this is that we cannot call 2870 * reservation. The reason for this is that we cannot call
@@ -2937,13 +2877,7 @@ xfs_rmdir(
2937 * when we call xfs_iget. Instead we get an unlocked reference 2877 * when we call xfs_iget. Instead we get an unlocked reference
2938 * to the inode before getting our log reservation. 2878 * to the inode before getting our log reservation.
2939 */ 2879 */
2940 error = xfs_get_dir_entry(dentry, &cdp); 2880 IHOLD(cdp);
2941 if (error) {
2942 REMOVE_DEBUG_TRACE(__LINE__);
2943 goto std_return;
2944 }
2945 mp = dp->i_mount;
2946 dm_di_mode = cdp->i_d.di_mode;
2947 2881
2948 /* 2882 /*
2949 * Get the dquots for the inodes. 2883 * Get the dquots for the inodes.
@@ -3020,7 +2954,7 @@ xfs_rmdir(
3020 goto error_return; 2954 goto error_return;
3021 } 2955 }
3022 2956
3023 error = xfs_dir_removename(tp, dp, name, namelen, cdp->i_ino, 2957 error = xfs_dir_removename(tp, dp, name, cdp->i_ino,
3024 &first_block, &free_list, resblks); 2958 &first_block, &free_list, resblks);
3025 if (error) 2959 if (error)
3026 goto error1; 2960 goto error1;
@@ -3098,9 +3032,9 @@ xfs_rmdir(
3098 std_return: 3032 std_return:
3099 if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTREMOVE)) { 3033 if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTREMOVE)) {
3100 (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE, 3034 (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE,
3101 dir_vp, DM_RIGHT_NULL, 3035 dp, DM_RIGHT_NULL,
3102 NULL, DM_RIGHT_NULL, 3036 NULL, DM_RIGHT_NULL,
3103 name, NULL, dm_di_mode, 3037 name->name, NULL, cdp->i_d.di_mode,
3104 error, 0); 3038 error, 0);
3105 } 3039 }
3106 return error; 3040 return error;
@@ -3118,13 +3052,12 @@ xfs_rmdir(
3118int 3052int
3119xfs_symlink( 3053xfs_symlink(
3120 xfs_inode_t *dp, 3054 xfs_inode_t *dp,
3121 bhv_vname_t *dentry, 3055 struct xfs_name *link_name,
3122 char *target_path, 3056 const char *target_path,
3123 mode_t mode, 3057 mode_t mode,
3124 bhv_vnode_t **vpp, 3058 xfs_inode_t **ipp,
3125 cred_t *credp) 3059 cred_t *credp)
3126{ 3060{
3127 bhv_vnode_t *dir_vp = XFS_ITOV(dp);
3128 xfs_mount_t *mp = dp->i_mount; 3061 xfs_mount_t *mp = dp->i_mount;
3129 xfs_trans_t *tp; 3062 xfs_trans_t *tp;
3130 xfs_inode_t *ip; 3063 xfs_inode_t *ip;
@@ -3140,17 +3073,15 @@ xfs_symlink(
3140 int nmaps; 3073 int nmaps;
3141 xfs_bmbt_irec_t mval[SYMLINK_MAPS]; 3074 xfs_bmbt_irec_t mval[SYMLINK_MAPS];
3142 xfs_daddr_t d; 3075 xfs_daddr_t d;
3143 char *cur_chunk; 3076 const char *cur_chunk;
3144 int byte_cnt; 3077 int byte_cnt;
3145 int n; 3078 int n;
3146 xfs_buf_t *bp; 3079 xfs_buf_t *bp;
3147 xfs_prid_t prid; 3080 xfs_prid_t prid;
3148 struct xfs_dquot *udqp, *gdqp; 3081 struct xfs_dquot *udqp, *gdqp;
3149 uint resblks; 3082 uint resblks;
3150 char *link_name = VNAME(dentry);
3151 int link_namelen;
3152 3083
3153 *vpp = NULL; 3084 *ipp = NULL;
3154 error = 0; 3085 error = 0;
3155 ip = NULL; 3086 ip = NULL;
3156 tp = NULL; 3087 tp = NULL;
@@ -3160,44 +3091,17 @@ xfs_symlink(
3160 if (XFS_FORCED_SHUTDOWN(mp)) 3091 if (XFS_FORCED_SHUTDOWN(mp))
3161 return XFS_ERROR(EIO); 3092 return XFS_ERROR(EIO);
3162 3093
3163 link_namelen = VNAMELEN(dentry);
3164
3165 /* 3094 /*
3166 * Check component lengths of the target path name. 3095 * Check component lengths of the target path name.
3167 */ 3096 */
3168 pathlen = strlen(target_path); 3097 pathlen = strlen(target_path);
3169 if (pathlen >= MAXPATHLEN) /* total string too long */ 3098 if (pathlen >= MAXPATHLEN) /* total string too long */
3170 return XFS_ERROR(ENAMETOOLONG); 3099 return XFS_ERROR(ENAMETOOLONG);
3171 if (pathlen >= MAXNAMELEN) { /* is any component too long? */
3172 int len, total;
3173 char *path;
3174
3175 for (total = 0, path = target_path; total < pathlen;) {
3176 /*
3177 * Skip any slashes.
3178 */
3179 while(*path == '/') {
3180 total++;
3181 path++;
3182 }
3183
3184 /*
3185 * Count up to the next slash or end of path.
3186 * Error out if the component is bigger than MAXNAMELEN.
3187 */
3188 for(len = 0; *path != '/' && total < pathlen;total++, path++) {
3189 if (++len >= MAXNAMELEN) {
3190 error = ENAMETOOLONG;
3191 return error;
3192 }
3193 }
3194 }
3195 }
3196 3100
3197 if (DM_EVENT_ENABLED(dp, DM_EVENT_SYMLINK)) { 3101 if (DM_EVENT_ENABLED(dp, DM_EVENT_SYMLINK)) {
3198 error = XFS_SEND_NAMESP(mp, DM_EVENT_SYMLINK, dir_vp, 3102 error = XFS_SEND_NAMESP(mp, DM_EVENT_SYMLINK, dp,
3199 DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, 3103 DM_RIGHT_NULL, NULL, DM_RIGHT_NULL,
3200 link_name, target_path, 0, 0, 0); 3104 link_name->name, target_path, 0, 0, 0);
3201 if (error) 3105 if (error)
3202 return error; 3106 return error;
3203 } 3107 }
@@ -3229,7 +3133,7 @@ xfs_symlink(
3229 fs_blocks = 0; 3133 fs_blocks = 0;
3230 else 3134 else
3231 fs_blocks = XFS_B_TO_FSB(mp, pathlen); 3135 fs_blocks = XFS_B_TO_FSB(mp, pathlen);
3232 resblks = XFS_SYMLINK_SPACE_RES(mp, link_namelen, fs_blocks); 3136 resblks = XFS_SYMLINK_SPACE_RES(mp, link_name->len, fs_blocks);
3233 error = xfs_trans_reserve(tp, resblks, XFS_SYMLINK_LOG_RES(mp), 0, 3137 error = xfs_trans_reserve(tp, resblks, XFS_SYMLINK_LOG_RES(mp), 0,
3234 XFS_TRANS_PERM_LOG_RES, XFS_SYMLINK_LOG_COUNT); 3138 XFS_TRANS_PERM_LOG_RES, XFS_SYMLINK_LOG_COUNT);
3235 if (error == ENOSPC && fs_blocks == 0) { 3139 if (error == ENOSPC && fs_blocks == 0) {
@@ -3263,8 +3167,8 @@ xfs_symlink(
3263 /* 3167 /*
3264 * Check for ability to enter directory entry, if no space reserved. 3168 * Check for ability to enter directory entry, if no space reserved.
3265 */ 3169 */
3266 if (resblks == 0 && 3170 error = xfs_dir_canenter(tp, dp, link_name, resblks);
3267 (error = xfs_dir_canenter(tp, dp, link_name, link_namelen))) 3171 if (error)
3268 goto error_return; 3172 goto error_return;
3269 /* 3173 /*
3270 * Initialize the bmap freelist prior to calling either 3174 * Initialize the bmap freelist prior to calling either
@@ -3289,7 +3193,7 @@ xfs_symlink(
3289 * transaction cancel unlocking dp so don't do it explicitly in the 3193 * transaction cancel unlocking dp so don't do it explicitly in the
3290 * error path. 3194 * error path.
3291 */ 3195 */
3292 VN_HOLD(dir_vp); 3196 IHOLD(dp);
3293 xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); 3197 xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
3294 unlock_dp_on_error = B_FALSE; 3198 unlock_dp_on_error = B_FALSE;
3295 3199
@@ -3356,8 +3260,8 @@ xfs_symlink(
3356 /* 3260 /*
3357 * Create the directory entry for the symlink. 3261 * Create the directory entry for the symlink.
3358 */ 3262 */
3359 error = xfs_dir_createname(tp, dp, link_name, link_namelen, ip->i_ino, 3263 error = xfs_dir_createname(tp, dp, link_name, ip->i_ino,
3360 &first_block, &free_list, resblks); 3264 &first_block, &free_list, resblks);
3361 if (error) 3265 if (error)
3362 goto error1; 3266 goto error1;
3363 xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 3267 xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
@@ -3399,19 +3303,14 @@ xfs_symlink(
3399std_return: 3303std_return:
3400 if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTSYMLINK)) { 3304 if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTSYMLINK)) {
3401 (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTSYMLINK, 3305 (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTSYMLINK,
3402 dir_vp, DM_RIGHT_NULL, 3306 dp, DM_RIGHT_NULL,
3403 error ? NULL : XFS_ITOV(ip), 3307 error ? NULL : ip,
3404 DM_RIGHT_NULL, link_name, target_path, 3308 DM_RIGHT_NULL, link_name->name,
3405 0, error, 0); 3309 target_path, 0, error, 0);
3406 } 3310 }
3407 3311
3408 if (!error) { 3312 if (!error)
3409 bhv_vnode_t *vp; 3313 *ipp = ip;
3410
3411 ASSERT(ip);
3412 vp = XFS_ITOV(ip);
3413 *vpp = vp;
3414 }
3415 return error; 3314 return error;
3416 3315
3417 error2: 3316 error2:
@@ -3431,60 +3330,11 @@ std_return:
3431} 3330}
3432 3331
3433int 3332int
3434xfs_rwlock(
3435 xfs_inode_t *ip,
3436 bhv_vrwlock_t locktype)
3437{
3438 if (S_ISDIR(ip->i_d.di_mode))
3439 return 1;
3440 if (locktype == VRWLOCK_WRITE) {
3441 xfs_ilock(ip, XFS_IOLOCK_EXCL);
3442 } else if (locktype == VRWLOCK_TRY_READ) {
3443 return xfs_ilock_nowait(ip, XFS_IOLOCK_SHARED);
3444 } else if (locktype == VRWLOCK_TRY_WRITE) {
3445 return xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL);
3446 } else {
3447 ASSERT((locktype == VRWLOCK_READ) ||
3448 (locktype == VRWLOCK_WRITE_DIRECT));
3449 xfs_ilock(ip, XFS_IOLOCK_SHARED);
3450 }
3451
3452 return 1;
3453}
3454
3455
3456void
3457xfs_rwunlock(
3458 xfs_inode_t *ip,
3459 bhv_vrwlock_t locktype)
3460{
3461 if (S_ISDIR(ip->i_d.di_mode))
3462 return;
3463 if (locktype == VRWLOCK_WRITE) {
3464 /*
3465 * In the write case, we may have added a new entry to
3466 * the reference cache. This might store a pointer to
3467 * an inode to be released in this inode. If it is there,
3468 * clear the pointer and release the inode after unlocking
3469 * this one.
3470 */
3471 xfs_refcache_iunlock(ip, XFS_IOLOCK_EXCL);
3472 } else {
3473 ASSERT((locktype == VRWLOCK_READ) ||
3474 (locktype == VRWLOCK_WRITE_DIRECT));
3475 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
3476 }
3477 return;
3478}
3479
3480
3481int
3482xfs_inode_flush( 3333xfs_inode_flush(
3483 xfs_inode_t *ip, 3334 xfs_inode_t *ip,
3484 int flags) 3335 int flags)
3485{ 3336{
3486 xfs_mount_t *mp = ip->i_mount; 3337 xfs_mount_t *mp = ip->i_mount;
3487 xfs_inode_log_item_t *iip = ip->i_itemp;
3488 int error = 0; 3338 int error = 0;
3489 3339
3490 if (XFS_FORCED_SHUTDOWN(mp)) 3340 if (XFS_FORCED_SHUTDOWN(mp))
@@ -3494,33 +3344,9 @@ xfs_inode_flush(
3494 * Bypass inodes which have already been cleaned by 3344 * Bypass inodes which have already been cleaned by
3495 * the inode flush clustering code inside xfs_iflush 3345 * the inode flush clustering code inside xfs_iflush
3496 */ 3346 */
3497 if ((ip->i_update_core == 0) && 3347 if (xfs_inode_clean(ip))
3498 ((iip == NULL) || !(iip->ili_format.ilf_fields & XFS_ILOG_ALL)))
3499 return 0; 3348 return 0;
3500 3349
3501 if (flags & FLUSH_LOG) {
3502 if (iip && iip->ili_last_lsn) {
3503 xlog_t *log = mp->m_log;
3504 xfs_lsn_t sync_lsn;
3505 int log_flags = XFS_LOG_FORCE;
3506
3507 spin_lock(&log->l_grant_lock);
3508 sync_lsn = log->l_last_sync_lsn;
3509 spin_unlock(&log->l_grant_lock);
3510
3511 if ((XFS_LSN_CMP(iip->ili_last_lsn, sync_lsn) > 0)) {
3512 if (flags & FLUSH_SYNC)
3513 log_flags |= XFS_LOG_SYNC;
3514 error = xfs_log_force(mp, iip->ili_last_lsn, log_flags);
3515 if (error)
3516 return error;
3517 }
3518
3519 if (ip->i_update_core == 0)
3520 return 0;
3521 }
3522 }
3523
3524 /* 3350 /*
3525 * We make this non-blocking if the inode is contended, 3351 * We make this non-blocking if the inode is contended,
3526 * return EAGAIN to indicate to the caller that they 3352 * return EAGAIN to indicate to the caller that they
@@ -3528,30 +3354,22 @@ xfs_inode_flush(
3528 * blocking on inodes inside another operation right 3354 * blocking on inodes inside another operation right
3529 * now, they get caught later by xfs_sync. 3355 * now, they get caught later by xfs_sync.
3530 */ 3356 */
3531 if (flags & FLUSH_INODE) { 3357 if (flags & FLUSH_SYNC) {
3532 int flush_flags; 3358 xfs_ilock(ip, XFS_ILOCK_SHARED);
3533 3359 xfs_iflock(ip);
3534 if (flags & FLUSH_SYNC) { 3360 } else if (xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) {
3535 xfs_ilock(ip, XFS_ILOCK_SHARED); 3361 if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip)) {
3536 xfs_iflock(ip); 3362 xfs_iunlock(ip, XFS_ILOCK_SHARED);
3537 } else if (xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) {
3538 if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip)) {
3539 xfs_iunlock(ip, XFS_ILOCK_SHARED);
3540 return EAGAIN;
3541 }
3542 } else {
3543 return EAGAIN; 3363 return EAGAIN;
3544 } 3364 }
3545 3365 } else {
3546 if (flags & FLUSH_SYNC) 3366 return EAGAIN;
3547 flush_flags = XFS_IFLUSH_SYNC;
3548 else
3549 flush_flags = XFS_IFLUSH_ASYNC;
3550
3551 error = xfs_iflush(ip, flush_flags);
3552 xfs_iunlock(ip, XFS_ILOCK_SHARED);
3553 } 3367 }
3554 3368
3369 error = xfs_iflush(ip, (flags & FLUSH_SYNC) ? XFS_IFLUSH_SYNC
3370 : XFS_IFLUSH_ASYNC_NOBLOCK);
3371 xfs_iunlock(ip, XFS_ILOCK_SHARED);
3372
3555 return error; 3373 return error;
3556} 3374}
3557 3375
@@ -3694,12 +3512,12 @@ xfs_finish_reclaim(
3694 * We get the flush lock regardless, though, just to make sure 3512 * We get the flush lock regardless, though, just to make sure
3695 * we don't free it while it is being flushed. 3513 * we don't free it while it is being flushed.
3696 */ 3514 */
3697 if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) { 3515 if (!locked) {
3698 if (!locked) { 3516 xfs_ilock(ip, XFS_ILOCK_EXCL);
3699 xfs_ilock(ip, XFS_ILOCK_EXCL); 3517 xfs_iflock(ip);
3700 xfs_iflock(ip); 3518 }
3701 }
3702 3519
3520 if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
3703 if (ip->i_update_core || 3521 if (ip->i_update_core ||
3704 ((ip->i_itemp != NULL) && 3522 ((ip->i_itemp != NULL) &&
3705 (ip->i_itemp->ili_format.ilf_fields != 0))) { 3523 (ip->i_itemp->ili_format.ilf_fields != 0))) {
@@ -3719,17 +3537,11 @@ xfs_finish_reclaim(
3719 ASSERT(ip->i_update_core == 0); 3537 ASSERT(ip->i_update_core == 0);
3720 ASSERT(ip->i_itemp == NULL || 3538 ASSERT(ip->i_itemp == NULL ||
3721 ip->i_itemp->ili_format.ilf_fields == 0); 3539 ip->i_itemp->ili_format.ilf_fields == 0);
3722 xfs_iunlock(ip, XFS_ILOCK_EXCL);
3723 } else if (locked) {
3724 /*
3725 * We are not interested in doing an iflush if we're
3726 * in the process of shutting down the filesystem forcibly.
3727 * So, just reclaim the inode.
3728 */
3729 xfs_ifunlock(ip);
3730 xfs_iunlock(ip, XFS_ILOCK_EXCL);
3731 } 3540 }
3732 3541
3542 xfs_ifunlock(ip);
3543 xfs_iunlock(ip, XFS_ILOCK_EXCL);
3544
3733 reclaim: 3545 reclaim:
3734 xfs_ireclaim(ip); 3546 xfs_ireclaim(ip);
3735 return 0; 3547 return 0;
@@ -3845,9 +3657,8 @@ xfs_alloc_file_space(
3845 end_dmi_offset = offset+len; 3657 end_dmi_offset = offset+len;
3846 if (end_dmi_offset > ip->i_size) 3658 if (end_dmi_offset > ip->i_size)
3847 end_dmi_offset = ip->i_size; 3659 end_dmi_offset = ip->i_size;
3848 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, XFS_ITOV(ip), 3660 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, ip, offset,
3849 offset, end_dmi_offset - offset, 3661 end_dmi_offset - offset, 0, NULL);
3850 0, NULL);
3851 if (error) 3662 if (error)
3852 return error; 3663 return error;
3853 } 3664 }
@@ -3956,8 +3767,8 @@ dmapi_enospc_check:
3956 if (error == ENOSPC && (attr_flags & ATTR_DMI) == 0 && 3767 if (error == ENOSPC && (attr_flags & ATTR_DMI) == 0 &&
3957 DM_EVENT_ENABLED(ip, DM_EVENT_NOSPACE)) { 3768 DM_EVENT_ENABLED(ip, DM_EVENT_NOSPACE)) {
3958 error = XFS_SEND_NAMESP(mp, DM_EVENT_NOSPACE, 3769 error = XFS_SEND_NAMESP(mp, DM_EVENT_NOSPACE,
3959 XFS_ITOV(ip), DM_RIGHT_NULL, 3770 ip, DM_RIGHT_NULL,
3960 XFS_ITOV(ip), DM_RIGHT_NULL, 3771 ip, DM_RIGHT_NULL,
3961 NULL, NULL, 0, 0, 0); /* Delay flag intentionally unused */ 3772 NULL, NULL, 0, 0, 0); /* Delay flag intentionally unused */
3962 if (error == 0) 3773 if (error == 0)
3963 goto retry; /* Maybe DMAPI app. has made space */ 3774 goto retry; /* Maybe DMAPI app. has made space */
@@ -4021,7 +3832,8 @@ xfs_zero_remaining_bytes(
4021 XFS_BUF_READ(bp); 3832 XFS_BUF_READ(bp);
4022 XFS_BUF_SET_ADDR(bp, XFS_FSB_TO_DB(ip, imap.br_startblock)); 3833 XFS_BUF_SET_ADDR(bp, XFS_FSB_TO_DB(ip, imap.br_startblock));
4023 xfsbdstrat(mp, bp); 3834 xfsbdstrat(mp, bp);
4024 if ((error = xfs_iowait(bp))) { 3835 error = xfs_iowait(bp);
3836 if (error) {
4025 xfs_ioerror_alert("xfs_zero_remaining_bytes(read)", 3837 xfs_ioerror_alert("xfs_zero_remaining_bytes(read)",
4026 mp, bp, XFS_BUF_ADDR(bp)); 3838 mp, bp, XFS_BUF_ADDR(bp));
4027 break; 3839 break;
@@ -4033,7 +3845,8 @@ xfs_zero_remaining_bytes(
4033 XFS_BUF_UNREAD(bp); 3845 XFS_BUF_UNREAD(bp);
4034 XFS_BUF_WRITE(bp); 3846 XFS_BUF_WRITE(bp);
4035 xfsbdstrat(mp, bp); 3847 xfsbdstrat(mp, bp);
4036 if ((error = xfs_iowait(bp))) { 3848 error = xfs_iowait(bp);
3849 if (error) {
4037 xfs_ioerror_alert("xfs_zero_remaining_bytes(write)", 3850 xfs_ioerror_alert("xfs_zero_remaining_bytes(write)",
4038 mp, bp, XFS_BUF_ADDR(bp)); 3851 mp, bp, XFS_BUF_ADDR(bp));
4039 break; 3852 break;
@@ -4102,7 +3915,7 @@ xfs_free_file_space(
4102 DM_EVENT_ENABLED(ip, DM_EVENT_WRITE)) { 3915 DM_EVENT_ENABLED(ip, DM_EVENT_WRITE)) {
4103 if (end_dmi_offset > ip->i_size) 3916 if (end_dmi_offset > ip->i_size)
4104 end_dmi_offset = ip->i_size; 3917 end_dmi_offset = ip->i_size;
4105 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, vp, 3918 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, ip,
4106 offset, end_dmi_offset - offset, 3919 offset, end_dmi_offset - offset,
4107 AT_DELAY_FLAG(attr_flags), NULL); 3920 AT_DELAY_FLAG(attr_flags), NULL);
4108 if (error) 3921 if (error)