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
|