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 --- |