diff options
Diffstat (limited to 'fs/xfs/xfs_vnodeops.c')
| -rw-r--r-- | fs/xfs/xfs_vnodeops.c | 505 |
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 | |||
| 1477 | error_cancel: | ||
| 1478 | ASSERT(XFS_FORCED_SHUTDOWN(mp)); | ||
| 1479 | xfs_trans_cancel(tp, 0); | ||
| 1480 | error_unlock: | ||
| 1481 | *tpp = NULL; | ||
| 1482 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
| 1483 | return error; | ||
| 1478 | } | 1484 | } |
| 1479 | 1485 | ||
| 1480 | int | 1486 | int |
| @@ -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( | |||
| 1765 | int | 1771 | int |
| 1766 | xfs_lookup( | 1772 | xfs_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( | |||
| 1791 | int | 1797 | int |
| 1792 | xfs_create( | 1798 | xfs_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 | ||
| 1977 | std_return: | 1977 | std_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; | |||
| 2272 | int | 2272 | int |
| 2273 | xfs_remove( | 2273 | xfs_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( | |||
| 2511 | int | 2475 | int |
| 2512 | xfs_link( | 2476 | xfs_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( | |||
| 2650 | std_return: | 2608 | std_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: | |||
| 2669 | int | 2627 | int |
| 2670 | xfs_mkdir( | 2628 | xfs_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: | |||
| 2885 | int | 2837 | int |
| 2886 | xfs_rmdir( | 2838 | xfs_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( | |||
| 3118 | int | 3052 | int |
| 3119 | xfs_symlink( | 3053 | xfs_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( | |||
| 3399 | std_return: | 3303 | std_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 | ||
| 3433 | int | 3332 | int |
| 3434 | xfs_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 | |||
| 3456 | void | ||
| 3457 | xfs_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 | |||
| 3481 | int | ||
| 3482 | xfs_inode_flush( | 3333 | xfs_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) |
