diff options
| author | Christoph Hellwig <hch@infradead.org> | 2007-08-28 02:12:30 -0400 |
|---|---|---|
| committer | Tim Shimmin <tes@chook.melbourne.sgi.com> | 2007-10-15 02:54:29 -0400 |
| commit | 993386c19afa53fa54d00c7721e56ba820b3400d (patch) | |
| tree | 1715fdeb9cc5ea99466e179b54e84b168fd5e127 /fs/xfs/xfs_vnodeops.c | |
| parent | b93bd20cd59eb7ec172f95d08b100fea688d8bcf (diff) | |
[XFS] decontaminate vnode operations from behavior details
All vnode ops now take struct xfs_inode pointers and the behaviour related
glue is split out into methods of it's own. This required fixing
xfs_create/mkdir/symlink to not mess with the inode pointer but rather use
a separate boolean for error handling. Thanks to Dave Chinner for that
fix.
SGI-PV: 969608
SGI-Modid: xfs-linux-melb:xfs-kern:29492a
Signed-off-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Tim Shimmin <tes@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_vnodeops.c')
| -rw-r--r-- | fs/xfs/xfs_vnodeops.c | 427 |
1 files changed, 124 insertions, 303 deletions
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 15bc01b2d6a0..2b30fa690b4a 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
| @@ -52,15 +52,13 @@ | |||
| 52 | #include "xfs_trans_space.h" | 52 | #include "xfs_trans_space.h" |
| 53 | #include "xfs_log_priv.h" | 53 | #include "xfs_log_priv.h" |
| 54 | #include "xfs_filestream.h" | 54 | #include "xfs_filestream.h" |
| 55 | #include "xfs_vnodeops.h" | ||
| 55 | 56 | ||
| 56 | STATIC int | 57 | int |
| 57 | xfs_open( | 58 | xfs_open( |
| 58 | bhv_desc_t *bdp, | 59 | xfs_inode_t *ip) |
| 59 | cred_t *credp) | ||
| 60 | { | 60 | { |
| 61 | int mode; | 61 | int mode; |
| 62 | bhv_vnode_t *vp = BHV_TO_VNODE(bdp); | ||
| 63 | xfs_inode_t *ip = XFS_BHVTOI(bdp); | ||
| 64 | 62 | ||
| 65 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) | 63 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) |
| 66 | return XFS_ERROR(EIO); | 64 | return XFS_ERROR(EIO); |
| @@ -69,7 +67,7 @@ xfs_open( | |||
| 69 | * If it's a directory with any blocks, read-ahead block 0 | 67 | * If it's a directory with any blocks, read-ahead block 0 |
| 70 | * as we're almost certain to have the next operation be a read there. | 68 | * as we're almost certain to have the next operation be a read there. |
| 71 | */ | 69 | */ |
| 72 | if (VN_ISDIR(vp) && ip->i_d.di_nextents > 0) { | 70 | if (S_ISDIR(ip->i_d.di_mode) && ip->i_d.di_nextents > 0) { |
| 73 | mode = xfs_ilock_map_shared(ip); | 71 | mode = xfs_ilock_map_shared(ip); |
| 74 | if (ip->i_d.di_nextents > 0) | 72 | if (ip->i_d.di_nextents > 0) |
| 75 | (void)xfs_da_reada_buf(NULL, ip, 0, XFS_DATA_FORK); | 73 | (void)xfs_da_reada_buf(NULL, ip, 0, XFS_DATA_FORK); |
| @@ -81,23 +79,17 @@ xfs_open( | |||
| 81 | /* | 79 | /* |
| 82 | * xfs_getattr | 80 | * xfs_getattr |
| 83 | */ | 81 | */ |
| 84 | STATIC int | 82 | int |
| 85 | xfs_getattr( | 83 | xfs_getattr( |
| 86 | bhv_desc_t *bdp, | 84 | xfs_inode_t *ip, |
| 87 | bhv_vattr_t *vap, | 85 | bhv_vattr_t *vap, |
| 88 | int flags, | 86 | int flags) |
| 89 | cred_t *credp) | ||
| 90 | { | 87 | { |
| 91 | xfs_inode_t *ip; | 88 | bhv_vnode_t *vp = XFS_ITOV(ip); |
| 92 | xfs_mount_t *mp; | 89 | xfs_mount_t *mp = ip->i_mount; |
| 93 | bhv_vnode_t *vp; | ||
| 94 | 90 | ||
| 95 | vp = BHV_TO_VNODE(bdp); | ||
| 96 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | 91 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); |
| 97 | 92 | ||
| 98 | ip = XFS_BHVTOI(bdp); | ||
| 99 | mp = ip->i_mount; | ||
| 100 | |||
| 101 | if (XFS_FORCED_SHUTDOWN(mp)) | 93 | if (XFS_FORCED_SHUTDOWN(mp)) |
| 102 | return XFS_ERROR(EIO); | 94 | return XFS_ERROR(EIO); |
| 103 | 95 | ||
| @@ -215,14 +207,14 @@ xfs_getattr( | |||
| 215 | */ | 207 | */ |
| 216 | int | 208 | int |
| 217 | xfs_setattr( | 209 | xfs_setattr( |
| 218 | bhv_desc_t *bdp, | 210 | xfs_inode_t *ip, |
| 219 | bhv_vattr_t *vap, | 211 | bhv_vattr_t *vap, |
| 220 | int flags, | 212 | int flags, |
| 221 | cred_t *credp) | 213 | cred_t *credp) |
| 222 | { | 214 | { |
| 223 | xfs_inode_t *ip; | 215 | bhv_vnode_t *vp = XFS_ITOV(ip); |
| 216 | xfs_mount_t *mp = ip->i_mount; | ||
| 224 | xfs_trans_t *tp; | 217 | xfs_trans_t *tp; |
| 225 | xfs_mount_t *mp; | ||
| 226 | int mask; | 218 | int mask; |
| 227 | int code; | 219 | int code; |
| 228 | uint lock_flags; | 220 | uint lock_flags; |
| @@ -230,14 +222,12 @@ xfs_setattr( | |||
| 230 | uid_t uid=0, iuid=0; | 222 | uid_t uid=0, iuid=0; |
| 231 | gid_t gid=0, igid=0; | 223 | gid_t gid=0, igid=0; |
| 232 | int timeflags = 0; | 224 | int timeflags = 0; |
| 233 | bhv_vnode_t *vp; | ||
| 234 | xfs_prid_t projid=0, iprojid=0; | 225 | xfs_prid_t projid=0, iprojid=0; |
| 235 | int mandlock_before, mandlock_after; | 226 | int mandlock_before, mandlock_after; |
| 236 | struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2; | 227 | struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2; |
| 237 | int file_owner; | 228 | int file_owner; |
| 238 | int need_iolock = 1; | 229 | int need_iolock = 1; |
| 239 | 230 | ||
| 240 | vp = BHV_TO_VNODE(bdp); | ||
| 241 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | 231 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); |
| 242 | 232 | ||
| 243 | if (vp->v_vfsp->vfs_flag & VFS_RDONLY) | 233 | if (vp->v_vfsp->vfs_flag & VFS_RDONLY) |
| @@ -251,9 +241,6 @@ xfs_setattr( | |||
| 251 | return XFS_ERROR(EINVAL); | 241 | return XFS_ERROR(EINVAL); |
| 252 | } | 242 | } |
| 253 | 243 | ||
| 254 | ip = XFS_BHVTOI(bdp); | ||
| 255 | mp = ip->i_mount; | ||
| 256 | |||
| 257 | if (XFS_FORCED_SHUTDOWN(mp)) | 244 | if (XFS_FORCED_SHUTDOWN(mp)) |
| 258 | return XFS_ERROR(EIO); | 245 | return XFS_ERROR(EIO); |
| 259 | 246 | ||
| @@ -924,19 +911,16 @@ xfs_setattr( | |||
| 924 | * xfs_access | 911 | * xfs_access |
| 925 | * Null conversion from vnode mode bits to inode mode bits, as in efs. | 912 | * Null conversion from vnode mode bits to inode mode bits, as in efs. |
| 926 | */ | 913 | */ |
| 927 | STATIC int | 914 | int |
| 928 | xfs_access( | 915 | xfs_access( |
| 929 | bhv_desc_t *bdp, | 916 | xfs_inode_t *ip, |
| 930 | int mode, | 917 | int mode, |
| 931 | cred_t *credp) | 918 | cred_t *credp) |
| 932 | { | 919 | { |
| 933 | xfs_inode_t *ip; | ||
| 934 | int error; | 920 | int error; |
| 935 | 921 | ||
| 936 | vn_trace_entry(BHV_TO_VNODE(bdp), __FUNCTION__, | 922 | vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); |
| 937 | (inst_t *)__return_address); | ||
| 938 | 923 | ||
| 939 | ip = XFS_BHVTOI(bdp); | ||
| 940 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 924 | xfs_ilock(ip, XFS_ILOCK_SHARED); |
| 941 | error = xfs_iaccess(ip, mode, credp); | 925 | error = xfs_iaccess(ip, mode, credp); |
| 942 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | 926 | xfs_iunlock(ip, XFS_ILOCK_SHARED); |
| @@ -998,16 +982,11 @@ xfs_readlink_bmap( | |||
| 998 | return error; | 982 | return error; |
| 999 | } | 983 | } |
| 1000 | 984 | ||
| 1001 | /* | 985 | int |
| 1002 | * xfs_readlink | ||
| 1003 | * | ||
| 1004 | */ | ||
| 1005 | STATIC int | ||
| 1006 | xfs_readlink( | 986 | xfs_readlink( |
| 1007 | bhv_desc_t *bdp, | 987 | xfs_inode_t *ip, |
| 1008 | char *link) | 988 | char *link) |
| 1009 | { | 989 | { |
| 1010 | xfs_inode_t *ip = XFS_BHVTOI(bdp); | ||
| 1011 | xfs_mount_t *mp = ip->i_mount; | 990 | xfs_mount_t *mp = ip->i_mount; |
| 1012 | int pathlen; | 991 | int pathlen; |
| 1013 | int error = 0; | 992 | int error = 0; |
| @@ -1047,23 +1026,18 @@ xfs_readlink( | |||
| 1047 | * be held while flushing the data, so acquire after we're done | 1026 | * be held while flushing the data, so acquire after we're done |
| 1048 | * with that. | 1027 | * with that. |
| 1049 | */ | 1028 | */ |
| 1050 | STATIC int | 1029 | int |
| 1051 | xfs_fsync( | 1030 | xfs_fsync( |
| 1052 | bhv_desc_t *bdp, | 1031 | xfs_inode_t *ip, |
| 1053 | int flag, | 1032 | int flag, |
| 1054 | cred_t *credp, | ||
| 1055 | xfs_off_t start, | 1033 | xfs_off_t start, |
| 1056 | xfs_off_t stop) | 1034 | xfs_off_t stop) |
| 1057 | { | 1035 | { |
| 1058 | xfs_inode_t *ip; | ||
| 1059 | xfs_trans_t *tp; | 1036 | xfs_trans_t *tp; |
| 1060 | int error; | 1037 | int error; |
| 1061 | int log_flushed = 0, changed = 1; | 1038 | int log_flushed = 0, changed = 1; |
| 1062 | 1039 | ||
| 1063 | vn_trace_entry(BHV_TO_VNODE(bdp), | 1040 | vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); |
| 1064 | __FUNCTION__, (inst_t *)__return_address); | ||
| 1065 | |||
| 1066 | ip = XFS_BHVTOI(bdp); | ||
| 1067 | 1041 | ||
| 1068 | ASSERT(start >= 0 && stop >= -1); | 1042 | ASSERT(start >= 0 && stop >= -1); |
| 1069 | 1043 | ||
| @@ -1533,19 +1507,14 @@ xfs_inactive_attrs( | |||
| 1533 | return 0; | 1507 | return 0; |
| 1534 | } | 1508 | } |
| 1535 | 1509 | ||
| 1536 | STATIC int | 1510 | int |
| 1537 | xfs_release( | 1511 | xfs_release( |
| 1538 | bhv_desc_t *bdp) | 1512 | xfs_inode_t *ip) |
| 1539 | { | 1513 | { |
| 1540 | xfs_inode_t *ip; | 1514 | bhv_vnode_t *vp = XFS_ITOV(ip); |
| 1541 | bhv_vnode_t *vp; | 1515 | xfs_mount_t *mp = ip->i_mount; |
| 1542 | xfs_mount_t *mp; | ||
| 1543 | int error; | 1516 | int error; |
| 1544 | 1517 | ||
| 1545 | vp = BHV_TO_VNODE(bdp); | ||
| 1546 | ip = XFS_BHVTOI(bdp); | ||
| 1547 | mp = ip->i_mount; | ||
| 1548 | |||
| 1549 | if (!VN_ISREG(vp) || (ip->i_d.di_mode == 0)) | 1518 | if (!VN_ISREG(vp) || (ip->i_d.di_mode == 0)) |
| 1550 | return 0; | 1519 | return 0; |
| 1551 | 1520 | ||
| @@ -1611,13 +1580,11 @@ xfs_release( | |||
| 1611 | * now be truncated. Also, we clear all of the read-ahead state | 1580 | * now be truncated. Also, we clear all of the read-ahead state |
| 1612 | * kept for the inode here since the file is now closed. | 1581 | * kept for the inode here since the file is now closed. |
| 1613 | */ | 1582 | */ |
| 1614 | STATIC int | 1583 | int |
| 1615 | xfs_inactive( | 1584 | xfs_inactive( |
| 1616 | bhv_desc_t *bdp, | 1585 | xfs_inode_t *ip) |
| 1617 | cred_t *credp) | ||
| 1618 | { | 1586 | { |
| 1619 | xfs_inode_t *ip; | 1587 | bhv_vnode_t *vp = XFS_ITOV(ip); |
| 1620 | bhv_vnode_t *vp; | ||
| 1621 | xfs_bmap_free_t free_list; | 1588 | xfs_bmap_free_t free_list; |
| 1622 | xfs_fsblock_t first_block; | 1589 | xfs_fsblock_t first_block; |
| 1623 | int committed; | 1590 | int committed; |
| @@ -1626,11 +1593,8 @@ xfs_inactive( | |||
| 1626 | int error; | 1593 | int error; |
| 1627 | int truncate; | 1594 | int truncate; |
| 1628 | 1595 | ||
| 1629 | vp = BHV_TO_VNODE(bdp); | ||
| 1630 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | 1596 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); |
| 1631 | 1597 | ||
| 1632 | ip = XFS_BHVTOI(bdp); | ||
| 1633 | |||
| 1634 | /* | 1598 | /* |
| 1635 | * If the inode is already free, then there can be nothing | 1599 | * If the inode is already free, then there can be nothing |
| 1636 | * to clean up here. | 1600 | * to clean up here. |
| @@ -1831,34 +1795,24 @@ xfs_inactive( | |||
| 1831 | } | 1795 | } |
| 1832 | 1796 | ||
| 1833 | 1797 | ||
| 1834 | /* | 1798 | int |
| 1835 | * xfs_lookup | ||
| 1836 | */ | ||
| 1837 | STATIC int | ||
| 1838 | xfs_lookup( | 1799 | xfs_lookup( |
| 1839 | bhv_desc_t *dir_bdp, | 1800 | xfs_inode_t *dp, |
| 1840 | bhv_vname_t *dentry, | 1801 | bhv_vname_t *dentry, |
| 1841 | bhv_vnode_t **vpp, | 1802 | bhv_vnode_t **vpp) |
| 1842 | int flags, | ||
| 1843 | bhv_vnode_t *rdir, | ||
| 1844 | cred_t *credp) | ||
| 1845 | { | 1803 | { |
| 1846 | xfs_inode_t *dp, *ip; | 1804 | xfs_inode_t *ip; |
| 1847 | xfs_ino_t e_inum; | 1805 | xfs_ino_t e_inum; |
| 1848 | int error; | 1806 | int error; |
| 1849 | uint lock_mode; | 1807 | uint lock_mode; |
| 1850 | bhv_vnode_t *dir_vp; | ||
| 1851 | |||
| 1852 | dir_vp = BHV_TO_VNODE(dir_bdp); | ||
| 1853 | vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); | ||
| 1854 | 1808 | ||
| 1855 | dp = XFS_BHVTOI(dir_bdp); | 1809 | vn_trace_entry(XFS_ITOV(dp), __FUNCTION__, (inst_t *)__return_address); |
| 1856 | 1810 | ||
| 1857 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) | 1811 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) |
| 1858 | return XFS_ERROR(EIO); | 1812 | return XFS_ERROR(EIO); |
| 1859 | 1813 | ||
| 1860 | lock_mode = xfs_ilock_map_shared(dp); | 1814 | lock_mode = xfs_ilock_map_shared(dp); |
| 1861 | error = xfs_dir_lookup_int(dir_bdp, lock_mode, dentry, &e_inum, &ip); | 1815 | error = xfs_dir_lookup_int(dp, lock_mode, dentry, &e_inum, &ip); |
| 1862 | if (!error) { | 1816 | if (!error) { |
| 1863 | *vpp = XFS_ITOV(ip); | 1817 | *vpp = XFS_ITOV(ip); |
| 1864 | ITRACE(ip); | 1818 | ITRACE(ip); |
| @@ -1867,29 +1821,25 @@ xfs_lookup( | |||
| 1867 | return error; | 1821 | return error; |
| 1868 | } | 1822 | } |
| 1869 | 1823 | ||
| 1870 | 1824 | int | |
| 1871 | /* | ||
| 1872 | * xfs_create (create a new file). | ||
| 1873 | */ | ||
| 1874 | STATIC int | ||
| 1875 | xfs_create( | 1825 | xfs_create( |
| 1876 | bhv_desc_t *dir_bdp, | 1826 | xfs_inode_t *dp, |
| 1877 | bhv_vname_t *dentry, | 1827 | bhv_vname_t *dentry, |
| 1878 | bhv_vattr_t *vap, | 1828 | bhv_vattr_t *vap, |
| 1879 | bhv_vnode_t **vpp, | 1829 | bhv_vnode_t **vpp, |
| 1880 | cred_t *credp) | 1830 | cred_t *credp) |
| 1881 | { | 1831 | { |
| 1882 | char *name = VNAME(dentry); | 1832 | char *name = VNAME(dentry); |
| 1883 | bhv_vnode_t *dir_vp; | 1833 | xfs_mount_t *mp = dp->i_mount; |
| 1884 | xfs_inode_t *dp, *ip; | 1834 | bhv_vnode_t *dir_vp = XFS_ITOV(dp); |
| 1835 | xfs_inode_t *ip; | ||
| 1885 | bhv_vnode_t *vp = NULL; | 1836 | bhv_vnode_t *vp = NULL; |
| 1886 | xfs_trans_t *tp; | 1837 | xfs_trans_t *tp; |
| 1887 | xfs_mount_t *mp; | ||
| 1888 | xfs_dev_t rdev; | 1838 | xfs_dev_t rdev; |
| 1889 | int error; | 1839 | int error; |
| 1890 | xfs_bmap_free_t free_list; | 1840 | xfs_bmap_free_t free_list; |
| 1891 | xfs_fsblock_t first_block; | 1841 | xfs_fsblock_t first_block; |
| 1892 | boolean_t dp_joined_to_trans; | 1842 | boolean_t unlock_dp_on_error = B_FALSE; |
| 1893 | int dm_event_sent = 0; | 1843 | int dm_event_sent = 0; |
| 1894 | uint cancel_flags; | 1844 | uint cancel_flags; |
| 1895 | int committed; | 1845 | int committed; |
| @@ -1900,12 +1850,8 @@ xfs_create( | |||
| 1900 | int namelen; | 1850 | int namelen; |
| 1901 | 1851 | ||
| 1902 | ASSERT(!*vpp); | 1852 | ASSERT(!*vpp); |
| 1903 | dir_vp = BHV_TO_VNODE(dir_bdp); | ||
| 1904 | vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); | 1853 | vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); |
| 1905 | 1854 | ||
| 1906 | dp = XFS_BHVTOI(dir_bdp); | ||
| 1907 | mp = dp->i_mount; | ||
| 1908 | |||
| 1909 | dm_di_mode = vap->va_mode; | 1855 | dm_di_mode = vap->va_mode; |
| 1910 | namelen = VNAMELEN(dentry); | 1856 | namelen = VNAMELEN(dentry); |
| 1911 | 1857 | ||
| @@ -1943,7 +1889,6 @@ xfs_create( | |||
| 1943 | goto std_return; | 1889 | goto std_return; |
| 1944 | 1890 | ||
| 1945 | ip = NULL; | 1891 | ip = NULL; |
| 1946 | dp_joined_to_trans = B_FALSE; | ||
| 1947 | 1892 | ||
| 1948 | tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE); | 1893 | tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE); |
| 1949 | cancel_flags = XFS_TRANS_RELEASE_LOG_RES; | 1894 | cancel_flags = XFS_TRANS_RELEASE_LOG_RES; |
| @@ -1963,11 +1908,11 @@ xfs_create( | |||
| 1963 | } | 1908 | } |
| 1964 | if (error) { | 1909 | if (error) { |
| 1965 | cancel_flags = 0; | 1910 | cancel_flags = 0; |
| 1966 | dp = NULL; | ||
| 1967 | goto error_return; | 1911 | goto error_return; |
| 1968 | } | 1912 | } |
| 1969 | 1913 | ||
| 1970 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); | 1914 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); |
| 1915 | unlock_dp_on_error = B_TRUE; | ||
| 1971 | 1916 | ||
| 1972 | XFS_BMAP_INIT(&free_list, &first_block); | 1917 | XFS_BMAP_INIT(&free_list, &first_block); |
| 1973 | 1918 | ||
| @@ -2001,15 +1946,15 @@ xfs_create( | |||
| 2001 | ASSERT(ismrlocked (&ip->i_lock, MR_UPDATE)); | 1946 | ASSERT(ismrlocked (&ip->i_lock, MR_UPDATE)); |
| 2002 | 1947 | ||
| 2003 | /* | 1948 | /* |
| 2004 | * Now we join the directory inode to the transaction. | 1949 | * Now we join the directory inode to the transaction. We do not do it |
| 2005 | * We do not do it earlier because xfs_dir_ialloc | 1950 | * earlier because xfs_dir_ialloc might commit the previous transaction |
| 2006 | * might commit the previous transaction (and release | 1951 | * (and release all the locks). An error from here on will result in |
| 2007 | * all the locks). | 1952 | * the transaction cancel unlocking dp so don't do it explicitly in the |
| 1953 | * error path. | ||
| 2008 | */ | 1954 | */ |
| 2009 | |||
| 2010 | VN_HOLD(dir_vp); | 1955 | VN_HOLD(dir_vp); |
| 2011 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); | 1956 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); |
| 2012 | dp_joined_to_trans = B_TRUE; | 1957 | unlock_dp_on_error = B_FALSE; |
| 2013 | 1958 | ||
| 2014 | error = xfs_dir_createname(tp, dp, name, namelen, ip->i_ino, | 1959 | error = xfs_dir_createname(tp, dp, name, namelen, ip->i_ino, |
| 2015 | &first_block, &free_list, resblks ? | 1960 | &first_block, &free_list, resblks ? |
| @@ -2075,7 +2020,7 @@ xfs_create( | |||
| 2075 | 2020 | ||
| 2076 | std_return: | 2021 | std_return: |
| 2077 | if ((*vpp || (error != 0 && dm_event_sent != 0)) && | 2022 | if ((*vpp || (error != 0 && dm_event_sent != 0)) && |
| 2078 | DM_EVENT_ENABLED(XFS_BHVTOI(dir_bdp), DM_EVENT_POSTCREATE)) { | 2023 | DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) { |
| 2079 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, | 2024 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, |
| 2080 | dir_vp, DM_RIGHT_NULL, | 2025 | dir_vp, DM_RIGHT_NULL, |
| 2081 | *vpp ? vp:NULL, | 2026 | *vpp ? vp:NULL, |
| @@ -2092,11 +2037,12 @@ std_return: | |||
| 2092 | if (tp != NULL) | 2037 | if (tp != NULL) |
| 2093 | xfs_trans_cancel(tp, cancel_flags); | 2038 | xfs_trans_cancel(tp, cancel_flags); |
| 2094 | 2039 | ||
| 2095 | if (!dp_joined_to_trans && (dp != NULL)) | ||
| 2096 | xfs_iunlock(dp, XFS_ILOCK_EXCL); | ||
| 2097 | XFS_QM_DQRELE(mp, udqp); | 2040 | XFS_QM_DQRELE(mp, udqp); |
| 2098 | XFS_QM_DQRELE(mp, gdqp); | 2041 | XFS_QM_DQRELE(mp, gdqp); |
| 2099 | 2042 | ||
| 2043 | if (unlock_dp_on_error) | ||
| 2044 | xfs_iunlock(dp, XFS_ILOCK_EXCL); | ||
| 2045 | |||
| 2100 | goto std_return; | 2046 | goto std_return; |
| 2101 | 2047 | ||
| 2102 | abort_rele: | 2048 | abort_rele: |
| @@ -2367,22 +2313,16 @@ int remove_which_error_return = 0; | |||
| 2367 | #define REMOVE_DEBUG_TRACE(x) | 2313 | #define REMOVE_DEBUG_TRACE(x) |
| 2368 | #endif /* ! DEBUG */ | 2314 | #endif /* ! DEBUG */ |
| 2369 | 2315 | ||
| 2370 | 2316 | int | |
| 2371 | /* | ||
| 2372 | * xfs_remove | ||
| 2373 | * | ||
| 2374 | */ | ||
| 2375 | STATIC int | ||
| 2376 | xfs_remove( | 2317 | xfs_remove( |
| 2377 | bhv_desc_t *dir_bdp, | 2318 | xfs_inode_t *dp, |
| 2378 | bhv_vname_t *dentry, | 2319 | bhv_vname_t *dentry) |
| 2379 | cred_t *credp) | ||
| 2380 | { | 2320 | { |
| 2381 | bhv_vnode_t *dir_vp; | 2321 | bhv_vnode_t *dir_vp = XFS_ITOV(dp); |
| 2382 | char *name = VNAME(dentry); | 2322 | char *name = VNAME(dentry); |
| 2383 | xfs_inode_t *dp, *ip; | 2323 | xfs_mount_t *mp = dp->i_mount; |
| 2324 | xfs_inode_t *ip; | ||
| 2384 | xfs_trans_t *tp = NULL; | 2325 | xfs_trans_t *tp = NULL; |
| 2385 | xfs_mount_t *mp; | ||
| 2386 | int error = 0; | 2326 | int error = 0; |
| 2387 | xfs_bmap_free_t free_list; | 2327 | xfs_bmap_free_t free_list; |
| 2388 | xfs_fsblock_t first_block; | 2328 | xfs_fsblock_t first_block; |
| @@ -2393,12 +2333,8 @@ xfs_remove( | |||
| 2393 | uint resblks; | 2333 | uint resblks; |
| 2394 | int namelen; | 2334 | int namelen; |
| 2395 | 2335 | ||
| 2396 | dir_vp = BHV_TO_VNODE(dir_bdp); | ||
| 2397 | vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); | 2336 | vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); |
| 2398 | 2337 | ||
| 2399 | dp = XFS_BHVTOI(dir_bdp); | ||
| 2400 | mp = dp->i_mount; | ||
| 2401 | |||
| 2402 | if (XFS_FORCED_SHUTDOWN(mp)) | 2338 | if (XFS_FORCED_SHUTDOWN(mp)) |
| 2403 | return XFS_ERROR(EIO); | 2339 | return XFS_ERROR(EIO); |
| 2404 | 2340 | ||
| @@ -2623,42 +2559,32 @@ xfs_remove( | |||
| 2623 | goto std_return; | 2559 | goto std_return; |
| 2624 | } | 2560 | } |
| 2625 | 2561 | ||
| 2626 | 2562 | int | |
| 2627 | /* | ||
| 2628 | * xfs_link | ||
| 2629 | * | ||
| 2630 | */ | ||
| 2631 | STATIC int | ||
| 2632 | xfs_link( | 2563 | xfs_link( |
| 2633 | bhv_desc_t *target_dir_bdp, | 2564 | xfs_inode_t *tdp, |
| 2634 | bhv_vnode_t *src_vp, | 2565 | bhv_vnode_t *src_vp, |
| 2635 | bhv_vname_t *dentry, | 2566 | bhv_vname_t *dentry) |
| 2636 | cred_t *credp) | ||
| 2637 | { | 2567 | { |
| 2638 | xfs_inode_t *tdp, *sip; | 2568 | bhv_vnode_t *target_dir_vp = XFS_ITOV(tdp); |
| 2569 | xfs_mount_t *mp = tdp->i_mount; | ||
| 2570 | xfs_inode_t *sip = xfs_vtoi(src_vp); | ||
| 2639 | xfs_trans_t *tp; | 2571 | xfs_trans_t *tp; |
| 2640 | xfs_mount_t *mp; | ||
| 2641 | xfs_inode_t *ips[2]; | 2572 | xfs_inode_t *ips[2]; |
| 2642 | int error; | 2573 | int error; |
| 2643 | xfs_bmap_free_t free_list; | 2574 | xfs_bmap_free_t free_list; |
| 2644 | xfs_fsblock_t first_block; | 2575 | xfs_fsblock_t first_block; |
| 2645 | int cancel_flags; | 2576 | int cancel_flags; |
| 2646 | int committed; | 2577 | int committed; |
| 2647 | bhv_vnode_t *target_dir_vp; | ||
| 2648 | int resblks; | 2578 | int resblks; |
| 2649 | char *target_name = VNAME(dentry); | 2579 | char *target_name = VNAME(dentry); |
| 2650 | int target_namelen; | 2580 | int target_namelen; |
| 2651 | 2581 | ||
| 2652 | target_dir_vp = BHV_TO_VNODE(target_dir_bdp); | ||
| 2653 | vn_trace_entry(target_dir_vp, __FUNCTION__, (inst_t *)__return_address); | 2582 | vn_trace_entry(target_dir_vp, __FUNCTION__, (inst_t *)__return_address); |
| 2654 | vn_trace_entry(src_vp, __FUNCTION__, (inst_t *)__return_address); | 2583 | vn_trace_entry(src_vp, __FUNCTION__, (inst_t *)__return_address); |
| 2655 | 2584 | ||
| 2656 | target_namelen = VNAMELEN(dentry); | 2585 | target_namelen = VNAMELEN(dentry); |
| 2657 | ASSERT(!VN_ISDIR(src_vp)); | 2586 | ASSERT(!VN_ISDIR(src_vp)); |
| 2658 | 2587 | ||
| 2659 | sip = xfs_vtoi(src_vp); | ||
| 2660 | tdp = XFS_BHVTOI(target_dir_bdp); | ||
| 2661 | mp = tdp->i_mount; | ||
| 2662 | if (XFS_FORCED_SHUTDOWN(mp)) | 2588 | if (XFS_FORCED_SHUTDOWN(mp)) |
| 2663 | return XFS_ERROR(EIO); | 2589 | return XFS_ERROR(EIO); |
| 2664 | 2590 | ||
| @@ -2791,50 +2717,38 @@ std_return: | |||
| 2791 | } | 2717 | } |
| 2792 | 2718 | ||
| 2793 | 2719 | ||
| 2794 | /* | 2720 | int |
| 2795 | * xfs_mkdir | ||
| 2796 | * | ||
| 2797 | */ | ||
| 2798 | STATIC int | ||
| 2799 | xfs_mkdir( | 2721 | xfs_mkdir( |
| 2800 | bhv_desc_t *dir_bdp, | 2722 | xfs_inode_t *dp, |
| 2801 | bhv_vname_t *dentry, | 2723 | bhv_vname_t *dentry, |
| 2802 | bhv_vattr_t *vap, | 2724 | bhv_vattr_t *vap, |
| 2803 | bhv_vnode_t **vpp, | 2725 | bhv_vnode_t **vpp, |
| 2804 | cred_t *credp) | 2726 | cred_t *credp) |
| 2805 | { | 2727 | { |
| 2728 | bhv_vnode_t *dir_vp = XFS_ITOV(dp); | ||
| 2806 | char *dir_name = VNAME(dentry); | 2729 | char *dir_name = VNAME(dentry); |
| 2807 | xfs_inode_t *dp; | 2730 | int dir_namelen = VNAMELEN(dentry); |
| 2731 | xfs_mount_t *mp = dp->i_mount; | ||
| 2808 | xfs_inode_t *cdp; /* inode of created dir */ | 2732 | xfs_inode_t *cdp; /* inode of created dir */ |
| 2809 | bhv_vnode_t *cvp; /* vnode of created dir */ | 2733 | bhv_vnode_t *cvp; /* vnode of created dir */ |
| 2810 | xfs_trans_t *tp; | 2734 | xfs_trans_t *tp; |
| 2811 | xfs_mount_t *mp; | ||
| 2812 | int cancel_flags; | 2735 | int cancel_flags; |
| 2813 | int error; | 2736 | int error; |
| 2814 | int committed; | 2737 | int committed; |
| 2815 | xfs_bmap_free_t free_list; | 2738 | xfs_bmap_free_t free_list; |
| 2816 | xfs_fsblock_t first_block; | 2739 | xfs_fsblock_t first_block; |
| 2817 | bhv_vnode_t *dir_vp; | 2740 | boolean_t unlock_dp_on_error = B_FALSE; |
| 2818 | boolean_t dp_joined_to_trans; | ||
| 2819 | boolean_t created = B_FALSE; | 2741 | boolean_t created = B_FALSE; |
| 2820 | int dm_event_sent = 0; | 2742 | int dm_event_sent = 0; |
| 2821 | xfs_prid_t prid; | 2743 | xfs_prid_t prid; |
| 2822 | struct xfs_dquot *udqp, *gdqp; | 2744 | struct xfs_dquot *udqp, *gdqp; |
| 2823 | uint resblks; | 2745 | uint resblks; |
| 2824 | int dm_di_mode; | 2746 | int dm_di_mode; |
| 2825 | int dir_namelen; | ||
| 2826 | |||
| 2827 | dir_vp = BHV_TO_VNODE(dir_bdp); | ||
| 2828 | dp = XFS_BHVTOI(dir_bdp); | ||
| 2829 | mp = dp->i_mount; | ||
| 2830 | 2747 | ||
| 2831 | if (XFS_FORCED_SHUTDOWN(mp)) | 2748 | if (XFS_FORCED_SHUTDOWN(mp)) |
| 2832 | return XFS_ERROR(EIO); | 2749 | return XFS_ERROR(EIO); |
| 2833 | 2750 | ||
| 2834 | dir_namelen = VNAMELEN(dentry); | ||
| 2835 | |||
| 2836 | tp = NULL; | 2751 | tp = NULL; |
| 2837 | dp_joined_to_trans = B_FALSE; | ||
| 2838 | dm_di_mode = vap->va_mode; | 2752 | dm_di_mode = vap->va_mode; |
| 2839 | 2753 | ||
| 2840 | if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) { | 2754 | if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) { |
| @@ -2882,11 +2796,11 @@ xfs_mkdir( | |||
| 2882 | } | 2796 | } |
| 2883 | if (error) { | 2797 | if (error) { |
| 2884 | cancel_flags = 0; | 2798 | cancel_flags = 0; |
| 2885 | dp = NULL; | ||
| 2886 | goto error_return; | 2799 | goto error_return; |
| 2887 | } | 2800 | } |
| 2888 | 2801 | ||
| 2889 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); | 2802 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); |
| 2803 | unlock_dp_on_error = B_TRUE; | ||
| 2890 | 2804 | ||
| 2891 | /* | 2805 | /* |
| 2892 | * Check for directory link count overflow. | 2806 | * Check for directory link count overflow. |
| @@ -2923,11 +2837,13 @@ xfs_mkdir( | |||
| 2923 | * Now we add the directory inode to the transaction. | 2837 | * Now we add the directory inode to the transaction. |
| 2924 | * We waited until now since xfs_dir_ialloc might start | 2838 | * We waited until now since xfs_dir_ialloc might start |
| 2925 | * a new transaction. Had we joined the transaction | 2839 | * a new transaction. Had we joined the transaction |
| 2926 | * earlier, the locks might have gotten released. | 2840 | * earlier, the locks might have gotten released. An error |
| 2841 | * from here on will result in the transaction cancel | ||
| 2842 | * unlocking dp so don't do it explicitly in the error path. | ||
| 2927 | */ | 2843 | */ |
| 2928 | VN_HOLD(dir_vp); | 2844 | VN_HOLD(dir_vp); |
| 2929 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); | 2845 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); |
| 2930 | dp_joined_to_trans = B_TRUE; | 2846 | unlock_dp_on_error = B_FALSE; |
| 2931 | 2847 | ||
| 2932 | XFS_BMAP_INIT(&free_list, &first_block); | 2848 | XFS_BMAP_INIT(&free_list, &first_block); |
| 2933 | 2849 | ||
| @@ -2995,7 +2911,7 @@ xfs_mkdir( | |||
| 2995 | 2911 | ||
| 2996 | std_return: | 2912 | std_return: |
| 2997 | if ((created || (error != 0 && dm_event_sent != 0)) && | 2913 | if ((created || (error != 0 && dm_event_sent != 0)) && |
| 2998 | DM_EVENT_ENABLED(XFS_BHVTOI(dir_bdp), DM_EVENT_POSTCREATE)) { | 2914 | DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) { |
| 2999 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, | 2915 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, |
| 3000 | dir_vp, DM_RIGHT_NULL, | 2916 | dir_vp, DM_RIGHT_NULL, |
| 3001 | created ? XFS_ITOV(cdp):NULL, | 2917 | created ? XFS_ITOV(cdp):NULL, |
| @@ -3015,49 +2931,36 @@ std_return: | |||
| 3015 | XFS_QM_DQRELE(mp, udqp); | 2931 | XFS_QM_DQRELE(mp, udqp); |
| 3016 | XFS_QM_DQRELE(mp, gdqp); | 2932 | XFS_QM_DQRELE(mp, gdqp); |
| 3017 | 2933 | ||
| 3018 | if (!dp_joined_to_trans && (dp != NULL)) { | 2934 | if (unlock_dp_on_error) |
| 3019 | xfs_iunlock(dp, XFS_ILOCK_EXCL); | 2935 | xfs_iunlock(dp, XFS_ILOCK_EXCL); |
| 3020 | } | ||
| 3021 | 2936 | ||
| 3022 | goto std_return; | 2937 | goto std_return; |
| 3023 | } | 2938 | } |
| 3024 | 2939 | ||
| 3025 | 2940 | int | |
| 3026 | /* | ||
| 3027 | * xfs_rmdir | ||
| 3028 | * | ||
| 3029 | */ | ||
| 3030 | STATIC int | ||
| 3031 | xfs_rmdir( | 2941 | xfs_rmdir( |
| 3032 | bhv_desc_t *dir_bdp, | 2942 | xfs_inode_t *dp, |
| 3033 | bhv_vname_t *dentry, | 2943 | bhv_vname_t *dentry) |
| 3034 | cred_t *credp) | ||
| 3035 | { | 2944 | { |
| 2945 | bhv_vnode_t *dir_vp = XFS_ITOV(dp); | ||
| 3036 | char *name = VNAME(dentry); | 2946 | char *name = VNAME(dentry); |
| 3037 | xfs_inode_t *dp; | 2947 | int namelen = VNAMELEN(dentry); |
| 3038 | xfs_inode_t *cdp; /* child directory */ | 2948 | xfs_mount_t *mp = dp->i_mount; |
| 2949 | xfs_inode_t *cdp; /* child directory */ | ||
| 3039 | xfs_trans_t *tp; | 2950 | xfs_trans_t *tp; |
| 3040 | xfs_mount_t *mp; | ||
| 3041 | int error; | 2951 | int error; |
| 3042 | xfs_bmap_free_t free_list; | 2952 | xfs_bmap_free_t free_list; |
| 3043 | xfs_fsblock_t first_block; | 2953 | xfs_fsblock_t first_block; |
| 3044 | int cancel_flags; | 2954 | int cancel_flags; |
| 3045 | int committed; | 2955 | int committed; |
| 3046 | bhv_vnode_t *dir_vp; | ||
| 3047 | int dm_di_mode = S_IFDIR; | 2956 | int dm_di_mode = S_IFDIR; |
| 3048 | int last_cdp_link; | 2957 | int last_cdp_link; |
| 3049 | int namelen; | ||
| 3050 | uint resblks; | 2958 | uint resblks; |
| 3051 | 2959 | ||
| 3052 | dir_vp = BHV_TO_VNODE(dir_bdp); | ||
| 3053 | dp = XFS_BHVTOI(dir_bdp); | ||
| 3054 | mp = dp->i_mount; | ||
| 3055 | |||
| 3056 | vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); | 2960 | vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); |
| 3057 | 2961 | ||
| 3058 | if (XFS_FORCED_SHUTDOWN(XFS_BHVTOI(dir_bdp)->i_mount)) | 2962 | if (XFS_FORCED_SHUTDOWN(mp)) |
| 3059 | return XFS_ERROR(EIO); | 2963 | return XFS_ERROR(EIO); |
| 3060 | namelen = VNAMELEN(dentry); | ||
| 3061 | 2964 | ||
| 3062 | if (!xfs_get_dir_entry(dentry, &cdp)) { | 2965 | if (!xfs_get_dir_entry(dentry, &cdp)) { |
| 3063 | dm_di_mode = cdp->i_d.di_mode; | 2966 | dm_di_mode = cdp->i_d.di_mode; |
| @@ -3272,25 +3175,24 @@ xfs_rmdir( | |||
| 3272 | goto std_return; | 3175 | goto std_return; |
| 3273 | } | 3176 | } |
| 3274 | 3177 | ||
| 3275 | STATIC int | 3178 | int |
| 3276 | xfs_symlink( | 3179 | xfs_symlink( |
| 3277 | bhv_desc_t *dir_bdp, | 3180 | xfs_inode_t *dp, |
| 3278 | bhv_vname_t *dentry, | 3181 | bhv_vname_t *dentry, |
| 3279 | bhv_vattr_t *vap, | 3182 | bhv_vattr_t *vap, |
| 3280 | char *target_path, | 3183 | char *target_path, |
| 3281 | bhv_vnode_t **vpp, | 3184 | bhv_vnode_t **vpp, |
| 3282 | cred_t *credp) | 3185 | cred_t *credp) |
| 3283 | { | 3186 | { |
| 3187 | bhv_vnode_t *dir_vp = XFS_ITOV(dp); | ||
| 3188 | xfs_mount_t *mp = dp->i_mount; | ||
| 3284 | xfs_trans_t *tp; | 3189 | xfs_trans_t *tp; |
| 3285 | xfs_mount_t *mp; | ||
| 3286 | xfs_inode_t *dp; | ||
| 3287 | xfs_inode_t *ip; | 3190 | xfs_inode_t *ip; |
| 3288 | int error; | 3191 | int error; |
| 3289 | int pathlen; | 3192 | int pathlen; |
| 3290 | xfs_bmap_free_t free_list; | 3193 | xfs_bmap_free_t free_list; |
| 3291 | xfs_fsblock_t first_block; | 3194 | xfs_fsblock_t first_block; |
| 3292 | boolean_t dp_joined_to_trans; | 3195 | boolean_t unlock_dp_on_error = B_FALSE; |
| 3293 | bhv_vnode_t *dir_vp; | ||
| 3294 | uint cancel_flags; | 3196 | uint cancel_flags; |
| 3295 | int committed; | 3197 | int committed; |
| 3296 | xfs_fileoff_t first_fsb; | 3198 | xfs_fileoff_t first_fsb; |
| @@ -3309,16 +3211,12 @@ xfs_symlink( | |||
| 3309 | int link_namelen; | 3211 | int link_namelen; |
| 3310 | 3212 | ||
| 3311 | *vpp = NULL; | 3213 | *vpp = NULL; |
| 3312 | dir_vp = BHV_TO_VNODE(dir_bdp); | ||
| 3313 | dp = XFS_BHVTOI(dir_bdp); | ||
| 3314 | dp_joined_to_trans = B_FALSE; | ||
| 3315 | error = 0; | 3214 | error = 0; |
| 3316 | ip = NULL; | 3215 | ip = NULL; |
| 3317 | tp = NULL; | 3216 | tp = NULL; |
| 3318 | 3217 | ||
| 3319 | vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); | 3218 | vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); |
| 3320 | 3219 | ||
| 3321 | mp = dp->i_mount; | ||
| 3322 | 3220 | ||
| 3323 | if (XFS_FORCED_SHUTDOWN(mp)) | 3221 | if (XFS_FORCED_SHUTDOWN(mp)) |
| 3324 | return XFS_ERROR(EIO); | 3222 | return XFS_ERROR(EIO); |
| @@ -3404,11 +3302,11 @@ xfs_symlink( | |||
| 3404 | } | 3302 | } |
| 3405 | if (error) { | 3303 | if (error) { |
| 3406 | cancel_flags = 0; | 3304 | cancel_flags = 0; |
| 3407 | dp = NULL; | ||
| 3408 | goto error_return; | 3305 | goto error_return; |
| 3409 | } | 3306 | } |
| 3410 | 3307 | ||
| 3411 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); | 3308 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); |
| 3309 | unlock_dp_on_error = B_TRUE; | ||
| 3412 | 3310 | ||
| 3413 | /* | 3311 | /* |
| 3414 | * Check whether the directory allows new symlinks or not. | 3312 | * Check whether the directory allows new symlinks or not. |
| @@ -3449,9 +3347,14 @@ xfs_symlink( | |||
| 3449 | } | 3347 | } |
| 3450 | ITRACE(ip); | 3348 | ITRACE(ip); |
| 3451 | 3349 | ||
| 3350 | /* | ||
| 3351 | * An error after we've joined dp to the transaction will result in the | ||
| 3352 | * transaction cancel unlocking dp so don't do it explicitly in the | ||
| 3353 | * error path. | ||
| 3354 | */ | ||
| 3452 | VN_HOLD(dir_vp); | 3355 | VN_HOLD(dir_vp); |
| 3453 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); | 3356 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); |
| 3454 | dp_joined_to_trans = B_TRUE; | 3357 | unlock_dp_on_error = B_FALSE; |
| 3455 | 3358 | ||
| 3456 | /* | 3359 | /* |
| 3457 | * Also attach the dquot(s) to it, if applicable. | 3360 | * Also attach the dquot(s) to it, if applicable. |
| @@ -3557,7 +3460,7 @@ xfs_symlink( | |||
| 3557 | /* Fall through to std_return with error = 0 or errno from | 3460 | /* Fall through to std_return with error = 0 or errno from |
| 3558 | * xfs_trans_commit */ | 3461 | * xfs_trans_commit */ |
| 3559 | std_return: | 3462 | std_return: |
| 3560 | if (DM_EVENT_ENABLED(XFS_BHVTOI(dir_bdp), DM_EVENT_POSTSYMLINK)) { | 3463 | if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTSYMLINK)) { |
| 3561 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTSYMLINK, | 3464 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTSYMLINK, |
| 3562 | dir_vp, DM_RIGHT_NULL, | 3465 | dir_vp, DM_RIGHT_NULL, |
| 3563 | error ? NULL : XFS_ITOV(ip), | 3466 | error ? NULL : XFS_ITOV(ip), |
| @@ -3584,9 +3487,8 @@ std_return: | |||
| 3584 | XFS_QM_DQRELE(mp, udqp); | 3487 | XFS_QM_DQRELE(mp, udqp); |
| 3585 | XFS_QM_DQRELE(mp, gdqp); | 3488 | XFS_QM_DQRELE(mp, gdqp); |
| 3586 | 3489 | ||
| 3587 | if (!dp_joined_to_trans && (dp != NULL)) { | 3490 | if (unlock_dp_on_error) |
| 3588 | xfs_iunlock(dp, XFS_ILOCK_EXCL); | 3491 | xfs_iunlock(dp, XFS_ILOCK_EXCL); |
| 3589 | } | ||
| 3590 | 3492 | ||
| 3591 | goto std_return; | 3493 | goto std_return; |
| 3592 | } | 3494 | } |
| @@ -3598,20 +3500,16 @@ std_return: | |||
| 3598 | * A fid routine that takes a pointer to a previously allocated | 3500 | * A fid routine that takes a pointer to a previously allocated |
| 3599 | * fid structure (like xfs_fast_fid) but uses a 64 bit inode number. | 3501 | * fid structure (like xfs_fast_fid) but uses a 64 bit inode number. |
| 3600 | */ | 3502 | */ |
| 3601 | STATIC int | 3503 | int |
| 3602 | xfs_fid2( | 3504 | xfs_fid2( |
| 3603 | bhv_desc_t *bdp, | 3505 | xfs_inode_t *ip, |
| 3604 | fid_t *fidp) | 3506 | fid_t *fidp) |
| 3605 | { | 3507 | { |
| 3606 | xfs_inode_t *ip; | 3508 | xfs_fid2_t *xfid = (xfs_fid2_t *)fidp; |
| 3607 | xfs_fid2_t *xfid; | ||
| 3608 | 3509 | ||
| 3609 | vn_trace_entry(BHV_TO_VNODE(bdp), __FUNCTION__, | 3510 | vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); |
| 3610 | (inst_t *)__return_address); | ||
| 3611 | ASSERT(sizeof(fid_t) >= sizeof(xfs_fid2_t)); | 3511 | ASSERT(sizeof(fid_t) >= sizeof(xfs_fid2_t)); |
| 3612 | 3512 | ||
| 3613 | xfid = (xfs_fid2_t *)fidp; | ||
| 3614 | ip = XFS_BHVTOI(bdp); | ||
| 3615 | xfid->fid_len = sizeof(xfs_fid2_t) - sizeof(xfid->fid_len); | 3513 | xfid->fid_len = sizeof(xfs_fid2_t) - sizeof(xfid->fid_len); |
| 3616 | xfid->fid_pad = 0; | 3514 | xfid->fid_pad = 0; |
| 3617 | /* | 3515 | /* |
| @@ -3625,21 +3523,13 @@ xfs_fid2( | |||
| 3625 | } | 3523 | } |
| 3626 | 3524 | ||
| 3627 | 3525 | ||
| 3628 | /* | ||
| 3629 | * xfs_rwlock | ||
| 3630 | */ | ||
| 3631 | int | 3526 | int |
| 3632 | xfs_rwlock( | 3527 | xfs_rwlock( |
| 3633 | bhv_desc_t *bdp, | 3528 | xfs_inode_t *ip, |
| 3634 | bhv_vrwlock_t locktype) | 3529 | bhv_vrwlock_t locktype) |
| 3635 | { | 3530 | { |
| 3636 | xfs_inode_t *ip; | 3531 | if (S_ISDIR(ip->i_d.di_mode)) |
| 3637 | bhv_vnode_t *vp; | ||
| 3638 | |||
| 3639 | vp = BHV_TO_VNODE(bdp); | ||
| 3640 | if (VN_ISDIR(vp)) | ||
| 3641 | return 1; | 3532 | return 1; |
| 3642 | ip = XFS_BHVTOI(bdp); | ||
| 3643 | if (locktype == VRWLOCK_WRITE) { | 3533 | if (locktype == VRWLOCK_WRITE) { |
| 3644 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | 3534 | xfs_ilock(ip, XFS_IOLOCK_EXCL); |
| 3645 | } else if (locktype == VRWLOCK_TRY_READ) { | 3535 | } else if (locktype == VRWLOCK_TRY_READ) { |
| @@ -3656,21 +3546,13 @@ xfs_rwlock( | |||
| 3656 | } | 3546 | } |
| 3657 | 3547 | ||
| 3658 | 3548 | ||
| 3659 | /* | ||
| 3660 | * xfs_rwunlock | ||
| 3661 | */ | ||
| 3662 | void | 3549 | void |
| 3663 | xfs_rwunlock( | 3550 | xfs_rwunlock( |
| 3664 | bhv_desc_t *bdp, | 3551 | xfs_inode_t *ip, |
| 3665 | bhv_vrwlock_t locktype) | 3552 | bhv_vrwlock_t locktype) |
| 3666 | { | 3553 | { |
| 3667 | xfs_inode_t *ip; | 3554 | if (S_ISDIR(ip->i_d.di_mode)) |
| 3668 | bhv_vnode_t *vp; | 3555 | return; |
| 3669 | |||
| 3670 | vp = BHV_TO_VNODE(bdp); | ||
| 3671 | if (VN_ISDIR(vp)) | ||
| 3672 | return; | ||
| 3673 | ip = XFS_BHVTOI(bdp); | ||
| 3674 | if (locktype == VRWLOCK_WRITE) { | 3556 | if (locktype == VRWLOCK_WRITE) { |
| 3675 | /* | 3557 | /* |
| 3676 | * In the write case, we may have added a new entry to | 3558 | * In the write case, we may have added a new entry to |
| @@ -3688,20 +3570,16 @@ xfs_rwunlock( | |||
| 3688 | return; | 3570 | return; |
| 3689 | } | 3571 | } |
| 3690 | 3572 | ||
| 3691 | STATIC int | 3573 | |
| 3574 | int | ||
| 3692 | xfs_inode_flush( | 3575 | xfs_inode_flush( |
| 3693 | bhv_desc_t *bdp, | 3576 | xfs_inode_t *ip, |
| 3694 | int flags) | 3577 | int flags) |
| 3695 | { | 3578 | { |
| 3696 | xfs_inode_t *ip; | 3579 | xfs_mount_t *mp = ip->i_mount; |
| 3697 | xfs_mount_t *mp; | 3580 | xfs_inode_log_item_t *iip = ip->i_itemp; |
| 3698 | xfs_inode_log_item_t *iip; | ||
| 3699 | int error = 0; | 3581 | int error = 0; |
| 3700 | 3582 | ||
| 3701 | ip = XFS_BHVTOI(bdp); | ||
| 3702 | mp = ip->i_mount; | ||
| 3703 | iip = ip->i_itemp; | ||
| 3704 | |||
| 3705 | if (XFS_FORCED_SHUTDOWN(mp)) | 3583 | if (XFS_FORCED_SHUTDOWN(mp)) |
| 3706 | return XFS_ERROR(EIO); | 3584 | return XFS_ERROR(EIO); |
| 3707 | 3585 | ||
| @@ -3770,24 +3648,20 @@ xfs_inode_flush( | |||
| 3770 | return error; | 3648 | return error; |
| 3771 | } | 3649 | } |
| 3772 | 3650 | ||
| 3651 | |||
| 3773 | int | 3652 | int |
| 3774 | xfs_set_dmattrs ( | 3653 | xfs_set_dmattrs( |
| 3775 | bhv_desc_t *bdp, | 3654 | xfs_inode_t *ip, |
| 3776 | u_int evmask, | 3655 | u_int evmask, |
| 3777 | u_int16_t state, | 3656 | u_int16_t state) |
| 3778 | cred_t *credp) | ||
| 3779 | { | 3657 | { |
| 3780 | xfs_inode_t *ip; | 3658 | xfs_mount_t *mp = ip->i_mount; |
| 3781 | xfs_trans_t *tp; | 3659 | xfs_trans_t *tp; |
| 3782 | xfs_mount_t *mp; | ||
| 3783 | int error; | 3660 | int error; |
| 3784 | 3661 | ||
| 3785 | if (!capable(CAP_SYS_ADMIN)) | 3662 | if (!capable(CAP_SYS_ADMIN)) |
| 3786 | return XFS_ERROR(EPERM); | 3663 | return XFS_ERROR(EPERM); |
| 3787 | 3664 | ||
| 3788 | ip = XFS_BHVTOI(bdp); | ||
| 3789 | mp = ip->i_mount; | ||
| 3790 | |||
| 3791 | if (XFS_FORCED_SHUTDOWN(mp)) | 3665 | if (XFS_FORCED_SHUTDOWN(mp)) |
| 3792 | return XFS_ERROR(EIO); | 3666 | return XFS_ERROR(EIO); |
| 3793 | 3667 | ||
| @@ -3810,15 +3684,11 @@ xfs_set_dmattrs ( | |||
| 3810 | return error; | 3684 | return error; |
| 3811 | } | 3685 | } |
| 3812 | 3686 | ||
| 3813 | STATIC int | 3687 | int |
| 3814 | xfs_reclaim( | 3688 | xfs_reclaim( |
| 3815 | bhv_desc_t *bdp) | 3689 | xfs_inode_t *ip) |
| 3816 | { | 3690 | { |
| 3817 | xfs_inode_t *ip; | 3691 | bhv_vnode_t *vp = XFS_ITOV(ip); |
| 3818 | bhv_vnode_t *vp; | ||
| 3819 | |||
| 3820 | vp = BHV_TO_VNODE(bdp); | ||
| 3821 | ip = XFS_BHVTOI(bdp); | ||
| 3822 | 3692 | ||
| 3823 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | 3693 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); |
| 3824 | 3694 | ||
| @@ -4495,35 +4365,29 @@ xfs_free_file_space( | |||
| 4495 | */ | 4365 | */ |
| 4496 | int | 4366 | int |
| 4497 | xfs_change_file_space( | 4367 | xfs_change_file_space( |
| 4498 | bhv_desc_t *bdp, | 4368 | xfs_inode_t *ip, |
| 4499 | int cmd, | 4369 | int cmd, |
| 4500 | xfs_flock64_t *bf, | 4370 | xfs_flock64_t *bf, |
| 4501 | xfs_off_t offset, | 4371 | xfs_off_t offset, |
| 4502 | cred_t *credp, | 4372 | cred_t *credp, |
| 4503 | int attr_flags) | 4373 | int attr_flags) |
| 4504 | { | 4374 | { |
| 4375 | xfs_mount_t *mp = ip->i_mount; | ||
| 4505 | int clrprealloc; | 4376 | int clrprealloc; |
| 4506 | int error; | 4377 | int error; |
| 4507 | xfs_fsize_t fsize; | 4378 | xfs_fsize_t fsize; |
| 4508 | xfs_inode_t *ip; | ||
| 4509 | xfs_mount_t *mp; | ||
| 4510 | int setprealloc; | 4379 | int setprealloc; |
| 4511 | xfs_off_t startoffset; | 4380 | xfs_off_t startoffset; |
| 4512 | xfs_off_t llen; | 4381 | xfs_off_t llen; |
| 4513 | xfs_trans_t *tp; | 4382 | xfs_trans_t *tp; |
| 4514 | bhv_vattr_t va; | 4383 | bhv_vattr_t va; |
| 4515 | bhv_vnode_t *vp; | ||
| 4516 | |||
| 4517 | vp = BHV_TO_VNODE(bdp); | ||
| 4518 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | ||
| 4519 | 4384 | ||
| 4520 | ip = XFS_BHVTOI(bdp); | 4385 | vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); |
| 4521 | mp = ip->i_mount; | ||
| 4522 | 4386 | ||
| 4523 | /* | 4387 | /* |
| 4524 | * must be a regular file and have write permission | 4388 | * must be a regular file and have write permission |
| 4525 | */ | 4389 | */ |
| 4526 | if (!VN_ISREG(vp)) | 4390 | if (!S_ISREG(ip->i_d.di_mode)) |
| 4527 | return XFS_ERROR(EINVAL); | 4391 | return XFS_ERROR(EINVAL); |
| 4528 | 4392 | ||
| 4529 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 4393 | xfs_ilock(ip, XFS_ILOCK_SHARED); |
| @@ -4605,7 +4469,7 @@ xfs_change_file_space( | |||
| 4605 | va.va_mask = XFS_AT_SIZE; | 4469 | va.va_mask = XFS_AT_SIZE; |
| 4606 | va.va_size = startoffset; | 4470 | va.va_size = startoffset; |
| 4607 | 4471 | ||
| 4608 | error = xfs_setattr(bdp, &va, attr_flags, credp); | 4472 | error = xfs_setattr(ip, &va, attr_flags, credp); |
| 4609 | 4473 | ||
| 4610 | if (error) | 4474 | if (error) |
| 4611 | return error; | 4475 | return error; |
| @@ -4664,46 +4528,3 @@ xfs_change_file_space( | |||
| 4664 | 4528 | ||
| 4665 | return error; | 4529 | return error; |
| 4666 | } | 4530 | } |
| 4667 | |||
| 4668 | bhv_vnodeops_t xfs_vnodeops = { | ||
| 4669 | BHV_IDENTITY_INIT(VN_BHV_XFS,VNODE_POSITION_XFS), | ||
| 4670 | .vop_open = xfs_open, | ||
| 4671 | .vop_read = xfs_read, | ||
| 4672 | #ifdef HAVE_SPLICE | ||
| 4673 | .vop_splice_read = xfs_splice_read, | ||
| 4674 | .vop_splice_write = xfs_splice_write, | ||
| 4675 | #endif | ||
| 4676 | .vop_write = xfs_write, | ||
| 4677 | .vop_ioctl = xfs_ioctl, | ||
| 4678 | .vop_getattr = xfs_getattr, | ||
| 4679 | .vop_setattr = xfs_setattr, | ||
| 4680 | .vop_access = xfs_access, | ||
| 4681 | .vop_lookup = xfs_lookup, | ||
| 4682 | .vop_create = xfs_create, | ||
| 4683 | .vop_remove = xfs_remove, | ||
| 4684 | .vop_link = xfs_link, | ||
| 4685 | .vop_rename = xfs_rename, | ||
| 4686 | .vop_mkdir = xfs_mkdir, | ||
| 4687 | .vop_rmdir = xfs_rmdir, | ||
| 4688 | .vop_readdir = xfs_readdir, | ||
| 4689 | .vop_symlink = xfs_symlink, | ||
| 4690 | .vop_readlink = xfs_readlink, | ||
| 4691 | .vop_fsync = xfs_fsync, | ||
| 4692 | .vop_inactive = xfs_inactive, | ||
| 4693 | .vop_fid2 = xfs_fid2, | ||
| 4694 | .vop_rwlock = xfs_rwlock, | ||
| 4695 | .vop_rwunlock = xfs_rwunlock, | ||
| 4696 | .vop_bmap = xfs_bmap, | ||
| 4697 | .vop_reclaim = xfs_reclaim, | ||
| 4698 | .vop_attr_get = xfs_attr_get, | ||
| 4699 | .vop_attr_set = xfs_attr_set, | ||
| 4700 | .vop_attr_remove = xfs_attr_remove, | ||
| 4701 | .vop_attr_list = xfs_attr_list, | ||
| 4702 | .vop_link_removed = (vop_link_removed_t)fs_noval, | ||
| 4703 | .vop_vnode_change = (vop_vnode_change_t)fs_noval, | ||
| 4704 | .vop_tosspages = fs_tosspages, | ||
| 4705 | .vop_flushinval_pages = fs_flushinval_pages, | ||
| 4706 | .vop_flush_pages = fs_flush_pages, | ||
| 4707 | .vop_release = xfs_release, | ||
| 4708 | .vop_iflush = xfs_inode_flush, | ||
| 4709 | }; | ||
