Deleted Added
sdiff udiff text old ( 280258 ) new ( 260817 )
full compact
1/*-
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.

--- 21 unchanged lines hidden (view full) ---

30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
35 */
36
37#include <sys/cdefs.h>
38__FBSDID("$FreeBSD: stable/10/sys/kern/vfs_syscalls.c 280258 2015-03-19 13:37:36Z rwatson $");
39
40#include "opt_capsicum.h"
41#include "opt_compat.h"
42#include "opt_kdtrace.h"
43#include "opt_ktrace.h"
44
45#include <sys/param.h>
46#include <sys/systm.h>
47#include <sys/bio.h>
48#include <sys/buf.h>
49#include <sys/capsicum.h>
50#include <sys/disk.h>
51#include <sys/sysent.h>
52#include <sys/malloc.h>
53#include <sys/mount.h>
54#include <sys/mutex.h>
55#include <sys/sysproto.h>
56#include <sys/namei.h>
57#include <sys/filedesc.h>

--- 52 unchanged lines hidden (view full) ---

110/*
111 * The module initialization routine for POSIX asynchronous I/O will
112 * set this to the version of AIO that it implements. (Zero means
113 * that it is not implemented.) This value is used here by pathconf()
114 * and in kern_descrip.c by fpathconf().
115 */
116int async_io_version;
117
118/*
119 * Sync each mounted filesystem.
120 */
121#ifndef _SYS_SYSPROTO_H_
122struct sync_args {
123 int dummy;
124};
125#endif

--- 693 unchanged lines hidden (view full) ---

819 struct filedesc *fdp;
820{
821 struct vnode *vp;
822 struct file *fp;
823 int fd;
824
825 FILEDESC_LOCK_ASSERT(fdp);
826
827 for (fd = 0; fd <= fdp->fd_lastfile; fd++) {
828 fp = fget_locked(fdp, fd);
829 if (fp == NULL)
830 continue;
831 if (fp->f_type == DTYPE_VNODE) {
832 vp = fp->f_vnode;
833 if (vp->v_type == VDIR)
834 return (EPERM);
835 }

--- 445 unchanged lines hidden (view full) ---

1281 default:
1282 error = EINVAL;
1283 break;
1284 }
1285 if (error != 0)
1286 return (error);
1287restart:
1288 bwillwrite();
1289 NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 |
1290 NOCACHE, pathseg, path, fd, cap_rights_init(&rights, CAP_MKNODAT),
1291 td);
1292 if ((error = namei(&nd)) != 0)
1293 return (error);
1294 vp = nd.ni_vp;
1295 if (vp != NULL) {
1296 NDFREE(&nd, NDF_ONLY_PNBUF);
1297 if (vp == nd.ni_dvp)
1298 vrele(nd.ni_dvp);
1299 else

--- 103 unchanged lines hidden (view full) ---

1403 struct vattr vattr;
1404 struct nameidata nd;
1405 cap_rights_t rights;
1406 int error;
1407
1408 AUDIT_ARG_MODE(mode);
1409restart:
1410 bwillwrite();
1411 NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 |
1412 NOCACHE, pathseg, path, fd, cap_rights_init(&rights, CAP_MKFIFOAT),
1413 td);
1414 if ((error = namei(&nd)) != 0)
1415 return (error);
1416 if (nd.ni_vp != NULL) {
1417 NDFREE(&nd, NDF_ONLY_PNBUF);
1418 if (nd.ni_vp == nd.ni_dvp)
1419 vrele(nd.ni_dvp);
1420 else
1421 vput(nd.ni_dvp);

--- 122 unchanged lines hidden (view full) ---

1544 enum uio_seg segflg, int follow)
1545{
1546 struct vnode *vp;
1547 struct mount *mp;
1548 struct nameidata nd;
1549 cap_rights_t rights;
1550 int error;
1551
1552again:
1553 bwillwrite();
1554 NDINIT_AT(&nd, LOOKUP, follow | AUDITVNODE1, segflg, path1, fd1, td);
1555
1556 if ((error = namei(&nd)) != 0)
1557 return (error);
1558 NDFREE(&nd, NDF_ONLY_PNBUF);
1559 vp = nd.ni_vp;
1560 if (vp->v_type == VDIR) {
1561 vrele(vp);
1562 return (EPERM); /* POSIX */
1563 }
1564 NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE2 |
1565 NOCACHE, segflg, path2, fd2, cap_rights_init(&rights, CAP_LINKAT),
1566 td);
1567 if ((error = namei(&nd)) == 0) {
1568 if (nd.ni_vp != NULL) {
1569 NDFREE(&nd, NDF_ONLY_PNBUF);
1570 if (nd.ni_dvp == nd.ni_vp)
1571 vrele(nd.ni_dvp);
1572 else
1573 vput(nd.ni_dvp);
1574 vrele(nd.ni_vp);
1575 vrele(vp);
1576 return (EEXIST);
1577 } else if (nd.ni_dvp->v_mount != vp->v_mount) {
1578 /*
1579 * Cross-device link. No need to recheck
1580 * vp->v_type, since it cannot change, except
1581 * to VBAD.
1582 */
1583 NDFREE(&nd, NDF_ONLY_PNBUF);
1584 vput(nd.ni_dvp);
1585 vrele(vp);
1586 return (EXDEV);
1587 } else if ((error = vn_lock(vp, LK_EXCLUSIVE)) == 0) {
1588 error = can_hardlink(vp, td->td_ucred);
1589#ifdef MAC
1590 if (error == 0)
1591 error = mac_vnode_check_link(td->td_ucred,
1592 nd.ni_dvp, vp, &nd.ni_cnd);
1593#endif
1594 if (error != 0) {
1595 vput(vp);
1596 vput(nd.ni_dvp);
1597 NDFREE(&nd, NDF_ONLY_PNBUF);
1598 return (error);
1599 }
1600 error = vn_start_write(vp, &mp, V_NOWAIT);
1601 if (error != 0) {
1602 vput(vp);
1603 vput(nd.ni_dvp);
1604 NDFREE(&nd, NDF_ONLY_PNBUF);
1605 error = vn_start_write(NULL, &mp,
1606 V_XSLEEP | PCATCH);
1607 if (error != 0)
1608 return (error);
1609 goto again;
1610 }
1611 error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
1612 VOP_UNLOCK(vp, 0);
1613 vput(nd.ni_dvp);
1614 vn_finished_write(mp);
1615 NDFREE(&nd, NDF_ONLY_PNBUF);
1616 } else {
1617 vput(nd.ni_dvp);
1618 NDFREE(&nd, NDF_ONLY_PNBUF);
1619 vrele(vp);
1620 goto again;
1621 }
1622 }
1623 vrele(vp);
1624 return (error);
1625}
1626
1627/*
1628 * Make a symbolic link.
1629 */
1630#ifndef _SYS_SYSPROTO_H_
1631struct symlink_args {

--- 51 unchanged lines hidden (view full) ---

1683 } else {
1684 syspath = uma_zalloc(namei_zone, M_WAITOK);
1685 if ((error = copyinstr(path1, syspath, MAXPATHLEN, NULL)) != 0)
1686 goto out;
1687 }
1688 AUDIT_ARG_TEXT(syspath);
1689restart:
1690 bwillwrite();
1691 NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 |
1692 NOCACHE, segflg, path2, fd, cap_rights_init(&rights, CAP_SYMLINKAT),
1693 td);
1694 if ((error = namei(&nd)) != 0)
1695 goto out;
1696 if (nd.ni_vp) {
1697 NDFREE(&nd, NDF_ONLY_PNBUF);
1698 if (nd.ni_vp == nd.ni_dvp)
1699 vrele(nd.ni_dvp);
1700 else
1701 vput(nd.ni_dvp);

--- 875 unchanged lines hidden (view full) ---

2577 auio.uio_iov = &aiov;
2578 auio.uio_iovcnt = 1;
2579 auio.uio_offset = 0;
2580 auio.uio_rw = UIO_READ;
2581 auio.uio_segflg = bufseg;
2582 auio.uio_td = td;
2583 auio.uio_resid = count;
2584 error = VOP_READLINK(vp, &auio, td->td_ucred);
2585 td->td_retval[0] = count - auio.uio_resid;
2586 }
2587 vput(vp);
2588 return (error);
2589}
2590
2591/*
2592 * Common implementation code for chflags() and fchflags().
2593 */
2594static int
2595setfflags(td, vp, flags)

--- 930 unchanged lines hidden (view full) ---

3526 enum uio_seg pathseg)
3527{
3528 struct mount *mp = NULL;
3529 struct vnode *tvp, *fvp, *tdvp;
3530 struct nameidata fromnd, tond;
3531 cap_rights_t rights;
3532 int error;
3533
3534again:
3535 bwillwrite();
3536#ifdef MAC
3537 NDINIT_ATRIGHTS(&fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART |
3538 AUDITVNODE1, pathseg, old, oldfd,
3539 cap_rights_init(&rights, CAP_RENAMEAT), td);
3540#else
3541 NDINIT_ATRIGHTS(&fromnd, DELETE, WANTPARENT | SAVESTART | AUDITVNODE1,
3542 pathseg, old, oldfd, cap_rights_init(&rights, CAP_RENAMEAT), td);

--- 4 unchanged lines hidden (view full) ---

3547#ifdef MAC
3548 error = mac_vnode_check_rename_from(td->td_ucred, fromnd.ni_dvp,
3549 fromnd.ni_vp, &fromnd.ni_cnd);
3550 VOP_UNLOCK(fromnd.ni_dvp, 0);
3551 if (fromnd.ni_dvp != fromnd.ni_vp)
3552 VOP_UNLOCK(fromnd.ni_vp, 0);
3553#endif
3554 fvp = fromnd.ni_vp;
3555 NDINIT_ATRIGHTS(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE |
3556 SAVESTART | AUDITVNODE2, pathseg, new, newfd,
3557 cap_rights_init(&rights, CAP_LINKAT), td);
3558 if (fromnd.ni_vp->v_type == VDIR)
3559 tond.ni_cnd.cn_flags |= WILLBEDIR;
3560 if ((error = namei(&tond)) != 0) {
3561 /* Translate error code for rename("dir1", "dir2/."). */
3562 if (error == EISDIR && fvp->v_type == VDIR)
3563 error = EINVAL;
3564 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3565 vrele(fromnd.ni_dvp);
3566 vrele(fvp);
3567 goto out1;
3568 }
3569 tdvp = tond.ni_dvp;
3570 tvp = tond.ni_vp;
3571 error = vn_start_write(fvp, &mp, V_NOWAIT);
3572 if (error != 0) {
3573 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3574 NDFREE(&tond, NDF_ONLY_PNBUF);
3575 if (tvp != NULL)
3576 vput(tvp);
3577 if (tdvp == tvp)
3578 vrele(tdvp);
3579 else
3580 vput(tdvp);
3581 vrele(fromnd.ni_dvp);
3582 vrele(fvp);
3583 vrele(tond.ni_startdir);
3584 if (fromnd.ni_startdir != NULL)
3585 vrele(fromnd.ni_startdir);
3586 error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH);
3587 if (error != 0)
3588 return (error);
3589 goto again;
3590 }
3591 if (tvp != NULL) {
3592 if (fvp->v_type == VDIR && tvp->v_type != VDIR) {
3593 error = ENOTDIR;
3594 goto out;
3595 } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) {
3596 error = EISDIR;
3597 goto out;
3598 }

--- 104 unchanged lines hidden (view full) ---

3703 struct vattr vattr;
3704 struct nameidata nd;
3705 cap_rights_t rights;
3706 int error;
3707
3708 AUDIT_ARG_MODE(mode);
3709restart:
3710 bwillwrite();
3711 NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 |
3712 NOCACHE, segflg, path, fd, cap_rights_init(&rights, CAP_MKDIRAT),
3713 td);
3714 nd.ni_cnd.cn_flags |= WILLBEDIR;
3715 if ((error = namei(&nd)) != 0)
3716 return (error);
3717 vp = nd.ni_vp;
3718 if (vp != NULL) {
3719 NDFREE(&nd, NDF_ONLY_PNBUF);
3720 /*
3721 * XXX namei called with LOCKPARENT but not LOCKLEAF has

--- 822 unchanged lines hidden (view full) ---

4544{
4545 struct file *fp;
4546 struct mount *mp;
4547 struct vnode *vp;
4548 cap_rights_t rights;
4549 off_t olen, ooffset;
4550 int error;
4551
4552 if (offset < 0 || len <= 0)
4553 return (EINVAL);
4554 /* Check for wrap. */
4555 if (offset > OFF_MAX - len)
4556 return (EFBIG);
4557 error = fget(td, fd, cap_rights_init(&rights, CAP_WRITE), &fp);
4558 if (error != 0)
4559 return (error);
4560 if ((fp->f_ops->fo_flags & DFLAG_SEEKABLE) == 0) {
4561 error = ESPIPE;
4562 goto out;
4563 }
4564 if ((fp->f_flag & FWRITE) == 0) {
4565 error = EBADF;
4566 goto out;
4567 }
4568 if (fp->f_type != DTYPE_VNODE) {
4569 error = ENODEV;
4570 goto out;
4571 }
4572 vp = fp->f_vnode;
4573 if (vp->v_type != VREG) {
4574 error = ENODEV;
4575 goto out;
4576 }
4577
4578 /* Allocating blocks may take a long time, so iterate. */
4579 for (;;) {
4580 olen = len;
4581 ooffset = offset;
4582
4583 bwillwrite();
4584 mp = NULL;

--- 18 unchanged lines hidden (view full) ---

4603 ooffset, olen, offset, len);
4604 }
4605 if (error != 0 || len == 0)
4606 break;
4607 KASSERT(olen > len, ("Iteration did not make progress?"));
4608 maybe_yield();
4609 }
4610 out:
4611 fdrop(fp, td);
4612 return (error);
4613}
4614
4615int
4616sys_posix_fallocate(struct thread *td, struct posix_fallocate_args *uap)
4617{
4618
4619 td->td_retval[0] = kern_posix_fallocate(td, uap->fd, uap->offset,
4620 uap->len);
4621 return (0);
4622}
4623
4624/*
4625 * Unlike madvise(2), we do not make a best effort to remember every
4626 * possible caching hint. Instead, we remember the last setting with
4627 * the exception that we will allow POSIX_FADV_NORMAL to adjust the
4628 * region of any current setting.
4629 */

--- 23 unchanged lines hidden (view full) ---

4653 break;
4654 default:
4655 return (EINVAL);
4656 }
4657 /* XXX: CAP_POSIX_FADVISE? */
4658 error = fget(td, fd, cap_rights_init(&rights), &fp);
4659 if (error != 0)
4660 goto out;
4661 if ((fp->f_ops->fo_flags & DFLAG_SEEKABLE) == 0) {
4662 error = ESPIPE;
4663 goto out;
4664 }
4665 if (fp->f_type != DTYPE_VNODE) {
4666 error = ENODEV;
4667 goto out;
4668 }
4669 vp = fp->f_vnode;
4670 if (vp->v_type != VREG) {
4671 error = ENODEV;
4672 goto out;
4673 }

--- 74 unchanged lines hidden (view full) ---

4748 free(new, M_FADVISE);
4749 return (error);
4750}
4751
4752int
4753sys_posix_fadvise(struct thread *td, struct posix_fadvise_args *uap)
4754{
4755
4756 td->td_retval[0] = kern_posix_fadvise(td, uap->fd, uap->offset,
4757 uap->len, uap->advice);
4758 return (0);
4759}