| @@ -4862,1586 +4862,1586 @@ zfs_inactive(vnode_t *vp, cred_t *cr, ca | | | @@ -4862,1586 +4862,1586 @@ zfs_inactive(vnode_t *vp, cred_t *cr, ca |
4862 | } | | 4862 | } |
4863 | rw_exit(&zfsvfs->z_teardown_inactive_lock); | | 4863 | rw_exit(&zfsvfs->z_teardown_inactive_lock); |
4864 | } | | 4864 | } |
4865 | | | 4865 | |
4866 | | | 4866 | |
4867 | #ifdef __FreeBSD__ | | 4867 | #ifdef __FreeBSD__ |
4868 | CTASSERT(sizeof(struct zfid_short) <= sizeof(struct fid)); | | 4868 | CTASSERT(sizeof(struct zfid_short) <= sizeof(struct fid)); |
4869 | CTASSERT(sizeof(struct zfid_long) <= sizeof(struct fid)); | | 4869 | CTASSERT(sizeof(struct zfid_long) <= sizeof(struct fid)); |
4870 | #endif | | 4870 | #endif |
4871 | | | 4871 | |
4872 | /*ARGSUSED*/ | | 4872 | /*ARGSUSED*/ |
4873 | static int | | 4873 | static int |
4874 | zfs_fid(vnode_t *vp, fid_t *fidp, caller_context_t *ct) | | 4874 | zfs_fid(vnode_t *vp, fid_t *fidp, caller_context_t *ct) |
4875 | { | | 4875 | { |
4876 | znode_t *zp = VTOZ(vp); | | 4876 | znode_t *zp = VTOZ(vp); |
4877 | zfsvfs_t *zfsvfs = zp->z_zfsvfs; | | 4877 | zfsvfs_t *zfsvfs = zp->z_zfsvfs; |
4878 | uint32_t gen; | | 4878 | uint32_t gen; |
4879 | uint64_t gen64; | | 4879 | uint64_t gen64; |
4880 | uint64_t object = zp->z_id; | | 4880 | uint64_t object = zp->z_id; |
4881 | zfid_short_t *zfid; | | 4881 | zfid_short_t *zfid; |
4882 | int size, i, error; | | 4882 | int size, i, error; |
4883 | | | 4883 | |
4884 | ZFS_ENTER(zfsvfs); | | 4884 | ZFS_ENTER(zfsvfs); |
4885 | ZFS_VERIFY_ZP(zp); | | 4885 | ZFS_VERIFY_ZP(zp); |
4886 | | | 4886 | |
4887 | if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(zfsvfs), | | 4887 | if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(zfsvfs), |
4888 | &gen64, sizeof (uint64_t))) != 0) { | | 4888 | &gen64, sizeof (uint64_t))) != 0) { |
4889 | ZFS_EXIT(zfsvfs); | | 4889 | ZFS_EXIT(zfsvfs); |
4890 | return (error); | | 4890 | return (error); |
4891 | } | | 4891 | } |
4892 | | | 4892 | |
4893 | gen = (uint32_t)gen64; | | 4893 | gen = (uint32_t)gen64; |
4894 | | | 4894 | |
4895 | size = (zfsvfs->z_parent != zfsvfs) ? LONG_FID_LEN : SHORT_FID_LEN; | | 4895 | size = (zfsvfs->z_parent != zfsvfs) ? LONG_FID_LEN : SHORT_FID_LEN; |
4896 | | | 4896 | |
4897 | #ifdef illumos | | 4897 | #ifdef illumos |
4898 | if (fidp->fid_len < size) { | | 4898 | if (fidp->fid_len < size) { |
4899 | fidp->fid_len = size; | | 4899 | fidp->fid_len = size; |
4900 | ZFS_EXIT(zfsvfs); | | 4900 | ZFS_EXIT(zfsvfs); |
4901 | return (SET_ERROR(ENOSPC)); | | 4901 | return (SET_ERROR(ENOSPC)); |
4902 | } | | 4902 | } |
4903 | #else | | 4903 | #else |
4904 | fidp->fid_len = size; | | 4904 | fidp->fid_len = size; |
4905 | #endif | | 4905 | #endif |
4906 | | | 4906 | |
4907 | zfid = (zfid_short_t *)fidp; | | 4907 | zfid = (zfid_short_t *)fidp; |
4908 | | | 4908 | |
4909 | zfid->zf_len = size; | | 4909 | zfid->zf_len = size; |
4910 | | | 4910 | |
4911 | for (i = 0; i < sizeof (zfid->zf_object); i++) | | 4911 | for (i = 0; i < sizeof (zfid->zf_object); i++) |
4912 | zfid->zf_object[i] = (uint8_t)(object >> (8 * i)); | | 4912 | zfid->zf_object[i] = (uint8_t)(object >> (8 * i)); |
4913 | | | 4913 | |
4914 | /* Must have a non-zero generation number to distinguish from .zfs */ | | 4914 | /* Must have a non-zero generation number to distinguish from .zfs */ |
4915 | if (gen == 0) | | 4915 | if (gen == 0) |
4916 | gen = 1; | | 4916 | gen = 1; |
4917 | for (i = 0; i < sizeof (zfid->zf_gen); i++) | | 4917 | for (i = 0; i < sizeof (zfid->zf_gen); i++) |
4918 | zfid->zf_gen[i] = (uint8_t)(gen >> (8 * i)); | | 4918 | zfid->zf_gen[i] = (uint8_t)(gen >> (8 * i)); |
4919 | | | 4919 | |
4920 | if (size == LONG_FID_LEN) { | | 4920 | if (size == LONG_FID_LEN) { |
4921 | uint64_t objsetid = dmu_objset_id(zfsvfs->z_os); | | 4921 | uint64_t objsetid = dmu_objset_id(zfsvfs->z_os); |
4922 | zfid_long_t *zlfid; | | 4922 | zfid_long_t *zlfid; |
4923 | | | 4923 | |
4924 | zlfid = (zfid_long_t *)fidp; | | 4924 | zlfid = (zfid_long_t *)fidp; |
4925 | | | 4925 | |
4926 | for (i = 0; i < sizeof (zlfid->zf_setid); i++) | | 4926 | for (i = 0; i < sizeof (zlfid->zf_setid); i++) |
4927 | zlfid->zf_setid[i] = (uint8_t)(objsetid >> (8 * i)); | | 4927 | zlfid->zf_setid[i] = (uint8_t)(objsetid >> (8 * i)); |
4928 | | | 4928 | |
4929 | /* XXX - this should be the generation number for the objset */ | | 4929 | /* XXX - this should be the generation number for the objset */ |
4930 | for (i = 0; i < sizeof (zlfid->zf_setgen); i++) | | 4930 | for (i = 0; i < sizeof (zlfid->zf_setgen); i++) |
4931 | zlfid->zf_setgen[i] = 0; | | 4931 | zlfid->zf_setgen[i] = 0; |
4932 | } | | 4932 | } |
4933 | | | 4933 | |
4934 | ZFS_EXIT(zfsvfs); | | 4934 | ZFS_EXIT(zfsvfs); |
4935 | return (0); | | 4935 | return (0); |
4936 | } | | 4936 | } |
4937 | | | 4937 | |
4938 | static int | | 4938 | static int |
4939 | zfs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr, | | 4939 | zfs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr, |
4940 | caller_context_t *ct) | | 4940 | caller_context_t *ct) |
4941 | { | | 4941 | { |
4942 | znode_t *zp, *xzp; | | 4942 | znode_t *zp, *xzp; |
4943 | zfsvfs_t *zfsvfs; | | 4943 | zfsvfs_t *zfsvfs; |
4944 | int error; | | 4944 | int error; |
4945 | | | 4945 | |
4946 | switch (cmd) { | | 4946 | switch (cmd) { |
4947 | case _PC_LINK_MAX: | | 4947 | case _PC_LINK_MAX: |
4948 | *valp = INT_MAX; | | 4948 | *valp = INT_MAX; |
4949 | return (0); | | 4949 | return (0); |
4950 | | | 4950 | |
4951 | case _PC_FILESIZEBITS: | | 4951 | case _PC_FILESIZEBITS: |
4952 | *valp = 64; | | 4952 | *valp = 64; |
4953 | return (0); | | 4953 | return (0); |
4954 | #ifdef illumos | | 4954 | #ifdef illumos |
4955 | case _PC_XATTR_EXISTS: | | 4955 | case _PC_XATTR_EXISTS: |
4956 | zp = VTOZ(vp); | | 4956 | zp = VTOZ(vp); |
4957 | zfsvfs = zp->z_zfsvfs; | | 4957 | zfsvfs = zp->z_zfsvfs; |
4958 | ZFS_ENTER(zfsvfs); | | 4958 | ZFS_ENTER(zfsvfs); |
4959 | ZFS_VERIFY_ZP(zp); | | 4959 | ZFS_VERIFY_ZP(zp); |
4960 | *valp = 0; | | 4960 | *valp = 0; |
4961 | error = zfs_dirent_lookup(zp, "", &xzp, | | 4961 | error = zfs_dirent_lookup(zp, "", &xzp, |
4962 | ZXATTR | ZEXISTS | ZSHARED); | | 4962 | ZXATTR | ZEXISTS | ZSHARED); |
4963 | if (error == 0) { | | 4963 | if (error == 0) { |
4964 | if (!zfs_dirempty(xzp)) | | 4964 | if (!zfs_dirempty(xzp)) |
4965 | *valp = 1; | | 4965 | *valp = 1; |
4966 | vrele(ZTOV(xzp)); | | 4966 | vrele(ZTOV(xzp)); |
4967 | } else if (error == ENOENT) { | | 4967 | } else if (error == ENOENT) { |
4968 | /* | | 4968 | /* |
4969 | * If there aren't extended attributes, it's the | | 4969 | * If there aren't extended attributes, it's the |
4970 | * same as having zero of them. | | 4970 | * same as having zero of them. |
4971 | */ | | 4971 | */ |
4972 | error = 0; | | 4972 | error = 0; |
4973 | } | | 4973 | } |
4974 | ZFS_EXIT(zfsvfs); | | 4974 | ZFS_EXIT(zfsvfs); |
4975 | return (error); | | 4975 | return (error); |
4976 | | | 4976 | |
4977 | case _PC_SATTR_ENABLED: | | 4977 | case _PC_SATTR_ENABLED: |
4978 | case _PC_SATTR_EXISTS: | | 4978 | case _PC_SATTR_EXISTS: |
4979 | *valp = vfs_has_feature(vp->v_vfsp, VFSFT_SYSATTR_VIEWS) && | | 4979 | *valp = vfs_has_feature(vp->v_vfsp, VFSFT_SYSATTR_VIEWS) && |
4980 | (vp->v_type == VREG || vp->v_type == VDIR); | | 4980 | (vp->v_type == VREG || vp->v_type == VDIR); |
4981 | return (0); | | 4981 | return (0); |
4982 | | | 4982 | |
4983 | case _PC_ACCESS_FILTERING: | | 4983 | case _PC_ACCESS_FILTERING: |
4984 | *valp = vfs_has_feature(vp->v_vfsp, VFSFT_ACCESS_FILTER) && | | 4984 | *valp = vfs_has_feature(vp->v_vfsp, VFSFT_ACCESS_FILTER) && |
4985 | vp->v_type == VDIR; | | 4985 | vp->v_type == VDIR; |
4986 | return (0); | | 4986 | return (0); |
4987 | | | 4987 | |
4988 | case _PC_ACL_ENABLED: | | 4988 | case _PC_ACL_ENABLED: |
4989 | *valp = _ACL_ACE_ENABLED; | | 4989 | *valp = _ACL_ACE_ENABLED; |
4990 | return (0); | | 4990 | return (0); |
4991 | #endif /* illumos */ | | 4991 | #endif /* illumos */ |
4992 | case _PC_MIN_HOLE_SIZE: | | 4992 | case _PC_MIN_HOLE_SIZE: |
4993 | *valp = (int)SPA_MINBLOCKSIZE; | | 4993 | *valp = (int)SPA_MINBLOCKSIZE; |
4994 | return (0); | | 4994 | return (0); |
4995 | #ifdef illumos | | 4995 | #ifdef illumos |
4996 | case _PC_TIMESTAMP_RESOLUTION: | | 4996 | case _PC_TIMESTAMP_RESOLUTION: |
4997 | /* nanosecond timestamp resolution */ | | 4997 | /* nanosecond timestamp resolution */ |
4998 | *valp = 1L; | | 4998 | *valp = 1L; |
4999 | return (0); | | 4999 | return (0); |
5000 | #endif | | 5000 | #endif |
5001 | case _PC_ACL_EXTENDED: | | 5001 | case _PC_ACL_EXTENDED: |
5002 | *valp = 0; | | 5002 | *valp = 0; |
5003 | return (0); | | 5003 | return (0); |
5004 | | | 5004 | |
5005 | #ifndef __NetBSD__ | | 5005 | #ifndef __NetBSD__ |
5006 | case _PC_ACL_NFS4: | | 5006 | case _PC_ACL_NFS4: |
5007 | *valp = 1; | | 5007 | *valp = 1; |
5008 | return (0); | | 5008 | return (0); |
5009 | | | 5009 | |
5010 | case _PC_ACL_PATH_MAX: | | 5010 | case _PC_ACL_PATH_MAX: |
5011 | *valp = ACL_MAX_ENTRIES; | | 5011 | *valp = ACL_MAX_ENTRIES; |
5012 | return (0); | | 5012 | return (0); |
5013 | #endif | | 5013 | #endif |
5014 | | | 5014 | |
5015 | default: | | 5015 | default: |
5016 | return (EOPNOTSUPP); | | 5016 | return (EOPNOTSUPP); |
5017 | } | | 5017 | } |
5018 | } | | 5018 | } |
5019 | | | 5019 | |
5020 | /*ARGSUSED*/ | | 5020 | /*ARGSUSED*/ |
5021 | static int | | 5021 | static int |
5022 | zfs_getsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, cred_t *cr, | | 5022 | zfs_getsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, cred_t *cr, |
5023 | caller_context_t *ct) | | 5023 | caller_context_t *ct) |
5024 | { | | 5024 | { |
5025 | znode_t *zp = VTOZ(vp); | | 5025 | znode_t *zp = VTOZ(vp); |
5026 | zfsvfs_t *zfsvfs = zp->z_zfsvfs; | | 5026 | zfsvfs_t *zfsvfs = zp->z_zfsvfs; |
5027 | int error; | | 5027 | int error; |
5028 | boolean_t skipaclchk = (flag & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE; | | 5028 | boolean_t skipaclchk = (flag & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE; |
5029 | | | 5029 | |
5030 | ZFS_ENTER(zfsvfs); | | 5030 | ZFS_ENTER(zfsvfs); |
5031 | ZFS_VERIFY_ZP(zp); | | 5031 | ZFS_VERIFY_ZP(zp); |
5032 | error = zfs_getacl(zp, vsecp, skipaclchk, cr); | | 5032 | error = zfs_getacl(zp, vsecp, skipaclchk, cr); |
5033 | ZFS_EXIT(zfsvfs); | | 5033 | ZFS_EXIT(zfsvfs); |
5034 | | | 5034 | |
5035 | return (error); | | 5035 | return (error); |
5036 | } | | 5036 | } |
5037 | | | 5037 | |
5038 | /*ARGSUSED*/ | | 5038 | /*ARGSUSED*/ |
5039 | int | | 5039 | int |
5040 | zfs_setsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, cred_t *cr, | | 5040 | zfs_setsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, cred_t *cr, |
5041 | caller_context_t *ct) | | 5041 | caller_context_t *ct) |
5042 | { | | 5042 | { |
5043 | znode_t *zp = VTOZ(vp); | | 5043 | znode_t *zp = VTOZ(vp); |
5044 | zfsvfs_t *zfsvfs = zp->z_zfsvfs; | | 5044 | zfsvfs_t *zfsvfs = zp->z_zfsvfs; |
5045 | int error; | | 5045 | int error; |
5046 | boolean_t skipaclchk = (flag & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE; | | 5046 | boolean_t skipaclchk = (flag & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE; |
5047 | zilog_t *zilog = zfsvfs->z_log; | | 5047 | zilog_t *zilog = zfsvfs->z_log; |
5048 | | | 5048 | |
5049 | ZFS_ENTER(zfsvfs); | | 5049 | ZFS_ENTER(zfsvfs); |
5050 | ZFS_VERIFY_ZP(zp); | | 5050 | ZFS_VERIFY_ZP(zp); |
5051 | | | 5051 | |
5052 | error = zfs_setacl(zp, vsecp, skipaclchk, cr); | | 5052 | error = zfs_setacl(zp, vsecp, skipaclchk, cr); |
5053 | | | 5053 | |
5054 | if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) | | 5054 | if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) |
5055 | zil_commit(zilog, 0); | | 5055 | zil_commit(zilog, 0); |
5056 | | | 5056 | |
5057 | ZFS_EXIT(zfsvfs); | | 5057 | ZFS_EXIT(zfsvfs); |
5058 | return (error); | | 5058 | return (error); |
5059 | } | | 5059 | } |
5060 | | | 5060 | |
5061 | static int | | 5061 | static int |
5062 | ioflags(int ioflags) | | 5062 | ioflags(int ioflags) |
5063 | { | | 5063 | { |
5064 | int flags = 0; | | 5064 | int flags = 0; |
5065 | | | 5065 | |
5066 | if (ioflags & IO_APPEND) | | 5066 | if (ioflags & IO_APPEND) |
5067 | flags |= FAPPEND; | | 5067 | flags |= FAPPEND; |
5068 | if (ioflags & IO_NDELAY) | | 5068 | if (ioflags & IO_NDELAY) |
5069 | flags |= FNONBLOCK; | | 5069 | flags |= FNONBLOCK; |
5070 | if (ioflags & IO_SYNC) | | 5070 | if (ioflags & IO_SYNC) |
5071 | flags |= (FSYNC | FDSYNC | FRSYNC); | | 5071 | flags |= (FSYNC | FDSYNC | FRSYNC); |
5072 | | | 5072 | |
5073 | return (flags); | | 5073 | return (flags); |
5074 | } | | 5074 | } |
5075 | | | 5075 | |
5076 | #ifdef __NetBSD__ | | 5076 | #ifdef __NetBSD__ |
5077 | | | 5077 | |
5078 | static int | | 5078 | static int |
5079 | zfs_netbsd_open(void *v) | | 5079 | zfs_netbsd_open(void *v) |
5080 | { | | 5080 | { |
5081 | struct vop_open_args *ap = v; | | 5081 | struct vop_open_args *ap = v; |
5082 | | | 5082 | |
5083 | return (zfs_open(&ap->a_vp, ap->a_mode, ap->a_cred, NULL)); | | 5083 | return (zfs_open(&ap->a_vp, ap->a_mode, ap->a_cred, NULL)); |
5084 | } | | 5084 | } |
5085 | | | 5085 | |
5086 | static int | | 5086 | static int |
5087 | zfs_netbsd_close(void *v) | | 5087 | zfs_netbsd_close(void *v) |
5088 | { | | 5088 | { |
5089 | struct vop_close_args *ap = v; | | 5089 | struct vop_close_args *ap = v; |
5090 | | | 5090 | |
5091 | return (zfs_close(ap->a_vp, ap->a_fflag, 0, 0, ap->a_cred, NULL)); | | 5091 | return (zfs_close(ap->a_vp, ap->a_fflag, 0, 0, ap->a_cred, NULL)); |
5092 | } | | 5092 | } |
5093 | | | 5093 | |
5094 | static int | | 5094 | static int |
5095 | zfs_netbsd_ioctl(void *v) | | 5095 | zfs_netbsd_ioctl(void *v) |
5096 | { | | 5096 | { |
5097 | struct vop_ioctl_args *ap = v; | | 5097 | struct vop_ioctl_args *ap = v; |
5098 | | | 5098 | |
5099 | return (zfs_ioctl(ap->a_vp, ap->a_command, (intptr_t)ap->a_data, | | 5099 | return (zfs_ioctl(ap->a_vp, ap->a_command, (intptr_t)ap->a_data, |
5100 | ap->a_fflag, ap->a_cred, NULL, NULL)); | | 5100 | ap->a_fflag, ap->a_cred, NULL, NULL)); |
5101 | } | | 5101 | } |
5102 | | | 5102 | |
5103 | | | 5103 | |
5104 | static int | | 5104 | static int |
5105 | zfs_netbsd_read(void *v) | | 5105 | zfs_netbsd_read(void *v) |
5106 | { | | 5106 | { |
5107 | struct vop_read_args *ap = v; | | 5107 | struct vop_read_args *ap = v; |
5108 | vnode_t *vp = ap->a_vp; | | 5108 | vnode_t *vp = ap->a_vp; |
5109 | znode_t *zp = VTOZ(vp); | | 5109 | znode_t *zp = VTOZ(vp); |
5110 | | | 5110 | |
5111 | switch (vp->v_type) { | | 5111 | switch (vp->v_type) { |
5112 | case VBLK: | | 5112 | case VBLK: |
5113 | case VCHR: | | 5113 | case VCHR: |
5114 | ZFS_ACCESSTIME_STAMP(zp->z_zfsvfs, zp); | | 5114 | ZFS_ACCESSTIME_STAMP(zp->z_zfsvfs, zp); |
5115 | return (VOCALL(spec_vnodeop_p, VOFFSET(vop_read), ap)); | | 5115 | return (VOCALL(spec_vnodeop_p, VOFFSET(vop_read), ap)); |
5116 | case VFIFO: | | 5116 | case VFIFO: |
5117 | ZFS_ACCESSTIME_STAMP(zp->z_zfsvfs, zp); | | 5117 | ZFS_ACCESSTIME_STAMP(zp->z_zfsvfs, zp); |
5118 | return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_read), ap)); | | 5118 | return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_read), ap)); |
5119 | } | | 5119 | } |
5120 | | | 5120 | |
5121 | return (zfs_read(vp, ap->a_uio, ioflags(ap->a_ioflag), ap->a_cred, NULL)); | | 5121 | return (zfs_read(vp, ap->a_uio, ioflags(ap->a_ioflag), ap->a_cred, NULL)); |
5122 | } | | 5122 | } |
5123 | | | 5123 | |
5124 | static int | | 5124 | static int |
5125 | zfs_netbsd_write(void *v) | | 5125 | zfs_netbsd_write(void *v) |
5126 | { | | 5126 | { |
5127 | struct vop_write_args *ap = v; | | 5127 | struct vop_write_args *ap = v; |
5128 | vnode_t *vp = ap->a_vp; | | 5128 | vnode_t *vp = ap->a_vp; |
5129 | znode_t *zp = VTOZ(vp); | | 5129 | znode_t *zp = VTOZ(vp); |
5130 | struct uio *uio = ap->a_uio; | | 5130 | struct uio *uio = ap->a_uio; |
5131 | off_t osize = zp->z_size; | | 5131 | off_t osize = zp->z_size; |
5132 | int error, resid; | | 5132 | int error, resid; |
5133 | | | 5133 | |
5134 | switch (vp->v_type) { | | 5134 | switch (vp->v_type) { |
5135 | case VBLK: | | 5135 | case VBLK: |
5136 | case VCHR: | | 5136 | case VCHR: |
5137 | GOP_MARKUPDATE(vp, GOP_UPDATE_MODIFIED); | | 5137 | GOP_MARKUPDATE(vp, GOP_UPDATE_MODIFIED); |
5138 | return (VOCALL(spec_vnodeop_p, VOFFSET(vop_write), ap)); | | 5138 | return (VOCALL(spec_vnodeop_p, VOFFSET(vop_write), ap)); |
5139 | case VFIFO: | | 5139 | case VFIFO: |
5140 | GOP_MARKUPDATE(vp, GOP_UPDATE_MODIFIED); | | 5140 | GOP_MARKUPDATE(vp, GOP_UPDATE_MODIFIED); |
5141 | return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_write), ap)); | | 5141 | return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_write), ap)); |
5142 | } | | 5142 | } |
5143 | | | 5143 | |
5144 | resid = uio->uio_resid; | | 5144 | resid = uio->uio_resid; |
5145 | error = zfs_write(vp, uio, ioflags(ap->a_ioflag), ap->a_cred, NULL); | | 5145 | error = zfs_write(vp, uio, ioflags(ap->a_ioflag), ap->a_cred, NULL); |
5146 | if (resid > uio->uio_resid) | | 5146 | if (resid > uio->uio_resid) |
5147 | VN_KNOTE(vp, NOTE_WRITE | | | 5147 | VN_KNOTE(vp, NOTE_WRITE | |
5148 | (zp->z_size > osize ? NOTE_EXTEND : 0)); | | 5148 | (zp->z_size > osize ? NOTE_EXTEND : 0)); |
5149 | | | 5149 | |
5150 | return error; | | 5150 | return error; |
5151 | } | | 5151 | } |
5152 | | | 5152 | |
5153 | static int | | 5153 | static int |
5154 | zfs_netbsd_access(void *v) | | 5154 | zfs_netbsd_access(void *v) |
5155 | { | | 5155 | { |
5156 | struct vop_access_args /* { | | 5156 | struct vop_access_args /* { |
5157 | struct vnode *a_vp; | | 5157 | struct vnode *a_vp; |
5158 | int a_mode; | | 5158 | int a_mode; |
5159 | kauth_cred_t a_cred; | | 5159 | kauth_cred_t a_cred; |
5160 | } */ *ap = v; | | 5160 | } */ *ap = v; |
5161 | struct vnode *vp = ap->a_vp; | | 5161 | struct vnode *vp = ap->a_vp; |
5162 | int mode = ap->a_mode; | | 5162 | int mode = ap->a_mode; |
5163 | mode_t zfs_mode = 0; | | 5163 | mode_t zfs_mode = 0; |
5164 | kauth_cred_t cred = ap->a_cred; | | 5164 | kauth_cred_t cred = ap->a_cred; |
5165 | int error; | | 5165 | int error; |
5166 | | | 5166 | |
5167 | /* | | 5167 | /* |
5168 | * XXX This is really random, especially the left shift by six, | | 5168 | * XXX This is really random, especially the left shift by six, |
5169 | * and it exists only because of randomness in zfs_unix_to_v4 | | 5169 | * and it exists only because of randomness in zfs_unix_to_v4 |
5170 | * and zfs_zaccess_rwx in zfs_acl.c. | | 5170 | * and zfs_zaccess_rwx in zfs_acl.c. |
5171 | */ | | 5171 | */ |
5172 | if (mode & VREAD) | | 5172 | if (mode & VREAD) |
5173 | zfs_mode |= S_IROTH; | | 5173 | zfs_mode |= S_IROTH; |
5174 | if (mode & VWRITE) | | 5174 | if (mode & VWRITE) |
5175 | zfs_mode |= S_IWOTH; | | 5175 | zfs_mode |= S_IWOTH; |
5176 | if (mode & VEXEC) | | 5176 | if (mode & VEXEC) |
5177 | zfs_mode |= S_IXOTH; | | 5177 | zfs_mode |= S_IXOTH; |
5178 | zfs_mode <<= 6; | | 5178 | zfs_mode <<= 6; |
5179 | | | 5179 | |
5180 | KASSERT(VOP_ISLOCKED(vp)); | | 5180 | KASSERT(VOP_ISLOCKED(vp)); |
5181 | error = zfs_access(vp, zfs_mode, 0, cred, NULL); | | 5181 | error = zfs_access(vp, zfs_mode, 0, cred, NULL); |
5182 | | | 5182 | |
5183 | /* We expect EACCES as common error. */ | | 5183 | /* We expect EACCES as common error. */ |
5184 | if (error == EPERM) | | 5184 | if (error == EPERM) |
5185 | error = EACCES; | | 5185 | error = EACCES; |
5186 | | | 5186 | |
5187 | return (error); | | 5187 | return (error); |
5188 | } | | 5188 | } |
5189 | | | 5189 | |
5190 | static int | | 5190 | static int |
5191 | zfs_netbsd_lookup(void *v) | | 5191 | zfs_netbsd_lookup(void *v) |
5192 | { | | 5192 | { |
5193 | struct vop_lookup_v2_args /* { | | 5193 | struct vop_lookup_v2_args /* { |
5194 | struct vnode *a_dvp; | | 5194 | struct vnode *a_dvp; |
5195 | struct vnode **a_vpp; | | 5195 | struct vnode **a_vpp; |
5196 | struct componentname *a_cnp; | | 5196 | struct componentname *a_cnp; |
5197 | } */ *ap = v; | | 5197 | } */ *ap = v; |
5198 | struct vnode *dvp = ap->a_dvp; | | 5198 | struct vnode *dvp = ap->a_dvp; |
5199 | struct vnode **vpp = ap->a_vpp; | | 5199 | struct vnode **vpp = ap->a_vpp; |
5200 | struct componentname *cnp = ap->a_cnp; | | 5200 | struct componentname *cnp = ap->a_cnp; |
5201 | char *nm, short_nm[31]; | | 5201 | char *nm, short_nm[31]; |
5202 | int error; | | 5202 | int error; |
5203 | int iswhiteout; | | 5203 | int iswhiteout; |
5204 | | | 5204 | |
5205 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); | | 5205 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); |
5206 | | | 5206 | |
5207 | *vpp = NULL; | | 5207 | *vpp = NULL; |
5208 | | | 5208 | |
5209 | /* | | 5209 | /* |
5210 | * Do an access check before the cache lookup. zfs_lookup does | | 5210 | * Do an access check before the cache lookup. zfs_lookup does |
5211 | * an access check too, but it's too scary to contemplate | | 5211 | * an access check too, but it's too scary to contemplate |
5212 | * injecting our namecache stuff into zfs internals. | | 5212 | * injecting our namecache stuff into zfs internals. |
5213 | * | | 5213 | * |
5214 | * XXX Is this the correct access check? | | 5214 | * XXX Is this the correct access check? |
5215 | */ | | 5215 | */ |
5216 | if ((error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred)) != 0) | | 5216 | if ((error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred)) != 0) |
5217 | goto out; | | 5217 | goto out; |
5218 | | | 5218 | |
5219 | /* | | 5219 | /* |
5220 | * Check the namecache before entering zfs_lookup. | | 5220 | * Check the namecache before entering zfs_lookup. |
5221 | * cache_lookup does the locking dance for us. | | 5221 | * cache_lookup does the locking dance for us. |
5222 | */ | | 5222 | */ |
5223 | if (cache_lookup(dvp, cnp->cn_nameptr, cnp->cn_namelen, | | 5223 | if (cache_lookup(dvp, cnp->cn_nameptr, cnp->cn_namelen, |
5224 | cnp->cn_nameiop, cnp->cn_flags, &iswhiteout, vpp)) { | | 5224 | cnp->cn_nameiop, cnp->cn_flags, &iswhiteout, vpp)) { |
5225 | if (iswhiteout) { | | 5225 | if (iswhiteout) { |
5226 | cnp->cn_flags |= ISWHITEOUT; | | 5226 | cnp->cn_flags |= ISWHITEOUT; |
5227 | } | | 5227 | } |
5228 | return *vpp == NULL ? ENOENT : 0; | | 5228 | return *vpp == NULL ? ENOENT : 0; |
5229 | } | | 5229 | } |
5230 | | | 5230 | |
5231 | /* | | 5231 | /* |
5232 | * zfs_lookup wants a null-terminated component name, but namei | | 5232 | * zfs_lookup wants a null-terminated component name, but namei |
5233 | * gives us a pointer into the full pathname. | | 5233 | * gives us a pointer into the full pathname. |
5234 | */ | | 5234 | */ |
5235 | ASSERT(cnp->cn_namelen < PATH_MAX - 1); | | 5235 | ASSERT(cnp->cn_namelen < PATH_MAX - 1); |
5236 | if (cnp->cn_namelen + 1 > sizeof(short_nm)) | | 5236 | if (cnp->cn_namelen + 1 > sizeof(short_nm)) |
5237 | nm = PNBUF_GET(); | | 5237 | nm = PNBUF_GET(); |
5238 | else | | 5238 | else |
5239 | nm = short_nm; | | 5239 | nm = short_nm; |
5240 | (void)strlcpy(nm, cnp->cn_nameptr, cnp->cn_namelen + 1); | | 5240 | (void)strlcpy(nm, cnp->cn_nameptr, cnp->cn_namelen + 1); |
5241 | | | 5241 | |
5242 | error = zfs_lookup(dvp, nm, vpp, 0, cnp, cnp->cn_nameiop, cnp->cn_cred); | | 5242 | error = zfs_lookup(dvp, nm, vpp, 0, cnp, cnp->cn_nameiop, cnp->cn_cred); |
5243 | | | 5243 | |
5244 | if (nm != short_nm) | | 5244 | if (nm != short_nm) |
5245 | PNBUF_PUT(nm); | | 5245 | PNBUF_PUT(nm); |
5246 | | | 5246 | |
5247 | /* | | 5247 | /* |
5248 | * Translate errors to match our namei insanity. Also, if the | | 5248 | * Translate errors to match our namei insanity. Also, if the |
5249 | * caller wants to create an entry here, it's apparently our | | 5249 | * caller wants to create an entry here, it's apparently our |
5250 | * responsibility as lookup to make sure that's permissible. | | 5250 | * responsibility as lookup to make sure that's permissible. |
5251 | * Go figure. | | 5251 | * Go figure. |
5252 | */ | | 5252 | */ |
5253 | if (cnp->cn_flags & ISLASTCN) { | | 5253 | if (cnp->cn_flags & ISLASTCN) { |
5254 | switch (cnp->cn_nameiop) { | | 5254 | switch (cnp->cn_nameiop) { |
5255 | case CREATE: | | 5255 | case CREATE: |
5256 | case RENAME: | | 5256 | case RENAME: |
5257 | if (error == ENOENT) { | | 5257 | if (error == ENOENT) { |
5258 | error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred); | | 5258 | error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred); |
5259 | if (error) | | 5259 | if (error) |
5260 | break; | | 5260 | break; |
5261 | error = EJUSTRETURN; | | 5261 | error = EJUSTRETURN; |
5262 | break; | | 5262 | break; |
5263 | } | | 5263 | } |
5264 | break; | | 5264 | break; |
5265 | case DELETE: | | 5265 | case DELETE: |
5266 | if (error == 0) { | | 5266 | if (error == 0) { |
5267 | error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred); | | 5267 | error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred); |
5268 | if (error) { | | 5268 | if (error) { |
5269 | VN_RELE(*vpp); | | 5269 | VN_RELE(*vpp); |
5270 | *vpp = NULL; | | 5270 | *vpp = NULL; |
5271 | } | | 5271 | } |
5272 | } | | 5272 | } |
5273 | break; | | 5273 | break; |
5274 | } | | 5274 | } |
5275 | } | | 5275 | } |
5276 | | | 5276 | |
5277 | if (error) { | | 5277 | if (error) { |
5278 | KASSERT(*vpp == NULL); | | 5278 | KASSERT(*vpp == NULL); |
5279 | goto out; | | 5279 | goto out; |
5280 | } | | 5280 | } |
5281 | KASSERT(*vpp != NULL); | | 5281 | KASSERT(*vpp != NULL); |
5282 | | | 5282 | |
5283 | if ((cnp->cn_namelen == 1) && (cnp->cn_nameptr[0] == '.')) { | | 5283 | if ((cnp->cn_namelen == 1) && (cnp->cn_nameptr[0] == '.')) { |
5284 | KASSERT(!(cnp->cn_flags & ISDOTDOT)); | | 5284 | KASSERT(!(cnp->cn_flags & ISDOTDOT)); |
5285 | KASSERT(dvp == *vpp); | | 5285 | KASSERT(dvp == *vpp); |
5286 | } else if ((cnp->cn_namelen == 2) && | | 5286 | } else if ((cnp->cn_namelen == 2) && |
5287 | (cnp->cn_nameptr[0] == '.') && | | 5287 | (cnp->cn_nameptr[0] == '.') && |
5288 | (cnp->cn_nameptr[1] == '.')) { | | 5288 | (cnp->cn_nameptr[1] == '.')) { |
5289 | KASSERT(cnp->cn_flags & ISDOTDOT); | | 5289 | KASSERT(cnp->cn_flags & ISDOTDOT); |
5290 | } else { | | 5290 | } else { |
5291 | KASSERT(!(cnp->cn_flags & ISDOTDOT)); | | 5291 | KASSERT(!(cnp->cn_flags & ISDOTDOT)); |
5292 | } | | 5292 | } |
5293 | | | 5293 | |
5294 | out: | | 5294 | out: |
5295 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); | | 5295 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); |
5296 | | | 5296 | |
5297 | /* | | 5297 | /* |
5298 | * Insert name into cache if appropriate. | | 5298 | * Insert name into cache if appropriate. |
5299 | */ | | 5299 | */ |
5300 | | | 5300 | |
5301 | if (error == 0 || (error == ENOENT && cnp->cn_nameiop != CREATE)) | | 5301 | if (error == 0 || (error == ENOENT && cnp->cn_nameiop != CREATE)) |
5302 | cache_enter(dvp, *vpp, cnp->cn_nameptr, cnp->cn_namelen, | | 5302 | cache_enter(dvp, *vpp, cnp->cn_nameptr, cnp->cn_namelen, |
5303 | cnp->cn_flags); | | 5303 | cnp->cn_flags); |
5304 | | | 5304 | |
5305 | return (error); | | 5305 | return (error); |
5306 | } | | 5306 | } |
5307 | | | 5307 | |
5308 | static int | | 5308 | static int |
5309 | zfs_netbsd_create(void *v) | | 5309 | zfs_netbsd_create(void *v) |
5310 | { | | 5310 | { |
5311 | struct vop_create_v3_args /* { | | 5311 | struct vop_create_v3_args /* { |
5312 | struct vnode *a_dvp; | | 5312 | struct vnode *a_dvp; |
5313 | struct vnode **a_vpp; | | 5313 | struct vnode **a_vpp; |
5314 | struct componentname *a_cnp; | | 5314 | struct componentname *a_cnp; |
5315 | struct vattr *a_vap; | | 5315 | struct vattr *a_vap; |
5316 | } */ *ap = v; | | 5316 | } */ *ap = v; |
5317 | struct vnode *dvp = ap->a_dvp; | | 5317 | struct vnode *dvp = ap->a_dvp; |
5318 | struct vnode **vpp = ap->a_vpp; | | 5318 | struct vnode **vpp = ap->a_vpp; |
5319 | struct componentname *cnp = ap->a_cnp; | | 5319 | struct componentname *cnp = ap->a_cnp; |
5320 | struct vattr *vap = ap->a_vap; | | 5320 | struct vattr *vap = ap->a_vap; |
5321 | char *nm; | | 5321 | char *nm; |
5322 | int mode; | | 5322 | int mode; |
5323 | int error; | | 5323 | int error; |
5324 | | | 5324 | |
5325 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); | | 5325 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); |
5326 | | | 5326 | |
5327 | vattr_init_mask(vap); | | 5327 | vattr_init_mask(vap); |
5328 | mode = vap->va_mode & ALLPERMS; | | 5328 | mode = vap->va_mode & ALLPERMS; |
5329 | | | 5329 | |
5330 | /* ZFS wants a null-terminated name. */ | | 5330 | /* ZFS wants a null-terminated name. */ |
5331 | nm = PNBUF_GET(); | | 5331 | nm = PNBUF_GET(); |
5332 | (void)strlcpy(nm, cnp->cn_nameptr, cnp->cn_namelen + 1); | | 5332 | (void)strlcpy(nm, cnp->cn_nameptr, cnp->cn_namelen + 1); |
5333 | | | 5333 | |
5334 | /* XXX !EXCL is wrong here... */ | | 5334 | /* XXX !EXCL is wrong here... */ |
5335 | error = zfs_create(dvp, nm, vap, !EXCL, mode, vpp, cnp->cn_cred, NULL); | | 5335 | error = zfs_create(dvp, nm, vap, !EXCL, mode, vpp, cnp->cn_cred, NULL); |
5336 | | | 5336 | |
5337 | PNBUF_PUT(nm); | | 5337 | PNBUF_PUT(nm); |
5338 | | | 5338 | |
5339 | KASSERT((error == 0) == (*vpp != NULL)); | | 5339 | KASSERT((error == 0) == (*vpp != NULL)); |
5340 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); | | 5340 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); |
5341 | if (error == 0) | | 5341 | if (error == 0) |
5342 | VN_KNOTE(dvp, NOTE_WRITE); | | 5342 | VN_KNOTE(dvp, NOTE_WRITE); |
5343 | if (*vpp != NULL) | | 5343 | if (*vpp != NULL) |
5344 | VOP_UNLOCK(*vpp, 0); | | 5344 | VOP_UNLOCK(*vpp, 0); |
5345 | | | 5345 | |
5346 | return (error); | | 5346 | return (error); |
5347 | } | | 5347 | } |
5348 | | | 5348 | |
5349 | static int | | 5349 | static int |
5350 | zfs_netbsd_mknod(void *v) | | 5350 | zfs_netbsd_mknod(void *v) |
5351 | { | | 5351 | { |
5352 | struct vop_mknod_v3_args /* { | | 5352 | struct vop_mknod_v3_args /* { |
5353 | struct vnode *a_dvp; | | 5353 | struct vnode *a_dvp; |
5354 | struct vnode **a_vpp; | | 5354 | struct vnode **a_vpp; |
5355 | struct componentname *a_cnp; | | 5355 | struct componentname *a_cnp; |
5356 | struct vattr *a_vap; | | 5356 | struct vattr *a_vap; |
5357 | } */ *ap = v; | | 5357 | } */ *ap = v; |
5358 | struct vnode *dvp = ap->a_dvp; | | 5358 | struct vnode *dvp = ap->a_dvp; |
5359 | struct vnode **vpp = ap->a_vpp; | | 5359 | struct vnode **vpp = ap->a_vpp; |
5360 | struct componentname *cnp = ap->a_cnp; | | 5360 | struct componentname *cnp = ap->a_cnp; |
5361 | struct vattr *vap = ap->a_vap; | | 5361 | struct vattr *vap = ap->a_vap; |
5362 | char *nm; | | 5362 | char *nm; |
5363 | int mode; | | 5363 | int mode; |
5364 | int error; | | 5364 | int error; |
5365 | | | 5365 | |
5366 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); | | 5366 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); |
5367 | | | 5367 | |
5368 | vattr_init_mask(vap); | | 5368 | vattr_init_mask(vap); |
5369 | mode = vap->va_mode & ALLPERMS; | | 5369 | mode = vap->va_mode & ALLPERMS; |
5370 | | | 5370 | |
5371 | /* ZFS wants a null-terminated name. */ | | 5371 | /* ZFS wants a null-terminated name. */ |
5372 | nm = PNBUF_GET(); | | 5372 | nm = PNBUF_GET(); |
5373 | (void)strlcpy(nm, cnp->cn_nameptr, cnp->cn_namelen + 1); | | 5373 | (void)strlcpy(nm, cnp->cn_nameptr, cnp->cn_namelen + 1); |
5374 | | | 5374 | |
5375 | /* XXX !EXCL is wrong here... */ | | 5375 | /* XXX !EXCL is wrong here... */ |
5376 | error = zfs_create(dvp, nm, vap, !EXCL, mode, vpp, cnp->cn_cred, NULL); | | 5376 | error = zfs_create(dvp, nm, vap, !EXCL, mode, vpp, cnp->cn_cred, NULL); |
5377 | | | 5377 | |
5378 | PNBUF_PUT(nm); | | 5378 | PNBUF_PUT(nm); |
5379 | | | 5379 | |
5380 | KASSERT((error == 0) == (*vpp != NULL)); | | 5380 | KASSERT((error == 0) == (*vpp != NULL)); |
5381 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); | | 5381 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); |
5382 | if (error == 0) | | 5382 | if (error == 0) |
5383 | VN_KNOTE(dvp, NOTE_WRITE); | | 5383 | VN_KNOTE(dvp, NOTE_WRITE); |
5384 | if (*vpp != NULL) | | 5384 | if (*vpp != NULL) |
5385 | VOP_UNLOCK(*vpp, 0); | | 5385 | VOP_UNLOCK(*vpp, 0); |
5386 | | | 5386 | |
5387 | return (error); | | 5387 | return (error); |
5388 | } | | 5388 | } |
5389 | | | 5389 | |
5390 | static int | | 5390 | static int |
5391 | zfs_netbsd_remove(void *v) | | 5391 | zfs_netbsd_remove(void *v) |
5392 | { | | 5392 | { |
5393 | struct vop_remove_v2_args /* { | | 5393 | struct vop_remove_v2_args /* { |
5394 | struct vnode *a_dvp; | | 5394 | struct vnode *a_dvp; |
5395 | struct vnode *a_vp; | | 5395 | struct vnode *a_vp; |
5396 | struct componentname *a_cnp; | | 5396 | struct componentname *a_cnp; |
5397 | } */ *ap = v; | | 5397 | } */ *ap = v; |
5398 | struct vnode *dvp = ap->a_dvp; | | 5398 | struct vnode *dvp = ap->a_dvp; |
5399 | struct vnode *vp = ap->a_vp; | | 5399 | struct vnode *vp = ap->a_vp; |
5400 | struct componentname *cnp = ap->a_cnp; | | 5400 | struct componentname *cnp = ap->a_cnp; |
5401 | char *nm; | | 5401 | char *nm; |
5402 | int error; | | 5402 | int error; |
5403 | | | 5403 | |
5404 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); | | 5404 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); |
5405 | KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); | | 5405 | KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); |
5406 | | | 5406 | |
5407 | /* ZFS wants a null-terminated name. */ | | 5407 | /* ZFS wants a null-terminated name. */ |
5408 | nm = PNBUF_GET(); | | 5408 | nm = PNBUF_GET(); |
5409 | (void)strlcpy(nm, cnp->cn_nameptr, cnp->cn_namelen + 1); | | 5409 | (void)strlcpy(nm, cnp->cn_nameptr, cnp->cn_namelen + 1); |
5410 | | | 5410 | |
5411 | error = zfs_remove(dvp, vp, nm, cnp->cn_cred); | | 5411 | error = zfs_remove(dvp, vp, nm, cnp->cn_cred); |
5412 | | | 5412 | |
5413 | PNBUF_PUT(nm); | | 5413 | PNBUF_PUT(nm); |
5414 | if (error == 0) { | | 5414 | if (error == 0) { |
5415 | VN_KNOTE(vp, NOTE_DELETE); | | 5415 | VN_KNOTE(vp, NOTE_DELETE); |
5416 | VN_KNOTE(dvp, NOTE_WRITE); | | 5416 | VN_KNOTE(dvp, NOTE_WRITE); |
5417 | } | | 5417 | } |
5418 | vput(vp); | | 5418 | vput(vp); |
5419 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); | | 5419 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); |
5420 | return (error); | | 5420 | return (error); |
5421 | } | | 5421 | } |
5422 | | | 5422 | |
5423 | static int | | 5423 | static int |
5424 | zfs_netbsd_mkdir(void *v) | | 5424 | zfs_netbsd_mkdir(void *v) |
5425 | { | | 5425 | { |
5426 | struct vop_mkdir_v3_args /* { | | 5426 | struct vop_mkdir_v3_args /* { |
5427 | struct vnode *a_dvp; | | 5427 | struct vnode *a_dvp; |
5428 | struct vnode **a_vpp; | | 5428 | struct vnode **a_vpp; |
5429 | struct componentname *a_cnp; | | 5429 | struct componentname *a_cnp; |
5430 | struct vattr *a_vap; | | 5430 | struct vattr *a_vap; |
5431 | } */ *ap = v; | | 5431 | } */ *ap = v; |
5432 | struct vnode *dvp = ap->a_dvp; | | 5432 | struct vnode *dvp = ap->a_dvp; |
5433 | struct vnode **vpp = ap->a_vpp; | | 5433 | struct vnode **vpp = ap->a_vpp; |
5434 | struct componentname *cnp = ap->a_cnp; | | 5434 | struct componentname *cnp = ap->a_cnp; |
5435 | struct vattr *vap = ap->a_vap; | | 5435 | struct vattr *vap = ap->a_vap; |
5436 | char *nm; | | 5436 | char *nm; |
5437 | int error; | | 5437 | int error; |
5438 | | | 5438 | |
5439 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); | | 5439 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); |
5440 | | | 5440 | |
5441 | vattr_init_mask(vap); | | 5441 | vattr_init_mask(vap); |
5442 | | | 5442 | |
5443 | /* ZFS wants a null-terminated name. */ | | 5443 | /* ZFS wants a null-terminated name. */ |
5444 | nm = PNBUF_GET(); | | 5444 | nm = PNBUF_GET(); |
5445 | (void)strlcpy(nm, cnp->cn_nameptr, cnp->cn_namelen + 1); | | 5445 | (void)strlcpy(nm, cnp->cn_nameptr, cnp->cn_namelen + 1); |
5446 | | | 5446 | |
5447 | error = zfs_mkdir(dvp, nm, vap, vpp, cnp->cn_cred); | | 5447 | error = zfs_mkdir(dvp, nm, vap, vpp, cnp->cn_cred); |
5448 | | | 5448 | |
5449 | PNBUF_PUT(nm); | | 5449 | PNBUF_PUT(nm); |
5450 | | | 5450 | |
5451 | KASSERT((error == 0) == (*vpp != NULL)); | | 5451 | KASSERT((error == 0) == (*vpp != NULL)); |
5452 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); | | 5452 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); |
5453 | if (error == 0) | | 5453 | if (error == 0) |
5454 | VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK); | | 5454 | VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK); |
5455 | if (*vpp != NULL) | | 5455 | if (*vpp != NULL) |
5456 | VOP_UNLOCK(*vpp, 0); | | 5456 | VOP_UNLOCK(*vpp, 0); |
5457 | | | 5457 | |
5458 | return (error); | | 5458 | return (error); |
5459 | } | | 5459 | } |
5460 | | | 5460 | |
5461 | static int | | 5461 | static int |
5462 | zfs_netbsd_rmdir(void *v) | | 5462 | zfs_netbsd_rmdir(void *v) |
5463 | { | | 5463 | { |
5464 | struct vop_rmdir_v2_args /* { | | 5464 | struct vop_rmdir_v2_args /* { |
5465 | struct vnode *a_dvp; | | 5465 | struct vnode *a_dvp; |
5466 | struct vnode *a_vp; | | 5466 | struct vnode *a_vp; |
5467 | struct componentname *a_cnp; | | 5467 | struct componentname *a_cnp; |
5468 | } */ *ap = v; | | 5468 | } */ *ap = v; |
5469 | struct vnode *dvp = ap->a_dvp; | | 5469 | struct vnode *dvp = ap->a_dvp; |
5470 | struct vnode *vp = ap->a_vp; | | 5470 | struct vnode *vp = ap->a_vp; |
5471 | struct componentname *cnp = ap->a_cnp; | | 5471 | struct componentname *cnp = ap->a_cnp; |
5472 | char *nm; | | 5472 | char *nm; |
5473 | int error; | | 5473 | int error; |
5474 | | | 5474 | |
5475 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); | | 5475 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); |
5476 | KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); | | 5476 | KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); |
5477 | | | 5477 | |
5478 | /* ZFS wants a null-terminated name. */ | | 5478 | /* ZFS wants a null-terminated name. */ |
5479 | nm = PNBUF_GET(); | | 5479 | nm = PNBUF_GET(); |
5480 | (void)strlcpy(nm, cnp->cn_nameptr, cnp->cn_namelen + 1); | | 5480 | (void)strlcpy(nm, cnp->cn_nameptr, cnp->cn_namelen + 1); |
5481 | | | 5481 | |
5482 | error = zfs_rmdir(dvp, vp, nm, cnp->cn_cred); | | 5482 | error = zfs_rmdir(dvp, vp, nm, cnp->cn_cred); |
5483 | | | 5483 | |
5484 | PNBUF_PUT(nm); | | 5484 | PNBUF_PUT(nm); |
5485 | if (error == 0) { | | 5485 | if (error == 0) { |
5486 | VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK); | | 5486 | VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK); |
5487 | VN_KNOTE(vp, NOTE_DELETE); | | 5487 | VN_KNOTE(vp, NOTE_DELETE); |
5488 | } | | 5488 | } |
5489 | vput(vp); | | 5489 | vput(vp); |
5490 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); | | 5490 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); |
5491 | return error; | | 5491 | return error; |
5492 | } | | 5492 | } |
5493 | | | 5493 | |
5494 | static int | | 5494 | static int |
5495 | zfs_netbsd_readdir(void *v) | | 5495 | zfs_netbsd_readdir(void *v) |
5496 | { | | 5496 | { |
5497 | struct vop_readdir_args *ap = v; | | 5497 | struct vop_readdir_args *ap = v; |
5498 | | | 5498 | |
5499 | return (zfs_readdir(ap->a_vp, ap->a_uio, ap->a_cred, ap->a_eofflag, | | 5499 | return (zfs_readdir(ap->a_vp, ap->a_uio, ap->a_cred, ap->a_eofflag, |
5500 | ap->a_ncookies, ap->a_cookies)); | | 5500 | ap->a_ncookies, ap->a_cookies)); |
5501 | } | | 5501 | } |
5502 | | | 5502 | |
5503 | static int | | 5503 | static int |
5504 | zfs_netbsd_fsync(void *v) | | 5504 | zfs_netbsd_fsync(void *v) |
5505 | { | | 5505 | { |
5506 | struct vop_fsync_args *ap = v; | | 5506 | struct vop_fsync_args *ap = v; |
5507 | | | 5507 | |
5508 | return (zfs_fsync(ap->a_vp, ap->a_flags, ap->a_cred, NULL)); | | 5508 | return (zfs_fsync(ap->a_vp, ap->a_flags, ap->a_cred, NULL)); |
5509 | } | | 5509 | } |
5510 | | | 5510 | |
5511 | static int | | 5511 | static int |
5512 | zfs_spec_fsync(void *v) | | 5512 | zfs_spec_fsync(void *v) |
5513 | { | | 5513 | { |
5514 | struct vop_fsync_args *ap = v; | | 5514 | struct vop_fsync_args *ap = v; |
5515 | int error; | | 5515 | int error; |
5516 | | | 5516 | |
5517 | error = spec_fsync(v); | | 5517 | error = spec_fsync(v); |
5518 | if (error) | | 5518 | if (error) |
5519 | return error; | | 5519 | return error; |
5520 | | | 5520 | |
5521 | return (zfs_fsync(ap->a_vp, ap->a_flags, ap->a_cred, NULL)); | | 5521 | return (zfs_fsync(ap->a_vp, ap->a_flags, ap->a_cred, NULL)); |
5522 | } | | 5522 | } |
5523 | | | 5523 | |
5524 | static int | | 5524 | static int |
5525 | zfs_netbsd_getattr(void *v) | | 5525 | zfs_netbsd_getattr(void *v) |
5526 | { | | 5526 | { |
5527 | struct vop_getattr_args *ap = v; | | 5527 | struct vop_getattr_args *ap = v; |
5528 | vattr_t *vap = ap->a_vap; | | 5528 | vattr_t *vap = ap->a_vap; |
5529 | xvattr_t xvap; | | 5529 | xvattr_t xvap; |
5530 | u_long fflags = 0; | | 5530 | u_long fflags = 0; |
5531 | int error; | | 5531 | int error; |
5532 | | | 5532 | |
5533 | xva_init(&xvap); | | 5533 | xva_init(&xvap); |
5534 | xvap.xva_vattr = *vap; | | 5534 | xvap.xva_vattr = *vap; |
5535 | xvap.xva_vattr.va_mask |= AT_XVATTR; | | 5535 | xvap.xva_vattr.va_mask |= AT_XVATTR; |
5536 | | | 5536 | |
5537 | /* Convert chflags into ZFS-type flags. */ | | 5537 | /* Convert chflags into ZFS-type flags. */ |
5538 | /* XXX: what about SF_SETTABLE?. */ | | 5538 | /* XXX: what about SF_SETTABLE?. */ |
5539 | XVA_SET_REQ(&xvap, XAT_IMMUTABLE); | | 5539 | XVA_SET_REQ(&xvap, XAT_IMMUTABLE); |
5540 | XVA_SET_REQ(&xvap, XAT_APPENDONLY); | | 5540 | XVA_SET_REQ(&xvap, XAT_APPENDONLY); |
5541 | XVA_SET_REQ(&xvap, XAT_NOUNLINK); | | 5541 | XVA_SET_REQ(&xvap, XAT_NOUNLINK); |
5542 | XVA_SET_REQ(&xvap, XAT_NODUMP); | | 5542 | XVA_SET_REQ(&xvap, XAT_NODUMP); |
5543 | error = zfs_getattr(ap->a_vp, (vattr_t *)&xvap, 0, ap->a_cred, NULL); | | 5543 | error = zfs_getattr(ap->a_vp, (vattr_t *)&xvap, 0, ap->a_cred, NULL); |
5544 | if (error != 0) | | 5544 | if (error != 0) |
5545 | return (error); | | 5545 | return (error); |
5546 | | | 5546 | |
5547 | /* Convert ZFS xattr into chflags. */ | | 5547 | /* Convert ZFS xattr into chflags. */ |
5548 | #define FLAG_CHECK(fflag, xflag, xfield) do { \ | | 5548 | #define FLAG_CHECK(fflag, xflag, xfield) do { \ |
5549 | if (XVA_ISSET_RTN(&xvap, (xflag)) && (xfield) != 0) \ | | 5549 | if (XVA_ISSET_RTN(&xvap, (xflag)) && (xfield) != 0) \ |
5550 | fflags |= (fflag); \ | | 5550 | fflags |= (fflag); \ |
5551 | } while (0) | | 5551 | } while (0) |
5552 | FLAG_CHECK(SF_IMMUTABLE, XAT_IMMUTABLE, | | 5552 | FLAG_CHECK(SF_IMMUTABLE, XAT_IMMUTABLE, |
5553 | xvap.xva_xoptattrs.xoa_immutable); | | 5553 | xvap.xva_xoptattrs.xoa_immutable); |
5554 | FLAG_CHECK(SF_APPEND, XAT_APPENDONLY, | | 5554 | FLAG_CHECK(SF_APPEND, XAT_APPENDONLY, |
5555 | xvap.xva_xoptattrs.xoa_appendonly); | | 5555 | xvap.xva_xoptattrs.xoa_appendonly); |
5556 | FLAG_CHECK(SF_NOUNLINK, XAT_NOUNLINK, | | 5556 | FLAG_CHECK(SF_NOUNLINK, XAT_NOUNLINK, |
5557 | xvap.xva_xoptattrs.xoa_nounlink); | | 5557 | xvap.xva_xoptattrs.xoa_nounlink); |
5558 | FLAG_CHECK(UF_NODUMP, XAT_NODUMP, | | 5558 | FLAG_CHECK(UF_NODUMP, XAT_NODUMP, |
5559 | xvap.xva_xoptattrs.xoa_nodump); | | 5559 | xvap.xva_xoptattrs.xoa_nodump); |
5560 | #undef FLAG_CHECK | | 5560 | #undef FLAG_CHECK |
5561 | *vap = xvap.xva_vattr; | | 5561 | *vap = xvap.xva_vattr; |
5562 | vap->va_flags = fflags; | | 5562 | vap->va_flags = fflags; |
5563 | return (0); | | 5563 | return (0); |
5564 | } | | 5564 | } |
5565 | | | 5565 | |
5566 | static int | | 5566 | static int |
5567 | zfs_netbsd_setattr(void *v) | | 5567 | zfs_netbsd_setattr(void *v) |
5568 | { | | 5568 | { |
5569 | struct vop_setattr_args *ap = v; | | 5569 | struct vop_setattr_args *ap = v; |
5570 | vnode_t *vp = ap->a_vp; | | 5570 | vnode_t *vp = ap->a_vp; |
5571 | vattr_t *vap = ap->a_vap; | | 5571 | vattr_t *vap = ap->a_vap; |
5572 | cred_t *cred = ap->a_cred; | | 5572 | cred_t *cred = ap->a_cred; |
5573 | znode_t *zp = VTOZ(vp); | | 5573 | znode_t *zp = VTOZ(vp); |
5574 | xvattr_t xvap; | | 5574 | xvattr_t xvap; |
5575 | kauth_action_t action; | | 5575 | kauth_action_t action; |
5576 | u_long fflags, sfflags = 0; | | 5576 | u_long fflags, sfflags = 0; |
5577 | uint64_t zflags; | | 5577 | uint64_t zflags; |
5578 | int error, flags = 0; | | 5578 | int error, flags = 0; |
5579 | bool changing_sysflags; | | 5579 | bool changing_sysflags; |
5580 | | | 5580 | |
5581 | vattr_init_mask(vap); | | 5581 | vattr_init_mask(vap); |
5582 | vap->va_mask &= ~AT_NOSET; | | 5582 | vap->va_mask &= ~AT_NOSET; |
5583 | if (ISSET(vap->va_vaflags, VA_UTIMES_NULL)) | | 5583 | if (ISSET(vap->va_vaflags, VA_UTIMES_NULL)) |
5584 | flags |= ATTR_UTIME; | | 5584 | flags |= ATTR_UTIME; |
5585 | | | 5585 | |
5586 | xva_init(&xvap); | | 5586 | xva_init(&xvap); |
5587 | xvap.xva_vattr = *vap; | | 5587 | xvap.xva_vattr = *vap; |
5588 | | | 5588 | |
5589 | zflags = VTOZ(vp)->z_pflags; | | 5589 | zflags = VTOZ(vp)->z_pflags; |
5590 | | | 5590 | |
5591 | /* Ignore size changes on device nodes. */ | | 5591 | /* Ignore size changes on device nodes. */ |
5592 | if (vp->v_type == VBLK || vp->v_type == VCHR) | | 5592 | if (vp->v_type == VBLK || vp->v_type == VCHR) |
5593 | xvap.xva_vattr.va_mask &= ~AT_SIZE; | | 5593 | xvap.xva_vattr.va_mask &= ~AT_SIZE; |
5594 | if (vap->va_flags != VNOVAL) { | | 5594 | if (vap->va_flags != VNOVAL) { |
5595 | int error; | | 5595 | int error; |
5596 | | | 5596 | |
5597 | fflags = vap->va_flags; | | 5597 | fflags = vap->va_flags; |
5598 | if ((fflags & ~(SF_IMMUTABLE|SF_APPEND|SF_NOUNLINK|UF_NODUMP)) != 0) | | 5598 | if ((fflags & ~(SF_IMMUTABLE|SF_APPEND|SF_NOUNLINK|UF_NODUMP)) != 0) |
5599 | return (EOPNOTSUPP); | | 5599 | return (EOPNOTSUPP); |
5600 | | | 5600 | |
5601 | #define FLAG_CHANGE(fflag, zflag, xflag, xfield) do { \ | | 5601 | #define FLAG_CHANGE(fflag, zflag, xflag, xfield) do { \ |
5602 | if (((fflags & (fflag)) && !(zflags & (zflag))) || \ | | 5602 | if (((fflags & (fflag)) && !(zflags & (zflag))) || \ |
5603 | ((zflags & (zflag)) && !(fflags & (fflag)))) { \ | | 5603 | ((zflags & (zflag)) && !(fflags & (fflag)))) { \ |
5604 | XVA_SET_REQ(&xvap, (xflag)); \ | | 5604 | XVA_SET_REQ(&xvap, (xflag)); \ |
5605 | (xfield) = ((fflags & (fflag)) != 0); \ | | 5605 | (xfield) = ((fflags & (fflag)) != 0); \ |
5606 | if (((fflag) & SF_SETTABLE) != 0) \ | | 5606 | if (((fflag) & SF_SETTABLE) != 0) \ |
5607 | sfflags |= (fflag); \ | | 5607 | sfflags |= (fflag); \ |
5608 | } \ | | 5608 | } \ |
5609 | } while (0) | | 5609 | } while (0) |
5610 | /* Convert chflags into ZFS-type flags. */ | | 5610 | /* Convert chflags into ZFS-type flags. */ |
5611 | /* XXX: what about SF_SETTABLE?. */ | | 5611 | /* XXX: what about SF_SETTABLE?. */ |
5612 | FLAG_CHANGE(SF_IMMUTABLE, ZFS_IMMUTABLE, XAT_IMMUTABLE, | | 5612 | FLAG_CHANGE(SF_IMMUTABLE, ZFS_IMMUTABLE, XAT_IMMUTABLE, |
5613 | xvap.xva_xoptattrs.xoa_immutable); | | 5613 | xvap.xva_xoptattrs.xoa_immutable); |
5614 | FLAG_CHANGE(SF_APPEND, ZFS_APPENDONLY, XAT_APPENDONLY, | | 5614 | FLAG_CHANGE(SF_APPEND, ZFS_APPENDONLY, XAT_APPENDONLY, |
5615 | xvap.xva_xoptattrs.xoa_appendonly); | | 5615 | xvap.xva_xoptattrs.xoa_appendonly); |
5616 | FLAG_CHANGE(SF_NOUNLINK, ZFS_NOUNLINK, XAT_NOUNLINK, | | 5616 | FLAG_CHANGE(SF_NOUNLINK, ZFS_NOUNLINK, XAT_NOUNLINK, |
5617 | xvap.xva_xoptattrs.xoa_nounlink); | | 5617 | xvap.xva_xoptattrs.xoa_nounlink); |
5618 | FLAG_CHANGE(UF_NODUMP, ZFS_NODUMP, XAT_NODUMP, | | 5618 | FLAG_CHANGE(UF_NODUMP, ZFS_NODUMP, XAT_NODUMP, |
5619 | xvap.xva_xoptattrs.xoa_nodump); | | 5619 | xvap.xva_xoptattrs.xoa_nodump); |
5620 | #undef FLAG_CHANGE | | 5620 | #undef FLAG_CHANGE |
5621 | | | 5621 | |
5622 | action = KAUTH_VNODE_WRITE_FLAGS; | | 5622 | action = KAUTH_VNODE_WRITE_FLAGS; |
5623 | changing_sysflags = false; | | 5623 | changing_sysflags = false; |
5624 | | | 5624 | |
5625 | if (zflags & (ZFS_IMMUTABLE|ZFS_APPENDONLY|ZFS_NOUNLINK)) { | | 5625 | if (zflags & (ZFS_IMMUTABLE|ZFS_APPENDONLY|ZFS_NOUNLINK)) { |
5626 | action |= KAUTH_VNODE_HAS_SYSFLAGS; | | 5626 | action |= KAUTH_VNODE_HAS_SYSFLAGS; |
5627 | } | | 5627 | } |
5628 | if (sfflags != 0) { | | 5628 | if (sfflags != 0) { |
5629 | action |= KAUTH_VNODE_WRITE_SYSFLAGS; | | 5629 | action |= KAUTH_VNODE_WRITE_SYSFLAGS; |
5630 | changing_sysflags = true; | | 5630 | changing_sysflags = true; |
5631 | } | | 5631 | } |
5632 | | | 5632 | |
5633 | error = kauth_authorize_vnode(cred, action, vp, NULL, | | 5633 | error = kauth_authorize_vnode(cred, action, vp, NULL, |
5634 | genfs_can_chflags(cred, vp->v_type, zp->z_uid, | | 5634 | genfs_can_chflags(cred, vp->v_type, zp->z_uid, |
5635 | changing_sysflags)); | | 5635 | changing_sysflags)); |
5636 | if (error) | | 5636 | if (error) |
5637 | return error; | | 5637 | return error; |
5638 | } | | 5638 | } |
5639 | | | 5639 | |
5640 | if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL || | | 5640 | if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL || |
5641 | vap->va_birthtime.tv_sec != VNOVAL) { | | 5641 | vap->va_birthtime.tv_sec != VNOVAL) { |
5642 | error = kauth_authorize_vnode(cred, KAUTH_VNODE_WRITE_TIMES, vp, | | 5642 | error = kauth_authorize_vnode(cred, KAUTH_VNODE_WRITE_TIMES, vp, |
5643 | NULL, genfs_can_chtimes(vp, vap->va_vaflags, zp->z_uid, | | 5643 | NULL, genfs_can_chtimes(vp, vap->va_vaflags, zp->z_uid, |
5644 | cred)); | | 5644 | cred)); |
5645 | if (error) | | 5645 | if (error) |
5646 | return error; | | 5646 | return error; |
5647 | } | | 5647 | } |
5648 | | | 5648 | |
5649 | error = zfs_setattr(vp, (vattr_t *)&xvap, flags, cred, NULL); | | 5649 | error = zfs_setattr(vp, (vattr_t *)&xvap, flags, cred, NULL); |
5650 | if (error == 0) | | 5650 | if (error == 0) |
5651 | VN_KNOTE(vp, NOTE_ATTRIB); | | 5651 | VN_KNOTE(vp, NOTE_ATTRIB); |
5652 | | | 5652 | |
5653 | return error; | | 5653 | return error; |
5654 | } | | 5654 | } |
5655 | | | 5655 | |
5656 | static int | | 5656 | static int |
5657 | zfs_netbsd_rename(void *v) | | 5657 | zfs_netbsd_rename(void *v) |
5658 | { | | 5658 | { |
5659 | struct vop_rename_args /* { | | 5659 | struct vop_rename_args /* { |
5660 | struct vnode *a_fdvp; | | 5660 | struct vnode *a_fdvp; |
5661 | struct vnode *a_fvp; | | 5661 | struct vnode *a_fvp; |
5662 | struct componentname *a_fcnp; | | 5662 | struct componentname *a_fcnp; |
5663 | struct vnode *a_tdvp; | | 5663 | struct vnode *a_tdvp; |
5664 | struct vnode *a_tvp; | | 5664 | struct vnode *a_tvp; |
5665 | struct componentname *a_tcnp; | | 5665 | struct componentname *a_tcnp; |
5666 | } */ *ap = v; | | 5666 | } */ *ap = v; |
5667 | vnode_t *fdvp = ap->a_fdvp; | | 5667 | vnode_t *fdvp = ap->a_fdvp; |
5668 | vnode_t *fvp = ap->a_fvp; | | 5668 | vnode_t *fvp = ap->a_fvp; |
5669 | struct componentname *fcnp = ap->a_fcnp; | | 5669 | struct componentname *fcnp = ap->a_fcnp; |
5670 | vnode_t *tdvp = ap->a_tdvp; | | 5670 | vnode_t *tdvp = ap->a_tdvp; |
5671 | vnode_t *tvp = ap->a_tvp; | | 5671 | vnode_t *tvp = ap->a_tvp; |
5672 | struct componentname *tcnp = ap->a_tcnp; | | 5672 | struct componentname *tcnp = ap->a_tcnp; |
5673 | kauth_cred_t cred; | | 5673 | kauth_cred_t cred; |
5674 | int error; | | 5674 | int error; |
5675 | | | 5675 | |
5676 | KASSERT(VOP_ISLOCKED(tdvp) == LK_EXCLUSIVE); | | 5676 | KASSERT(VOP_ISLOCKED(tdvp) == LK_EXCLUSIVE); |
5677 | KASSERT(tvp == NULL || VOP_ISLOCKED(tvp) == LK_EXCLUSIVE); | | 5677 | KASSERT(tvp == NULL || VOP_ISLOCKED(tvp) == LK_EXCLUSIVE); |
5678 | KASSERT(fdvp->v_type == VDIR); | | 5678 | KASSERT(fdvp->v_type == VDIR); |
5679 | KASSERT(tdvp->v_type == VDIR); | | 5679 | KASSERT(tdvp->v_type == VDIR); |
5680 | | | 5680 | |
5681 | cred = fcnp->cn_cred; | | 5681 | cred = fcnp->cn_cred; |
5682 | | | 5682 | |
5683 | /* | | 5683 | /* |
5684 | * XXX Want a better equality test. `tcnp->cn_cred == cred' | | 5684 | * XXX Want a better equality test. `tcnp->cn_cred == cred' |
5685 | * hoses p2k because puffs transmits the creds separately and | | 5685 | * hoses p2k because puffs transmits the creds separately and |
5686 | * allocates distinct but equivalent structures for them. | | 5686 | * allocates distinct but equivalent structures for them. |
5687 | */ | | 5687 | */ |
5688 | KASSERT(kauth_cred_uidmatch(cred, tcnp->cn_cred)); | | 5688 | KASSERT(kauth_cred_uidmatch(cred, tcnp->cn_cred)); |
5689 | | | 5689 | |
5690 | /* | | 5690 | /* |
5691 | * Drop the insane locks. | | 5691 | * Drop the insane locks. |
5692 | */ | | 5692 | */ |
5693 | VOP_UNLOCK(tdvp, 0); | | 5693 | VOP_UNLOCK(tdvp, 0); |
5694 | if (tvp != NULL && tvp != tdvp) | | 5694 | if (tvp != NULL && tvp != tdvp) |
5695 | VOP_UNLOCK(tvp, 0); | | 5695 | VOP_UNLOCK(tvp, 0); |
5696 | | | 5696 | |
5697 | /* | | 5697 | /* |
5698 | * Release the source and target nodes; zfs_rename will look | | 5698 | * Release the source and target nodes; zfs_rename will look |
5699 | * them up again once the locking situation is sane. | | 5699 | * them up again once the locking situation is sane. |
5700 | */ | | 5700 | */ |
5701 | VN_RELE(fvp); | | 5701 | VN_RELE(fvp); |
5702 | if (tvp != NULL) | | 5702 | if (tvp != NULL) |
5703 | VN_RELE(tvp); | | 5703 | VN_RELE(tvp); |
5704 | fvp = NULL; | | 5704 | fvp = NULL; |
5705 | tvp = NULL; | | 5705 | tvp = NULL; |
5706 | | | 5706 | |
5707 | /* | | 5707 | /* |
5708 | * Do the rename ZFSly. | | 5708 | * Do the rename ZFSly. |
5709 | */ | | 5709 | */ |
5710 | error = zfs_rename(fdvp, &fvp, fcnp, tdvp, &tvp, tcnp, cred); | | 5710 | error = zfs_rename(fdvp, &fvp, fcnp, tdvp, &tvp, tcnp, cred); |
5711 | | | 5711 | |
5712 | /* | | 5712 | /* |
5713 | * Release the directories now too, because the VOP_RENAME | | 5713 | * Release the directories now too, because the VOP_RENAME |
5714 | * protocol is insane. | | 5714 | * protocol is insane. |
5715 | */ | | 5715 | */ |
5716 | | | 5716 | |
5717 | VN_RELE(fdvp); | | 5717 | VN_RELE(fdvp); |
5718 | VN_RELE(tdvp); | | 5718 | VN_RELE(tdvp); |
5719 | if (fvp != NULL) | | 5719 | if (fvp != NULL) |
5720 | VN_RELE(fvp); | | 5720 | VN_RELE(fvp); |
5721 | if (tvp != NULL) | | 5721 | if (tvp != NULL) |
5722 | VN_RELE(tvp); | | 5722 | VN_RELE(tvp); |
5723 | | | 5723 | |
5724 | return (error); | | 5724 | return (error); |
5725 | } | | 5725 | } |
5726 | | | 5726 | |
5727 | static int | | 5727 | static int |
5728 | zfs_netbsd_symlink(void *v) | | 5728 | zfs_netbsd_symlink(void *v) |
5729 | { | | 5729 | { |
5730 | struct vop_symlink_v3_args /* { | | 5730 | struct vop_symlink_v3_args /* { |
5731 | struct vnode *a_dvp; | | 5731 | struct vnode *a_dvp; |
5732 | struct vnode **a_vpp; | | 5732 | struct vnode **a_vpp; |
5733 | struct componentname *a_cnp; | | 5733 | struct componentname *a_cnp; |
5734 | struct vattr *a_vap; | | 5734 | struct vattr *a_vap; |
5735 | char *a_target; | | 5735 | char *a_target; |
5736 | } */ *ap = v; | | 5736 | } */ *ap = v; |
5737 | struct vnode *dvp = ap->a_dvp; | | 5737 | struct vnode *dvp = ap->a_dvp; |
5738 | struct vnode **vpp = ap->a_vpp; | | 5738 | struct vnode **vpp = ap->a_vpp; |
5739 | struct componentname *cnp = ap->a_cnp; | | 5739 | struct componentname *cnp = ap->a_cnp; |
5740 | struct vattr *vap = ap->a_vap; | | 5740 | struct vattr *vap = ap->a_vap; |
5741 | char *target = ap->a_target; | | 5741 | char *target = ap->a_target; |
5742 | char *nm; | | 5742 | char *nm; |
5743 | int error; | | 5743 | int error; |
5744 | | | 5744 | |
5745 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); | | 5745 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); |
5746 | | | 5746 | |
5747 | vap->va_type = VLNK; /* Netbsd: Syscall only sets va_mode. */ | | 5747 | vap->va_type = VLNK; /* Netbsd: Syscall only sets va_mode. */ |
5748 | vattr_init_mask(vap); | | 5748 | vattr_init_mask(vap); |
5749 | | | 5749 | |
5750 | /* ZFS wants a null-terminated name. */ | | 5750 | /* ZFS wants a null-terminated name. */ |
5751 | nm = PNBUF_GET(); | | 5751 | nm = PNBUF_GET(); |
5752 | (void)strlcpy(nm, cnp->cn_nameptr, cnp->cn_namelen + 1); | | 5752 | (void)strlcpy(nm, cnp->cn_nameptr, cnp->cn_namelen + 1); |
5753 | | | 5753 | |
5754 | error = zfs_symlink(dvp, vpp, nm, vap, target, cnp->cn_cred, 0); | | 5754 | error = zfs_symlink(dvp, vpp, nm, vap, target, cnp->cn_cred, 0); |
5755 | | | 5755 | |
5756 | PNBUF_PUT(nm); | | 5756 | PNBUF_PUT(nm); |
5757 | if (error == 0) | | 5757 | if (error == 0) |
5758 | VN_KNOTE(ap->a_dvp, NOTE_WRITE); | | 5758 | VN_KNOTE(ap->a_dvp, NOTE_WRITE); |
5759 | KASSERT((error == 0) == (*vpp != NULL)); | | 5759 | KASSERT((error == 0) == (*vpp != NULL)); |
5760 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); | | 5760 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); |
5761 | if (*vpp != NULL) | | 5761 | if (*vpp != NULL) |
5762 | VOP_UNLOCK(*vpp, 0); | | 5762 | VOP_UNLOCK(*vpp, 0); |
5763 | | | 5763 | |
5764 | return (error); | | 5764 | return (error); |
5765 | } | | 5765 | } |
5766 | | | 5766 | |
5767 | static int | | 5767 | static int |
5768 | zfs_netbsd_readlink(void *v) | | 5768 | zfs_netbsd_readlink(void *v) |
5769 | { | | 5769 | { |
5770 | struct vop_readlink_args *ap = v; | | 5770 | struct vop_readlink_args *ap = v; |
5771 | | | 5771 | |
5772 | return (zfs_readlink(ap->a_vp, ap->a_uio, ap->a_cred, NULL)); | | 5772 | return (zfs_readlink(ap->a_vp, ap->a_uio, ap->a_cred, NULL)); |
5773 | } | | 5773 | } |
5774 | | | 5774 | |
5775 | static int | | 5775 | static int |
5776 | zfs_netbsd_link(void *v) | | 5776 | zfs_netbsd_link(void *v) |
5777 | { | | 5777 | { |
5778 | struct vop_link_v2_args /* { | | 5778 | struct vop_link_v2_args /* { |
5779 | struct vnode *a_dvp; | | 5779 | struct vnode *a_dvp; |
5780 | struct vnode *a_vp; | | 5780 | struct vnode *a_vp; |
5781 | struct componentname *a_cnp; | | 5781 | struct componentname *a_cnp; |
5782 | } */ *ap = v; | | 5782 | } */ *ap = v; |
5783 | struct vnode *dvp = ap->a_dvp; | | 5783 | struct vnode *dvp = ap->a_dvp; |
5784 | struct vnode *vp = ap->a_vp; | | 5784 | struct vnode *vp = ap->a_vp; |
5785 | struct componentname *cnp = ap->a_cnp; | | 5785 | struct componentname *cnp = ap->a_cnp; |
5786 | char *nm; | | 5786 | char *nm; |
5787 | int error; | | 5787 | int error; |
5788 | | | 5788 | |
5789 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); | | 5789 | KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); |
5790 | | | 5790 | |
5791 | /* ZFS wants a null-terminated name. */ | | 5791 | /* ZFS wants a null-terminated name. */ |
5792 | nm = PNBUF_GET(); | | 5792 | nm = PNBUF_GET(); |
5793 | (void)strlcpy(nm, cnp->cn_nameptr, cnp->cn_namelen + 1); | | 5793 | (void)strlcpy(nm, cnp->cn_nameptr, cnp->cn_namelen + 1); |
5794 | | | 5794 | |
5795 | vn_lock(vp, LK_EXCLUSIVE); | | 5795 | vn_lock(vp, LK_EXCLUSIVE); |
5796 | error = zfs_link(dvp, vp, nm, cnp->cn_cred, | | 5796 | error = zfs_link(dvp, vp, nm, cnp->cn_cred, |
5797 | NULL, 0); | | 5797 | NULL, 0); |
5798 | | | 5798 | |
5799 | PNBUF_PUT(nm); | | 5799 | PNBUF_PUT(nm); |
5800 | if (error == 0) { | | 5800 | if (error == 0) { |
5801 | VN_KNOTE(vp, NOTE_LINK); | | 5801 | VN_KNOTE(vp, NOTE_LINK); |
5802 | VN_KNOTE(dvp, NOTE_WRITE); | | 5802 | VN_KNOTE(dvp, NOTE_WRITE); |
5803 | } | | 5803 | } |
5804 | VOP_UNLOCK(vp, 0); | | 5804 | VOP_UNLOCK(vp, 0); |
5805 | return error; | | 5805 | return error; |
5806 | } | | 5806 | } |
5807 | | | 5807 | |
5808 | static int | | 5808 | static int |
5809 | zfs_netbsd_inactive(void *v) | | 5809 | zfs_netbsd_inactive(void *v) |
5810 | { | | 5810 | { |
5811 | struct vop_inactive_v2_args *ap = v; | | 5811 | struct vop_inactive_v2_args *ap = v; |
5812 | vnode_t *vp = ap->a_vp; | | 5812 | vnode_t *vp = ap->a_vp; |
5813 | znode_t *zp = VTOZ(vp); | | 5813 | znode_t *zp = VTOZ(vp); |
5814 | | | 5814 | |
5815 | /* | | 5815 | /* |
5816 | * NetBSD: nothing to do here, other than indicate if the | | 5816 | * NetBSD: nothing to do here, other than indicate if the |
5817 | * vnode should be reclaimed. No need to lock, if we race | | 5817 | * vnode should be reclaimed. No need to lock, if we race |
5818 | * vrele() will call us again. | | 5818 | * vrele() will call us again. |
5819 | */ | | 5819 | */ |
5820 | *ap->a_recycle = (zp->z_unlinked != 0); | | 5820 | *ap->a_recycle = (zp->z_unlinked != 0); |
5821 | | | 5821 | |
5822 | return (0); | | 5822 | return (0); |
5823 | } | | 5823 | } |
5824 | | | 5824 | |
5825 | static int | | 5825 | static int |
5826 | zfs_netbsd_reclaim(void *v) | | 5826 | zfs_netbsd_reclaim(void *v) |
5827 | { | | 5827 | { |
5828 | struct vop_reclaim_v2_args /* { | | 5828 | struct vop_reclaim_v2_args /* { |
5829 | struct vnode *a_vp; | | 5829 | struct vnode *a_vp; |
5830 | } */ *ap = v; | | 5830 | } */ *ap = v; |
5831 | struct vnode *vp = ap->a_vp; | | 5831 | struct vnode *vp = ap->a_vp; |
5832 | znode_t *zp; | | 5832 | znode_t *zp; |
5833 | zfsvfs_t *zfsvfs; | | 5833 | zfsvfs_t *zfsvfs; |
5834 | int error; | | 5834 | int error; |
5835 | | | 5835 | |
5836 | VOP_UNLOCK(vp, 0); | | 5836 | VOP_UNLOCK(vp, 0); |
5837 | zp = VTOZ(vp); | | 5837 | zp = VTOZ(vp); |
5838 | zfsvfs = zp->z_zfsvfs; | | 5838 | zfsvfs = zp->z_zfsvfs; |
5839 | | | 5839 | |
5840 | KASSERTMSG(!vn_has_cached_data(vp), "vp %p", vp); | | 5840 | KASSERTMSG(!vn_has_cached_data(vp), "vp %p", vp); |
5841 | | | 5841 | |
5842 | rw_enter(&zfsvfs->z_teardown_inactive_lock, RW_READER); | | 5842 | rw_enter(&zfsvfs->z_teardown_inactive_lock, RW_READER); |
5843 | | | 5843 | |
5844 | /* | | 5844 | /* |
5845 | * Process a deferred atime update. | | 5845 | * Process a deferred atime update. |
5846 | */ | | 5846 | */ |
5847 | if (zp->z_atime_dirty && zp->z_unlinked == 0 && zp->z_sa_hdl != NULL) { | | 5847 | if (zp->z_atime_dirty && zp->z_unlinked == 0 && zp->z_sa_hdl != NULL) { |
5848 | dmu_tx_t *tx = dmu_tx_create(zfsvfs->z_os); | | 5848 | dmu_tx_t *tx = dmu_tx_create(zfsvfs->z_os); |
5849 | | | 5849 | |
5850 | dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE); | | 5850 | dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE); |
5851 | zfs_sa_upgrade_txholds(tx, zp); | | 5851 | zfs_sa_upgrade_txholds(tx, zp); |
5852 | error = dmu_tx_assign(tx, TXG_WAIT); | | 5852 | error = dmu_tx_assign(tx, TXG_WAIT); |
5853 | if (error) { | | 5853 | if (error) { |
5854 | dmu_tx_abort(tx); | | 5854 | dmu_tx_abort(tx); |
5855 | } else { | | 5855 | } else { |
5856 | (void) sa_update(zp->z_sa_hdl, SA_ZPL_ATIME(zfsvfs), | | 5856 | (void) sa_update(zp->z_sa_hdl, SA_ZPL_ATIME(zfsvfs), |
5857 | (void *)&zp->z_atime, sizeof (zp->z_atime), tx); | | 5857 | (void *)&zp->z_atime, sizeof (zp->z_atime), tx); |
5858 | zp->z_atime_dirty = 0; | | 5858 | zp->z_atime_dirty = 0; |
5859 | dmu_tx_commit(tx); | | 5859 | dmu_tx_commit(tx); |
5860 | } | | 5860 | } |
5861 | } | | | |
5862 | | | 5861 | |
5863 | if (zfsvfs->z_log) | | 5862 | if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) |
5864 | zil_commit(zfsvfs->z_log, zp->z_id); | | 5863 | zil_commit(zfsvfs->z_log, zp->z_id); |
| | | 5864 | } |
5865 | | | 5865 | |
5866 | if (zp->z_sa_hdl == NULL) | | 5866 | if (zp->z_sa_hdl == NULL) |
5867 | zfs_znode_free(zp); | | 5867 | zfs_znode_free(zp); |
5868 | else | | 5868 | else |
5869 | zfs_zinactive(zp); | | 5869 | zfs_zinactive(zp); |
5870 | rw_exit(&zfsvfs->z_teardown_inactive_lock); | | 5870 | rw_exit(&zfsvfs->z_teardown_inactive_lock); |
5871 | return 0; | | 5871 | return 0; |
5872 | } | | 5872 | } |
5873 | | | 5873 | |
5874 | static int | | 5874 | static int |
5875 | zfs_netbsd_fid(void *v) | | 5875 | zfs_netbsd_fid(void *v) |
5876 | { | | 5876 | { |
5877 | struct vop_fid_args *ap = v; | | 5877 | struct vop_fid_args *ap = v; |
5878 | | | 5878 | |
5879 | return (zfs_fid(ap->a_vp, (void *)ap->a_fid, NULL)); | | 5879 | return (zfs_fid(ap->a_vp, (void *)ap->a_fid, NULL)); |
5880 | } | | 5880 | } |
5881 | | | 5881 | |
5882 | static int | | 5882 | static int |
5883 | zfs_netbsd_pathconf(void *v) | | 5883 | zfs_netbsd_pathconf(void *v) |
5884 | { | | 5884 | { |
5885 | struct vop_pathconf_args *ap = v; | | 5885 | struct vop_pathconf_args *ap = v; |
5886 | ulong_t val; | | 5886 | ulong_t val; |
5887 | int error; | | 5887 | int error; |
5888 | | | 5888 | |
5889 | error = zfs_pathconf(ap->a_vp, ap->a_name, &val, curthread->l_cred, NULL); | | 5889 | error = zfs_pathconf(ap->a_vp, ap->a_name, &val, curthread->l_cred, NULL); |
5890 | if (error == 0) | | 5890 | if (error == 0) |
5891 | *ap->a_retval = val; | | 5891 | *ap->a_retval = val; |
5892 | else if (error == EOPNOTSUPP) { | | 5892 | else if (error == EOPNOTSUPP) { |
5893 | switch (ap->a_name) { | | 5893 | switch (ap->a_name) { |
5894 | case _PC_NAME_MAX: | | 5894 | case _PC_NAME_MAX: |
5895 | *ap->a_retval = NAME_MAX; | | 5895 | *ap->a_retval = NAME_MAX; |
5896 | return (0); | | 5896 | return (0); |
5897 | case _PC_PATH_MAX: | | 5897 | case _PC_PATH_MAX: |
5898 | *ap->a_retval = PATH_MAX; | | 5898 | *ap->a_retval = PATH_MAX; |
5899 | return (0); | | 5899 | return (0); |
5900 | case _PC_LINK_MAX: | | 5900 | case _PC_LINK_MAX: |
5901 | *ap->a_retval = LINK_MAX; | | 5901 | *ap->a_retval = LINK_MAX; |
5902 | return (0); | | 5902 | return (0); |
5903 | case _PC_MAX_CANON: | | 5903 | case _PC_MAX_CANON: |
5904 | *ap->a_retval = MAX_CANON; | | 5904 | *ap->a_retval = MAX_CANON; |
5905 | return (0); | | 5905 | return (0); |
5906 | case _PC_MAX_INPUT: | | 5906 | case _PC_MAX_INPUT: |
5907 | *ap->a_retval = MAX_INPUT; | | 5907 | *ap->a_retval = MAX_INPUT; |
5908 | return (0); | | 5908 | return (0); |
5909 | case _PC_PIPE_BUF: | | 5909 | case _PC_PIPE_BUF: |
5910 | *ap->a_retval = PIPE_BUF; | | 5910 | *ap->a_retval = PIPE_BUF; |
5911 | return (0); | | 5911 | return (0); |
5912 | case _PC_CHOWN_RESTRICTED: | | 5912 | case _PC_CHOWN_RESTRICTED: |
5913 | *ap->a_retval = 1; | | 5913 | *ap->a_retval = 1; |
5914 | return (0); | | 5914 | return (0); |
5915 | case _PC_NO_TRUNC: | | 5915 | case _PC_NO_TRUNC: |
5916 | *ap->a_retval = 1; | | 5916 | *ap->a_retval = 1; |
5917 | return (0); | | 5917 | return (0); |
5918 | case _PC_VDISABLE: | | 5918 | case _PC_VDISABLE: |
5919 | *ap->a_retval = _POSIX_VDISABLE; | | 5919 | *ap->a_retval = _POSIX_VDISABLE; |
5920 | return (0); | | 5920 | return (0); |
5921 | default: | | 5921 | default: |
5922 | return (EINVAL); | | 5922 | return (EINVAL); |
5923 | } | | 5923 | } |
5924 | /* NOTREACHED */ | | 5924 | /* NOTREACHED */ |
5925 | } | | 5925 | } |
5926 | return (error); | | 5926 | return (error); |
5927 | } | | 5927 | } |
5928 | | | 5928 | |
5929 | static int | | 5929 | static int |
5930 | zfs_netbsd_advlock(void *v) | | 5930 | zfs_netbsd_advlock(void *v) |
5931 | { | | 5931 | { |
5932 | struct vop_advlock_args /* { | | 5932 | struct vop_advlock_args /* { |
5933 | struct vnode *a_vp; | | 5933 | struct vnode *a_vp; |
5934 | void *a_id; | | 5934 | void *a_id; |
5935 | int a_op; | | 5935 | int a_op; |
5936 | struct flock *a_fl; | | 5936 | struct flock *a_fl; |
5937 | int a_flags; | | 5937 | int a_flags; |
5938 | } */ *ap = v; | | 5938 | } */ *ap = v; |
5939 | struct vnode *vp; | | 5939 | struct vnode *vp; |
5940 | struct znode *zp; | | 5940 | struct znode *zp; |
5941 | struct zfsvfs *zfsvfs; | | 5941 | struct zfsvfs *zfsvfs; |
5942 | int error; | | 5942 | int error; |
5943 | | | 5943 | |
5944 | vp = ap->a_vp; | | 5944 | vp = ap->a_vp; |
5945 | zp = VTOZ(vp); | | 5945 | zp = VTOZ(vp); |
5946 | zfsvfs = zp->z_zfsvfs; | | 5946 | zfsvfs = zp->z_zfsvfs; |
5947 | | | 5947 | |
5948 | ZFS_ENTER(zfsvfs); | | 5948 | ZFS_ENTER(zfsvfs); |
5949 | ZFS_VERIFY_ZP(zp); | | 5949 | ZFS_VERIFY_ZP(zp); |
5950 | error = lf_advlock(ap, &zp->z_lockf, zp->z_size); | | 5950 | error = lf_advlock(ap, &zp->z_lockf, zp->z_size); |
5951 | ZFS_EXIT(zfsvfs); | | 5951 | ZFS_EXIT(zfsvfs); |
5952 | | | 5952 | |
5953 | return error; | | 5953 | return error; |
5954 | } | | 5954 | } |
5955 | | | 5955 | |
5956 | static int | | 5956 | static int |
5957 | zfs_netbsd_getpages(void *v) | | 5957 | zfs_netbsd_getpages(void *v) |
5958 | { | | 5958 | { |
5959 | struct vop_getpages_args /* { | | 5959 | struct vop_getpages_args /* { |
5960 | struct vnode *a_vp; | | 5960 | struct vnode *a_vp; |
5961 | voff_t a_offset; | | 5961 | voff_t a_offset; |
5962 | struct vm_page **a_m; | | 5962 | struct vm_page **a_m; |
5963 | int *a_count; | | 5963 | int *a_count; |
5964 | int a_centeridx; | | 5964 | int a_centeridx; |
5965 | vm_prot_t a_access_type; | | 5965 | vm_prot_t a_access_type; |
5966 | int a_advice; | | 5966 | int a_advice; |
5967 | int a_flags; | | 5967 | int a_flags; |
5968 | } */ * const ap = v; | | 5968 | } */ * const ap = v; |
5969 | | | 5969 | |
5970 | vnode_t *const vp = ap->a_vp; | | 5970 | vnode_t *const vp = ap->a_vp; |
5971 | off_t offset = ap->a_offset + (ap->a_centeridx << PAGE_SHIFT); | | 5971 | off_t offset = ap->a_offset + (ap->a_centeridx << PAGE_SHIFT); |
5972 | const int flags = ap->a_flags; | | 5972 | const int flags = ap->a_flags; |
5973 | const bool async = (flags & PGO_SYNCIO) == 0; | | 5973 | const bool async = (flags & PGO_SYNCIO) == 0; |
5974 | const bool memwrite = (ap->a_access_type & VM_PROT_WRITE) != 0; | | 5974 | const bool memwrite = (ap->a_access_type & VM_PROT_WRITE) != 0; |
5975 | | | 5975 | |
5976 | struct uvm_object * const uobj = &vp->v_uobj; | | 5976 | struct uvm_object * const uobj = &vp->v_uobj; |
5977 | krwlock_t * const rw = uobj->vmobjlock; | | 5977 | krwlock_t * const rw = uobj->vmobjlock; |
5978 | znode_t *zp = VTOZ(vp); | | 5978 | znode_t *zp = VTOZ(vp); |
5979 | zfsvfs_t *zfsvfs = zp->z_zfsvfs; | | 5979 | zfsvfs_t *zfsvfs = zp->z_zfsvfs; |
5980 | vfs_t *mp; | | 5980 | vfs_t *mp; |
5981 | struct vm_page *pg; | | 5981 | struct vm_page *pg; |
5982 | caddr_t va; | | 5982 | caddr_t va; |
5983 | int npages, found, err = 0; | | 5983 | int npages, found, err = 0; |
5984 | | | 5984 | |
5985 | if (flags & PGO_LOCKED) { | | 5985 | if (flags & PGO_LOCKED) { |
5986 | *ap->a_count = 0; | | 5986 | *ap->a_count = 0; |
5987 | ap->a_m[ap->a_centeridx] = NULL; | | 5987 | ap->a_m[ap->a_centeridx] = NULL; |
5988 | return EBUSY; | | 5988 | return EBUSY; |
5989 | } | | 5989 | } |
5990 | rw_exit(rw); | | 5990 | rw_exit(rw); |
5991 | | | 5991 | |
5992 | if (async) { | | 5992 | if (async) { |
5993 | return 0; | | 5993 | return 0; |
5994 | } | | 5994 | } |
5995 | if (*ap->a_count != 1) { | | 5995 | if (*ap->a_count != 1) { |
5996 | return EBUSY; | | 5996 | return EBUSY; |
5997 | } | | 5997 | } |
5998 | | | 5998 | |
5999 | mp = vp->v_mount; | | 5999 | mp = vp->v_mount; |
6000 | fstrans_start(mp); | | 6000 | fstrans_start(mp); |
6001 | if (vp->v_mount != mp) { | | 6001 | if (vp->v_mount != mp) { |
6002 | fstrans_done(mp); | | 6002 | fstrans_done(mp); |
6003 | return ENOENT; | | 6003 | return ENOENT; |
6004 | } | | 6004 | } |
6005 | ZFS_ENTER(zfsvfs); | | 6005 | ZFS_ENTER(zfsvfs); |
6006 | ZFS_VERIFY_ZP(zp); | | 6006 | ZFS_VERIFY_ZP(zp); |
6007 | | | 6007 | |
6008 | rw_enter(rw, RW_WRITER); | | 6008 | rw_enter(rw, RW_WRITER); |
6009 | if (offset >= vp->v_size) { | | 6009 | if (offset >= vp->v_size) { |
6010 | rw_exit(rw); | | 6010 | rw_exit(rw); |
6011 | ZFS_EXIT(zfsvfs); | | 6011 | ZFS_EXIT(zfsvfs); |
6012 | fstrans_done(mp); | | 6012 | fstrans_done(mp); |
6013 | return EINVAL; | | 6013 | return EINVAL; |
6014 | } | | 6014 | } |
6015 | npages = 1; | | 6015 | npages = 1; |
6016 | pg = NULL; | | 6016 | pg = NULL; |
6017 | uvn_findpages(uobj, offset, &npages, &pg, NULL, UFP_ALL); | | 6017 | uvn_findpages(uobj, offset, &npages, &pg, NULL, UFP_ALL); |
6018 | | | 6018 | |
6019 | if (pg->flags & PG_FAKE) { | | 6019 | if (pg->flags & PG_FAKE) { |
6020 | rw_exit(rw); | | 6020 | rw_exit(rw); |
6021 | | | 6021 | |
6022 | va = zfs_map_page(pg, S_WRITE); | | 6022 | va = zfs_map_page(pg, S_WRITE); |
6023 | err = dmu_read(zfsvfs->z_os, zp->z_id, offset, PAGE_SIZE, | | 6023 | err = dmu_read(zfsvfs->z_os, zp->z_id, offset, PAGE_SIZE, |
6024 | va, DMU_READ_PREFETCH); | | 6024 | va, DMU_READ_PREFETCH); |
6025 | zfs_unmap_page(pg, va); | | 6025 | zfs_unmap_page(pg, va); |
6026 | | | 6026 | |
6027 | rw_enter(rw, RW_WRITER); | | 6027 | rw_enter(rw, RW_WRITER); |
6028 | pg->flags &= ~(PG_FAKE); | | 6028 | pg->flags &= ~(PG_FAKE); |
6029 | } | | 6029 | } |
6030 | | | 6030 | |
6031 | if (memwrite) { | | 6031 | if (memwrite) { |
6032 | if (uvm_pagegetdirty(pg) == UVM_PAGE_STATUS_CLEAN) { | | 6032 | if (uvm_pagegetdirty(pg) == UVM_PAGE_STATUS_CLEAN) { |
6033 | /* For write faults, start dirtiness tracking. */ | | 6033 | /* For write faults, start dirtiness tracking. */ |
6034 | uvm_pagemarkdirty(pg, UVM_PAGE_STATUS_UNKNOWN); | | 6034 | uvm_pagemarkdirty(pg, UVM_PAGE_STATUS_UNKNOWN); |
6035 | } | | 6035 | } |
6036 | mutex_enter(vp->v_interlock); | | 6036 | mutex_enter(vp->v_interlock); |
6037 | if ((vp->v_iflag & VI_ONWORKLST) == 0) { | | 6037 | if ((vp->v_iflag & VI_ONWORKLST) == 0) { |
6038 | vn_syncer_add_to_worklist(vp, filedelay); | | 6038 | vn_syncer_add_to_worklist(vp, filedelay); |
6039 | } | | 6039 | } |
6040 | if ((vp->v_iflag & (VI_WRMAP|VI_WRMAPDIRTY)) == VI_WRMAP) { | | 6040 | if ((vp->v_iflag & (VI_WRMAP|VI_WRMAPDIRTY)) == VI_WRMAP) { |
6041 | vp->v_iflag |= VI_WRMAPDIRTY; | | 6041 | vp->v_iflag |= VI_WRMAPDIRTY; |
6042 | } | | 6042 | } |
6043 | mutex_exit(vp->v_interlock); | | 6043 | mutex_exit(vp->v_interlock); |
6044 | } | | 6044 | } |
6045 | rw_exit(rw); | | 6045 | rw_exit(rw); |
6046 | ap->a_m[ap->a_centeridx] = pg; | | 6046 | ap->a_m[ap->a_centeridx] = pg; |
6047 | | | 6047 | |
6048 | ZFS_EXIT(zfsvfs); | | 6048 | ZFS_EXIT(zfsvfs); |
6049 | fstrans_done(mp); | | 6049 | fstrans_done(mp); |
6050 | | | 6050 | |
6051 | return (err); | | 6051 | return (err); |
6052 | } | | 6052 | } |
6053 | | | 6053 | |
6054 | static int | | 6054 | static int |
6055 | zfs_putapage(vnode_t *vp, page_t **pp, int count, int flags) | | 6055 | zfs_putapage(vnode_t *vp, page_t **pp, int count, int flags) |
6056 | { | | 6056 | { |
6057 | znode_t *zp = VTOZ(vp); | | 6057 | znode_t *zp = VTOZ(vp); |
6058 | zfsvfs_t *zfsvfs = zp->z_zfsvfs; | | 6058 | zfsvfs_t *zfsvfs = zp->z_zfsvfs; |
6059 | dmu_tx_t *tx; | | 6059 | dmu_tx_t *tx; |
6060 | voff_t off, koff; | | 6060 | voff_t off, koff; |
6061 | voff_t len, klen; | | 6061 | voff_t len, klen; |
6062 | int err; | | 6062 | int err; |
6063 | | | 6063 | |
6064 | bool async = (flags & PGO_SYNCIO) == 0; | | 6064 | bool async = (flags & PGO_SYNCIO) == 0; |
6065 | bool *cleanedp; | | 6065 | bool *cleanedp; |
6066 | struct uvm_object *uobj = &vp->v_uobj; | | 6066 | struct uvm_object *uobj = &vp->v_uobj; |
6067 | krwlock_t *rw = uobj->vmobjlock; | | 6067 | krwlock_t *rw = uobj->vmobjlock; |
6068 | | | 6068 | |
6069 | if (zp->z_sa_hdl == NULL) { | | 6069 | if (zp->z_sa_hdl == NULL) { |
6070 | err = 0; | | 6070 | err = 0; |
6071 | goto out_unbusy; | | 6071 | goto out_unbusy; |
6072 | } | | 6072 | } |
6073 | | | 6073 | |
6074 | off = pp[0]->offset; | | 6074 | off = pp[0]->offset; |
6075 | len = count * PAGESIZE; | | 6075 | len = count * PAGESIZE; |
6076 | KASSERT(off + len <= round_page(zp->z_size)); | | 6076 | KASSERT(off + len <= round_page(zp->z_size)); |
6077 | | | 6077 | |
6078 | if (zfs_owner_overquota(zfsvfs, zp, B_FALSE) || | | 6078 | if (zfs_owner_overquota(zfsvfs, zp, B_FALSE) || |
6079 | zfs_owner_overquota(zfsvfs, zp, B_TRUE)) { | | 6079 | zfs_owner_overquota(zfsvfs, zp, B_TRUE)) { |
6080 | err = SET_ERROR(EDQUOT); | | 6080 | err = SET_ERROR(EDQUOT); |
6081 | goto out; | | 6081 | goto out; |
6082 | } | | 6082 | } |
6083 | tx = dmu_tx_create(zfsvfs->z_os); | | 6083 | tx = dmu_tx_create(zfsvfs->z_os); |
6084 | dmu_tx_hold_write(tx, zp->z_id, off, len); | | 6084 | dmu_tx_hold_write(tx, zp->z_id, off, len); |
6085 | | | 6085 | |
6086 | dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE); | | 6086 | dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE); |
6087 | zfs_sa_upgrade_txholds(tx, zp); | | 6087 | zfs_sa_upgrade_txholds(tx, zp); |
6088 | err = dmu_tx_assign(tx, TXG_WAIT); | | 6088 | err = dmu_tx_assign(tx, TXG_WAIT); |
6089 | if (err != 0) { | | 6089 | if (err != 0) { |
6090 | dmu_tx_abort(tx); | | 6090 | dmu_tx_abort(tx); |
6091 | goto out; | | 6091 | goto out; |
6092 | } | | 6092 | } |
6093 | | | 6093 | |
6094 | if (zp->z_blksz <= PAGESIZE) { | | 6094 | if (zp->z_blksz <= PAGESIZE) { |
6095 | KASSERTMSG(count == 1, "vp %p pp %p count %d", vp, pp, count); | | 6095 | KASSERTMSG(count == 1, "vp %p pp %p count %d", vp, pp, count); |
6096 | caddr_t va = zfs_map_page(*pp, S_READ); | | 6096 | caddr_t va = zfs_map_page(*pp, S_READ); |
6097 | ASSERT3U(len, <=, PAGESIZE); | | 6097 | ASSERT3U(len, <=, PAGESIZE); |
6098 | dmu_write(zfsvfs->z_os, zp->z_id, off, len, va, tx); | | 6098 | dmu_write(zfsvfs->z_os, zp->z_id, off, len, va, tx); |
6099 | zfs_unmap_page(*pp, va); | | 6099 | zfs_unmap_page(*pp, va); |
6100 | } else { | | 6100 | } else { |
6101 | err = dmu_write_pages(zfsvfs->z_os, zp->z_id, off, len, pp, tx); | | 6101 | err = dmu_write_pages(zfsvfs->z_os, zp->z_id, off, len, pp, tx); |
6102 | } | | 6102 | } |
6103 | cleanedp = tsd_get(zfs_putpage_key); | | 6103 | cleanedp = tsd_get(zfs_putpage_key); |
6104 | *cleanedp = true; | | 6104 | *cleanedp = true; |
6105 | | | 6105 | |
6106 | if (err == 0) { | | 6106 | if (err == 0) { |
6107 | uint64_t mtime[2], ctime[2]; | | 6107 | uint64_t mtime[2], ctime[2]; |
6108 | sa_bulk_attr_t bulk[3]; | | 6108 | sa_bulk_attr_t bulk[3]; |
6109 | int count = 0; | | 6109 | int count = 0; |
6110 | | | 6110 | |
6111 | SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), NULL, | | 6111 | SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), NULL, |
6112 | &mtime, 16); | | 6112 | &mtime, 16); |
6113 | SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL, | | 6113 | SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL, |
6114 | &ctime, 16); | | 6114 | &ctime, 16); |
6115 | SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), NULL, | | 6115 | SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), NULL, |
6116 | &zp->z_pflags, 8); | | 6116 | &zp->z_pflags, 8); |
6117 | zfs_tstamp_update_setup(zp, CONTENT_MODIFIED, mtime, ctime, | | 6117 | zfs_tstamp_update_setup(zp, CONTENT_MODIFIED, mtime, ctime, |
6118 | B_TRUE); | | 6118 | B_TRUE); |
6119 | err = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx); | | 6119 | err = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx); |
6120 | ASSERT0(err); | | 6120 | ASSERT0(err); |
6121 | zfs_log_write(zfsvfs->z_log, tx, TX_WRITE, zp, off, len, 0); | | 6121 | zfs_log_write(zfsvfs->z_log, tx, TX_WRITE, zp, off, len, 0); |
6122 | } | | 6122 | } |
6123 | dmu_tx_commit(tx); | | 6123 | dmu_tx_commit(tx); |
6124 | | | 6124 | |
6125 | out_unbusy: | | 6125 | out_unbusy: |
6126 | rw_enter(rw, RW_WRITER); | | 6126 | rw_enter(rw, RW_WRITER); |
6127 | uvm_page_unbusy(pp, count); | | 6127 | uvm_page_unbusy(pp, count); |
6128 | rw_exit(rw); | | 6128 | rw_exit(rw); |
6129 | | | 6129 | |
6130 | out: | | 6130 | out: |
6131 | return (err); | | 6131 | return (err); |
6132 | } | | 6132 | } |
6133 | | | 6133 | |
6134 | static void | | 6134 | static void |
6135 | zfs_netbsd_gop_markupdate(vnode_t *vp, int flags) | | 6135 | zfs_netbsd_gop_markupdate(vnode_t *vp, int flags) |
6136 | { | | 6136 | { |
6137 | znode_t *zp = VTOZ(vp); | | 6137 | znode_t *zp = VTOZ(vp); |
6138 | zfsvfs_t *zfsvfs = zp->z_zfsvfs; | | 6138 | zfsvfs_t *zfsvfs = zp->z_zfsvfs; |
6139 | dmu_tx_t *tx; | | 6139 | dmu_tx_t *tx; |
6140 | sa_bulk_attr_t bulk[2]; | | 6140 | sa_bulk_attr_t bulk[2]; |
6141 | uint64_t mtime[2], ctime[2]; | | 6141 | uint64_t mtime[2], ctime[2]; |
6142 | int count = 0, err; | | 6142 | int count = 0, err; |
6143 | | | 6143 | |
6144 | KASSERT(flags == GOP_UPDATE_MODIFIED); | | 6144 | KASSERT(flags == GOP_UPDATE_MODIFIED); |
6145 | | | 6145 | |
6146 | tx = dmu_tx_create(zfsvfs->z_os); | | 6146 | tx = dmu_tx_create(zfsvfs->z_os); |
6147 | err = dmu_tx_assign(tx, TXG_WAIT); | | 6147 | err = dmu_tx_assign(tx, TXG_WAIT); |
6148 | if (err != 0) { | | 6148 | if (err != 0) { |
6149 | dmu_tx_abort(tx); | | 6149 | dmu_tx_abort(tx); |
6150 | return; | | 6150 | return; |
6151 | } | | 6151 | } |
6152 | SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), NULL, &mtime, 16); | | 6152 | SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), NULL, &mtime, 16); |
6153 | SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL, &ctime, 16); | | 6153 | SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL, &ctime, 16); |
6154 | zfs_tstamp_update_setup(zp, CONTENT_MODIFIED, mtime, ctime, B_TRUE); | | 6154 | zfs_tstamp_update_setup(zp, CONTENT_MODIFIED, mtime, ctime, B_TRUE); |
6155 | dmu_tx_commit(tx); | | 6155 | dmu_tx_commit(tx); |
6156 | } | | 6156 | } |
6157 | | | 6157 | |
6158 | static int | | 6158 | static int |
6159 | zfs_netbsd_putpages(void *v) | | 6159 | zfs_netbsd_putpages(void *v) |
6160 | { | | 6160 | { |
6161 | struct vop_putpages_args /* { | | 6161 | struct vop_putpages_args /* { |
6162 | struct vnode *a_vp; | | 6162 | struct vnode *a_vp; |
6163 | voff_t a_offlo; | | 6163 | voff_t a_offlo; |
6164 | voff_t a_offhi; | | 6164 | voff_t a_offhi; |
6165 | int a_flags; | | 6165 | int a_flags; |
6166 | } */ * const ap = v; | | 6166 | } */ * const ap = v; |
6167 | | | 6167 | |
6168 | struct vnode *vp = ap->a_vp; | | 6168 | struct vnode *vp = ap->a_vp; |
6169 | voff_t offlo = ap->a_offlo; | | 6169 | voff_t offlo = ap->a_offlo; |
6170 | voff_t offhi = ap->a_offhi; | | 6170 | voff_t offhi = ap->a_offhi; |
6171 | int flags = ap->a_flags; | | 6171 | int flags = ap->a_flags; |
6172 | | | 6172 | |
6173 | znode_t *zp = VTOZ(vp); | | 6173 | znode_t *zp = VTOZ(vp); |
6174 | zfsvfs_t *zfsvfs = zp->z_zfsvfs; | | 6174 | zfsvfs_t *zfsvfs = zp->z_zfsvfs; |
6175 | rl_t *rl = NULL; | | 6175 | rl_t *rl = NULL; |
6176 | uint64_t len; | | 6176 | uint64_t len; |
6177 | int error; | | 6177 | int error; |
6178 | bool cleaned = false; | | 6178 | bool cleaned = false; |
6179 | | | 6179 | |
6180 | bool async = (flags & PGO_SYNCIO) == 0; | | 6180 | bool async = (flags & PGO_SYNCIO) == 0; |
6181 | bool cleaning = (flags & PGO_CLEANIT) != 0; | | 6181 | bool cleaning = (flags & PGO_CLEANIT) != 0; |
6182 | | | 6182 | |
6183 | if (cleaning) { | | 6183 | if (cleaning) { |
6184 | ASSERT((offlo & PAGE_MASK) == 0 && (offhi & PAGE_MASK) == 0); | | 6184 | ASSERT((offlo & PAGE_MASK) == 0 && (offhi & PAGE_MASK) == 0); |
6185 | ASSERT(offlo < offhi || offhi == 0); | | 6185 | ASSERT(offlo < offhi || offhi == 0); |
6186 | if (offhi == 0) | | 6186 | if (offhi == 0) |
6187 | len = UINT64_MAX; | | 6187 | len = UINT64_MAX; |
6188 | else | | 6188 | else |
6189 | len = offhi - offlo; | | 6189 | len = offhi - offlo; |
6190 | rw_exit(vp->v_uobj.vmobjlock); | | 6190 | rw_exit(vp->v_uobj.vmobjlock); |
6191 | if (curlwp == uvm.pagedaemon_lwp) { | | 6191 | if (curlwp == uvm.pagedaemon_lwp) { |
6192 | error = fstrans_start_nowait(vp->v_mount); | | 6192 | error = fstrans_start_nowait(vp->v_mount); |
6193 | if (error) | | 6193 | if (error) |
6194 | return error; | | 6194 | return error; |
6195 | } else { | | 6195 | } else { |
6196 | vfs_t *mp = vp->v_mount; | | 6196 | vfs_t *mp = vp->v_mount; |
6197 | fstrans_start(mp); | | 6197 | fstrans_start(mp); |
6198 | if (vp->v_mount != mp) { | | 6198 | if (vp->v_mount != mp) { |
6199 | fstrans_done(mp); | | 6199 | fstrans_done(mp); |
6200 | ASSERT(!vn_has_cached_data(vp)); | | 6200 | ASSERT(!vn_has_cached_data(vp)); |
6201 | return 0; | | 6201 | return 0; |
6202 | } | | 6202 | } |
6203 | } | | 6203 | } |
6204 | /* | | 6204 | /* |
6205 | * Cannot use ZFS_ENTER() here as it returns with error | | 6205 | * Cannot use ZFS_ENTER() here as it returns with error |
6206 | * if z_unmounted. The next statement is equivalent. | | 6206 | * if z_unmounted. The next statement is equivalent. |
6207 | */ | | 6207 | */ |
6208 | rrm_enter(&zfsvfs->z_teardown_lock, RW_READER, FTAG); | | 6208 | rrm_enter(&zfsvfs->z_teardown_lock, RW_READER, FTAG); |
6209 | | | 6209 | |
6210 | rl = zfs_range_lock(zp, offlo, len, RL_WRITER); | | 6210 | rl = zfs_range_lock(zp, offlo, len, RL_WRITER); |
6211 | rw_enter(vp->v_uobj.vmobjlock, RW_WRITER); | | 6211 | rw_enter(vp->v_uobj.vmobjlock, RW_WRITER); |
6212 | tsd_set(zfs_putpage_key, &cleaned); | | 6212 | tsd_set(zfs_putpage_key, &cleaned); |
6213 | } | | 6213 | } |
6214 | error = genfs_putpages(v); | | 6214 | error = genfs_putpages(v); |
6215 | if (cleaning) { | | 6215 | if (cleaning) { |
6216 | tsd_set(zfs_putpage_key, NULL); | | 6216 | tsd_set(zfs_putpage_key, NULL); |
6217 | zfs_range_unlock(rl); | | 6217 | zfs_range_unlock(rl); |
6218 | | | 6218 | |
6219 | /* | | 6219 | /* |
6220 | * Only zil_commit() if we cleaned something. This avoids | | 6220 | * Only zil_commit() if we cleaned something. This avoids |
6221 | * deadlock if we're called from zfs_netbsd_setsize(). | | 6221 | * deadlock if we're called from zfs_netbsd_setsize(). |
6222 | */ | | 6222 | */ |
6223 | | | 6223 | |
6224 | if (cleaned) | | 6224 | if (cleaned) |
6225 | if (!async || zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) | | 6225 | if (!async || zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) |
6226 | zil_commit(zfsvfs->z_log, zp->z_id); | | 6226 | zil_commit(zfsvfs->z_log, zp->z_id); |
6227 | ZFS_EXIT(zfsvfs); | | 6227 | ZFS_EXIT(zfsvfs); |
6228 | fstrans_done(vp->v_mount); | | 6228 | fstrans_done(vp->v_mount); |
6229 | } | | 6229 | } |
6230 | return error; | | 6230 | return error; |
6231 | } | | 6231 | } |
6232 | | | 6232 | |
6233 | /* | | 6233 | /* |
6234 | * Restrict the putpages range to the ZFS block containing the offset. | | 6234 | * Restrict the putpages range to the ZFS block containing the offset. |
6235 | */ | | 6235 | */ |
6236 | static void | | 6236 | static void |
6237 | zfs_netbsd_gop_putrange(struct vnode *vp, off_t off, off_t *lop, off_t *hip) | | 6237 | zfs_netbsd_gop_putrange(struct vnode *vp, off_t off, off_t *lop, off_t *hip) |
6238 | { | | 6238 | { |
6239 | znode_t *zp = VTOZ(vp); | | 6239 | znode_t *zp = VTOZ(vp); |
6240 | | | 6240 | |
6241 | *lop = trunc_page(rounddown2(off, zp->z_blksz)); | | 6241 | *lop = trunc_page(rounddown2(off, zp->z_blksz)); |
6242 | *hip = round_page(*lop + zp->z_blksz); | | 6242 | *hip = round_page(*lop + zp->z_blksz); |
6243 | } | | 6243 | } |
6244 | | | 6244 | |
6245 | void | | 6245 | void |
6246 | zfs_netbsd_setsize(vnode_t *vp, off_t size) | | 6246 | zfs_netbsd_setsize(vnode_t *vp, off_t size) |
6247 | { | | 6247 | { |
6248 | struct uvm_object *uobj = &vp->v_uobj; | | 6248 | struct uvm_object *uobj = &vp->v_uobj; |
6249 | krwlock_t *rw = uobj->vmobjlock; | | 6249 | krwlock_t *rw = uobj->vmobjlock; |
6250 | page_t *pg; | | 6250 | page_t *pg; |
6251 | int count, pgoff; | | 6251 | int count, pgoff; |
6252 | caddr_t va; | | 6252 | caddr_t va; |
6253 | off_t tsize; | | 6253 | off_t tsize; |
6254 | | | 6254 | |
6255 | uvm_vnp_setsize(vp, size); | | 6255 | uvm_vnp_setsize(vp, size); |
6256 | if (!vn_has_cached_data(vp)) | | 6256 | if (!vn_has_cached_data(vp)) |
6257 | return; | | 6257 | return; |
6258 | | | 6258 | |
6259 | tsize = trunc_page(size); | | 6259 | tsize = trunc_page(size); |
6260 | if (tsize == size) | | 6260 | if (tsize == size) |
6261 | return; | | 6261 | return; |
6262 | | | 6262 | |
6263 | /* | | 6263 | /* |
6264 | * If there's a partial page, we need to zero the tail. | | 6264 | * If there's a partial page, we need to zero the tail. |
6265 | */ | | 6265 | */ |
6266 | | | 6266 | |
6267 | rw_enter(rw, RW_WRITER); | | 6267 | rw_enter(rw, RW_WRITER); |
6268 | count = 1; | | 6268 | count = 1; |
6269 | pg = NULL; | | 6269 | pg = NULL; |
6270 | if (uvn_findpages(uobj, tsize, &count, &pg, NULL, UFP_NOALLOC)) { | | 6270 | if (uvn_findpages(uobj, tsize, &count, &pg, NULL, UFP_NOALLOC)) { |
6271 | va = zfs_map_page(pg, S_WRITE); | | 6271 | va = zfs_map_page(pg, S_WRITE); |
6272 | pgoff = size - tsize; | | 6272 | pgoff = size - tsize; |
6273 | memset(va + pgoff, 0, PAGESIZE - pgoff); | | 6273 | memset(va + pgoff, 0, PAGESIZE - pgoff); |
6274 | zfs_unmap_page(pg, va); | | 6274 | zfs_unmap_page(pg, va); |
6275 | uvm_page_unbusy(&pg, 1); | | 6275 | uvm_page_unbusy(&pg, 1); |
6276 | } | | 6276 | } |
6277 | | | 6277 | |
6278 | rw_exit(rw); | | 6278 | rw_exit(rw); |
6279 | } | | 6279 | } |
6280 | | | 6280 | |
6281 | static int | | 6281 | static int |
6282 | zfs_netbsd_print(void *v) | | 6282 | zfs_netbsd_print(void *v) |
6283 | { | | 6283 | { |
6284 | struct vop_print_args /* { | | 6284 | struct vop_print_args /* { |
6285 | struct vnode *a_vp; | | 6285 | struct vnode *a_vp; |
6286 | } */ *ap = v; | | 6286 | } */ *ap = v; |
6287 | vnode_t *vp; | | 6287 | vnode_t *vp; |
6288 | znode_t *zp; | | 6288 | znode_t *zp; |
6289 | | | 6289 | |
6290 | vp = ap->a_vp; | | 6290 | vp = ap->a_vp; |
6291 | zp = VTOZ(vp); | | 6291 | zp = VTOZ(vp); |
6292 | | | 6292 | |
6293 | printf("\tino %" PRIu64 " size %" PRIu64 "\n", | | 6293 | printf("\tino %" PRIu64 " size %" PRIu64 "\n", |
6294 | zp->z_id, zp->z_size); | | 6294 | zp->z_id, zp->z_size); |
6295 | return 0; | | 6295 | return 0; |
6296 | } | | 6296 | } |
6297 | | | 6297 | |
6298 | const struct genfs_ops zfs_genfsops = { | | 6298 | const struct genfs_ops zfs_genfsops = { |
6299 | .gop_write = zfs_putapage, | | 6299 | .gop_write = zfs_putapage, |
6300 | .gop_markupdate = zfs_netbsd_gop_markupdate, | | 6300 | .gop_markupdate = zfs_netbsd_gop_markupdate, |
6301 | .gop_putrange = zfs_netbsd_gop_putrange, | | 6301 | .gop_putrange = zfs_netbsd_gop_putrange, |
6302 | }; | | 6302 | }; |
6303 | | | 6303 | |
6304 | #define zfs_netbsd_lock genfs_lock | | 6304 | #define zfs_netbsd_lock genfs_lock |
6305 | #define zfs_netbsd_unlock genfs_unlock | | 6305 | #define zfs_netbsd_unlock genfs_unlock |
6306 | #define zfs_netbsd_islocked genfs_islocked | | 6306 | #define zfs_netbsd_islocked genfs_islocked |
6307 | #define zfs_netbsd_seek genfs_seek | | 6307 | #define zfs_netbsd_seek genfs_seek |
6308 | #define zfs_netbsd_mmap genfs_mmap | | 6308 | #define zfs_netbsd_mmap genfs_mmap |
6309 | #define zfs_netbsd_fcntl genfs_fcntl | | 6309 | #define zfs_netbsd_fcntl genfs_fcntl |
6310 | | | 6310 | |
6311 | int (**zfs_vnodeop_p)(void *); | | 6311 | int (**zfs_vnodeop_p)(void *); |
6312 | const struct vnodeopv_entry_desc zfs_vnodeop_entries[] = { | | 6312 | const struct vnodeopv_entry_desc zfs_vnodeop_entries[] = { |
6313 | { &vop_default_desc, vn_default_error }, | | 6313 | { &vop_default_desc, vn_default_error }, |
6314 | { &vop_lookup_desc, zfs_netbsd_lookup }, | | 6314 | { &vop_lookup_desc, zfs_netbsd_lookup }, |
6315 | { &vop_create_desc, zfs_netbsd_create }, | | 6315 | { &vop_create_desc, zfs_netbsd_create }, |
6316 | { &vop_mknod_desc, zfs_netbsd_mknod }, | | 6316 | { &vop_mknod_desc, zfs_netbsd_mknod }, |
6317 | { &vop_open_desc, zfs_netbsd_open }, | | 6317 | { &vop_open_desc, zfs_netbsd_open }, |
6318 | { &vop_close_desc, zfs_netbsd_close }, | | 6318 | { &vop_close_desc, zfs_netbsd_close }, |
6319 | { &vop_access_desc, zfs_netbsd_access }, | | 6319 | { &vop_access_desc, zfs_netbsd_access }, |
6320 | { &vop_getattr_desc, zfs_netbsd_getattr }, | | 6320 | { &vop_getattr_desc, zfs_netbsd_getattr }, |
6321 | { &vop_setattr_desc, zfs_netbsd_setattr }, | | 6321 | { &vop_setattr_desc, zfs_netbsd_setattr }, |
6322 | { &vop_read_desc, zfs_netbsd_read }, | | 6322 | { &vop_read_desc, zfs_netbsd_read }, |
6323 | { &vop_write_desc, zfs_netbsd_write }, | | 6323 | { &vop_write_desc, zfs_netbsd_write }, |
6324 | { &vop_ioctl_desc, zfs_netbsd_ioctl }, | | 6324 | { &vop_ioctl_desc, zfs_netbsd_ioctl }, |
6325 | { &vop_poll_desc, genfs_poll }, | | 6325 | { &vop_poll_desc, genfs_poll }, |
6326 | { &vop_kqfilter_desc, genfs_kqfilter }, | | 6326 | { &vop_kqfilter_desc, genfs_kqfilter }, |
6327 | { &vop_revoke_desc, genfs_revoke }, | | 6327 | { &vop_revoke_desc, genfs_revoke }, |
6328 | { &vop_fsync_desc, zfs_netbsd_fsync }, | | 6328 | { &vop_fsync_desc, zfs_netbsd_fsync }, |
6329 | { &vop_remove_desc, zfs_netbsd_remove }, | | 6329 | { &vop_remove_desc, zfs_netbsd_remove }, |
6330 | { &vop_link_desc, zfs_netbsd_link }, | | 6330 | { &vop_link_desc, zfs_netbsd_link }, |
6331 | { &vop_lock_desc, zfs_netbsd_lock }, | | 6331 | { &vop_lock_desc, zfs_netbsd_lock }, |
6332 | { &vop_unlock_desc, zfs_netbsd_unlock }, | | 6332 | { &vop_unlock_desc, zfs_netbsd_unlock }, |
6333 | { &vop_rename_desc, zfs_netbsd_rename }, | | 6333 | { &vop_rename_desc, zfs_netbsd_rename }, |
6334 | { &vop_mkdir_desc, zfs_netbsd_mkdir }, | | 6334 | { &vop_mkdir_desc, zfs_netbsd_mkdir }, |
6335 | { &vop_rmdir_desc, zfs_netbsd_rmdir }, | | 6335 | { &vop_rmdir_desc, zfs_netbsd_rmdir }, |
6336 | { &vop_symlink_desc, zfs_netbsd_symlink }, | | 6336 | { &vop_symlink_desc, zfs_netbsd_symlink }, |
6337 | { &vop_readdir_desc, zfs_netbsd_readdir }, | | 6337 | { &vop_readdir_desc, zfs_netbsd_readdir }, |
6338 | { &vop_readlink_desc, zfs_netbsd_readlink }, | | 6338 | { &vop_readlink_desc, zfs_netbsd_readlink }, |
6339 | { &vop_inactive_desc, zfs_netbsd_inactive }, | | 6339 | { &vop_inactive_desc, zfs_netbsd_inactive }, |
6340 | { &vop_reclaim_desc, zfs_netbsd_reclaim }, | | 6340 | { &vop_reclaim_desc, zfs_netbsd_reclaim }, |
6341 | { &vop_pathconf_desc, zfs_netbsd_pathconf }, | | 6341 | { &vop_pathconf_desc, zfs_netbsd_pathconf }, |
6342 | { &vop_seek_desc, zfs_netbsd_seek }, | | 6342 | { &vop_seek_desc, zfs_netbsd_seek }, |
6343 | { &vop_getpages_desc, zfs_netbsd_getpages }, | | 6343 | { &vop_getpages_desc, zfs_netbsd_getpages }, |
6344 | { &vop_putpages_desc, zfs_netbsd_putpages }, | | 6344 | { &vop_putpages_desc, zfs_netbsd_putpages }, |
6345 | { &vop_mmap_desc, zfs_netbsd_mmap }, | | 6345 | { &vop_mmap_desc, zfs_netbsd_mmap }, |
6346 | { &vop_islocked_desc, zfs_netbsd_islocked }, | | 6346 | { &vop_islocked_desc, zfs_netbsd_islocked }, |
6347 | { &vop_advlock_desc, zfs_netbsd_advlock }, | | 6347 | { &vop_advlock_desc, zfs_netbsd_advlock }, |
6348 | { &vop_print_desc, zfs_netbsd_print }, | | 6348 | { &vop_print_desc, zfs_netbsd_print }, |
6349 | { &vop_fcntl_desc, zfs_netbsd_fcntl }, | | 6349 | { &vop_fcntl_desc, zfs_netbsd_fcntl }, |
6350 | { NULL, NULL } | | 6350 | { NULL, NULL } |
6351 | }; | | 6351 | }; |
6352 | | | 6352 | |
6353 | const struct vnodeopv_desc zfs_vnodeop_opv_desc = | | 6353 | const struct vnodeopv_desc zfs_vnodeop_opv_desc = |
6354 | { &zfs_vnodeop_p, zfs_vnodeop_entries }; | | 6354 | { &zfs_vnodeop_p, zfs_vnodeop_entries }; |
6355 | | | 6355 | |
6356 | int (**zfs_specop_p)(void *); | | 6356 | int (**zfs_specop_p)(void *); |
6357 | const struct vnodeopv_entry_desc zfs_specop_entries[] = { | | 6357 | const struct vnodeopv_entry_desc zfs_specop_entries[] = { |
6358 | { &vop_default_desc, vn_default_error }, | | 6358 | { &vop_default_desc, vn_default_error }, |
6359 | { &vop_lookup_desc, spec_lookup }, | | 6359 | { &vop_lookup_desc, spec_lookup }, |
6360 | { &vop_create_desc, spec_create }, | | 6360 | { &vop_create_desc, spec_create }, |
6361 | { &vop_mknod_desc, spec_mknod }, | | 6361 | { &vop_mknod_desc, spec_mknod }, |
6362 | { &vop_open_desc, spec_open }, | | 6362 | { &vop_open_desc, spec_open }, |
6363 | { &vop_close_desc, spec_close }, | | 6363 | { &vop_close_desc, spec_close }, |
6364 | { &vop_access_desc, zfs_netbsd_access }, | | 6364 | { &vop_access_desc, zfs_netbsd_access }, |
6365 | { &vop_getattr_desc, zfs_netbsd_getattr }, | | 6365 | { &vop_getattr_desc, zfs_netbsd_getattr }, |
6366 | { &vop_setattr_desc, zfs_netbsd_setattr }, | | 6366 | { &vop_setattr_desc, zfs_netbsd_setattr }, |
6367 | { &vop_read_desc, /**/zfs_netbsd_read }, | | 6367 | { &vop_read_desc, /**/zfs_netbsd_read }, |
6368 | { &vop_write_desc, /**/zfs_netbsd_write }, | | 6368 | { &vop_write_desc, /**/zfs_netbsd_write }, |
6369 | { &vop_ioctl_desc, spec_ioctl }, | | 6369 | { &vop_ioctl_desc, spec_ioctl }, |
6370 | { &vop_poll_desc, spec_poll }, | | 6370 | { &vop_poll_desc, spec_poll }, |
6371 | { &vop_kqfilter_desc, spec_kqfilter }, | | 6371 | { &vop_kqfilter_desc, spec_kqfilter }, |
6372 | { &vop_revoke_desc, spec_revoke }, | | 6372 | { &vop_revoke_desc, spec_revoke }, |
6373 | { &vop_fsync_desc, zfs_spec_fsync }, | | 6373 | { &vop_fsync_desc, zfs_spec_fsync }, |
6374 | { &vop_remove_desc, spec_remove }, | | 6374 | { &vop_remove_desc, spec_remove }, |
6375 | { &vop_link_desc, spec_link }, | | 6375 | { &vop_link_desc, spec_link }, |
6376 | { &vop_lock_desc, zfs_netbsd_lock }, | | 6376 | { &vop_lock_desc, zfs_netbsd_lock }, |
6377 | { &vop_unlock_desc, zfs_netbsd_unlock }, | | 6377 | { &vop_unlock_desc, zfs_netbsd_unlock }, |
6378 | { &vop_rename_desc, spec_rename }, | | 6378 | { &vop_rename_desc, spec_rename }, |
6379 | { &vop_mkdir_desc, spec_mkdir }, | | 6379 | { &vop_mkdir_desc, spec_mkdir }, |
6380 | { &vop_rmdir_desc, spec_rmdir }, | | 6380 | { &vop_rmdir_desc, spec_rmdir }, |
6381 | { &vop_symlink_desc, spec_symlink }, | | 6381 | { &vop_symlink_desc, spec_symlink }, |
6382 | { &vop_readdir_desc, spec_readdir }, | | 6382 | { &vop_readdir_desc, spec_readdir }, |
6383 | { &vop_readlink_desc, spec_readlink }, | | 6383 | { &vop_readlink_desc, spec_readlink }, |
6384 | { &vop_inactive_desc, zfs_netbsd_inactive }, | | 6384 | { &vop_inactive_desc, zfs_netbsd_inactive }, |
6385 | { &vop_reclaim_desc, zfs_netbsd_reclaim }, | | 6385 | { &vop_reclaim_desc, zfs_netbsd_reclaim }, |
6386 | { &vop_pathconf_desc, spec_pathconf }, | | 6386 | { &vop_pathconf_desc, spec_pathconf }, |
6387 | { &vop_seek_desc, spec_seek }, | | 6387 | { &vop_seek_desc, spec_seek }, |
6388 | { &vop_getpages_desc, spec_getpages }, | | 6388 | { &vop_getpages_desc, spec_getpages }, |
6389 | { &vop_putpages_desc, spec_putpages }, | | 6389 | { &vop_putpages_desc, spec_putpages }, |
6390 | { &vop_mmap_desc, spec_mmap }, | | 6390 | { &vop_mmap_desc, spec_mmap }, |
6391 | { &vop_islocked_desc, zfs_netbsd_islocked }, | | 6391 | { &vop_islocked_desc, zfs_netbsd_islocked }, |
6392 | { &vop_advlock_desc, spec_advlock }, | | 6392 | { &vop_advlock_desc, spec_advlock }, |
6393 | { &vop_strategy_desc, spec_strategy }, | | 6393 | { &vop_strategy_desc, spec_strategy }, |
6394 | { &vop_bwrite_desc, spec_bwrite }, | | 6394 | { &vop_bwrite_desc, spec_bwrite }, |
6395 | { &vop_print_desc, zfs_netbsd_print }, | | 6395 | { &vop_print_desc, zfs_netbsd_print }, |
6396 | { &vop_fcntl_desc, zfs_netbsd_fcntl }, | | 6396 | { &vop_fcntl_desc, zfs_netbsd_fcntl }, |
6397 | { NULL, NULL } | | 6397 | { NULL, NULL } |
6398 | }; | | 6398 | }; |
6399 | | | 6399 | |
6400 | const struct vnodeopv_desc zfs_specop_opv_desc = | | 6400 | const struct vnodeopv_desc zfs_specop_opv_desc = |
6401 | { &zfs_specop_p, zfs_specop_entries }; | | 6401 | { &zfs_specop_p, zfs_specop_entries }; |
6402 | | | 6402 | |
6403 | int (**zfs_fifoop_p)(void *); | | 6403 | int (**zfs_fifoop_p)(void *); |
6404 | const struct vnodeopv_entry_desc zfs_fifoop_entries[] = { | | 6404 | const struct vnodeopv_entry_desc zfs_fifoop_entries[] = { |
6405 | { &vop_default_desc, vn_default_error }, | | 6405 | { &vop_default_desc, vn_default_error }, |
6406 | { &vop_lookup_desc, vn_fifo_bypass }, | | 6406 | { &vop_lookup_desc, vn_fifo_bypass }, |
6407 | { &vop_create_desc, vn_fifo_bypass }, | | 6407 | { &vop_create_desc, vn_fifo_bypass }, |
6408 | { &vop_mknod_desc, vn_fifo_bypass }, | | 6408 | { &vop_mknod_desc, vn_fifo_bypass }, |
6409 | { &vop_open_desc, vn_fifo_bypass }, | | 6409 | { &vop_open_desc, vn_fifo_bypass }, |
6410 | { &vop_close_desc, vn_fifo_bypass }, | | 6410 | { &vop_close_desc, vn_fifo_bypass }, |
6411 | { &vop_access_desc, zfs_netbsd_access }, | | 6411 | { &vop_access_desc, zfs_netbsd_access }, |
6412 | { &vop_getattr_desc, zfs_netbsd_getattr }, | | 6412 | { &vop_getattr_desc, zfs_netbsd_getattr }, |
6413 | { &vop_setattr_desc, zfs_netbsd_setattr }, | | 6413 | { &vop_setattr_desc, zfs_netbsd_setattr }, |
6414 | { &vop_read_desc, /**/zfs_netbsd_read }, | | 6414 | { &vop_read_desc, /**/zfs_netbsd_read }, |
6415 | { &vop_write_desc, /**/zfs_netbsd_write }, | | 6415 | { &vop_write_desc, /**/zfs_netbsd_write }, |
6416 | { &vop_ioctl_desc, vn_fifo_bypass }, | | 6416 | { &vop_ioctl_desc, vn_fifo_bypass }, |
6417 | { &vop_poll_desc, vn_fifo_bypass }, | | 6417 | { &vop_poll_desc, vn_fifo_bypass }, |
6418 | { &vop_kqfilter_desc, vn_fifo_bypass }, | | 6418 | { &vop_kqfilter_desc, vn_fifo_bypass }, |
6419 | { &vop_revoke_desc, vn_fifo_bypass }, | | 6419 | { &vop_revoke_desc, vn_fifo_bypass }, |
6420 | { &vop_fsync_desc, zfs_netbsd_fsync }, | | 6420 | { &vop_fsync_desc, zfs_netbsd_fsync }, |
6421 | { &vop_remove_desc, vn_fifo_bypass }, | | 6421 | { &vop_remove_desc, vn_fifo_bypass }, |
6422 | { &vop_link_desc, vn_fifo_bypass }, | | 6422 | { &vop_link_desc, vn_fifo_bypass }, |
6423 | { &vop_lock_desc, zfs_netbsd_lock }, | | 6423 | { &vop_lock_desc, zfs_netbsd_lock }, |
6424 | { &vop_unlock_desc, zfs_netbsd_unlock }, | | 6424 | { &vop_unlock_desc, zfs_netbsd_unlock }, |
6425 | { &vop_rename_desc, vn_fifo_bypass }, | | 6425 | { &vop_rename_desc, vn_fifo_bypass }, |
6426 | { &vop_mkdir_desc, vn_fifo_bypass }, | | 6426 | { &vop_mkdir_desc, vn_fifo_bypass }, |
6427 | { &vop_rmdir_desc, vn_fifo_bypass }, | | 6427 | { &vop_rmdir_desc, vn_fifo_bypass }, |
6428 | { &vop_symlink_desc, vn_fifo_bypass }, | | 6428 | { &vop_symlink_desc, vn_fifo_bypass }, |
6429 | { &vop_readdir_desc, vn_fifo_bypass }, | | 6429 | { &vop_readdir_desc, vn_fifo_bypass }, |
6430 | { &vop_readlink_desc, vn_fifo_bypass }, | | 6430 | { &vop_readlink_desc, vn_fifo_bypass }, |
6431 | { &vop_inactive_desc, zfs_netbsd_inactive }, | | 6431 | { &vop_inactive_desc, zfs_netbsd_inactive }, |
6432 | { &vop_reclaim_desc, zfs_netbsd_reclaim }, | | 6432 | { &vop_reclaim_desc, zfs_netbsd_reclaim }, |
6433 | { &vop_pathconf_desc, vn_fifo_bypass }, | | 6433 | { &vop_pathconf_desc, vn_fifo_bypass }, |
6434 | { &vop_seek_desc, vn_fifo_bypass }, | | 6434 | { &vop_seek_desc, vn_fifo_bypass }, |
6435 | { &vop_putpages_desc, vn_fifo_bypass }, | | 6435 | { &vop_putpages_desc, vn_fifo_bypass }, |
6436 | { &vop_mmap_desc, vn_fifo_bypass }, | | 6436 | { &vop_mmap_desc, vn_fifo_bypass }, |
6437 | { &vop_islocked_desc, zfs_netbsd_islocked }, | | 6437 | { &vop_islocked_desc, zfs_netbsd_islocked }, |
6438 | { &vop_advlock_desc, vn_fifo_bypass }, | | 6438 | { &vop_advlock_desc, vn_fifo_bypass }, |
6439 | { &vop_print_desc, zfs_netbsd_print }, | | 6439 | { &vop_print_desc, zfs_netbsd_print }, |
6440 | { &vop_fcntl_desc, zfs_netbsd_fcntl }, | | 6440 | { &vop_fcntl_desc, zfs_netbsd_fcntl }, |
6441 | { NULL, NULL } | | 6441 | { NULL, NULL } |
6442 | }; | | 6442 | }; |
6443 | | | 6443 | |
6444 | const struct vnodeopv_desc zfs_fifoop_opv_desc = | | 6444 | const struct vnodeopv_desc zfs_fifoop_opv_desc = |
6445 | { &zfs_fifoop_p, zfs_fifoop_entries }; | | 6445 | { &zfs_fifoop_p, zfs_fifoop_entries }; |
6446 | | | 6446 | |
6447 | #endif /* __NetBSD__ */ | | 6447 | #endif /* __NetBSD__ */ |