diff options
Diffstat (limited to 'fs/xfs/xfs_vnodeops.c')
-rw-r--r-- | fs/xfs/xfs_vnodeops.c | 745 |
1 files changed, 245 insertions, 500 deletions
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 603459229904..5e3c57ca9981 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,22 +79,16 @@ 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 | |||
95 | vp = BHV_TO_VNODE(bdp); | ||
96 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | ||
97 | 90 | ||
98 | ip = XFS_BHVTOI(bdp); | 91 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); |
99 | mp = ip->i_mount; | ||
100 | 92 | ||
101 | if (XFS_FORCED_SHUTDOWN(mp)) | 93 | if (XFS_FORCED_SHUTDOWN(mp)) |
102 | return XFS_ERROR(EIO); | 94 | return XFS_ERROR(EIO); |
@@ -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,17 +222,15 @@ 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); | 231 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); |
241 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | ||
242 | 232 | ||
243 | if (vp->v_vfsp->vfs_flag & VFS_RDONLY) | 233 | if (mp->m_flags & XFS_MOUNT_RDONLY) |
244 | return XFS_ERROR(EROFS); | 234 | return XFS_ERROR(EROFS); |
245 | 235 | ||
246 | /* | 236 | /* |
@@ -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 | ||
@@ -337,7 +324,7 @@ xfs_setattr( | |||
337 | } | 324 | } |
338 | } | 325 | } |
339 | } else { | 326 | } else { |
340 | if (DM_EVENT_ENABLED (vp->v_vfsp, ip, DM_EVENT_TRUNCATE) && | 327 | if (DM_EVENT_ENABLED(ip, DM_EVENT_TRUNCATE) && |
341 | !(flags & ATTR_DMI)) { | 328 | !(flags & ATTR_DMI)) { |
342 | int dmflags = AT_DELAY_FLAG(flags) | DM_SEM_FLAG_WR; | 329 | int dmflags = AT_DELAY_FLAG(flags) | DM_SEM_FLAG_WR; |
343 | code = XFS_SEND_DATA(mp, DM_EVENT_TRUNCATE, vp, | 330 | code = XFS_SEND_DATA(mp, DM_EVENT_TRUNCATE, vp, |
@@ -605,13 +592,13 @@ xfs_setattr( | |||
605 | if (!code && | 592 | if (!code && |
606 | (ip->i_size != ip->i_d.di_size) && | 593 | (ip->i_size != ip->i_d.di_size) && |
607 | (vap->va_size > ip->i_d.di_size)) { | 594 | (vap->va_size > ip->i_d.di_size)) { |
608 | code = bhv_vop_flush_pages(XFS_ITOV(ip), | 595 | code = xfs_flush_pages(ip, |
609 | ip->i_d.di_size, vap->va_size, | 596 | ip->i_d.di_size, vap->va_size, |
610 | XFS_B_ASYNC, FI_NONE); | 597 | XFS_B_ASYNC, FI_NONE); |
611 | } | 598 | } |
612 | 599 | ||
613 | /* wait for all I/O to complete */ | 600 | /* wait for all I/O to complete */ |
614 | vn_iowait(vp); | 601 | vn_iowait(ip); |
615 | 602 | ||
616 | if (!code) | 603 | if (!code) |
617 | code = xfs_itruncate_data(ip, vap->va_size); | 604 | code = xfs_itruncate_data(ip, vap->va_size); |
@@ -673,7 +660,7 @@ xfs_setattr( | |||
673 | * vnode and flush it when the file is closed, and | 660 | * vnode and flush it when the file is closed, and |
674 | * do not wait the usual (long) time for writeout. | 661 | * do not wait the usual (long) time for writeout. |
675 | */ | 662 | */ |
676 | VTRUNCATE(vp); | 663 | xfs_iflags_set(ip, XFS_ITRUNCATED); |
677 | } | 664 | } |
678 | /* | 665 | /* |
679 | * Have to do this even if the file's size doesn't change. | 666 | * Have to do this even if the file's size doesn't change. |
@@ -877,10 +864,6 @@ xfs_setattr( | |||
877 | * racing calls to vop_vnode_change. | 864 | * racing calls to vop_vnode_change. |
878 | */ | 865 | */ |
879 | mandlock_after = MANDLOCK(vp, ip->i_d.di_mode); | 866 | mandlock_after = MANDLOCK(vp, ip->i_d.di_mode); |
880 | if (mandlock_before != mandlock_after) { | ||
881 | bhv_vop_vnode_change(vp, VCHANGE_FLAGS_ENF_LOCKING, | ||
882 | mandlock_after); | ||
883 | } | ||
884 | 867 | ||
885 | xfs_iunlock(ip, lock_flags); | 868 | xfs_iunlock(ip, lock_flags); |
886 | 869 | ||
@@ -896,7 +879,7 @@ xfs_setattr( | |||
896 | return code; | 879 | return code; |
897 | } | 880 | } |
898 | 881 | ||
899 | if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_ATTRIBUTE) && | 882 | if (DM_EVENT_ENABLED(ip, DM_EVENT_ATTRIBUTE) && |
900 | !(flags & ATTR_DMI)) { | 883 | !(flags & ATTR_DMI)) { |
901 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_ATTRIBUTE, vp, DM_RIGHT_NULL, | 884 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_ATTRIBUTE, vp, DM_RIGHT_NULL, |
902 | NULL, DM_RIGHT_NULL, NULL, NULL, | 885 | NULL, DM_RIGHT_NULL, NULL, NULL, |
@@ -924,19 +907,16 @@ xfs_setattr( | |||
924 | * xfs_access | 907 | * xfs_access |
925 | * Null conversion from vnode mode bits to inode mode bits, as in efs. | 908 | * Null conversion from vnode mode bits to inode mode bits, as in efs. |
926 | */ | 909 | */ |
927 | STATIC int | 910 | int |
928 | xfs_access( | 911 | xfs_access( |
929 | bhv_desc_t *bdp, | 912 | xfs_inode_t *ip, |
930 | int mode, | 913 | int mode, |
931 | cred_t *credp) | 914 | cred_t *credp) |
932 | { | 915 | { |
933 | xfs_inode_t *ip; | ||
934 | int error; | 916 | int error; |
935 | 917 | ||
936 | vn_trace_entry(BHV_TO_VNODE(bdp), __FUNCTION__, | 918 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); |
937 | (inst_t *)__return_address); | ||
938 | 919 | ||
939 | ip = XFS_BHVTOI(bdp); | ||
940 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 920 | xfs_ilock(ip, XFS_ILOCK_SHARED); |
941 | error = xfs_iaccess(ip, mode, credp); | 921 | error = xfs_iaccess(ip, mode, credp); |
942 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | 922 | xfs_iunlock(ip, XFS_ILOCK_SHARED); |
@@ -951,105 +931,88 @@ xfs_access( | |||
951 | */ | 931 | */ |
952 | #define SYMLINK_MAPS 2 | 932 | #define SYMLINK_MAPS 2 |
953 | 933 | ||
954 | /* | ||
955 | * xfs_readlink | ||
956 | * | ||
957 | */ | ||
958 | STATIC int | 934 | STATIC int |
959 | xfs_readlink( | 935 | xfs_readlink_bmap( |
960 | bhv_desc_t *bdp, | 936 | xfs_inode_t *ip, |
961 | uio_t *uiop, | 937 | char *link) |
962 | int ioflags, | ||
963 | cred_t *credp) | ||
964 | { | 938 | { |
965 | xfs_inode_t *ip; | 939 | xfs_mount_t *mp = ip->i_mount; |
966 | int count; | 940 | int pathlen = ip->i_d.di_size; |
967 | xfs_off_t offset; | 941 | int nmaps = SYMLINK_MAPS; |
968 | int pathlen; | ||
969 | bhv_vnode_t *vp; | ||
970 | int error = 0; | ||
971 | xfs_mount_t *mp; | ||
972 | int nmaps; | ||
973 | xfs_bmbt_irec_t mval[SYMLINK_MAPS]; | 942 | xfs_bmbt_irec_t mval[SYMLINK_MAPS]; |
974 | xfs_daddr_t d; | 943 | xfs_daddr_t d; |
975 | int byte_cnt; | 944 | int byte_cnt; |
976 | int n; | 945 | int n; |
977 | xfs_buf_t *bp; | 946 | xfs_buf_t *bp; |
947 | int error = 0; | ||
978 | 948 | ||
979 | vp = BHV_TO_VNODE(bdp); | 949 | error = xfs_bmapi(NULL, ip, 0, XFS_B_TO_FSB(mp, pathlen), 0, NULL, 0, |
980 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | 950 | mval, &nmaps, NULL, NULL); |
981 | 951 | if (error) | |
982 | ip = XFS_BHVTOI(bdp); | 952 | goto out; |
983 | mp = ip->i_mount; | ||
984 | 953 | ||
985 | if (XFS_FORCED_SHUTDOWN(mp)) | 954 | for (n = 0; n < nmaps; n++) { |
986 | return XFS_ERROR(EIO); | 955 | d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock); |
956 | byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount); | ||
987 | 957 | ||
988 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 958 | bp = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt), 0); |
959 | error = XFS_BUF_GETERROR(bp); | ||
960 | if (error) { | ||
961 | xfs_ioerror_alert("xfs_readlink", | ||
962 | ip->i_mount, bp, XFS_BUF_ADDR(bp)); | ||
963 | xfs_buf_relse(bp); | ||
964 | goto out; | ||
965 | } | ||
966 | if (pathlen < byte_cnt) | ||
967 | byte_cnt = pathlen; | ||
968 | pathlen -= byte_cnt; | ||
989 | 969 | ||
990 | ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFLNK); | 970 | memcpy(link, XFS_BUF_PTR(bp), byte_cnt); |
971 | xfs_buf_relse(bp); | ||
972 | } | ||
991 | 973 | ||
992 | offset = uiop->uio_offset; | 974 | link[ip->i_d.di_size] = '\0'; |
993 | count = uiop->uio_resid; | 975 | error = 0; |
994 | 976 | ||
995 | if (offset < 0) { | 977 | out: |
996 | error = XFS_ERROR(EINVAL); | 978 | return error; |
997 | goto error_return; | 979 | } |
998 | } | ||
999 | if (count <= 0) { | ||
1000 | error = 0; | ||
1001 | goto error_return; | ||
1002 | } | ||
1003 | 980 | ||
1004 | /* | 981 | int |
1005 | * See if the symlink is stored inline. | 982 | xfs_readlink( |
1006 | */ | 983 | xfs_inode_t *ip, |
1007 | pathlen = (int)ip->i_d.di_size; | 984 | char *link) |
985 | { | ||
986 | xfs_mount_t *mp = ip->i_mount; | ||
987 | int pathlen; | ||
988 | int error = 0; | ||
1008 | 989 | ||
1009 | if (ip->i_df.if_flags & XFS_IFINLINE) { | 990 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); |
1010 | error = xfs_uio_read(ip->i_df.if_u1.if_data, pathlen, uiop); | ||
1011 | } | ||
1012 | else { | ||
1013 | /* | ||
1014 | * Symlink not inline. Call bmap to get it in. | ||
1015 | */ | ||
1016 | nmaps = SYMLINK_MAPS; | ||
1017 | 991 | ||
1018 | error = xfs_bmapi(NULL, ip, 0, XFS_B_TO_FSB(mp, pathlen), | 992 | if (XFS_FORCED_SHUTDOWN(mp)) |
1019 | 0, NULL, 0, mval, &nmaps, NULL, NULL); | 993 | return XFS_ERROR(EIO); |
1020 | 994 | ||
1021 | if (error) { | 995 | xfs_ilock(ip, XFS_ILOCK_SHARED); |
1022 | goto error_return; | ||
1023 | } | ||
1024 | 996 | ||
1025 | for (n = 0; n < nmaps; n++) { | 997 | ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFLNK); |
1026 | d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock); | 998 | ASSERT(ip->i_d.di_size <= MAXPATHLEN); |
1027 | byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount); | ||
1028 | bp = xfs_buf_read(mp->m_ddev_targp, d, | ||
1029 | BTOBB(byte_cnt), 0); | ||
1030 | error = XFS_BUF_GETERROR(bp); | ||
1031 | if (error) { | ||
1032 | xfs_ioerror_alert("xfs_readlink", | ||
1033 | ip->i_mount, bp, XFS_BUF_ADDR(bp)); | ||
1034 | xfs_buf_relse(bp); | ||
1035 | goto error_return; | ||
1036 | } | ||
1037 | if (pathlen < byte_cnt) | ||
1038 | byte_cnt = pathlen; | ||
1039 | pathlen -= byte_cnt; | ||
1040 | 999 | ||
1041 | error = xfs_uio_read(XFS_BUF_PTR(bp), byte_cnt, uiop); | 1000 | pathlen = ip->i_d.di_size; |
1042 | xfs_buf_relse (bp); | 1001 | if (!pathlen) |
1043 | } | 1002 | goto out; |
1044 | 1003 | ||
1004 | if (ip->i_df.if_flags & XFS_IFINLINE) { | ||
1005 | memcpy(link, ip->i_df.if_u1.if_data, pathlen); | ||
1006 | link[pathlen] = '\0'; | ||
1007 | } else { | ||
1008 | error = xfs_readlink_bmap(ip, link); | ||
1045 | } | 1009 | } |
1046 | 1010 | ||
1047 | error_return: | 1011 | out: |
1048 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | 1012 | xfs_iunlock(ip, XFS_ILOCK_SHARED); |
1049 | return error; | 1013 | return error; |
1050 | } | 1014 | } |
1051 | 1015 | ||
1052 | |||
1053 | /* | 1016 | /* |
1054 | * xfs_fsync | 1017 | * xfs_fsync |
1055 | * | 1018 | * |
@@ -1059,23 +1022,18 @@ error_return: | |||
1059 | * be held while flushing the data, so acquire after we're done | 1022 | * be held while flushing the data, so acquire after we're done |
1060 | * with that. | 1023 | * with that. |
1061 | */ | 1024 | */ |
1062 | STATIC int | 1025 | int |
1063 | xfs_fsync( | 1026 | xfs_fsync( |
1064 | bhv_desc_t *bdp, | 1027 | xfs_inode_t *ip, |
1065 | int flag, | 1028 | int flag, |
1066 | cred_t *credp, | ||
1067 | xfs_off_t start, | 1029 | xfs_off_t start, |
1068 | xfs_off_t stop) | 1030 | xfs_off_t stop) |
1069 | { | 1031 | { |
1070 | xfs_inode_t *ip; | ||
1071 | xfs_trans_t *tp; | 1032 | xfs_trans_t *tp; |
1072 | int error; | 1033 | int error; |
1073 | int log_flushed = 0, changed = 1; | 1034 | int log_flushed = 0, changed = 1; |
1074 | 1035 | ||
1075 | vn_trace_entry(BHV_TO_VNODE(bdp), | 1036 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); |
1076 | __FUNCTION__, (inst_t *)__return_address); | ||
1077 | |||
1078 | ip = XFS_BHVTOI(bdp); | ||
1079 | 1037 | ||
1080 | ASSERT(start >= 0 && stop >= -1); | 1038 | ASSERT(start >= 0 && stop >= -1); |
1081 | 1039 | ||
@@ -1545,27 +1503,24 @@ xfs_inactive_attrs( | |||
1545 | return 0; | 1503 | return 0; |
1546 | } | 1504 | } |
1547 | 1505 | ||
1548 | STATIC int | 1506 | int |
1549 | xfs_release( | 1507 | xfs_release( |
1550 | bhv_desc_t *bdp) | 1508 | xfs_inode_t *ip) |
1551 | { | 1509 | { |
1552 | xfs_inode_t *ip; | 1510 | bhv_vnode_t *vp = XFS_ITOV(ip); |
1553 | bhv_vnode_t *vp; | 1511 | xfs_mount_t *mp = ip->i_mount; |
1554 | xfs_mount_t *mp; | ||
1555 | int error; | 1512 | int error; |
1556 | 1513 | ||
1557 | vp = BHV_TO_VNODE(bdp); | ||
1558 | ip = XFS_BHVTOI(bdp); | ||
1559 | mp = ip->i_mount; | ||
1560 | |||
1561 | if (!VN_ISREG(vp) || (ip->i_d.di_mode == 0)) | 1514 | if (!VN_ISREG(vp) || (ip->i_d.di_mode == 0)) |
1562 | return 0; | 1515 | return 0; |
1563 | 1516 | ||
1564 | /* If this is a read-only mount, don't do this (would generate I/O) */ | 1517 | /* If this is a read-only mount, don't do this (would generate I/O) */ |
1565 | if (vp->v_vfsp->vfs_flag & VFS_RDONLY) | 1518 | if (mp->m_flags & XFS_MOUNT_RDONLY) |
1566 | return 0; | 1519 | return 0; |
1567 | 1520 | ||
1568 | if (!XFS_FORCED_SHUTDOWN(mp)) { | 1521 | if (!XFS_FORCED_SHUTDOWN(mp)) { |
1522 | int truncated; | ||
1523 | |||
1569 | /* | 1524 | /* |
1570 | * If we are using filestreams, and we have an unlinked | 1525 | * If we are using filestreams, and we have an unlinked |
1571 | * file that we are processing the last close on, then nothing | 1526 | * file that we are processing the last close on, then nothing |
@@ -1586,8 +1541,9 @@ xfs_release( | |||
1586 | * significantly reducing the time window where we'd otherwise | 1541 | * significantly reducing the time window where we'd otherwise |
1587 | * be exposed to that problem. | 1542 | * be exposed to that problem. |
1588 | */ | 1543 | */ |
1589 | if (VUNTRUNCATE(vp) && VN_DIRTY(vp) && ip->i_delayed_blks > 0) | 1544 | truncated = xfs_iflags_test_and_clear(ip, XFS_ITRUNCATED); |
1590 | bhv_vop_flush_pages(vp, 0, -1, XFS_B_ASYNC, FI_NONE); | 1545 | if (truncated && VN_DIRTY(vp) && ip->i_delayed_blks > 0) |
1546 | xfs_flush_pages(ip, 0, -1, XFS_B_ASYNC, FI_NONE); | ||
1591 | } | 1547 | } |
1592 | 1548 | ||
1593 | #ifdef HAVE_REFCACHE | 1549 | #ifdef HAVE_REFCACHE |
@@ -1623,13 +1579,11 @@ xfs_release( | |||
1623 | * now be truncated. Also, we clear all of the read-ahead state | 1579 | * now be truncated. Also, we clear all of the read-ahead state |
1624 | * kept for the inode here since the file is now closed. | 1580 | * kept for the inode here since the file is now closed. |
1625 | */ | 1581 | */ |
1626 | STATIC int | 1582 | int |
1627 | xfs_inactive( | 1583 | xfs_inactive( |
1628 | bhv_desc_t *bdp, | 1584 | xfs_inode_t *ip) |
1629 | cred_t *credp) | ||
1630 | { | 1585 | { |
1631 | xfs_inode_t *ip; | 1586 | bhv_vnode_t *vp = XFS_ITOV(ip); |
1632 | bhv_vnode_t *vp; | ||
1633 | xfs_bmap_free_t free_list; | 1587 | xfs_bmap_free_t free_list; |
1634 | xfs_fsblock_t first_block; | 1588 | xfs_fsblock_t first_block; |
1635 | int committed; | 1589 | int committed; |
@@ -1638,10 +1592,7 @@ xfs_inactive( | |||
1638 | int error; | 1592 | int error; |
1639 | int truncate; | 1593 | int truncate; |
1640 | 1594 | ||
1641 | vp = BHV_TO_VNODE(bdp); | 1595 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); |
1642 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | ||
1643 | |||
1644 | ip = XFS_BHVTOI(bdp); | ||
1645 | 1596 | ||
1646 | /* | 1597 | /* |
1647 | * If the inode is already free, then there can be nothing | 1598 | * If the inode is already free, then there can be nothing |
@@ -1666,15 +1617,14 @@ xfs_inactive( | |||
1666 | 1617 | ||
1667 | mp = ip->i_mount; | 1618 | mp = ip->i_mount; |
1668 | 1619 | ||
1669 | if (ip->i_d.di_nlink == 0 && | 1620 | if (ip->i_d.di_nlink == 0 && DM_EVENT_ENABLED(ip, DM_EVENT_DESTROY)) { |
1670 | DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_DESTROY)) { | ||
1671 | (void) XFS_SEND_DESTROY(mp, vp, DM_RIGHT_NULL); | 1621 | (void) XFS_SEND_DESTROY(mp, vp, DM_RIGHT_NULL); |
1672 | } | 1622 | } |
1673 | 1623 | ||
1674 | error = 0; | 1624 | error = 0; |
1675 | 1625 | ||
1676 | /* If this is a read-only mount, don't do this (would generate I/O) */ | 1626 | /* If this is a read-only mount, don't do this (would generate I/O) */ |
1677 | if (vp->v_vfsp->vfs_flag & VFS_RDONLY) | 1627 | if (mp->m_flags & XFS_MOUNT_RDONLY) |
1678 | goto out; | 1628 | goto out; |
1679 | 1629 | ||
1680 | if (ip->i_d.di_nlink != 0) { | 1630 | if (ip->i_d.di_nlink != 0) { |
@@ -1844,34 +1794,24 @@ xfs_inactive( | |||
1844 | } | 1794 | } |
1845 | 1795 | ||
1846 | 1796 | ||
1847 | /* | 1797 | int |
1848 | * xfs_lookup | ||
1849 | */ | ||
1850 | STATIC int | ||
1851 | xfs_lookup( | 1798 | xfs_lookup( |
1852 | bhv_desc_t *dir_bdp, | 1799 | xfs_inode_t *dp, |
1853 | bhv_vname_t *dentry, | 1800 | bhv_vname_t *dentry, |
1854 | bhv_vnode_t **vpp, | 1801 | bhv_vnode_t **vpp) |
1855 | int flags, | ||
1856 | bhv_vnode_t *rdir, | ||
1857 | cred_t *credp) | ||
1858 | { | 1802 | { |
1859 | xfs_inode_t *dp, *ip; | 1803 | xfs_inode_t *ip; |
1860 | xfs_ino_t e_inum; | 1804 | xfs_ino_t e_inum; |
1861 | int error; | 1805 | int error; |
1862 | uint lock_mode; | 1806 | uint lock_mode; |
1863 | bhv_vnode_t *dir_vp; | ||
1864 | |||
1865 | dir_vp = BHV_TO_VNODE(dir_bdp); | ||
1866 | vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); | ||
1867 | 1807 | ||
1868 | dp = XFS_BHVTOI(dir_bdp); | 1808 | vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address); |
1869 | 1809 | ||
1870 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) | 1810 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) |
1871 | return XFS_ERROR(EIO); | 1811 | return XFS_ERROR(EIO); |
1872 | 1812 | ||
1873 | lock_mode = xfs_ilock_map_shared(dp); | 1813 | lock_mode = xfs_ilock_map_shared(dp); |
1874 | error = xfs_dir_lookup_int(dir_bdp, lock_mode, dentry, &e_inum, &ip); | 1814 | error = xfs_dir_lookup_int(dp, lock_mode, dentry, &e_inum, &ip); |
1875 | if (!error) { | 1815 | if (!error) { |
1876 | *vpp = XFS_ITOV(ip); | 1816 | *vpp = XFS_ITOV(ip); |
1877 | ITRACE(ip); | 1817 | ITRACE(ip); |
@@ -1880,53 +1820,43 @@ xfs_lookup( | |||
1880 | return error; | 1820 | return error; |
1881 | } | 1821 | } |
1882 | 1822 | ||
1883 | 1823 | int | |
1884 | /* | ||
1885 | * xfs_create (create a new file). | ||
1886 | */ | ||
1887 | STATIC int | ||
1888 | xfs_create( | 1824 | xfs_create( |
1889 | bhv_desc_t *dir_bdp, | 1825 | xfs_inode_t *dp, |
1890 | bhv_vname_t *dentry, | 1826 | bhv_vname_t *dentry, |
1891 | bhv_vattr_t *vap, | 1827 | mode_t mode, |
1828 | xfs_dev_t rdev, | ||
1892 | bhv_vnode_t **vpp, | 1829 | bhv_vnode_t **vpp, |
1893 | cred_t *credp) | 1830 | cred_t *credp) |
1894 | { | 1831 | { |
1895 | char *name = VNAME(dentry); | 1832 | char *name = VNAME(dentry); |
1896 | bhv_vnode_t *dir_vp; | 1833 | xfs_mount_t *mp = dp->i_mount; |
1897 | xfs_inode_t *dp, *ip; | 1834 | bhv_vnode_t *dir_vp = XFS_ITOV(dp); |
1835 | xfs_inode_t *ip; | ||
1898 | bhv_vnode_t *vp = NULL; | 1836 | bhv_vnode_t *vp = NULL; |
1899 | xfs_trans_t *tp; | 1837 | xfs_trans_t *tp; |
1900 | xfs_mount_t *mp; | ||
1901 | xfs_dev_t rdev; | ||
1902 | int error; | 1838 | int error; |
1903 | xfs_bmap_free_t free_list; | 1839 | xfs_bmap_free_t free_list; |
1904 | xfs_fsblock_t first_block; | 1840 | xfs_fsblock_t first_block; |
1905 | boolean_t dp_joined_to_trans; | 1841 | boolean_t unlock_dp_on_error = B_FALSE; |
1906 | int dm_event_sent = 0; | 1842 | int dm_event_sent = 0; |
1907 | uint cancel_flags; | 1843 | uint cancel_flags; |
1908 | int committed; | 1844 | int committed; |
1909 | xfs_prid_t prid; | 1845 | xfs_prid_t prid; |
1910 | struct xfs_dquot *udqp, *gdqp; | 1846 | struct xfs_dquot *udqp, *gdqp; |
1911 | uint resblks; | 1847 | uint resblks; |
1912 | int dm_di_mode; | ||
1913 | int namelen; | 1848 | int namelen; |
1914 | 1849 | ||
1915 | ASSERT(!*vpp); | 1850 | ASSERT(!*vpp); |
1916 | dir_vp = BHV_TO_VNODE(dir_bdp); | 1851 | vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address); |
1917 | vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); | ||
1918 | 1852 | ||
1919 | dp = XFS_BHVTOI(dir_bdp); | ||
1920 | mp = dp->i_mount; | ||
1921 | |||
1922 | dm_di_mode = vap->va_mode; | ||
1923 | namelen = VNAMELEN(dentry); | 1853 | namelen = VNAMELEN(dentry); |
1924 | 1854 | ||
1925 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) { | 1855 | if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) { |
1926 | error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE, | 1856 | error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE, |
1927 | dir_vp, DM_RIGHT_NULL, NULL, | 1857 | dir_vp, DM_RIGHT_NULL, NULL, |
1928 | DM_RIGHT_NULL, name, NULL, | 1858 | DM_RIGHT_NULL, name, NULL, |
1929 | dm_di_mode, 0, 0); | 1859 | mode, 0, 0); |
1930 | 1860 | ||
1931 | if (error) | 1861 | if (error) |
1932 | return error; | 1862 | return error; |
@@ -1941,8 +1871,6 @@ xfs_create( | |||
1941 | udqp = gdqp = NULL; | 1871 | udqp = gdqp = NULL; |
1942 | if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) | 1872 | if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) |
1943 | prid = dp->i_d.di_projid; | 1873 | prid = dp->i_d.di_projid; |
1944 | else if (vap->va_mask & XFS_AT_PROJID) | ||
1945 | prid = (xfs_prid_t)vap->va_projid; | ||
1946 | else | 1874 | else |
1947 | prid = (xfs_prid_t)dfltprid; | 1875 | prid = (xfs_prid_t)dfltprid; |
1948 | 1876 | ||
@@ -1956,7 +1884,6 @@ xfs_create( | |||
1956 | goto std_return; | 1884 | goto std_return; |
1957 | 1885 | ||
1958 | ip = NULL; | 1886 | ip = NULL; |
1959 | dp_joined_to_trans = B_FALSE; | ||
1960 | 1887 | ||
1961 | tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE); | 1888 | tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE); |
1962 | cancel_flags = XFS_TRANS_RELEASE_LOG_RES; | 1889 | cancel_flags = XFS_TRANS_RELEASE_LOG_RES; |
@@ -1976,11 +1903,11 @@ xfs_create( | |||
1976 | } | 1903 | } |
1977 | if (error) { | 1904 | if (error) { |
1978 | cancel_flags = 0; | 1905 | cancel_flags = 0; |
1979 | dp = NULL; | ||
1980 | goto error_return; | 1906 | goto error_return; |
1981 | } | 1907 | } |
1982 | 1908 | ||
1983 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); | 1909 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); |
1910 | unlock_dp_on_error = B_TRUE; | ||
1984 | 1911 | ||
1985 | XFS_BMAP_INIT(&free_list, &first_block); | 1912 | XFS_BMAP_INIT(&free_list, &first_block); |
1986 | 1913 | ||
@@ -1995,8 +1922,7 @@ xfs_create( | |||
1995 | 1922 | ||
1996 | if (resblks == 0 && (error = xfs_dir_canenter(tp, dp, name, namelen))) | 1923 | if (resblks == 0 && (error = xfs_dir_canenter(tp, dp, name, namelen))) |
1997 | goto error_return; | 1924 | goto error_return; |
1998 | rdev = (vap->va_mask & XFS_AT_RDEV) ? vap->va_rdev : 0; | 1925 | error = xfs_dir_ialloc(&tp, dp, mode, 1, |
1999 | error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 1, | ||
2000 | rdev, credp, prid, resblks > 0, | 1926 | rdev, credp, prid, resblks > 0, |
2001 | &ip, &committed); | 1927 | &ip, &committed); |
2002 | if (error) { | 1928 | if (error) { |
@@ -2014,15 +1940,15 @@ xfs_create( | |||
2014 | ASSERT(ismrlocked (&ip->i_lock, MR_UPDATE)); | 1940 | ASSERT(ismrlocked (&ip->i_lock, MR_UPDATE)); |
2015 | 1941 | ||
2016 | /* | 1942 | /* |
2017 | * Now we join the directory inode to the transaction. | 1943 | * Now we join the directory inode to the transaction. We do not do it |
2018 | * We do not do it earlier because xfs_dir_ialloc | 1944 | * earlier because xfs_dir_ialloc might commit the previous transaction |
2019 | * might commit the previous transaction (and release | 1945 | * (and release all the locks). An error from here on will result in |
2020 | * all the locks). | 1946 | * the transaction cancel unlocking dp so don't do it explicitly in the |
1947 | * error path. | ||
2021 | */ | 1948 | */ |
2022 | |||
2023 | VN_HOLD(dir_vp); | 1949 | VN_HOLD(dir_vp); |
2024 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); | 1950 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); |
2025 | dp_joined_to_trans = B_TRUE; | 1951 | unlock_dp_on_error = B_FALSE; |
2026 | 1952 | ||
2027 | error = xfs_dir_createname(tp, dp, name, namelen, ip->i_ino, | 1953 | error = xfs_dir_createname(tp, dp, name, namelen, ip->i_ino, |
2028 | &first_block, &free_list, resblks ? | 1954 | &first_block, &free_list, resblks ? |
@@ -2076,25 +2002,18 @@ xfs_create( | |||
2076 | XFS_QM_DQRELE(mp, udqp); | 2002 | XFS_QM_DQRELE(mp, udqp); |
2077 | XFS_QM_DQRELE(mp, gdqp); | 2003 | XFS_QM_DQRELE(mp, gdqp); |
2078 | 2004 | ||
2079 | /* | ||
2080 | * Propagate the fact that the vnode changed after the | ||
2081 | * xfs_inode locks have been released. | ||
2082 | */ | ||
2083 | bhv_vop_vnode_change(vp, VCHANGE_FLAGS_TRUNCATED, 3); | ||
2084 | |||
2085 | *vpp = vp; | 2005 | *vpp = vp; |
2086 | 2006 | ||
2087 | /* Fallthrough to std_return with error = 0 */ | 2007 | /* Fallthrough to std_return with error = 0 */ |
2088 | 2008 | ||
2089 | std_return: | 2009 | std_return: |
2090 | if ( (*vpp || (error != 0 && dm_event_sent != 0)) && | 2010 | if ((*vpp || (error != 0 && dm_event_sent != 0)) && |
2091 | DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp), | 2011 | DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) { |
2092 | DM_EVENT_POSTCREATE)) { | ||
2093 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, | 2012 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, |
2094 | dir_vp, DM_RIGHT_NULL, | 2013 | dir_vp, DM_RIGHT_NULL, |
2095 | *vpp ? vp:NULL, | 2014 | *vpp ? vp:NULL, |
2096 | DM_RIGHT_NULL, name, NULL, | 2015 | DM_RIGHT_NULL, name, NULL, |
2097 | dm_di_mode, error, 0); | 2016 | mode, error, 0); |
2098 | } | 2017 | } |
2099 | return error; | 2018 | return error; |
2100 | 2019 | ||
@@ -2106,11 +2025,12 @@ std_return: | |||
2106 | if (tp != NULL) | 2025 | if (tp != NULL) |
2107 | xfs_trans_cancel(tp, cancel_flags); | 2026 | xfs_trans_cancel(tp, cancel_flags); |
2108 | 2027 | ||
2109 | if (!dp_joined_to_trans && (dp != NULL)) | ||
2110 | xfs_iunlock(dp, XFS_ILOCK_EXCL); | ||
2111 | XFS_QM_DQRELE(mp, udqp); | 2028 | XFS_QM_DQRELE(mp, udqp); |
2112 | XFS_QM_DQRELE(mp, gdqp); | 2029 | XFS_QM_DQRELE(mp, gdqp); |
2113 | 2030 | ||
2031 | if (unlock_dp_on_error) | ||
2032 | xfs_iunlock(dp, XFS_ILOCK_EXCL); | ||
2033 | |||
2114 | goto std_return; | 2034 | goto std_return; |
2115 | 2035 | ||
2116 | abort_rele: | 2036 | abort_rele: |
@@ -2381,22 +2301,16 @@ int remove_which_error_return = 0; | |||
2381 | #define REMOVE_DEBUG_TRACE(x) | 2301 | #define REMOVE_DEBUG_TRACE(x) |
2382 | #endif /* ! DEBUG */ | 2302 | #endif /* ! DEBUG */ |
2383 | 2303 | ||
2384 | 2304 | int | |
2385 | /* | ||
2386 | * xfs_remove | ||
2387 | * | ||
2388 | */ | ||
2389 | STATIC int | ||
2390 | xfs_remove( | 2305 | xfs_remove( |
2391 | bhv_desc_t *dir_bdp, | 2306 | xfs_inode_t *dp, |
2392 | bhv_vname_t *dentry, | 2307 | bhv_vname_t *dentry) |
2393 | cred_t *credp) | ||
2394 | { | 2308 | { |
2395 | bhv_vnode_t *dir_vp; | 2309 | bhv_vnode_t *dir_vp = XFS_ITOV(dp); |
2396 | char *name = VNAME(dentry); | 2310 | char *name = VNAME(dentry); |
2397 | xfs_inode_t *dp, *ip; | 2311 | xfs_mount_t *mp = dp->i_mount; |
2312 | xfs_inode_t *ip; | ||
2398 | xfs_trans_t *tp = NULL; | 2313 | xfs_trans_t *tp = NULL; |
2399 | xfs_mount_t *mp; | ||
2400 | int error = 0; | 2314 | int error = 0; |
2401 | xfs_bmap_free_t free_list; | 2315 | xfs_bmap_free_t free_list; |
2402 | xfs_fsblock_t first_block; | 2316 | xfs_fsblock_t first_block; |
@@ -2407,11 +2321,7 @@ xfs_remove( | |||
2407 | uint resblks; | 2321 | uint resblks; |
2408 | int namelen; | 2322 | int namelen; |
2409 | 2323 | ||
2410 | dir_vp = BHV_TO_VNODE(dir_bdp); | 2324 | vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address); |
2411 | vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); | ||
2412 | |||
2413 | dp = XFS_BHVTOI(dir_bdp); | ||
2414 | mp = dp->i_mount; | ||
2415 | 2325 | ||
2416 | if (XFS_FORCED_SHUTDOWN(mp)) | 2326 | if (XFS_FORCED_SHUTDOWN(mp)) |
2417 | return XFS_ERROR(EIO); | 2327 | return XFS_ERROR(EIO); |
@@ -2423,7 +2333,7 @@ xfs_remove( | |||
2423 | IRELE(ip); | 2333 | IRELE(ip); |
2424 | } | 2334 | } |
2425 | 2335 | ||
2426 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) { | 2336 | if (DM_EVENT_ENABLED(dp, DM_EVENT_REMOVE)) { |
2427 | error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_vp, | 2337 | error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_vp, |
2428 | DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, | 2338 | DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, |
2429 | name, NULL, dm_di_mode, 0, 0); | 2339 | name, NULL, dm_di_mode, 0, 0); |
@@ -2454,7 +2364,7 @@ xfs_remove( | |||
2454 | 2364 | ||
2455 | dm_di_mode = ip->i_d.di_mode; | 2365 | dm_di_mode = ip->i_d.di_mode; |
2456 | 2366 | ||
2457 | vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); | 2367 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); |
2458 | 2368 | ||
2459 | ITRACE(ip); | 2369 | ITRACE(ip); |
2460 | 2370 | ||
@@ -2588,19 +2498,13 @@ xfs_remove( | |||
2588 | if (link_zero && xfs_inode_is_filestream(ip)) | 2498 | if (link_zero && xfs_inode_is_filestream(ip)) |
2589 | xfs_filestream_deassociate(ip); | 2499 | xfs_filestream_deassociate(ip); |
2590 | 2500 | ||
2591 | vn_trace_exit(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); | 2501 | vn_trace_exit(ip, __FUNCTION__, (inst_t *)__return_address); |
2592 | |||
2593 | /* | ||
2594 | * Let interposed file systems know about removed links. | ||
2595 | */ | ||
2596 | bhv_vop_link_removed(XFS_ITOV(ip), dir_vp, link_zero); | ||
2597 | 2502 | ||
2598 | IRELE(ip); | 2503 | IRELE(ip); |
2599 | 2504 | ||
2600 | /* Fall through to std_return with error = 0 */ | 2505 | /* Fall through to std_return with error = 0 */ |
2601 | std_return: | 2506 | std_return: |
2602 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, | 2507 | if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTREMOVE)) { |
2603 | DM_EVENT_POSTREMOVE)) { | ||
2604 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE, | 2508 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE, |
2605 | dir_vp, DM_RIGHT_NULL, | 2509 | dir_vp, DM_RIGHT_NULL, |
2606 | NULL, DM_RIGHT_NULL, | 2510 | NULL, DM_RIGHT_NULL, |
@@ -2638,46 +2542,36 @@ xfs_remove( | |||
2638 | goto std_return; | 2542 | goto std_return; |
2639 | } | 2543 | } |
2640 | 2544 | ||
2641 | 2545 | int | |
2642 | /* | ||
2643 | * xfs_link | ||
2644 | * | ||
2645 | */ | ||
2646 | STATIC int | ||
2647 | xfs_link( | 2546 | xfs_link( |
2648 | bhv_desc_t *target_dir_bdp, | 2547 | xfs_inode_t *tdp, |
2649 | bhv_vnode_t *src_vp, | 2548 | bhv_vnode_t *src_vp, |
2650 | bhv_vname_t *dentry, | 2549 | bhv_vname_t *dentry) |
2651 | cred_t *credp) | ||
2652 | { | 2550 | { |
2653 | xfs_inode_t *tdp, *sip; | 2551 | bhv_vnode_t *target_dir_vp = XFS_ITOV(tdp); |
2552 | xfs_mount_t *mp = tdp->i_mount; | ||
2553 | xfs_inode_t *sip = xfs_vtoi(src_vp); | ||
2654 | xfs_trans_t *tp; | 2554 | xfs_trans_t *tp; |
2655 | xfs_mount_t *mp; | ||
2656 | xfs_inode_t *ips[2]; | 2555 | xfs_inode_t *ips[2]; |
2657 | int error; | 2556 | int error; |
2658 | xfs_bmap_free_t free_list; | 2557 | xfs_bmap_free_t free_list; |
2659 | xfs_fsblock_t first_block; | 2558 | xfs_fsblock_t first_block; |
2660 | int cancel_flags; | 2559 | int cancel_flags; |
2661 | int committed; | 2560 | int committed; |
2662 | bhv_vnode_t *target_dir_vp; | ||
2663 | int resblks; | 2561 | int resblks; |
2664 | char *target_name = VNAME(dentry); | 2562 | char *target_name = VNAME(dentry); |
2665 | int target_namelen; | 2563 | int target_namelen; |
2666 | 2564 | ||
2667 | target_dir_vp = BHV_TO_VNODE(target_dir_bdp); | 2565 | vn_trace_entry(tdp, __FUNCTION__, (inst_t *)__return_address); |
2668 | vn_trace_entry(target_dir_vp, __FUNCTION__, (inst_t *)__return_address); | 2566 | vn_trace_entry(xfs_vtoi(src_vp), __FUNCTION__, (inst_t *)__return_address); |
2669 | vn_trace_entry(src_vp, __FUNCTION__, (inst_t *)__return_address); | ||
2670 | 2567 | ||
2671 | target_namelen = VNAMELEN(dentry); | 2568 | target_namelen = VNAMELEN(dentry); |
2672 | ASSERT(!VN_ISDIR(src_vp)); | 2569 | ASSERT(!VN_ISDIR(src_vp)); |
2673 | 2570 | ||
2674 | sip = xfs_vtoi(src_vp); | ||
2675 | tdp = XFS_BHVTOI(target_dir_bdp); | ||
2676 | mp = tdp->i_mount; | ||
2677 | if (XFS_FORCED_SHUTDOWN(mp)) | 2571 | if (XFS_FORCED_SHUTDOWN(mp)) |
2678 | return XFS_ERROR(EIO); | 2572 | return XFS_ERROR(EIO); |
2679 | 2573 | ||
2680 | if (DM_EVENT_ENABLED(src_vp->v_vfsp, tdp, DM_EVENT_LINK)) { | 2574 | if (DM_EVENT_ENABLED(tdp, DM_EVENT_LINK)) { |
2681 | error = XFS_SEND_NAMESP(mp, DM_EVENT_LINK, | 2575 | error = XFS_SEND_NAMESP(mp, DM_EVENT_LINK, |
2682 | target_dir_vp, DM_RIGHT_NULL, | 2576 | target_dir_vp, DM_RIGHT_NULL, |
2683 | src_vp, DM_RIGHT_NULL, | 2577 | src_vp, DM_RIGHT_NULL, |
@@ -2788,8 +2682,7 @@ xfs_link( | |||
2788 | 2682 | ||
2789 | /* Fall through to std_return with error = 0. */ | 2683 | /* Fall through to std_return with error = 0. */ |
2790 | std_return: | 2684 | std_return: |
2791 | if (DM_EVENT_ENABLED(src_vp->v_vfsp, sip, | 2685 | if (DM_EVENT_ENABLED(sip, DM_EVENT_POSTLINK)) { |
2792 | DM_EVENT_POSTLINK)) { | ||
2793 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTLINK, | 2686 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTLINK, |
2794 | target_dir_vp, DM_RIGHT_NULL, | 2687 | target_dir_vp, DM_RIGHT_NULL, |
2795 | src_vp, DM_RIGHT_NULL, | 2688 | src_vp, DM_RIGHT_NULL, |
@@ -2807,57 +2700,43 @@ std_return: | |||
2807 | } | 2700 | } |
2808 | 2701 | ||
2809 | 2702 | ||
2810 | /* | 2703 | int |
2811 | * xfs_mkdir | ||
2812 | * | ||
2813 | */ | ||
2814 | STATIC int | ||
2815 | xfs_mkdir( | 2704 | xfs_mkdir( |
2816 | bhv_desc_t *dir_bdp, | 2705 | xfs_inode_t *dp, |
2817 | bhv_vname_t *dentry, | 2706 | bhv_vname_t *dentry, |
2818 | bhv_vattr_t *vap, | 2707 | mode_t mode, |
2819 | bhv_vnode_t **vpp, | 2708 | bhv_vnode_t **vpp, |
2820 | cred_t *credp) | 2709 | cred_t *credp) |
2821 | { | 2710 | { |
2711 | bhv_vnode_t *dir_vp = XFS_ITOV(dp); | ||
2822 | char *dir_name = VNAME(dentry); | 2712 | char *dir_name = VNAME(dentry); |
2823 | xfs_inode_t *dp; | 2713 | int dir_namelen = VNAMELEN(dentry); |
2714 | xfs_mount_t *mp = dp->i_mount; | ||
2824 | xfs_inode_t *cdp; /* inode of created dir */ | 2715 | xfs_inode_t *cdp; /* inode of created dir */ |
2825 | bhv_vnode_t *cvp; /* vnode of created dir */ | 2716 | bhv_vnode_t *cvp; /* vnode of created dir */ |
2826 | xfs_trans_t *tp; | 2717 | xfs_trans_t *tp; |
2827 | xfs_mount_t *mp; | ||
2828 | int cancel_flags; | 2718 | int cancel_flags; |
2829 | int error; | 2719 | int error; |
2830 | int committed; | 2720 | int committed; |
2831 | xfs_bmap_free_t free_list; | 2721 | xfs_bmap_free_t free_list; |
2832 | xfs_fsblock_t first_block; | 2722 | xfs_fsblock_t first_block; |
2833 | bhv_vnode_t *dir_vp; | 2723 | boolean_t unlock_dp_on_error = B_FALSE; |
2834 | boolean_t dp_joined_to_trans; | ||
2835 | boolean_t created = B_FALSE; | 2724 | boolean_t created = B_FALSE; |
2836 | int dm_event_sent = 0; | 2725 | int dm_event_sent = 0; |
2837 | xfs_prid_t prid; | 2726 | xfs_prid_t prid; |
2838 | struct xfs_dquot *udqp, *gdqp; | 2727 | struct xfs_dquot *udqp, *gdqp; |
2839 | uint resblks; | 2728 | uint resblks; |
2840 | int dm_di_mode; | ||
2841 | int dir_namelen; | ||
2842 | |||
2843 | dir_vp = BHV_TO_VNODE(dir_bdp); | ||
2844 | dp = XFS_BHVTOI(dir_bdp); | ||
2845 | mp = dp->i_mount; | ||
2846 | 2729 | ||
2847 | if (XFS_FORCED_SHUTDOWN(mp)) | 2730 | if (XFS_FORCED_SHUTDOWN(mp)) |
2848 | return XFS_ERROR(EIO); | 2731 | return XFS_ERROR(EIO); |
2849 | 2732 | ||
2850 | dir_namelen = VNAMELEN(dentry); | ||
2851 | |||
2852 | tp = NULL; | 2733 | tp = NULL; |
2853 | dp_joined_to_trans = B_FALSE; | ||
2854 | dm_di_mode = vap->va_mode; | ||
2855 | 2734 | ||
2856 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) { | 2735 | if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) { |
2857 | error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE, | 2736 | error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE, |
2858 | dir_vp, DM_RIGHT_NULL, NULL, | 2737 | dir_vp, DM_RIGHT_NULL, NULL, |
2859 | DM_RIGHT_NULL, dir_name, NULL, | 2738 | DM_RIGHT_NULL, dir_name, NULL, |
2860 | dm_di_mode, 0, 0); | 2739 | mode, 0, 0); |
2861 | if (error) | 2740 | if (error) |
2862 | return error; | 2741 | return error; |
2863 | dm_event_sent = 1; | 2742 | dm_event_sent = 1; |
@@ -2865,14 +2744,12 @@ xfs_mkdir( | |||
2865 | 2744 | ||
2866 | /* Return through std_return after this point. */ | 2745 | /* Return through std_return after this point. */ |
2867 | 2746 | ||
2868 | vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); | 2747 | vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address); |
2869 | 2748 | ||
2870 | mp = dp->i_mount; | 2749 | mp = dp->i_mount; |
2871 | udqp = gdqp = NULL; | 2750 | udqp = gdqp = NULL; |
2872 | if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) | 2751 | if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) |
2873 | prid = dp->i_d.di_projid; | 2752 | prid = dp->i_d.di_projid; |
2874 | else if (vap->va_mask & XFS_AT_PROJID) | ||
2875 | prid = (xfs_prid_t)vap->va_projid; | ||
2876 | else | 2753 | else |
2877 | prid = (xfs_prid_t)dfltprid; | 2754 | prid = (xfs_prid_t)dfltprid; |
2878 | 2755 | ||
@@ -2898,11 +2775,11 @@ xfs_mkdir( | |||
2898 | } | 2775 | } |
2899 | if (error) { | 2776 | if (error) { |
2900 | cancel_flags = 0; | 2777 | cancel_flags = 0; |
2901 | dp = NULL; | ||
2902 | goto error_return; | 2778 | goto error_return; |
2903 | } | 2779 | } |
2904 | 2780 | ||
2905 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); | 2781 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); |
2782 | unlock_dp_on_error = B_TRUE; | ||
2906 | 2783 | ||
2907 | /* | 2784 | /* |
2908 | * Check for directory link count overflow. | 2785 | * Check for directory link count overflow. |
@@ -2925,7 +2802,7 @@ xfs_mkdir( | |||
2925 | /* | 2802 | /* |
2926 | * create the directory inode. | 2803 | * create the directory inode. |
2927 | */ | 2804 | */ |
2928 | error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 2, | 2805 | error = xfs_dir_ialloc(&tp, dp, mode, 2, |
2929 | 0, credp, prid, resblks > 0, | 2806 | 0, credp, prid, resblks > 0, |
2930 | &cdp, NULL); | 2807 | &cdp, NULL); |
2931 | if (error) { | 2808 | if (error) { |
@@ -2939,11 +2816,13 @@ xfs_mkdir( | |||
2939 | * Now we add the directory inode to the transaction. | 2816 | * Now we add the directory inode to the transaction. |
2940 | * We waited until now since xfs_dir_ialloc might start | 2817 | * We waited until now since xfs_dir_ialloc might start |
2941 | * a new transaction. Had we joined the transaction | 2818 | * a new transaction. Had we joined the transaction |
2942 | * earlier, the locks might have gotten released. | 2819 | * earlier, the locks might have gotten released. An error |
2820 | * from here on will result in the transaction cancel | ||
2821 | * unlocking dp so don't do it explicitly in the error path. | ||
2943 | */ | 2822 | */ |
2944 | VN_HOLD(dir_vp); | 2823 | VN_HOLD(dir_vp); |
2945 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); | 2824 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); |
2946 | dp_joined_to_trans = B_TRUE; | 2825 | unlock_dp_on_error = B_FALSE; |
2947 | 2826 | ||
2948 | XFS_BMAP_INIT(&free_list, &first_block); | 2827 | XFS_BMAP_INIT(&free_list, &first_block); |
2949 | 2828 | ||
@@ -3010,15 +2889,14 @@ xfs_mkdir( | |||
3010 | * xfs_trans_commit. */ | 2889 | * xfs_trans_commit. */ |
3011 | 2890 | ||
3012 | std_return: | 2891 | std_return: |
3013 | if ( (created || (error != 0 && dm_event_sent != 0)) && | 2892 | if ((created || (error != 0 && dm_event_sent != 0)) && |
3014 | DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp), | 2893 | DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) { |
3015 | DM_EVENT_POSTCREATE)) { | ||
3016 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, | 2894 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, |
3017 | dir_vp, DM_RIGHT_NULL, | 2895 | dir_vp, DM_RIGHT_NULL, |
3018 | created ? XFS_ITOV(cdp):NULL, | 2896 | created ? XFS_ITOV(cdp):NULL, |
3019 | DM_RIGHT_NULL, | 2897 | DM_RIGHT_NULL, |
3020 | dir_name, NULL, | 2898 | dir_name, NULL, |
3021 | dm_di_mode, error, 0); | 2899 | mode, error, 0); |
3022 | } | 2900 | } |
3023 | return error; | 2901 | return error; |
3024 | 2902 | ||
@@ -3032,56 +2910,43 @@ std_return: | |||
3032 | XFS_QM_DQRELE(mp, udqp); | 2910 | XFS_QM_DQRELE(mp, udqp); |
3033 | XFS_QM_DQRELE(mp, gdqp); | 2911 | XFS_QM_DQRELE(mp, gdqp); |
3034 | 2912 | ||
3035 | if (!dp_joined_to_trans && (dp != NULL)) { | 2913 | if (unlock_dp_on_error) |
3036 | xfs_iunlock(dp, XFS_ILOCK_EXCL); | 2914 | xfs_iunlock(dp, XFS_ILOCK_EXCL); |
3037 | } | ||
3038 | 2915 | ||
3039 | goto std_return; | 2916 | goto std_return; |
3040 | } | 2917 | } |
3041 | 2918 | ||
3042 | 2919 | int | |
3043 | /* | ||
3044 | * xfs_rmdir | ||
3045 | * | ||
3046 | */ | ||
3047 | STATIC int | ||
3048 | xfs_rmdir( | 2920 | xfs_rmdir( |
3049 | bhv_desc_t *dir_bdp, | 2921 | xfs_inode_t *dp, |
3050 | bhv_vname_t *dentry, | 2922 | bhv_vname_t *dentry) |
3051 | cred_t *credp) | ||
3052 | { | 2923 | { |
2924 | bhv_vnode_t *dir_vp = XFS_ITOV(dp); | ||
3053 | char *name = VNAME(dentry); | 2925 | char *name = VNAME(dentry); |
3054 | xfs_inode_t *dp; | 2926 | int namelen = VNAMELEN(dentry); |
3055 | xfs_inode_t *cdp; /* child directory */ | 2927 | xfs_mount_t *mp = dp->i_mount; |
2928 | xfs_inode_t *cdp; /* child directory */ | ||
3056 | xfs_trans_t *tp; | 2929 | xfs_trans_t *tp; |
3057 | xfs_mount_t *mp; | ||
3058 | int error; | 2930 | int error; |
3059 | xfs_bmap_free_t free_list; | 2931 | xfs_bmap_free_t free_list; |
3060 | xfs_fsblock_t first_block; | 2932 | xfs_fsblock_t first_block; |
3061 | int cancel_flags; | 2933 | int cancel_flags; |
3062 | int committed; | 2934 | int committed; |
3063 | bhv_vnode_t *dir_vp; | ||
3064 | int dm_di_mode = S_IFDIR; | 2935 | int dm_di_mode = S_IFDIR; |
3065 | int last_cdp_link; | 2936 | int last_cdp_link; |
3066 | int namelen; | ||
3067 | uint resblks; | 2937 | uint resblks; |
3068 | 2938 | ||
3069 | dir_vp = BHV_TO_VNODE(dir_bdp); | 2939 | vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address); |
3070 | dp = XFS_BHVTOI(dir_bdp); | ||
3071 | mp = dp->i_mount; | ||
3072 | |||
3073 | vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); | ||
3074 | 2940 | ||
3075 | if (XFS_FORCED_SHUTDOWN(XFS_BHVTOI(dir_bdp)->i_mount)) | 2941 | if (XFS_FORCED_SHUTDOWN(mp)) |
3076 | return XFS_ERROR(EIO); | 2942 | return XFS_ERROR(EIO); |
3077 | namelen = VNAMELEN(dentry); | ||
3078 | 2943 | ||
3079 | if (!xfs_get_dir_entry(dentry, &cdp)) { | 2944 | if (!xfs_get_dir_entry(dentry, &cdp)) { |
3080 | dm_di_mode = cdp->i_d.di_mode; | 2945 | dm_di_mode = cdp->i_d.di_mode; |
3081 | IRELE(cdp); | 2946 | IRELE(cdp); |
3082 | } | 2947 | } |
3083 | 2948 | ||
3084 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) { | 2949 | if (DM_EVENT_ENABLED(dp, DM_EVENT_REMOVE)) { |
3085 | error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, | 2950 | error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, |
3086 | dir_vp, DM_RIGHT_NULL, | 2951 | dir_vp, DM_RIGHT_NULL, |
3087 | NULL, DM_RIGHT_NULL, | 2952 | NULL, DM_RIGHT_NULL, |
@@ -3260,17 +3125,12 @@ xfs_rmdir( | |||
3260 | } | 3125 | } |
3261 | 3126 | ||
3262 | 3127 | ||
3263 | /* | ||
3264 | * Let interposed file systems know about removed links. | ||
3265 | */ | ||
3266 | bhv_vop_link_removed(XFS_ITOV(cdp), dir_vp, last_cdp_link); | ||
3267 | |||
3268 | IRELE(cdp); | 3128 | IRELE(cdp); |
3269 | 3129 | ||
3270 | /* Fall through to std_return with error = 0 or the errno | 3130 | /* Fall through to std_return with error = 0 or the errno |
3271 | * from xfs_trans_commit. */ | 3131 | * from xfs_trans_commit. */ |
3272 | std_return: | 3132 | std_return: |
3273 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_POSTREMOVE)) { | 3133 | if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTREMOVE)) { |
3274 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE, | 3134 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE, |
3275 | dir_vp, DM_RIGHT_NULL, | 3135 | dir_vp, DM_RIGHT_NULL, |
3276 | NULL, DM_RIGHT_NULL, | 3136 | NULL, DM_RIGHT_NULL, |
@@ -3289,56 +3149,24 @@ xfs_rmdir( | |||
3289 | goto std_return; | 3149 | goto std_return; |
3290 | } | 3150 | } |
3291 | 3151 | ||
3292 | 3152 | int | |
3293 | /* | ||
3294 | * Read dp's entries starting at uiop->uio_offset and translate them into | ||
3295 | * bufsize bytes worth of struct dirents starting at bufbase. | ||
3296 | */ | ||
3297 | STATIC int | ||
3298 | xfs_readdir( | ||
3299 | bhv_desc_t *dir_bdp, | ||
3300 | uio_t *uiop, | ||
3301 | cred_t *credp, | ||
3302 | int *eofp) | ||
3303 | { | ||
3304 | xfs_inode_t *dp; | ||
3305 | xfs_trans_t *tp = NULL; | ||
3306 | int error = 0; | ||
3307 | uint lock_mode; | ||
3308 | |||
3309 | vn_trace_entry(BHV_TO_VNODE(dir_bdp), __FUNCTION__, | ||
3310 | (inst_t *)__return_address); | ||
3311 | dp = XFS_BHVTOI(dir_bdp); | ||
3312 | |||
3313 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) | ||
3314 | return XFS_ERROR(EIO); | ||
3315 | |||
3316 | lock_mode = xfs_ilock_map_shared(dp); | ||
3317 | error = xfs_dir_getdents(tp, dp, uiop, eofp); | ||
3318 | xfs_iunlock_map_shared(dp, lock_mode); | ||
3319 | return error; | ||
3320 | } | ||
3321 | |||
3322 | |||
3323 | STATIC int | ||
3324 | xfs_symlink( | 3153 | xfs_symlink( |
3325 | bhv_desc_t *dir_bdp, | 3154 | xfs_inode_t *dp, |
3326 | bhv_vname_t *dentry, | 3155 | bhv_vname_t *dentry, |
3327 | bhv_vattr_t *vap, | ||
3328 | char *target_path, | 3156 | char *target_path, |
3157 | mode_t mode, | ||
3329 | bhv_vnode_t **vpp, | 3158 | bhv_vnode_t **vpp, |
3330 | cred_t *credp) | 3159 | cred_t *credp) |
3331 | { | 3160 | { |
3161 | bhv_vnode_t *dir_vp = XFS_ITOV(dp); | ||
3162 | xfs_mount_t *mp = dp->i_mount; | ||
3332 | xfs_trans_t *tp; | 3163 | xfs_trans_t *tp; |
3333 | xfs_mount_t *mp; | ||
3334 | xfs_inode_t *dp; | ||
3335 | xfs_inode_t *ip; | 3164 | xfs_inode_t *ip; |
3336 | int error; | 3165 | int error; |
3337 | int pathlen; | 3166 | int pathlen; |
3338 | xfs_bmap_free_t free_list; | 3167 | xfs_bmap_free_t free_list; |
3339 | xfs_fsblock_t first_block; | 3168 | xfs_fsblock_t first_block; |
3340 | boolean_t dp_joined_to_trans; | 3169 | boolean_t unlock_dp_on_error = B_FALSE; |
3341 | bhv_vnode_t *dir_vp; | ||
3342 | uint cancel_flags; | 3170 | uint cancel_flags; |
3343 | int committed; | 3171 | int committed; |
3344 | xfs_fileoff_t first_fsb; | 3172 | xfs_fileoff_t first_fsb; |
@@ -3357,16 +3185,12 @@ xfs_symlink( | |||
3357 | int link_namelen; | 3185 | int link_namelen; |
3358 | 3186 | ||
3359 | *vpp = NULL; | 3187 | *vpp = NULL; |
3360 | dir_vp = BHV_TO_VNODE(dir_bdp); | ||
3361 | dp = XFS_BHVTOI(dir_bdp); | ||
3362 | dp_joined_to_trans = B_FALSE; | ||
3363 | error = 0; | 3188 | error = 0; |
3364 | ip = NULL; | 3189 | ip = NULL; |
3365 | tp = NULL; | 3190 | tp = NULL; |
3366 | 3191 | ||
3367 | vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); | 3192 | vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address); |
3368 | 3193 | ||
3369 | mp = dp->i_mount; | ||
3370 | 3194 | ||
3371 | if (XFS_FORCED_SHUTDOWN(mp)) | 3195 | if (XFS_FORCED_SHUTDOWN(mp)) |
3372 | return XFS_ERROR(EIO); | 3196 | return XFS_ERROR(EIO); |
@@ -3405,7 +3229,7 @@ xfs_symlink( | |||
3405 | } | 3229 | } |
3406 | } | 3230 | } |
3407 | 3231 | ||
3408 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_SYMLINK)) { | 3232 | if (DM_EVENT_ENABLED(dp, DM_EVENT_SYMLINK)) { |
3409 | error = XFS_SEND_NAMESP(mp, DM_EVENT_SYMLINK, dir_vp, | 3233 | error = XFS_SEND_NAMESP(mp, DM_EVENT_SYMLINK, dir_vp, |
3410 | DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, | 3234 | DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, |
3411 | link_name, target_path, 0, 0, 0); | 3235 | link_name, target_path, 0, 0, 0); |
@@ -3418,8 +3242,6 @@ xfs_symlink( | |||
3418 | udqp = gdqp = NULL; | 3242 | udqp = gdqp = NULL; |
3419 | if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) | 3243 | if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) |
3420 | prid = dp->i_d.di_projid; | 3244 | prid = dp->i_d.di_projid; |
3421 | else if (vap->va_mask & XFS_AT_PROJID) | ||
3422 | prid = (xfs_prid_t)vap->va_projid; | ||
3423 | else | 3245 | else |
3424 | prid = (xfs_prid_t)dfltprid; | 3246 | prid = (xfs_prid_t)dfltprid; |
3425 | 3247 | ||
@@ -3452,11 +3274,11 @@ xfs_symlink( | |||
3452 | } | 3274 | } |
3453 | if (error) { | 3275 | if (error) { |
3454 | cancel_flags = 0; | 3276 | cancel_flags = 0; |
3455 | dp = NULL; | ||
3456 | goto error_return; | 3277 | goto error_return; |
3457 | } | 3278 | } |
3458 | 3279 | ||
3459 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); | 3280 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); |
3281 | unlock_dp_on_error = B_TRUE; | ||
3460 | 3282 | ||
3461 | /* | 3283 | /* |
3462 | * Check whether the directory allows new symlinks or not. | 3284 | * Check whether the directory allows new symlinks or not. |
@@ -3488,7 +3310,7 @@ xfs_symlink( | |||
3488 | /* | 3310 | /* |
3489 | * Allocate an inode for the symlink. | 3311 | * Allocate an inode for the symlink. |
3490 | */ | 3312 | */ |
3491 | error = xfs_dir_ialloc(&tp, dp, S_IFLNK | (vap->va_mode&~S_IFMT), | 3313 | error = xfs_dir_ialloc(&tp, dp, S_IFLNK | (mode & ~S_IFMT), |
3492 | 1, 0, credp, prid, resblks > 0, &ip, NULL); | 3314 | 1, 0, credp, prid, resblks > 0, &ip, NULL); |
3493 | if (error) { | 3315 | if (error) { |
3494 | if (error == ENOSPC) | 3316 | if (error == ENOSPC) |
@@ -3497,9 +3319,14 @@ xfs_symlink( | |||
3497 | } | 3319 | } |
3498 | ITRACE(ip); | 3320 | ITRACE(ip); |
3499 | 3321 | ||
3322 | /* | ||
3323 | * An error after we've joined dp to the transaction will result in the | ||
3324 | * transaction cancel unlocking dp so don't do it explicitly in the | ||
3325 | * error path. | ||
3326 | */ | ||
3500 | VN_HOLD(dir_vp); | 3327 | VN_HOLD(dir_vp); |
3501 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); | 3328 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); |
3502 | dp_joined_to_trans = B_TRUE; | 3329 | unlock_dp_on_error = B_FALSE; |
3503 | 3330 | ||
3504 | /* | 3331 | /* |
3505 | * Also attach the dquot(s) to it, if applicable. | 3332 | * Also attach the dquot(s) to it, if applicable. |
@@ -3605,8 +3432,7 @@ xfs_symlink( | |||
3605 | /* Fall through to std_return with error = 0 or errno from | 3432 | /* Fall through to std_return with error = 0 or errno from |
3606 | * xfs_trans_commit */ | 3433 | * xfs_trans_commit */ |
3607 | std_return: | 3434 | std_return: |
3608 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp), | 3435 | if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTSYMLINK)) { |
3609 | DM_EVENT_POSTSYMLINK)) { | ||
3610 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTSYMLINK, | 3436 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTSYMLINK, |
3611 | dir_vp, DM_RIGHT_NULL, | 3437 | dir_vp, DM_RIGHT_NULL, |
3612 | error ? NULL : XFS_ITOV(ip), | 3438 | error ? NULL : XFS_ITOV(ip), |
@@ -3633,9 +3459,8 @@ std_return: | |||
3633 | XFS_QM_DQRELE(mp, udqp); | 3459 | XFS_QM_DQRELE(mp, udqp); |
3634 | XFS_QM_DQRELE(mp, gdqp); | 3460 | XFS_QM_DQRELE(mp, gdqp); |
3635 | 3461 | ||
3636 | if (!dp_joined_to_trans && (dp != NULL)) { | 3462 | if (unlock_dp_on_error) |
3637 | xfs_iunlock(dp, XFS_ILOCK_EXCL); | 3463 | xfs_iunlock(dp, XFS_ILOCK_EXCL); |
3638 | } | ||
3639 | 3464 | ||
3640 | goto std_return; | 3465 | goto std_return; |
3641 | } | 3466 | } |
@@ -3647,20 +3472,16 @@ std_return: | |||
3647 | * A fid routine that takes a pointer to a previously allocated | 3472 | * A fid routine that takes a pointer to a previously allocated |
3648 | * fid structure (like xfs_fast_fid) but uses a 64 bit inode number. | 3473 | * fid structure (like xfs_fast_fid) but uses a 64 bit inode number. |
3649 | */ | 3474 | */ |
3650 | STATIC int | 3475 | int |
3651 | xfs_fid2( | 3476 | xfs_fid2( |
3652 | bhv_desc_t *bdp, | 3477 | xfs_inode_t *ip, |
3653 | fid_t *fidp) | 3478 | fid_t *fidp) |
3654 | { | 3479 | { |
3655 | xfs_inode_t *ip; | 3480 | xfs_fid2_t *xfid = (xfs_fid2_t *)fidp; |
3656 | xfs_fid2_t *xfid; | ||
3657 | 3481 | ||
3658 | vn_trace_entry(BHV_TO_VNODE(bdp), __FUNCTION__, | 3482 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); |
3659 | (inst_t *)__return_address); | ||
3660 | ASSERT(sizeof(fid_t) >= sizeof(xfs_fid2_t)); | 3483 | ASSERT(sizeof(fid_t) >= sizeof(xfs_fid2_t)); |
3661 | 3484 | ||
3662 | xfid = (xfs_fid2_t *)fidp; | ||
3663 | ip = XFS_BHVTOI(bdp); | ||
3664 | xfid->fid_len = sizeof(xfs_fid2_t) - sizeof(xfid->fid_len); | 3485 | xfid->fid_len = sizeof(xfs_fid2_t) - sizeof(xfid->fid_len); |
3665 | xfid->fid_pad = 0; | 3486 | xfid->fid_pad = 0; |
3666 | /* | 3487 | /* |
@@ -3674,21 +3495,13 @@ xfs_fid2( | |||
3674 | } | 3495 | } |
3675 | 3496 | ||
3676 | 3497 | ||
3677 | /* | ||
3678 | * xfs_rwlock | ||
3679 | */ | ||
3680 | int | 3498 | int |
3681 | xfs_rwlock( | 3499 | xfs_rwlock( |
3682 | bhv_desc_t *bdp, | 3500 | xfs_inode_t *ip, |
3683 | bhv_vrwlock_t locktype) | 3501 | bhv_vrwlock_t locktype) |
3684 | { | 3502 | { |
3685 | xfs_inode_t *ip; | 3503 | if (S_ISDIR(ip->i_d.di_mode)) |
3686 | bhv_vnode_t *vp; | ||
3687 | |||
3688 | vp = BHV_TO_VNODE(bdp); | ||
3689 | if (VN_ISDIR(vp)) | ||
3690 | return 1; | 3504 | return 1; |
3691 | ip = XFS_BHVTOI(bdp); | ||
3692 | if (locktype == VRWLOCK_WRITE) { | 3505 | if (locktype == VRWLOCK_WRITE) { |
3693 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | 3506 | xfs_ilock(ip, XFS_IOLOCK_EXCL); |
3694 | } else if (locktype == VRWLOCK_TRY_READ) { | 3507 | } else if (locktype == VRWLOCK_TRY_READ) { |
@@ -3705,21 +3518,13 @@ xfs_rwlock( | |||
3705 | } | 3518 | } |
3706 | 3519 | ||
3707 | 3520 | ||
3708 | /* | ||
3709 | * xfs_rwunlock | ||
3710 | */ | ||
3711 | void | 3521 | void |
3712 | xfs_rwunlock( | 3522 | xfs_rwunlock( |
3713 | bhv_desc_t *bdp, | 3523 | xfs_inode_t *ip, |
3714 | bhv_vrwlock_t locktype) | 3524 | bhv_vrwlock_t locktype) |
3715 | { | 3525 | { |
3716 | xfs_inode_t *ip; | 3526 | if (S_ISDIR(ip->i_d.di_mode)) |
3717 | bhv_vnode_t *vp; | 3527 | return; |
3718 | |||
3719 | vp = BHV_TO_VNODE(bdp); | ||
3720 | if (VN_ISDIR(vp)) | ||
3721 | return; | ||
3722 | ip = XFS_BHVTOI(bdp); | ||
3723 | if (locktype == VRWLOCK_WRITE) { | 3528 | if (locktype == VRWLOCK_WRITE) { |
3724 | /* | 3529 | /* |
3725 | * In the write case, we may have added a new entry to | 3530 | * In the write case, we may have added a new entry to |
@@ -3737,20 +3542,16 @@ xfs_rwunlock( | |||
3737 | return; | 3542 | return; |
3738 | } | 3543 | } |
3739 | 3544 | ||
3740 | STATIC int | 3545 | |
3546 | int | ||
3741 | xfs_inode_flush( | 3547 | xfs_inode_flush( |
3742 | bhv_desc_t *bdp, | 3548 | xfs_inode_t *ip, |
3743 | int flags) | 3549 | int flags) |
3744 | { | 3550 | { |
3745 | xfs_inode_t *ip; | 3551 | xfs_mount_t *mp = ip->i_mount; |
3746 | xfs_mount_t *mp; | 3552 | xfs_inode_log_item_t *iip = ip->i_itemp; |
3747 | xfs_inode_log_item_t *iip; | ||
3748 | int error = 0; | 3553 | int error = 0; |
3749 | 3554 | ||
3750 | ip = XFS_BHVTOI(bdp); | ||
3751 | mp = ip->i_mount; | ||
3752 | iip = ip->i_itemp; | ||
3753 | |||
3754 | if (XFS_FORCED_SHUTDOWN(mp)) | 3555 | if (XFS_FORCED_SHUTDOWN(mp)) |
3755 | return XFS_ERROR(EIO); | 3556 | return XFS_ERROR(EIO); |
3756 | 3557 | ||
@@ -3819,24 +3620,20 @@ xfs_inode_flush( | |||
3819 | return error; | 3620 | return error; |
3820 | } | 3621 | } |
3821 | 3622 | ||
3623 | |||
3822 | int | 3624 | int |
3823 | xfs_set_dmattrs ( | 3625 | xfs_set_dmattrs( |
3824 | bhv_desc_t *bdp, | 3626 | xfs_inode_t *ip, |
3825 | u_int evmask, | 3627 | u_int evmask, |
3826 | u_int16_t state, | 3628 | u_int16_t state) |
3827 | cred_t *credp) | ||
3828 | { | 3629 | { |
3829 | xfs_inode_t *ip; | 3630 | xfs_mount_t *mp = ip->i_mount; |
3830 | xfs_trans_t *tp; | 3631 | xfs_trans_t *tp; |
3831 | xfs_mount_t *mp; | ||
3832 | int error; | 3632 | int error; |
3833 | 3633 | ||
3834 | if (!capable(CAP_SYS_ADMIN)) | 3634 | if (!capable(CAP_SYS_ADMIN)) |
3835 | return XFS_ERROR(EPERM); | 3635 | return XFS_ERROR(EPERM); |
3836 | 3636 | ||
3837 | ip = XFS_BHVTOI(bdp); | ||
3838 | mp = ip->i_mount; | ||
3839 | |||
3840 | if (XFS_FORCED_SHUTDOWN(mp)) | 3637 | if (XFS_FORCED_SHUTDOWN(mp)) |
3841 | return XFS_ERROR(EIO); | 3638 | return XFS_ERROR(EIO); |
3842 | 3639 | ||
@@ -3859,17 +3656,13 @@ xfs_set_dmattrs ( | |||
3859 | return error; | 3656 | return error; |
3860 | } | 3657 | } |
3861 | 3658 | ||
3862 | STATIC int | 3659 | int |
3863 | xfs_reclaim( | 3660 | xfs_reclaim( |
3864 | bhv_desc_t *bdp) | 3661 | xfs_inode_t *ip) |
3865 | { | 3662 | { |
3866 | xfs_inode_t *ip; | 3663 | bhv_vnode_t *vp = XFS_ITOV(ip); |
3867 | bhv_vnode_t *vp; | ||
3868 | |||
3869 | vp = BHV_TO_VNODE(bdp); | ||
3870 | ip = XFS_BHVTOI(bdp); | ||
3871 | 3664 | ||
3872 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | 3665 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); |
3873 | 3666 | ||
3874 | ASSERT(!VN_MAPPED(vp)); | 3667 | ASSERT(!VN_MAPPED(vp)); |
3875 | 3668 | ||
@@ -3879,7 +3672,7 @@ xfs_reclaim( | |||
3879 | return 0; | 3672 | return 0; |
3880 | } | 3673 | } |
3881 | 3674 | ||
3882 | vn_iowait(vp); | 3675 | vn_iowait(ip); |
3883 | 3676 | ||
3884 | ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0); | 3677 | ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0); |
3885 | 3678 | ||
@@ -3911,7 +3704,8 @@ xfs_reclaim( | |||
3911 | XFS_MOUNT_ILOCK(mp); | 3704 | XFS_MOUNT_ILOCK(mp); |
3912 | spin_lock(&ip->i_flags_lock); | 3705 | spin_lock(&ip->i_flags_lock); |
3913 | __xfs_iflags_set(ip, XFS_IRECLAIMABLE); | 3706 | __xfs_iflags_set(ip, XFS_IRECLAIMABLE); |
3914 | vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip)); | 3707 | vn_to_inode(vp)->i_private = NULL; |
3708 | ip->i_vnode = NULL; | ||
3915 | spin_unlock(&ip->i_flags_lock); | 3709 | spin_unlock(&ip->i_flags_lock); |
3916 | list_add_tail(&ip->i_reclaim, &mp->m_del_inodes); | 3710 | list_add_tail(&ip->i_reclaim, &mp->m_del_inodes); |
3917 | XFS_MOUNT_IUNLOCK(mp); | 3711 | XFS_MOUNT_IUNLOCK(mp); |
@@ -3925,7 +3719,7 @@ xfs_finish_reclaim( | |||
3925 | int locked, | 3719 | int locked, |
3926 | int sync_mode) | 3720 | int sync_mode) |
3927 | { | 3721 | { |
3928 | xfs_ihash_t *ih = ip->i_hash; | 3722 | xfs_perag_t *pag = xfs_get_perag(ip->i_mount, ip->i_ino); |
3929 | bhv_vnode_t *vp = XFS_ITOV_NULL(ip); | 3723 | bhv_vnode_t *vp = XFS_ITOV_NULL(ip); |
3930 | int error; | 3724 | int error; |
3931 | 3725 | ||
@@ -3937,12 +3731,12 @@ xfs_finish_reclaim( | |||
3937 | * Once we have the XFS_IRECLAIM flag set it will not touch | 3731 | * Once we have the XFS_IRECLAIM flag set it will not touch |
3938 | * us. | 3732 | * us. |
3939 | */ | 3733 | */ |
3940 | write_lock(&ih->ih_lock); | 3734 | write_lock(&pag->pag_ici_lock); |
3941 | spin_lock(&ip->i_flags_lock); | 3735 | spin_lock(&ip->i_flags_lock); |
3942 | if (__xfs_iflags_test(ip, XFS_IRECLAIM) || | 3736 | if (__xfs_iflags_test(ip, XFS_IRECLAIM) || |
3943 | (!__xfs_iflags_test(ip, XFS_IRECLAIMABLE) && vp == NULL)) { | 3737 | (!__xfs_iflags_test(ip, XFS_IRECLAIMABLE) && vp == NULL)) { |
3944 | spin_unlock(&ip->i_flags_lock); | 3738 | spin_unlock(&ip->i_flags_lock); |
3945 | write_unlock(&ih->ih_lock); | 3739 | write_unlock(&pag->pag_ici_lock); |
3946 | if (locked) { | 3740 | if (locked) { |
3947 | xfs_ifunlock(ip); | 3741 | xfs_ifunlock(ip); |
3948 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 3742 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
@@ -3951,7 +3745,8 @@ xfs_finish_reclaim( | |||
3951 | } | 3745 | } |
3952 | __xfs_iflags_set(ip, XFS_IRECLAIM); | 3746 | __xfs_iflags_set(ip, XFS_IRECLAIM); |
3953 | spin_unlock(&ip->i_flags_lock); | 3747 | spin_unlock(&ip->i_flags_lock); |
3954 | write_unlock(&ih->ih_lock); | 3748 | write_unlock(&pag->pag_ici_lock); |
3749 | xfs_put_perag(ip->i_mount, pag); | ||
3955 | 3750 | ||
3956 | /* | 3751 | /* |
3957 | * If the inode is still dirty, then flush it out. If the inode | 3752 | * If the inode is still dirty, then flush it out. If the inode |
@@ -4085,7 +3880,7 @@ xfs_alloc_file_space( | |||
4085 | int committed; | 3880 | int committed; |
4086 | int error; | 3881 | int error; |
4087 | 3882 | ||
4088 | vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); | 3883 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); |
4089 | 3884 | ||
4090 | if (XFS_FORCED_SHUTDOWN(mp)) | 3885 | if (XFS_FORCED_SHUTDOWN(mp)) |
4091 | return XFS_ERROR(EIO); | 3886 | return XFS_ERROR(EIO); |
@@ -4109,7 +3904,7 @@ xfs_alloc_file_space( | |||
4109 | /* Generate a DMAPI event if needed. */ | 3904 | /* Generate a DMAPI event if needed. */ |
4110 | if (alloc_type != 0 && offset < ip->i_size && | 3905 | if (alloc_type != 0 && offset < ip->i_size && |
4111 | (attr_flags&ATTR_DMI) == 0 && | 3906 | (attr_flags&ATTR_DMI) == 0 && |
4112 | DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) { | 3907 | DM_EVENT_ENABLED(ip, DM_EVENT_WRITE)) { |
4113 | xfs_off_t end_dmi_offset; | 3908 | xfs_off_t end_dmi_offset; |
4114 | 3909 | ||
4115 | end_dmi_offset = offset+len; | 3910 | end_dmi_offset = offset+len; |
@@ -4223,9 +4018,8 @@ retry: | |||
4223 | allocatesize_fsb -= allocated_fsb; | 4018 | allocatesize_fsb -= allocated_fsb; |
4224 | } | 4019 | } |
4225 | dmapi_enospc_check: | 4020 | dmapi_enospc_check: |
4226 | if (error == ENOSPC && (attr_flags&ATTR_DMI) == 0 && | 4021 | if (error == ENOSPC && (attr_flags & ATTR_DMI) == 0 && |
4227 | DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_NOSPACE)) { | 4022 | DM_EVENT_ENABLED(ip, DM_EVENT_NOSPACE)) { |
4228 | |||
4229 | error = XFS_SEND_NAMESP(mp, DM_EVENT_NOSPACE, | 4023 | error = XFS_SEND_NAMESP(mp, DM_EVENT_NOSPACE, |
4230 | XFS_ITOV(ip), DM_RIGHT_NULL, | 4024 | XFS_ITOV(ip), DM_RIGHT_NULL, |
4231 | XFS_ITOV(ip), DM_RIGHT_NULL, | 4025 | XFS_ITOV(ip), DM_RIGHT_NULL, |
@@ -4356,7 +4150,7 @@ xfs_free_file_space( | |||
4356 | vp = XFS_ITOV(ip); | 4150 | vp = XFS_ITOV(ip); |
4357 | mp = ip->i_mount; | 4151 | mp = ip->i_mount; |
4358 | 4152 | ||
4359 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | 4153 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); |
4360 | 4154 | ||
4361 | if ((error = XFS_QM_DQATTACH(mp, ip, 0))) | 4155 | if ((error = XFS_QM_DQATTACH(mp, ip, 0))) |
4362 | return error; | 4156 | return error; |
@@ -4369,9 +4163,8 @@ xfs_free_file_space( | |||
4369 | end_dmi_offset = offset + len; | 4163 | end_dmi_offset = offset + len; |
4370 | endoffset_fsb = XFS_B_TO_FSBT(mp, end_dmi_offset); | 4164 | endoffset_fsb = XFS_B_TO_FSBT(mp, end_dmi_offset); |
4371 | 4165 | ||
4372 | if (offset < ip->i_size && | 4166 | if (offset < ip->i_size && (attr_flags & ATTR_DMI) == 0 && |
4373 | (attr_flags & ATTR_DMI) == 0 && | 4167 | DM_EVENT_ENABLED(ip, DM_EVENT_WRITE)) { |
4374 | DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) { | ||
4375 | if (end_dmi_offset > ip->i_size) | 4168 | if (end_dmi_offset > ip->i_size) |
4376 | end_dmi_offset = ip->i_size; | 4169 | end_dmi_offset = ip->i_size; |
4377 | error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, vp, | 4170 | error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, vp, |
@@ -4385,7 +4178,7 @@ xfs_free_file_space( | |||
4385 | need_iolock = 0; | 4178 | need_iolock = 0; |
4386 | if (need_iolock) { | 4179 | if (need_iolock) { |
4387 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | 4180 | xfs_ilock(ip, XFS_IOLOCK_EXCL); |
4388 | vn_iowait(vp); /* wait for the completion of any pending DIOs */ | 4181 | vn_iowait(ip); /* wait for the completion of any pending DIOs */ |
4389 | } | 4182 | } |
4390 | 4183 | ||
4391 | rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, NBPP); | 4184 | rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, NBPP); |
@@ -4394,7 +4187,8 @@ xfs_free_file_space( | |||
4394 | if (VN_CACHED(vp) != 0) { | 4187 | if (VN_CACHED(vp) != 0) { |
4395 | xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1, | 4188 | xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1, |
4396 | ctooff(offtoct(ioffset)), -1); | 4189 | ctooff(offtoct(ioffset)), -1); |
4397 | error = bhv_vop_flushinval_pages(vp, ctooff(offtoct(ioffset)), | 4190 | error = xfs_flushinval_pages(ip, |
4191 | ctooff(offtoct(ioffset)), | ||
4398 | -1, FI_REMAPF_LOCKED); | 4192 | -1, FI_REMAPF_LOCKED); |
4399 | if (error) | 4193 | if (error) |
4400 | goto out_unlock_iolock; | 4194 | goto out_unlock_iolock; |
@@ -4545,35 +4339,29 @@ xfs_free_file_space( | |||
4545 | */ | 4339 | */ |
4546 | int | 4340 | int |
4547 | xfs_change_file_space( | 4341 | xfs_change_file_space( |
4548 | bhv_desc_t *bdp, | 4342 | xfs_inode_t *ip, |
4549 | int cmd, | 4343 | int cmd, |
4550 | xfs_flock64_t *bf, | 4344 | xfs_flock64_t *bf, |
4551 | xfs_off_t offset, | 4345 | xfs_off_t offset, |
4552 | cred_t *credp, | 4346 | cred_t *credp, |
4553 | int attr_flags) | 4347 | int attr_flags) |
4554 | { | 4348 | { |
4349 | xfs_mount_t *mp = ip->i_mount; | ||
4555 | int clrprealloc; | 4350 | int clrprealloc; |
4556 | int error; | 4351 | int error; |
4557 | xfs_fsize_t fsize; | 4352 | xfs_fsize_t fsize; |
4558 | xfs_inode_t *ip; | ||
4559 | xfs_mount_t *mp; | ||
4560 | int setprealloc; | 4353 | int setprealloc; |
4561 | xfs_off_t startoffset; | 4354 | xfs_off_t startoffset; |
4562 | xfs_off_t llen; | 4355 | xfs_off_t llen; |
4563 | xfs_trans_t *tp; | 4356 | xfs_trans_t *tp; |
4564 | bhv_vattr_t va; | 4357 | bhv_vattr_t va; |
4565 | bhv_vnode_t *vp; | ||
4566 | 4358 | ||
4567 | vp = BHV_TO_VNODE(bdp); | 4359 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); |
4568 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | ||
4569 | |||
4570 | ip = XFS_BHVTOI(bdp); | ||
4571 | mp = ip->i_mount; | ||
4572 | 4360 | ||
4573 | /* | 4361 | /* |
4574 | * must be a regular file and have write permission | 4362 | * must be a regular file and have write permission |
4575 | */ | 4363 | */ |
4576 | if (!VN_ISREG(vp)) | 4364 | if (!S_ISREG(ip->i_d.di_mode)) |
4577 | return XFS_ERROR(EINVAL); | 4365 | return XFS_ERROR(EINVAL); |
4578 | 4366 | ||
4579 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 4367 | xfs_ilock(ip, XFS_ILOCK_SHARED); |
@@ -4655,7 +4443,7 @@ xfs_change_file_space( | |||
4655 | va.va_mask = XFS_AT_SIZE; | 4443 | va.va_mask = XFS_AT_SIZE; |
4656 | va.va_size = startoffset; | 4444 | va.va_size = startoffset; |
4657 | 4445 | ||
4658 | error = xfs_setattr(bdp, &va, attr_flags, credp); | 4446 | error = xfs_setattr(ip, &va, attr_flags, credp); |
4659 | 4447 | ||
4660 | if (error) | 4448 | if (error) |
4661 | return error; | 4449 | return error; |
@@ -4714,46 +4502,3 @@ xfs_change_file_space( | |||
4714 | 4502 | ||
4715 | return error; | 4503 | return error; |
4716 | } | 4504 | } |
4717 | |||
4718 | bhv_vnodeops_t xfs_vnodeops = { | ||
4719 | BHV_IDENTITY_INIT(VN_BHV_XFS,VNODE_POSITION_XFS), | ||
4720 | .vop_open = xfs_open, | ||
4721 | .vop_read = xfs_read, | ||
4722 | #ifdef HAVE_SPLICE | ||
4723 | .vop_splice_read = xfs_splice_read, | ||
4724 | .vop_splice_write = xfs_splice_write, | ||
4725 | #endif | ||
4726 | .vop_write = xfs_write, | ||
4727 | .vop_ioctl = xfs_ioctl, | ||
4728 | .vop_getattr = xfs_getattr, | ||
4729 | .vop_setattr = xfs_setattr, | ||
4730 | .vop_access = xfs_access, | ||
4731 | .vop_lookup = xfs_lookup, | ||
4732 | .vop_create = xfs_create, | ||
4733 | .vop_remove = xfs_remove, | ||
4734 | .vop_link = xfs_link, | ||
4735 | .vop_rename = xfs_rename, | ||
4736 | .vop_mkdir = xfs_mkdir, | ||
4737 | .vop_rmdir = xfs_rmdir, | ||
4738 | .vop_readdir = xfs_readdir, | ||
4739 | .vop_symlink = xfs_symlink, | ||
4740 | .vop_readlink = xfs_readlink, | ||
4741 | .vop_fsync = xfs_fsync, | ||
4742 | .vop_inactive = xfs_inactive, | ||
4743 | .vop_fid2 = xfs_fid2, | ||
4744 | .vop_rwlock = xfs_rwlock, | ||
4745 | .vop_rwunlock = xfs_rwunlock, | ||
4746 | .vop_bmap = xfs_bmap, | ||
4747 | .vop_reclaim = xfs_reclaim, | ||
4748 | .vop_attr_get = xfs_attr_get, | ||
4749 | .vop_attr_set = xfs_attr_set, | ||
4750 | .vop_attr_remove = xfs_attr_remove, | ||
4751 | .vop_attr_list = xfs_attr_list, | ||
4752 | .vop_link_removed = (vop_link_removed_t)fs_noval, | ||
4753 | .vop_vnode_change = (vop_vnode_change_t)fs_noval, | ||
4754 | .vop_tosspages = fs_tosspages, | ||
4755 | .vop_flushinval_pages = fs_flushinval_pages, | ||
4756 | .vop_flush_pages = fs_flush_pages, | ||
4757 | .vop_release = xfs_release, | ||
4758 | .vop_iflush = xfs_inode_flush, | ||
4759 | }; | ||