9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
23 *
24 * Copyright (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
25 * All rights reserved.
26 */
27
28 /*
29 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
30 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
31 */
32
33 #include <sys/param.h>
34 #include <sys/types.h>
35 #include <sys/systm.h>
36 #include <sys/cred.h>
37 #include <sys/time.h>
38 #include <sys/vnode.h>
39 #include <sys/vfs.h>
40 #include <sys/vfs_opreg.h>
41 #include <sys/file.h>
42 #include <sys/filio.h>
43 #include <sys/uio.h>
44 #include <sys/buf.h>
45 #include <sys/mman.h>
46 #include <sys/pathname.h>
47 #include <sys/dirent.h>
48 #include <sys/debug.h>
49 #include <sys/vmsystm.h>
1157 vap->va_size > MAXOFF32_T)
1158 return (EFBIG);
1159
1160 if (nfs_zone() != VTOMI(vp)->mi_zone)
1161 return (EIO);
1162
1163 va.va_mask = AT_UID | AT_MODE;
1164
1165 error = nfsgetattr(vp, &va, cr);
1166 if (error)
1167 return (error);
1168
1169 error = secpolicy_vnode_setattr(cr, vp, vap, &va, flags, nfs_accessx,
1170 vp);
1171
1172 if (error)
1173 return (error);
1174
1175 error = nfssetattr(vp, vap, flags, cr);
1176
1177 if (error == 0 && (mask & AT_SIZE) && vap->va_size == 0)
1178 vnevent_truncate(vp, ct);
1179
1180 return (error);
1181 }
1182
1183 static int
1184 nfssetattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr)
1185 {
1186 int error;
1187 uint_t mask;
1188 struct nfssaargs args;
1189 struct nfsattrstat ns;
1190 int douprintf;
1191 rnode_t *rp;
1192 struct vattr va;
1193 mode_t omode;
1194 mntinfo_t *mi;
1195 vsecattr_t *vsp;
1196 hrtime_t t;
1197
1198 mask = vap->va_mask;
2671 }
2672 }
2673 }
2674 mutex_exit(&rp->r_statelock);
2675 } else {
2676 /*
2677 * System V defines rename to return EEXIST, not
2678 * ENOTEMPTY if the target directory is not empty.
2679 * Over the wire, the error is NFSERR_ENOTEMPTY
2680 * which geterrno maps to ENOTEMPTY.
2681 */
2682 if (error == ENOTEMPTY)
2683 error = EEXIST;
2684 }
2685 }
2686
2687 if (error == 0) {
2688 if (nvp)
2689 vnevent_rename_dest(nvp, ndvp, nnm, ct);
2690
2691 if (odvp != ndvp)
2692 vnevent_rename_dest_dir(ndvp, ct);
2693
2694 ASSERT(ovp != NULL);
2695 vnevent_rename_src(ovp, odvp, onm, ct);
2696 }
2697
2698 if (nvp) {
2699 VN_RELE(nvp);
2700 }
2701 VN_RELE(ovp);
2702
2703 nfs_rw_exit(&odrp->r_rwlock);
2704 nfs_rw_exit(&ndrp->r_rwlock);
2705
2706 return (error);
2707 }
2708
2709 /* ARGSUSED */
2710 static int
2711 nfs_mkdir(vnode_t *dvp, char *nm, struct vattr *va, vnode_t **vpp, cred_t *cr,
2712 caller_context_t *ct, int flags, vsecattr_t *vsecp)
2713 {
2714 int error;
2715 struct nfscreatargs args;
4603
4604 error = convoff(vp, bfp, 0, offset);
4605 if (!error) {
4606 ASSERT(bfp->l_start >= 0);
4607 if (bfp->l_len == 0) {
4608 struct vattr va;
4609
4610 /*
4611 * ftruncate should not change the ctime and
4612 * mtime if we truncate the file to its
4613 * previous size.
4614 */
4615 va.va_mask = AT_SIZE;
4616 error = nfsgetattr(vp, &va, cr);
4617 if (error || va.va_size == bfp->l_start)
4618 return (error);
4619 va.va_mask = AT_SIZE;
4620 va.va_size = bfp->l_start;
4621 error = nfssetattr(vp, &va, 0, cr);
4622
4623 if (error == 0 && bfp->l_start == 0)
4624 vnevent_truncate(vp, ct);
4625 } else
4626 error = EINVAL;
4627 }
4628
4629 return (error);
4630 }
4631
4632 /* ARGSUSED */
4633 static int
4634 nfs_realvp(vnode_t *vp, vnode_t **vpp, caller_context_t *ct)
4635 {
4636
4637 return (EINVAL);
4638 }
4639
4640 /*
4641 * Setup and add an address space callback to do the work of the delmap call.
4642 * The callback will (and must be) deleted in the actual callback function.
4643 *
4644 * This is done in order to take care of the problem that we have with holding
|
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
23 *
24 * Copyright (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
25 * All rights reserved.
26 */
27
28 /*
29 * Copyright (c) 2014, Joyent, Inc. All rights reserved.
30 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
31 */
32
33 #include <sys/param.h>
34 #include <sys/types.h>
35 #include <sys/systm.h>
36 #include <sys/cred.h>
37 #include <sys/time.h>
38 #include <sys/vnode.h>
39 #include <sys/vfs.h>
40 #include <sys/vfs_opreg.h>
41 #include <sys/file.h>
42 #include <sys/filio.h>
43 #include <sys/uio.h>
44 #include <sys/buf.h>
45 #include <sys/mman.h>
46 #include <sys/pathname.h>
47 #include <sys/dirent.h>
48 #include <sys/debug.h>
49 #include <sys/vmsystm.h>
1157 vap->va_size > MAXOFF32_T)
1158 return (EFBIG);
1159
1160 if (nfs_zone() != VTOMI(vp)->mi_zone)
1161 return (EIO);
1162
1163 va.va_mask = AT_UID | AT_MODE;
1164
1165 error = nfsgetattr(vp, &va, cr);
1166 if (error)
1167 return (error);
1168
1169 error = secpolicy_vnode_setattr(cr, vp, vap, &va, flags, nfs_accessx,
1170 vp);
1171
1172 if (error)
1173 return (error);
1174
1175 error = nfssetattr(vp, vap, flags, cr);
1176
1177 if (error == 0 && (mask & AT_SIZE)) {
1178 if (vap->va_size == 0) {
1179 vnevent_truncate(vp, ct);
1180 } else {
1181 vnevent_resize(vp, ct);
1182 }
1183 }
1184
1185 return (error);
1186 }
1187
1188 static int
1189 nfssetattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr)
1190 {
1191 int error;
1192 uint_t mask;
1193 struct nfssaargs args;
1194 struct nfsattrstat ns;
1195 int douprintf;
1196 rnode_t *rp;
1197 struct vattr va;
1198 mode_t omode;
1199 mntinfo_t *mi;
1200 vsecattr_t *vsp;
1201 hrtime_t t;
1202
1203 mask = vap->va_mask;
2676 }
2677 }
2678 }
2679 mutex_exit(&rp->r_statelock);
2680 } else {
2681 /*
2682 * System V defines rename to return EEXIST, not
2683 * ENOTEMPTY if the target directory is not empty.
2684 * Over the wire, the error is NFSERR_ENOTEMPTY
2685 * which geterrno maps to ENOTEMPTY.
2686 */
2687 if (error == ENOTEMPTY)
2688 error = EEXIST;
2689 }
2690 }
2691
2692 if (error == 0) {
2693 if (nvp)
2694 vnevent_rename_dest(nvp, ndvp, nnm, ct);
2695
2696 ASSERT(ovp != NULL);
2697 vnevent_rename_src(ovp, odvp, onm, ct);
2698 vnevent_rename_dest_dir(ndvp, ovp, nnm, ct);
2699 }
2700
2701 if (nvp) {
2702 VN_RELE(nvp);
2703 }
2704 VN_RELE(ovp);
2705
2706 nfs_rw_exit(&odrp->r_rwlock);
2707 nfs_rw_exit(&ndrp->r_rwlock);
2708
2709 return (error);
2710 }
2711
2712 /* ARGSUSED */
2713 static int
2714 nfs_mkdir(vnode_t *dvp, char *nm, struct vattr *va, vnode_t **vpp, cred_t *cr,
2715 caller_context_t *ct, int flags, vsecattr_t *vsecp)
2716 {
2717 int error;
2718 struct nfscreatargs args;
4606
4607 error = convoff(vp, bfp, 0, offset);
4608 if (!error) {
4609 ASSERT(bfp->l_start >= 0);
4610 if (bfp->l_len == 0) {
4611 struct vattr va;
4612
4613 /*
4614 * ftruncate should not change the ctime and
4615 * mtime if we truncate the file to its
4616 * previous size.
4617 */
4618 va.va_mask = AT_SIZE;
4619 error = nfsgetattr(vp, &va, cr);
4620 if (error || va.va_size == bfp->l_start)
4621 return (error);
4622 va.va_mask = AT_SIZE;
4623 va.va_size = bfp->l_start;
4624 error = nfssetattr(vp, &va, 0, cr);
4625
4626 if (error == 0) {
4627 if (bfp->l_start == 0) {
4628 vnevent_truncate(vp, ct);
4629 } else {
4630 vnevent_resize(vp, ct);
4631 }
4632 }
4633 } else
4634 error = EINVAL;
4635 }
4636
4637 return (error);
4638 }
4639
4640 /* ARGSUSED */
4641 static int
4642 nfs_realvp(vnode_t *vp, vnode_t **vpp, caller_context_t *ct)
4643 {
4644
4645 return (EINVAL);
4646 }
4647
4648 /*
4649 * Setup and add an address space callback to do the work of the delmap call.
4650 * The callback will (and must be) deleted in the actual callback function.
4651 *
4652 * This is done in order to take care of the problem that we have with holding
|