Sun Mar 8 19:59:45 2020 UTC ()
Avoid unnecessary zil_commit on rm.

1. Issue zil_commit only if we're actually updating something --
   there's no need to commit if we're unlinking the file or if
   there's no atime update being applied.

2. Issue zil_commit only if the zfs has sync=always set -- for
   sync=standard there's no need for us to commit anything here since
   no application asked for an explicit sync.

Speeds up untarring base.tgz on top of itself by a factor of about
2x, and speeds up rm by a factor of about 10x, on my system with an
SSD SLOG over SATA.  Histogram of unlink, rmdir, and rename timing
shows dramatic reduction in latency for most samples.

(To be fair, this was not an improvement over zfs; issuing the
unnecessary zil_commit was a self-inflicted performance wound.)


(riastradh)
diff -r1.62 -r1.63 src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c

cvs diff -r1.62 -r1.63 src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c (switch to unified diff)

--- src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c 2020/02/23 15:46:38 1.62
+++ src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c 2020/03/08 19:59:45 1.63
@@ -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__
4868CTASSERT(sizeof(struct zfid_short) <= sizeof(struct fid)); 4868CTASSERT(sizeof(struct zfid_short) <= sizeof(struct fid));
4869CTASSERT(sizeof(struct zfid_long) <= sizeof(struct fid)); 4869CTASSERT(sizeof(struct zfid_long) <= sizeof(struct fid));
4870#endif 4870#endif
4871 4871
4872/*ARGSUSED*/ 4872/*ARGSUSED*/
4873static int 4873static int
4874zfs_fid(vnode_t *vp, fid_t *fidp, caller_context_t *ct) 4874zfs_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
4938static int 4938static int
4939zfs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr, 4939zfs_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*/
5021static int 5021static int
5022zfs_getsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, cred_t *cr, 5022zfs_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*/
5039int 5039int
5040zfs_setsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, cred_t *cr, 5040zfs_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
5061static int 5061static int
5062ioflags(int ioflags) 5062ioflags(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
5078static int 5078static int
5079zfs_netbsd_open(void *v) 5079zfs_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
5086static int 5086static int
5087zfs_netbsd_close(void *v) 5087zfs_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
5094static int 5094static int
5095zfs_netbsd_ioctl(void *v) 5095zfs_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
5104static int 5104static int
5105zfs_netbsd_read(void *v) 5105zfs_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
5124static int 5124static int
5125zfs_netbsd_write(void *v) 5125zfs_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
5153static int 5153static int
5154zfs_netbsd_access(void *v) 5154zfs_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
5190static int 5190static int
5191zfs_netbsd_lookup(void *v) 5191zfs_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
5294out: 5294out:
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
5308static int 5308static int
5309zfs_netbsd_create(void *v) 5309zfs_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
5349static int 5349static int
5350zfs_netbsd_mknod(void *v) 5350zfs_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
5390static int 5390static int
5391zfs_netbsd_remove(void *v) 5391zfs_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
5423static int 5423static int
5424zfs_netbsd_mkdir(void *v) 5424zfs_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
5461static int 5461static int
5462zfs_netbsd_rmdir(void *v) 5462zfs_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
5494static int 5494static int
5495zfs_netbsd_readdir(void *v) 5495zfs_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
5503static int 5503static int
5504zfs_netbsd_fsync(void *v) 5504zfs_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
5511static int 5511static int
5512zfs_spec_fsync(void *v) 5512zfs_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
5524static int 5524static int
5525zfs_netbsd_getattr(void *v) 5525zfs_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
5566static int 5566static int
5567zfs_netbsd_setattr(void *v) 5567zfs_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
5656static int 5656static int
5657zfs_netbsd_rename(void *v) 5657zfs_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
5727static int 5727static int
5728zfs_netbsd_symlink(void *v) 5728zfs_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
5767static int 5767static int
5768zfs_netbsd_readlink(void *v) 5768zfs_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
5775static int 5775static int
5776zfs_netbsd_link(void *v) 5776zfs_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
5808static int 5808static int
5809zfs_netbsd_inactive(void *v) 5809zfs_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
5825static int 5825static int
5826zfs_netbsd_reclaim(void *v) 5826zfs_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
5874static int 5874static int
5875zfs_netbsd_fid(void *v) 5875zfs_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
5882static int 5882static int
5883zfs_netbsd_pathconf(void *v) 5883zfs_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
5929static int 5929static int
5930zfs_netbsd_advlock(void *v) 5930zfs_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
5956static int 5956static int
5957zfs_netbsd_getpages(void *v) 5957zfs_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
6054static int 6054static int
6055zfs_putapage(vnode_t *vp, page_t **pp, int count, int flags) 6055zfs_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
6125out_unbusy: 6125out_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
6130out: 6130out:
6131 return (err); 6131 return (err);
6132} 6132}
6133 6133
6134static void 6134static void
6135zfs_netbsd_gop_markupdate(vnode_t *vp, int flags) 6135zfs_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
6158static int 6158static int
6159zfs_netbsd_putpages(void *v) 6159zfs_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 */
6236static void 6236static void
6237zfs_netbsd_gop_putrange(struct vnode *vp, off_t off, off_t *lop, off_t *hip) 6237zfs_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
6245void 6245void
6246zfs_netbsd_setsize(vnode_t *vp, off_t size) 6246zfs_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
6281static int 6281static int
6282zfs_netbsd_print(void *v) 6282zfs_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
6298const struct genfs_ops zfs_genfsops = { 6298const 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
6311int (**zfs_vnodeop_p)(void *); 6311int (**zfs_vnodeop_p)(void *);
6312const struct vnodeopv_entry_desc zfs_vnodeop_entries[] = { 6312const 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
6353const struct vnodeopv_desc zfs_vnodeop_opv_desc = 6353const struct vnodeopv_desc zfs_vnodeop_opv_desc =
6354 { &zfs_vnodeop_p, zfs_vnodeop_entries }; 6354 { &zfs_vnodeop_p, zfs_vnodeop_entries };
6355 6355
6356int (**zfs_specop_p)(void *); 6356int (**zfs_specop_p)(void *);
6357const struct vnodeopv_entry_desc zfs_specop_entries[] = { 6357const 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
6400const struct vnodeopv_desc zfs_specop_opv_desc = 6400const struct vnodeopv_desc zfs_specop_opv_desc =
6401 { &zfs_specop_p, zfs_specop_entries }; 6401 { &zfs_specop_p, zfs_specop_entries };
6402 6402
6403int (**zfs_fifoop_p)(void *); 6403int (**zfs_fifoop_p)(void *);
6404const struct vnodeopv_entry_desc zfs_fifoop_entries[] = { 6404const 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
6444const struct vnodeopv_desc zfs_fifoop_opv_desc = 6444const 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__ */