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-5291 lxbrand inotify02 LTP regression
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
OS-3294 add support for inotify
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>


   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   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 /*
  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Copyright (c) 2015, Joyent, Inc. All rights reserved.
  29  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  30  * Copyright 2016 RackTop Systems.
  31  */
  32 
  33 #include <sys/types.h>
  34 #include <sys/param.h>
  35 #include <sys/t_lock.h>
  36 #include <sys/systm.h>
  37 #include <sys/sysmacros.h>
  38 #include <sys/user.h>
  39 #include <sys/time.h>
  40 #include <sys/vfs.h>
  41 #include <sys/vfs_opreg.h>
  42 #include <sys/vnode.h>
  43 #include <sys/file.h>
  44 #include <sys/fcntl.h>
  45 #include <sys/flock.h>
  46 #include <sys/kmem.h>
  47 #include <sys/uio.h>
  48 #include <sys/errno.h>


 770 
 771         if (mask & (AT_UID | AT_GID | AT_MODE | AT_MTIME))
 772                 gethrestime(&tp->tn_ctime);
 773 
 774         if (mask & AT_SIZE) {
 775                 ASSERT(vp->v_type != VDIR);
 776 
 777                 /* Don't support large files. */
 778                 if (vap->va_size > MAXOFF_T) {
 779                         error = EFBIG;
 780                         goto out;
 781                 }
 782                 mutex_exit(&tp->tn_tlock);
 783 
 784                 rw_enter(&tp->tn_rwlock, RW_WRITER);
 785                 rw_enter(&tp->tn_contents, RW_WRITER);
 786                 error = tmpnode_trunc(tm, tp, (ulong_t)vap->va_size);
 787                 rw_exit(&tp->tn_contents);
 788                 rw_exit(&tp->tn_rwlock);
 789 
 790                 if (error == 0 && vap->va_size == 0)

 791                         vnevent_truncate(vp, ct);




 792 
 793                 goto out1;
 794         }
 795 out:
 796         mutex_exit(&tp->tn_tlock);
 797 out1:
 798         return (error);
 799 }
 800 
 801 /* ARGSUSED2 */
 802 static int
 803 tmp_access(
 804         struct vnode *vp,
 805         int mode,
 806         int flags,
 807         struct cred *cred,
 808         caller_context_t *ct)
 809 {
 810         struct tmpnode *tp = (struct tmpnode *)VTOTN(vp);
 811         int error;


1287         error = tdirdelete(fromparent, fromtp, onm, DR_RENAME, cred);
1288 
1289         /*
1290          * The following handles the case where our source tmpnode was
1291          * removed before we got to it.
1292          *
1293          * XXX We should also cleanup properly in the case where tdirdelete
1294          * fails for some other reason.  Currently this case shouldn't happen.
1295          * (see 1184991).
1296          */
1297         if (error == ENOENT)
1298                 error = 0;
1299 
1300         rw_exit(&fromtp->tn_rwlock);
1301         rw_exit(&fromparent->tn_rwlock);
1302 
1303         if (error == 0) {
1304                 vnevent_rename_src(TNTOV(fromtp), odvp, onm, ct);
1305                 /*
1306                  * vnevent_rename_dest is called in tdirenter().
1307                  * Notify the target dir if not same as source dir.
1308                  */
1309                 if (ndvp != odvp)
1310                         vnevent_rename_dest_dir(ndvp, ct);
1311         }
1312 
1313 done:
1314         tmpnode_rele(fromtp);
1315         mutex_exit(&tm->tm_renamelck);
1316 
1317         TRACE_5(TR_FAC_TMPFS, TR_TMPFS_RENAME,
1318             "tmpfs rename:ovp %p onm %s nvp %p nnm %s error %d", odvp, onm,
1319             ndvp, nnm, error);
1320         return (error);
1321 }
1322 
1323 /* ARGSUSED5 */
1324 static int
1325 tmp_mkdir(
1326         struct vnode *dvp,
1327         char *nm,
1328         struct vattr *va,
1329         struct vnode **vpp,
1330         struct cred *cred,


2327 /* ARGSUSED */
2328 static int
2329 tmp_space(
2330         struct vnode *vp,
2331         int cmd,
2332         struct flock64 *bfp,
2333         int flag,
2334         offset_t offset,
2335         cred_t *cred,
2336         caller_context_t *ct)
2337 {
2338         int error;
2339 
2340         if (cmd != F_FREESP)
2341                 return (EINVAL);
2342         if ((error = convoff(vp, bfp, 0, (offset_t)offset)) == 0) {
2343                 if ((bfp->l_start > MAXOFF_T) || (bfp->l_len > MAXOFF_T))
2344                         return (EFBIG);
2345                 error = tmp_freesp(vp, bfp, flag);
2346 
2347                 if (error == 0 && bfp->l_start == 0)

2348                         vnevent_truncate(vp, ct);


2349         }


2350         return (error);
2351 }
2352 
2353 /* ARGSUSED */
2354 static int
2355 tmp_seek(
2356         struct vnode *vp,
2357         offset_t ooff,
2358         offset_t *noffp,
2359         caller_context_t *ct)
2360 {
2361         return ((*noffp < 0 || *noffp > MAXOFFSET_T) ? EINVAL : 0);
2362 }
2363 
2364 /* ARGSUSED2 */
2365 static int
2366 tmp_rwlock(struct vnode *vp, int write_lock, caller_context_t *ctp)
2367 {
2368         struct tmpnode *tp = VTOTN(vp);
2369 




   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   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 /*
  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Copyright 2016, Joyent, Inc.
  29  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  30  * Copyright 2016 RackTop Systems.
  31  */
  32 
  33 #include <sys/types.h>
  34 #include <sys/param.h>
  35 #include <sys/t_lock.h>
  36 #include <sys/systm.h>
  37 #include <sys/sysmacros.h>
  38 #include <sys/user.h>
  39 #include <sys/time.h>
  40 #include <sys/vfs.h>
  41 #include <sys/vfs_opreg.h>
  42 #include <sys/vnode.h>
  43 #include <sys/file.h>
  44 #include <sys/fcntl.h>
  45 #include <sys/flock.h>
  46 #include <sys/kmem.h>
  47 #include <sys/uio.h>
  48 #include <sys/errno.h>


 770 
 771         if (mask & (AT_UID | AT_GID | AT_MODE | AT_MTIME))
 772                 gethrestime(&tp->tn_ctime);
 773 
 774         if (mask & AT_SIZE) {
 775                 ASSERT(vp->v_type != VDIR);
 776 
 777                 /* Don't support large files. */
 778                 if (vap->va_size > MAXOFF_T) {
 779                         error = EFBIG;
 780                         goto out;
 781                 }
 782                 mutex_exit(&tp->tn_tlock);
 783 
 784                 rw_enter(&tp->tn_rwlock, RW_WRITER);
 785                 rw_enter(&tp->tn_contents, RW_WRITER);
 786                 error = tmpnode_trunc(tm, tp, (ulong_t)vap->va_size);
 787                 rw_exit(&tp->tn_contents);
 788                 rw_exit(&tp->tn_rwlock);
 789 
 790                 if (error == 0) {
 791                         if (vap->va_size == 0) {
 792                                 vnevent_truncate(vp, ct);
 793                         } else {
 794                                 vnevent_resize(vp, ct);
 795                         }
 796                 }
 797 
 798                 goto out1;
 799         }
 800 out:
 801         mutex_exit(&tp->tn_tlock);
 802 out1:
 803         return (error);
 804 }
 805 
 806 /* ARGSUSED2 */
 807 static int
 808 tmp_access(
 809         struct vnode *vp,
 810         int mode,
 811         int flags,
 812         struct cred *cred,
 813         caller_context_t *ct)
 814 {
 815         struct tmpnode *tp = (struct tmpnode *)VTOTN(vp);
 816         int error;


1292         error = tdirdelete(fromparent, fromtp, onm, DR_RENAME, cred);
1293 
1294         /*
1295          * The following handles the case where our source tmpnode was
1296          * removed before we got to it.
1297          *
1298          * XXX We should also cleanup properly in the case where tdirdelete
1299          * fails for some other reason.  Currently this case shouldn't happen.
1300          * (see 1184991).
1301          */
1302         if (error == ENOENT)
1303                 error = 0;
1304 
1305         rw_exit(&fromtp->tn_rwlock);
1306         rw_exit(&fromparent->tn_rwlock);
1307 
1308         if (error == 0) {
1309                 vnevent_rename_src(TNTOV(fromtp), odvp, onm, ct);
1310                 /*
1311                  * vnevent_rename_dest is called in tdirenter().

1312                  */
1313                 vnevent_rename_dest_dir(ndvp, TNTOV(fromtp), nnm, ct);

1314         }
1315 
1316 done:
1317         tmpnode_rele(fromtp);
1318         mutex_exit(&tm->tm_renamelck);
1319 
1320         TRACE_5(TR_FAC_TMPFS, TR_TMPFS_RENAME,
1321             "tmpfs rename:ovp %p onm %s nvp %p nnm %s error %d", odvp, onm,
1322             ndvp, nnm, error);
1323         return (error);
1324 }
1325 
1326 /* ARGSUSED5 */
1327 static int
1328 tmp_mkdir(
1329         struct vnode *dvp,
1330         char *nm,
1331         struct vattr *va,
1332         struct vnode **vpp,
1333         struct cred *cred,


2330 /* ARGSUSED */
2331 static int
2332 tmp_space(
2333         struct vnode *vp,
2334         int cmd,
2335         struct flock64 *bfp,
2336         int flag,
2337         offset_t offset,
2338         cred_t *cred,
2339         caller_context_t *ct)
2340 {
2341         int error;
2342 
2343         if (cmd != F_FREESP)
2344                 return (EINVAL);
2345         if ((error = convoff(vp, bfp, 0, (offset_t)offset)) == 0) {
2346                 if ((bfp->l_start > MAXOFF_T) || (bfp->l_len > MAXOFF_T))
2347                         return (EFBIG);
2348                 error = tmp_freesp(vp, bfp, flag);
2349 
2350                 if (error == 0) {
2351                         if (bfp->l_start == 0) {
2352                                 vnevent_truncate(vp, ct);
2353                         } else {
2354                                 vnevent_resize(vp, ct);
2355                         }
2356                 }
2357         }
2358         return (error);
2359 }
2360 
2361 /* ARGSUSED */
2362 static int
2363 tmp_seek(
2364         struct vnode *vp,
2365         offset_t ooff,
2366         offset_t *noffp,
2367         caller_context_t *ct)
2368 {
2369         return ((*noffp < 0 || *noffp > MAXOFFSET_T) ? EINVAL : 0);
2370 }
2371 
2372 /* ARGSUSED2 */
2373 static int
2374 tmp_rwlock(struct vnode *vp, int write_lock, caller_context_t *ctp)
2375 {
2376         struct tmpnode *tp = VTOTN(vp);
2377