Home | History | Annotate | Line # | Download | only in kern
      1 /*	$NetBSD: vfs.c,v 1.10 2026/03/01 13:52:29 yamt Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2006-2007 Pawel Jakub Dawidek <pjd (at) FreeBSD.org>
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
     17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
     20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #include <sys/cdefs.h>
     30 #ifdef __FreeBSD__
     31 __FBSDID("$FreeBSD: head/sys/cddl/compat/opensolaris/kern/opensolaris_lookup.c 314194 2017-02-24 07:53:56Z avg $");
     32 #endif
     33 
     34 #include <sys/param.h>
     35 #include <sys/kernel.h>
     36 #include <sys/systm.h>
     37 #include <sys/mount.h>
     38 #include <sys/cred.h>
     39 #include <sys/vfs.h>
     40 #include <sys/pathname.h>
     41 #include <lib/libkern/libkern.h>
     42 
     43 int
     44 lookupname(char *dirname, enum uio_seg seg, enum symfollow follow,
     45     vnode_t **dirvpp, vnode_t **compvpp)
     46 {
     47 	int error;
     48 
     49 	KASSERT(seg == UIO_SYSSPACE);
     50 	KASSERT(dirvpp == NULL);
     51 
     52 	*compvpp = NULL;
     53 	error = namei_simple_kernel(dirname,
     54 	    follow == FOLLOW ? NSM_FOLLOW_NOEMULROOT : NSM_NOFOLLOW_NOEMULROOT,
     55 	    compvpp);
     56 
     57 	KASSERT(error == 0 || *compvpp == NULL);
     58 
     59         return error;
     60 }
     61 
     62 void
     63 vfs_setmntopt(vfs_t *vfsp, const char *name, const char *arg,
     64     int flags)
     65 {
     66 
     67 	if (strcmp("ro", name) == 0)
     68 		vfsp->mnt_flag |= MNT_RDONLY;
     69 
     70 	if (strcmp("rw", name) == 0)
     71 		vfsp->mnt_flag &= ~MNT_RDONLY;
     72 
     73 	if (strcmp("nodevices", name) == 0)
     74 		vfsp->mnt_flag |= MNT_NODEV;
     75 
     76 	if (strcmp("noatime", name) == 0)
     77 		vfsp->mnt_flag |= MNT_NOATIME;
     78 
     79 	if (strcmp("atime", name) == 0)
     80 		vfsp->mnt_flag &= ~MNT_NOATIME;
     81 
     82 	if (strcmp("nosuid", name) == 0)
     83 		vfsp->mnt_flag |= MNT_NOSUID;
     84 
     85 	if (strcmp("suid", name) == 0)
     86 		vfsp->mnt_flag &= ~MNT_NOSUID;
     87 
     88 	if (strcmp("noexec", name) == 0)
     89 		vfsp->mnt_flag |= MNT_NOEXEC;
     90 
     91 	if (strcmp("exec", name) == 0)
     92 		vfsp->mnt_flag &= ~MNT_NOEXEC;
     93 
     94 	vfsp->mnt_flag |= MNT_LOCAL;
     95 }
     96 
     97 void
     98 vfs_clearmntopt(vfs_t *vfsp, const char *name)
     99 {
    100 
    101 	if (strcmp("ro", name) == 0)
    102 		vfsp->mnt_flag |= MNT_RDONLY;
    103 
    104 	if (strcmp("rw", name) == 0)
    105 		vfsp->mnt_flag &= ~MNT_RDONLY;
    106 
    107 	if (strcmp("nodevices", name) == 0)
    108 		vfsp->mnt_flag &= ~MNT_NODEV;
    109 
    110 	if (strcmp("noatime", name) == 0)
    111 		vfsp->mnt_flag &= ~MNT_NOATIME;
    112 
    113 	if (strcmp("atime", name) == 0)
    114 		vfsp->mnt_flag |= MNT_NOATIME;
    115 
    116 	if (strcmp("nosuid", name) == 0)
    117 		vfsp->mnt_flag &= ~MNT_NOSUID;
    118 
    119 	if (strcmp("suid", name) == 0)
    120 		vfsp->mnt_flag |= MNT_NOSUID;
    121 
    122 	if (strcmp("noexec", name) == 0)
    123 		vfsp->mnt_flag &= ~MNT_NOEXEC;
    124 
    125 	if (strcmp("exec", name) == 0)
    126 		vfsp->mnt_flag |= MNT_NOEXEC;
    127 }
    128 
    129 int
    130 vfs_optionisset(const vfs_t *vfsp, const char *name, char **argp)
    131 {
    132 	/*
    133 	 * this api expects tri-state semantics for zfs.
    134 	 *
    135 	 * eg.
    136 	 *   - "ro"
    137 	 *   - "rw"
    138 	 *   - "unspecified" (ie. leave it to the corresponding zfs property)
    139 	 *
    140 	 * unfortunately, NetBSD system call interface (ie. MNT_xxx flags)
    141 	 * doesn't have a way for users to leave it unspecified.
    142 	 * (eg. as we don't have MNT_READWRITE, the lack of MNT_RDONLY
    143 	 * automatically implies read-write.)
    144 	 * this function treats a lack of mount option as "unspecified" to
    145 	 * allow users to leave it to be controlled by the corresponding
    146 	 * zfs property.
    147 	 * unfortunately, it means that there is no way for users to override
    148 	 * eg. "readonly" zfs property with a mount option. it's a bit shame,
    149 	 * but better than having no way to leave it to the properties. someday
    150 	 * we may want to introduce MNT_READWRITE...
    151 	 */
    152 
    153 	if (strcmp("ro", name) == 0)
    154 		return (vfsp->mnt_flag & MNT_RDONLY) != 0;
    155 
    156 	if (strcmp("nodevices", name) == 0)
    157 		return (vfsp->mnt_flag & MNT_NODEV) != 0;
    158 
    159 	if (strcmp("noatime", name) == 0)
    160 		return (vfsp->mnt_flag & MNT_NOATIME) != 0;
    161 
    162 	if (strcmp("nosuid", name) == 0)
    163 		return (vfsp->mnt_flag & MNT_NOSUID) != 0;
    164 
    165 	if (strcmp("noexec", name) == 0)
    166 		return (vfsp->mnt_flag & MNT_NOEXEC) != 0;
    167 
    168 	return 0;
    169 }
    170