Print this page
OS-5148 ftruncate at offset should emit proper events
Reviewed by: Bryan Cantrill <bryan@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
OS-3294 add support for inotify
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>


   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