Deleted Added
full compact
vfs_mount.c (132710) vfs_mount.c (132902)
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.

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

54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 */
60
61#include <sys/cdefs.h>
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.

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

54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 */
60
61#include <sys/cdefs.h>
62__FBSDID("$FreeBSD: head/sys/kern/vfs_mount.c 132710 2004-07-27 22:32:01Z phk $");
62__FBSDID("$FreeBSD: head/sys/kern/vfs_mount.c 132902 2004-07-30 22:08:52Z phk $");
63
64#include <sys/param.h>
65#include <sys/conf.h>
66#include <sys/cons.h>
67#include <sys/jail.h>
68#include <sys/kernel.h>
69#include <sys/linker.h>
70#include <sys/mac.h>

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

99
100static void checkdirs(struct vnode *olddp, struct vnode *newdp);
101static void gets(char *cp);
102static int vfs_domount(struct thread *td, const char *fstype,
103 char *fspath, int fsflags, void *fsdata, int compat);
104static int vfs_mount_alloc(struct vnode *dvp, struct vfsconf *vfsp,
105 const char *fspath, struct thread *td, struct mount **mpp);
106static int vfs_mountroot_ask(void);
63
64#include <sys/param.h>
65#include <sys/conf.h>
66#include <sys/cons.h>
67#include <sys/jail.h>
68#include <sys/kernel.h>
69#include <sys/linker.h>
70#include <sys/mac.h>

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

99
100static void checkdirs(struct vnode *olddp, struct vnode *newdp);
101static void gets(char *cp);
102static int vfs_domount(struct thread *td, const char *fstype,
103 char *fspath, int fsflags, void *fsdata, int compat);
104static int vfs_mount_alloc(struct vnode *dvp, struct vfsconf *vfsp,
105 const char *fspath, struct thread *td, struct mount **mpp);
106static int vfs_mountroot_ask(void);
107static int vfs_mountroot_try(char *mountfrom);
107static int vfs_mountroot_try(const char *mountfrom);
108static int vfs_donmount(struct thread *td, int fsflags,
109 struct uio *fsoptions);
110
111static int usermount = 0;
112SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0,
113 "Unprivileged users may mount and unmount file systems");
114
115MALLOC_DEFINE(M_MOUNT, "mount", "vfs mount structure");

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

143static char *cdrom_rootdevnames[] = {
144 "cd9660:cd0",
145 "cd9660:acd0",
146 NULL
147};
148
149/* legacy find-root code */
150char *rootdevnames[2] = {NULL, NULL};
108static int vfs_donmount(struct thread *td, int fsflags,
109 struct uio *fsoptions);
110
111static int usermount = 0;
112SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0,
113 "Unprivileged users may mount and unmount file systems");
114
115MALLOC_DEFINE(M_MOUNT, "mount", "vfs mount structure");

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

143static char *cdrom_rootdevnames[] = {
144 "cd9660:cd0",
145 "cd9660:acd0",
146 NULL
147};
148
149/* legacy find-root code */
150char *rootdevnames[2] = {NULL, NULL};
151static int setrootbyname(char *name);
152struct cdev *rootdev = NULL;
151struct cdev *rootdev = NULL;
152#ifdef ROOTDEVNAME
153const char *ctrootdevname = ROOTDEVNAME;
154#else
155const char *ctrootdevname = NULL;
156#endif
153
154/*
155 * Has to be dynamic as the value of rootdev can change; however, it can't
156 * change after the root is mounted, so a user process can't access this
157 * sysctl until after the value is unchangeable.
158 */
159static int
160sysctl_rootdev(SYSCTL_HANDLER_ARGS)

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

818 }
819 VOP_UNLOCK(vp, 0, td);
820
821 /* XXXMAC: pass to vfs_mount_alloc? */
822 if (compat == 0)
823 mp->mnt_optnew = fsdata;
824 }
825 /*
157
158/*
159 * Has to be dynamic as the value of rootdev can change; however, it can't
160 * change after the root is mounted, so a user process can't access this
161 * sysctl until after the value is unchangeable.
162 */
163static int
164sysctl_rootdev(SYSCTL_HANDLER_ARGS)

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

822 }
823 VOP_UNLOCK(vp, 0, td);
824
825 /* XXXMAC: pass to vfs_mount_alloc? */
826 if (compat == 0)
827 mp->mnt_optnew = fsdata;
828 }
829 /*
826 * Check if the fs implements the type VFS_[N]MOUNT()
830 * Check if the fs implements the type VFS_[O]MOUNT()
827 * function we are looking for.
828 */
831 * function we are looking for.
832 */
829 if ((compat == 0) == (mp->mnt_op->vfs_mount != NULL)) {
833 if ((compat == 0) == (mp->mnt_op->vfs_omount != NULL)) {
830 printf("%s doesn't support the %s mount syscall\n",
831 mp->mnt_vfc->vfc_name, compat ? "old" : "new");
832 VI_LOCK(vp);
833 vp->v_iflag &= ~VI_MOUNT;
834 VI_UNLOCK(vp);
835 if (mp->mnt_flag & MNT_UPDATE)
836 vfs_unbusy(mp, td);
837 else

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

849 mp->mnt_kern_flag |= MNTK_WANTRDWR;
850 mp->mnt_flag &=~ MNT_UPDATEMASK;
851 mp->mnt_flag |= fsflags & (MNT_UPDATEMASK | MNT_FORCE);
852 /*
853 * Mount the filesystem.
854 * XXX The final recipients of VFS_MOUNT just overwrite the ndp they
855 * get. No freeing of cn_pnbuf.
856 */
834 printf("%s doesn't support the %s mount syscall\n",
835 mp->mnt_vfc->vfc_name, compat ? "old" : "new");
836 VI_LOCK(vp);
837 vp->v_iflag &= ~VI_MOUNT;
838 VI_UNLOCK(vp);
839 if (mp->mnt_flag & MNT_UPDATE)
840 vfs_unbusy(mp, td);
841 else

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

853 mp->mnt_kern_flag |= MNTK_WANTRDWR;
854 mp->mnt_flag &=~ MNT_UPDATEMASK;
855 mp->mnt_flag |= fsflags & (MNT_UPDATEMASK | MNT_FORCE);
856 /*
857 * Mount the filesystem.
858 * XXX The final recipients of VFS_MOUNT just overwrite the ndp they
859 * get. No freeing of cn_pnbuf.
860 */
857 error = compat ? VFS_MOUNT(mp, fspath, fsdata, &nd, td) :
858 VFS_NMOUNT(mp, &nd, td);
861 if (compat)
862 error = VFS_OMOUNT(mp, fspath, fsdata, td);
863 else
864 error = VFS_MOUNT(mp, td);
859 if (!error) {
860 if (mp->mnt_opt != NULL)
861 vfs_freeopts(mp->mnt_opt);
862 mp->mnt_opt = mp->mnt_optnew;
863 }
864 /*
865 * Prevent external consumers of mount options from reading
866 * mnt_optnew.

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

1190
1191/*
1192 * Find and mount the root filesystem
1193 */
1194void
1195vfs_mountroot(void)
1196{
1197 char *cp;
865 if (!error) {
866 if (mp->mnt_opt != NULL)
867 vfs_freeopts(mp->mnt_opt);
868 mp->mnt_opt = mp->mnt_optnew;
869 }
870 /*
871 * Prevent external consumers of mount options from reading
872 * mnt_optnew.

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

1196
1197/*
1198 * Find and mount the root filesystem
1199 */
1200void
1201vfs_mountroot(void)
1202{
1203 char *cp;
1198 int error, i;
1204 int error, i, asked = 0;
1199
1205
1200 g_waitidle();
1201
1202 /*
1206
1207 /*
1203 * The root filesystem information is compiled in, and we are
1204 * booted with instructions to use it.
1208 * Wait for GEOM to settle down
1205 */
1209 */
1206#ifdef ROOTDEVNAME
1207 if ((boothowto & RB_DFLTROOT) && !vfs_mountroot_try(ROOTDEVNAME))
1208 return;
1209#endif
1210 g_waitidle();
1211
1210 /*
1212 /*
1211 * We are booted with instructions to prompt for the root filesystem,
1212 * or to use the compiled-in default when it doesn't exist.
1213 * We are booted with instructions to prompt for the root filesystem.
1213 */
1214 */
1214 if (boothowto & (RB_DFLTROOT | RB_ASKNAME)) {
1215 if (boothowto & RB_ASKNAME) {
1215 if (!vfs_mountroot_ask())
1216 return;
1216 if (!vfs_mountroot_ask())
1217 return;
1218 asked = 1;
1217 }
1218
1219 /*
1219 }
1220
1221 /*
1222 * The root filesystem information is compiled in, and we are
1223 * booted with instructions to use it.
1224 */
1225 if (ctrootdevname != NULL && (boothowto & RB_DFLTROOT)) {
1226 if (!vfs_mountroot_try(ctrootdevname))
1227 return;
1228 ctrootdevname = NULL;
1229 }
1230
1231 /*
1220 * We've been given the generic "use CDROM as root" flag. This is
1221 * necessary because one media may be used in many different
1222 * devices, so we need to search for them.
1223 */
1224 if (boothowto & RB_CDROM) {
1225 for (i = 0; cdrom_rootdevnames[i] != NULL; i++) {
1226 if (!vfs_mountroot_try(cdrom_rootdevnames[i]))
1227 return;
1228 }
1229 }
1230
1231 /*
1232 * Try to use the value read by the loader from /etc/fstab, or
1233 * supplied via some other means. This is the preferred
1234 * mechanism.
1235 */
1232 * We've been given the generic "use CDROM as root" flag. This is
1233 * necessary because one media may be used in many different
1234 * devices, so we need to search for them.
1235 */
1236 if (boothowto & RB_CDROM) {
1237 for (i = 0; cdrom_rootdevnames[i] != NULL; i++) {
1238 if (!vfs_mountroot_try(cdrom_rootdevnames[i]))
1239 return;
1240 }
1241 }
1242
1243 /*
1244 * Try to use the value read by the loader from /etc/fstab, or
1245 * supplied via some other means. This is the preferred
1246 * mechanism.
1247 */
1236 if ((cp = getenv("vfs.root.mountfrom")) != NULL) {
1248 cp = getenv("vfs.root.mountfrom");
1249 if (cp != NULL) {
1237 error = vfs_mountroot_try(cp);
1238 freeenv(cp);
1239 if (!error)
1240 return;
1241 }
1242
1243 /*
1250 error = vfs_mountroot_try(cp);
1251 freeenv(cp);
1252 if (!error)
1253 return;
1254 }
1255
1256 /*
1244 * Try values that may have been computed by the machine-dependant
1245 * legacy code.
1257 * Try values that may have been computed by code during boot
1246 */
1247 if (!vfs_mountroot_try(rootdevnames[0]))
1248 return;
1249 if (!vfs_mountroot_try(rootdevnames[1]))
1250 return;
1251
1252 /*
1258 */
1259 if (!vfs_mountroot_try(rootdevnames[0]))
1260 return;
1261 if (!vfs_mountroot_try(rootdevnames[1]))
1262 return;
1263
1264 /*
1253 * If we have a compiled-in default, and haven't already tried it, try
1254 * it now.
1265 * If we (still) have a compiled-in default, try it.
1255 */
1266 */
1256#ifdef ROOTDEVNAME
1257 if (!(boothowto & RB_DFLTROOT))
1258 if (!vfs_mountroot_try(ROOTDEVNAME))
1267 if (ctrootdevname != NULL)
1268 if (!vfs_mountroot_try(ctrootdevname))
1259 return;
1269 return;
1260#endif
1261
1262 /*
1263 * Everything so far has failed, prompt on the console if we haven't
1264 * already tried that.
1265 */
1270
1271 /*
1272 * Everything so far has failed, prompt on the console if we haven't
1273 * already tried that.
1274 */
1266 if (!(boothowto & (RB_DFLTROOT | RB_ASKNAME)) && !vfs_mountroot_ask())
1267 return;
1275 if (!asked)
1276 if (!vfs_mountroot_ask())
1277 return;
1268 panic("Root mount failed, startup aborted.");
1269}
1270
1271/*
1272 * Mount (mountfrom) as the root filesystem.
1273 */
1274static int
1278 panic("Root mount failed, startup aborted.");
1279}
1280
1281/*
1282 * Mount (mountfrom) as the root filesystem.
1283 */
1284static int
1275vfs_mountroot_try(char *mountfrom)
1285vfs_mountroot_try(const char *mountfrom)
1276{
1277 struct mount *mp;
1278 char *vfsname, *path;
1279 const char *devname;
1280 int error;
1281 char patt[32];
1282 int s;
1283

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

1305 error = vfs_rootmountalloc(vfsname, path[0] != 0 ? path : ROOTNAME,
1306 &mp);
1307 if (error != 0) {
1308 printf("Can't allocate root mount for filesystem '%s': %d\n",
1309 vfsname, error);
1310 goto done;
1311 }
1312
1286{
1287 struct mount *mp;
1288 char *vfsname, *path;
1289 const char *devname;
1290 int error;
1291 char patt[32];
1292 int s;
1293

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

1315 error = vfs_rootmountalloc(vfsname, path[0] != 0 ? path : ROOTNAME,
1316 &mp);
1317 if (error != 0) {
1318 printf("Can't allocate root mount for filesystem '%s': %d\n",
1319 vfsname, error);
1320 goto done;
1321 }
1322
1313 /* do our best to set rootdev */
1314 if (path[0] != '\0' && setrootbyname(path))
1315 printf("setrootbyname failed\n");
1323 /*
1324 * do our best to set rootdev
1325 * XXX: This does not belong here!
1326 */
1327 if (path[0] != '\0') {
1328 struct cdev *diskdev;
1329 diskdev = getdiskbyname(path);
1330 if (diskdev != NULL)
1331 rootdev = diskdev;
1332 else
1333 printf("setrootbyname failed\n");
1334 }
1316
1317 /* If the root device is a type "memory disk", mount RW */
1318 if (rootdev != NULL && devsw(rootdev) != NULL) {
1319 devname = devtoname(rootdev);
1320 if (devname[0] == 'm' && devname[1] == 'd')
1321 mp->mnt_flag &= ~MNT_RDONLY;
1322 }
1323
1335
1336 /* If the root device is a type "memory disk", mount RW */
1337 if (rootdev != NULL && devsw(rootdev) != NULL) {
1338 devname = devtoname(rootdev);
1339 if (devname[0] == 'm' && devname[1] == 'd')
1340 mp->mnt_flag &= ~MNT_RDONLY;
1341 }
1342
1324 error = VFS_MOUNT(mp, NULL, NULL, NULL, curthread);
1343 error = VFS_OMOUNT(mp, NULL, NULL, curthread);
1325
1326done:
1327 if (vfsname != NULL)
1328 free(vfsname, M_MOUNT);
1329 if (path != NULL)
1330 free(path, M_MOUNT);
1331 if (error != 0) {
1332 if (mp != NULL)

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

1446 vfsp = vfs_byname("devfs");
1447 if (vfsp == NULL)
1448 break;
1449 error = vfs_mount_alloc(NULLVP, vfsp, "/dev", td, &mp);
1450 if (error)
1451 break;
1452 mp->mnt_flag |= MNT_RDONLY;
1453
1344
1345done:
1346 if (vfsname != NULL)
1347 free(vfsname, M_MOUNT);
1348 if (path != NULL)
1349 free(path, M_MOUNT);
1350 if (error != 0) {
1351 if (mp != NULL)

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

1465 vfsp = vfs_byname("devfs");
1466 if (vfsp == NULL)
1467 break;
1468 error = vfs_mount_alloc(NULLVP, vfsp, "/dev", td, &mp);
1469 if (error)
1470 break;
1471 mp->mnt_flag |= MNT_RDONLY;
1472
1454 error = VFS_NMOUNT(mp, NULL, curthread);
1473 error = VFS_MOUNT(mp, curthread);
1455 if (error)
1456 break;
1457 VFS_START(mp, 0, td);
1458 VFS_ROOT(mp, &vroot, td);
1459 VOP_UNLOCK(vroot, 0, td);
1460
1461 NDINIT(&nid, LOOKUP, NOCACHE|FOLLOW,
1462 UIO_SYSSPACE, cp, curthread);

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

1474
1475 if (vroot != NULL)
1476 VFS_UNMOUNT(mp, 0, td);
1477 if (mp != NULL)
1478 vfs_mount_destroy(mp, td);
1479 return (dev);
1480}
1481
1474 if (error)
1475 break;
1476 VFS_START(mp, 0, td);
1477 VFS_ROOT(mp, &vroot, td);
1478 VOP_UNLOCK(vroot, 0, td);
1479
1480 NDINIT(&nid, LOOKUP, NOCACHE|FOLLOW,
1481 UIO_SYSSPACE, cp, curthread);

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

1493
1494 if (vroot != NULL)
1495 VFS_UNMOUNT(mp, 0, td);
1496 if (mp != NULL)
1497 vfs_mount_destroy(mp, td);
1498 return (dev);
1499}
1500
1482/*
1483 * Set rootdev to match (name), given that we expect it to
1484 * refer to a disk-like device.
1485 */
1486static int
1487setrootbyname(char *name)
1488{
1489 struct cdev *diskdev;
1490
1491 diskdev = getdiskbyname(name);
1492 if (diskdev != NULL) {
1493 rootdev = diskdev;
1494 return (0);
1495 }
1496
1497 return (1);
1498}
1499
1500/* Show the struct cdev *for a disk specified by name */
1501#ifdef DDB
1502DB_SHOW_COMMAND(disk, db_getdiskbyname)
1503{
1504 struct cdev *dev;
1505
1506 if (modif[0] == '\0') {
1507 db_error("usage: show disk/devicename");

--- 97 unchanged lines hidden ---
1501/* Show the struct cdev *for a disk specified by name */
1502#ifdef DDB
1503DB_SHOW_COMMAND(disk, db_getdiskbyname)
1504{
1505 struct cdev *dev;
1506
1507 if (modif[0] == '\0') {
1508 db_error("usage: show disk/devicename");

--- 97 unchanged lines hidden ---