The remaining part of nmount/omount/rootfs mount changes. I cannot sensibly

split the conversion of the remaining three filesystems out from the root
mounting changes, so in one go:

cd9660:
	Convert to nmount.
	Add omount compat shims.
	Remove dedicated rootfs mounting code.
	Use vfs_mountedfrom()
	Rely on vfs_mount.c calling VFS_STATFS()

nfs(client):
	Convert to nmount (the simple way, mount_nfs(8) is still necessary).
	Add omount compat shims.
	Drop COMPAT_PRELITE2 mount arg compatibility.

ffs:
	Convert to nmount.
	Add omount compat shims.
	Remove dedicated rootfs mounting code.
	Use vfs_mountedfrom()
	Rely on vfs_mount.c calling VFS_STATFS()

Remove vfs_omount() method, all filesystems are now converted.

Remove MNTK_WANTRDWR, handling RO/RW conversions is a filesystem
task, and they all do it now.

Change rootmounting to use DEVFS trampoline:

vfs_mount.c:
	Mount devfs on /.  Devfs needs no 'from' so this is clean.
	symlink /dev to /.  This makes it possible to lookup /dev/foo.
	Mount "real" root filesystem on /.
	Surgically move the devfs mountpoint from under the real root
	filesystem onto /dev in the real root filesystem.

Remove now unnecessary getdiskbyname().

kern_init.c:
	Don't do devfs mounting and rootvnode assignment here, it was
	already handled by vfs_mount.c.

Remove now unused bdevvp(), addaliasu() and addalias().  Put the
few necessary lines in devfs where they belong.  This eliminates the
second-last source of bogo vnodes, leaving only the lemming-syncer.

Remove rootdev variable, it doesn't give meaning in a global context and
was not trustworth anyway.  Correct information is provided by
statfs(/).
This commit is contained in:
Poul-Henning Kamp 2004-12-07 08:15:41 +00:00
parent 47837a50b0
commit 20a92a18f1
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=138509
12 changed files with 498 additions and 754 deletions

View File

@ -67,7 +67,8 @@ MALLOC_DEFINE(M_ISOFSNODE, "ISOFS node", "ISOFS vnode private part");
struct iconv_functions *cd9660_iconv = NULL;
static vfs_omount_t cd9660_omount;
static vfs_mount_t cd9660_mount;
static vfs_cmount_t cd9660_cmount;
static vfs_unmount_t cd9660_unmount;
static vfs_root_t cd9660_root;
static vfs_statfs_t cd9660_statfs;
@ -78,7 +79,8 @@ static vfs_vptofh_t cd9660_vptofh;
static struct vfsops cd9660_vfsops = {
.vfs_fhtovp = cd9660_fhtovp,
.vfs_init = cd9660_init,
.vfs_omount = cd9660_omount,
.vfs_mount = cd9660_mount,
.vfs_cmount = cd9660_cmount,
.vfs_root = cd9660_root,
.vfs_statfs = cd9660_statfs,
.vfs_uninit = cd9660_uninit,
@ -89,140 +91,79 @@ static struct vfsops cd9660_vfsops = {
VFS_SET(cd9660_vfsops, cd9660, VFCF_READONLY);
MODULE_VERSION(cd9660, 1);
/*
* Called by vfs_mountroot when iso is going to be mounted as root.
*/
static int iso_get_ssector(struct cdev *dev, struct thread *td);
static int iso_mountfs(struct vnode *devvp, struct mount *mp,
struct thread *td, struct iso_args *argp);
/*
* Try to find the start of the last data track on this CD-ROM. This
* is used to mount the last session of a multi-session CD. Bail out
* and return 0 if we fail, this is always a safe bet.
*/
static int
iso_get_ssector(dev, td)
struct cdev *dev;
struct thread *td;
{
struct ioc_toc_header h;
struct ioc_read_toc_single_entry t;
int i, error;
struct cdevsw *bd;
d_ioctl_t *ioctlp;
bd = dev_refthread(dev);
if (bd == NULL)
return 0;
ioctlp = bd->d_ioctl;
error = ioctlp(dev, CDIOREADTOCHEADER, (caddr_t)&h, FREAD, td);
if (error) {
dev_relthread(dev);
return 0;
}
for (i = h.ending_track; i >= 0; i--) {
t.address_format = CD_LBA_FORMAT;
t.track = i;
error = ioctlp(dev, CDIOREADTOCENTRY, (caddr_t)&t, FREAD, td);
if (error) {
dev_relthread(dev);
return 0;
}
if ((t.entry.control & 4) != 0)
/* found a data track */
break;
}
dev_relthread(dev);
if (i < 0)
return 0;
return ntohl(t.entry.addr.lba);
}
static int iso_mountroot(struct mount *mp, struct thread *td);
static int
iso_mountroot(mp, td)
struct mount *mp;
struct thread *td;
{
struct iso_args args;
struct vnode *rootvp;
int error;
if ((error = bdevvp(rootdev, &rootvp))) {
printf("iso_mountroot: can't find rootvp\n");
return (error);
}
args.flags = ISOFSMNT_ROOT;
vn_lock(rootvp, LK_EXCLUSIVE | LK_RETRY, td);
error = VOP_OPEN(rootvp, FREAD, FSCRED, td, -1);
VOP_UNLOCK(rootvp, 0, td);
if (error)
return error;
args.ssector = iso_get_ssector(rootdev, td);
(void)VOP_CLOSE(rootvp, FREAD, NOCRED, td);
if (bootverbose)
printf("iso_mountroot(): using session at block %d\n",
args.ssector);
if ((error = iso_mountfs(rootvp, mp, td, &args)) != 0)
return (error);
(void)cd9660_statfs(mp, &mp->mnt_stat, td);
return (0);
}
struct thread *td);
/*
* VFS Operations.
*
* mount system call
*/
static int
cd9660_omount(mp, path, data, td)
struct mount *mp;
char *path;
caddr_t data;
struct thread *td;
cd9660_cmount(struct mntarg *ma, void *data, int flags, struct thread *td)
{
struct iso_args args;
int error;
error = copyin(data, &args, sizeof args);
if (error)
return (error);
ma = mount_argsu(ma, "from", args.fspec, MAXPATHLEN);
ma = mount_arg(ma, "export", &args.export, sizeof args.export);
ma = mount_argsu(ma, "cs_disk", args.cs_disk, 64);
ma = mount_argsu(ma, "cs_local", args.cs_local, 64);
ma = mount_argf(ma, "ssector", "%u", args.ssector);
ma = mount_argb(ma, !(args.flags & ISOFSMNT_NORRIP), "norrip");
ma = mount_argb(ma, args.flags & ISOFSMNT_GENS, "nogens");
ma = mount_argb(ma, args.flags & ISOFSMNT_EXTATT, "noextatt");
ma = mount_argb(ma, !(args.flags & ISOFSMNT_NOJOLIET), "nojoliet");
ma = mount_argb(ma,
args.flags & ISOFSMNT_BROKENJOLIET, "nobrokenjoliet");
ma = mount_argb(ma, args.flags & ISOFSMNT_KICONV, "nokiconv");
ma = mount_argb(ma, args.flags & ISOFSMNT_EXTATT, "nogens");
error = kernel_mount(ma, flags);
return (error);
}
static int
cd9660_mount(struct mount *mp, struct thread *td)
{
struct vnode *devvp;
struct iso_args args;
size_t size;
int error;
struct export_args *export;
char *fspec;
int error, len;
mode_t accessmode;
struct iso_mnt *imp = 0;
struct nameidata ndp;
if (mp->mnt_flag & MNT_ROOTFS)
return (iso_mountroot(mp, td));
if ((error = copyin(data, (caddr_t)&args, sizeof (struct iso_args))))
return (error);
struct iso_mnt *imp = 0;
if ((mp->mnt_flag & MNT_RDONLY) == 0)
return (EROFS);
fspec = vfs_getopts(mp->mnt_optnew, "from", &error);
if (error)
return (error);
imp = VFSTOISOFS(mp);
/*
* If updating, check whether changing from read-only to
* read/write; if there is no device name, that's all we do.
*/
if (mp->mnt_flag & MNT_UPDATE) {
imp = VFSTOISOFS(mp);
if (args.fspec == 0)
return (vfs_export(mp, &args.export));
if (fspec == NULL) {
error = vfs_getopt(mp->mnt_optnew,
"export", (void **)&export, &len);
if (error || len != sizeof *export)
return (EINVAL);
return (vfs_export(mp, export));
}
}
/*
* Not an update, or updating the name: look up the name
* and verify that it refers to a sensible block device.
*/
NDINIT(&ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, td);
NDINIT(&ndp, LOOKUP, FOLLOW, UIO_SYSSPACE, fspec, td);
if ((error = namei(&ndp)))
return (error);
NDFREE(&ndp, NDF_ONLY_PNBUF);
@ -249,7 +190,7 @@ cd9660_omount(mp, path, data, td)
VOP_UNLOCK(devvp, 0, td);
if ((mp->mnt_flag & MNT_UPDATE) == 0) {
error = iso_mountfs(devvp, mp, td, &args);
error = iso_mountfs(devvp, mp, td);
} else {
if (devvp != imp->im_devvp)
error = EINVAL; /* needs translation */
@ -260,11 +201,7 @@ cd9660_omount(mp, path, data, td)
vrele(devvp);
return error;
}
imp = VFSTOISOFS(mp);
(void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
&size);
bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
(void) cd9660_statfs(mp, &mp->mnt_stat, td);
vfs_mountedfrom(mp, fspec);
return 0;
}
@ -272,11 +209,10 @@ cd9660_omount(mp, path, data, td)
* Common code for mount and mountroot
*/
static int
iso_mountfs(devvp, mp, td, argp)
iso_mountfs(devvp, mp, td)
struct vnode *devvp;
struct mount *mp;
struct thread *td;
struct iso_args *argp;
{
struct iso_mnt *isomp = (struct iso_mnt *)0;
struct buf *bp = NULL;
@ -292,12 +228,10 @@ iso_mountfs(devvp, mp, td, argp)
struct iso_sierra_primary_descriptor *pri_sierra = NULL;
struct iso_supplementary_descriptor *sup = NULL;
struct iso_directory_record *rootp;
int logical_block_size;
int logical_block_size, ssector;
struct g_consumer *cp;
struct bufobj *bo;
if (!(mp->mnt_flag & MNT_RDONLY))
return EROFS;
char *cs_local, *cs_disk;
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);
DROP_GIANT();
@ -324,8 +258,10 @@ iso_mountfs(devvp, mp, td, argp)
iso_bsize = ISO_DEFAULT_BLOCK_SIZE;
joliet_level = 0;
for (iso_blknum = 16 + argp->ssector;
iso_blknum < 100 + argp->ssector;
if (1 != vfs_scanopt(mp->mnt_optnew, "ssector", "%d", &ssector))
ssector = 0;
for (iso_blknum = 16 + ssector;
iso_blknum < 100 + ssector;
iso_blknum++) {
if ((error = bread(devvp, iso_blknum * btodb(iso_bsize),
iso_bsize, NOCRED, &bp)) != 0)
@ -357,7 +293,7 @@ iso_mountfs(devvp, mp, td, argp)
bp = NULL;
sup = (struct iso_supplementary_descriptor *)vdp;
if (!(argp->flags & ISOFSMNT_NOJOLIET)) {
if (vfs_flagopt(mp->mnt_optnew, "joliet", NULL, 0)) {
if (bcmp(sup->escape, "%/@", 3) == 0)
joliet_level = 1;
if (bcmp(sup->escape, "%/C", 3) == 0)
@ -366,7 +302,7 @@ iso_mountfs(devvp, mp, td, argp)
joliet_level = 3;
if ((isonum_711 (sup->flags) & 1) &&
(argp->flags & ISOFSMNT_BROKENJOLIET) == 0)
!vfs_flagopt(mp->mnt_optnew, "brokenjoliet", NULL, 0))
joliet_level = 0;
}
}
@ -427,7 +363,7 @@ iso_mountfs(devvp, mp, td, argp)
* can't do much better. This is also important for the NFS
* filehandle validation.
*/
isomp->volume_space_size += argp->ssector;
isomp->volume_space_size += ssector;
bcopy (rootp, isomp->root, sizeof isomp->root);
isomp->root_extent = isonum_733 (rootp->extent);
isomp->root_size = isonum_733 (rootp->size);
@ -448,8 +384,14 @@ iso_mountfs(devvp, mp, td, argp)
isomp->im_dev = dev;
isomp->im_devvp = devvp;
vfs_flagopt(mp->mnt_optnew, "rrip", &isomp->im_flags, ISOFSMNT_NORRIP);
vfs_flagopt(mp->mnt_optnew, "gens", &isomp->im_flags, ISOFSMNT_GENS);
vfs_flagopt(mp->mnt_optnew, "extatt", &isomp->im_flags, ISOFSMNT_EXTATT);
vfs_flagopt(mp->mnt_optnew, "joliet", &isomp->im_flags, ISOFSMNT_NOJOLIET);
vfs_flagopt(mp->mnt_optnew, "kiconv", &isomp->im_flags, ISOFSMNT_KICONV);
isomp->im_flags ^= (ISOFSMNT_NORRIP | ISOFSMNT_NOJOLIET);
/* Check the Rock Ridge Extention support */
if (!(argp->flags & ISOFSMNT_NORRIP)) {
if (vfs_flagopt(mp->mnt_optnew, "rrip", NULL, 0)) {
if ((error = bread(isomp->im_devvp,
(isomp->root_extent + isonum_711(rootp->ext_attr_length)) <<
(isomp->im_bshift - DEV_BSHIFT),
@ -459,9 +401,9 @@ iso_mountfs(devvp, mp, td, argp)
rootp = (struct iso_directory_record *)bp->b_data;
if ((isomp->rr_skip = cd9660_rrip_offset(rootp,isomp)) < 0) {
argp->flags |= ISOFSMNT_NORRIP;
isomp->im_flags |= ISOFSMNT_NORRIP;
} else {
argp->flags &= ~ISOFSMNT_GENS;
isomp->im_flags &= ~ISOFSMNT_GENS;
}
/*
@ -472,13 +414,16 @@ iso_mountfs(devvp, mp, td, argp)
brelse(bp);
bp = NULL;
}
isomp->im_flags = argp->flags & (ISOFSMNT_NORRIP | ISOFSMNT_GENS |
ISOFSMNT_EXTATT | ISOFSMNT_NOJOLIET |
ISOFSMNT_KICONV);
if (isomp->im_flags & ISOFSMNT_KICONV && cd9660_iconv) {
cd9660_iconv->open(argp->cs_local, argp->cs_disk, &isomp->im_d2l);
cd9660_iconv->open(argp->cs_disk, argp->cs_local, &isomp->im_l2d);
cs_local = vfs_getopts(mp->mnt_optnew, "cs_local", &error);
if (error)
goto out;
cs_disk = vfs_getopts(mp->mnt_optnew, "cs_disk", &error);
if (error)
goto out;
cd9660_iconv->open(cs_local, cs_disk, &isomp->im_d2l);
cd9660_iconv->open(cs_disk, cs_local, &isomp->im_l2d);
} else {
isomp->im_d2l = NULL;
isomp->im_l2d = NULL;

View File

@ -194,7 +194,14 @@ devfs_allocv(struct devfs_dirent *de, struct mount *mp, struct vnode **vpp, stru
if (de->de_dirent->d_type == DT_CHR) {
vp->v_type = VCHR;
vp = addaliasu(vp, dev->si_udev);
VI_LOCK(vp);
dev_lock();
dev->si_refcount++;
vp->v_rdev = dev;
SLIST_INSERT_HEAD(&dev->si_hlist, vp, v_specnext);
dev->si_usecount += vp->v_usecount;
dev_unlock();
VI_UNLOCK(vp);
vp->v_op = &devfs_specops;
} else if (de->de_dirent->d_type == DT_DIR) {
vp->v_type = VDIR;

View File

@ -67,7 +67,8 @@ MALLOC_DEFINE(M_ISOFSNODE, "ISOFS node", "ISOFS vnode private part");
struct iconv_functions *cd9660_iconv = NULL;
static vfs_omount_t cd9660_omount;
static vfs_mount_t cd9660_mount;
static vfs_cmount_t cd9660_cmount;
static vfs_unmount_t cd9660_unmount;
static vfs_root_t cd9660_root;
static vfs_statfs_t cd9660_statfs;
@ -78,7 +79,8 @@ static vfs_vptofh_t cd9660_vptofh;
static struct vfsops cd9660_vfsops = {
.vfs_fhtovp = cd9660_fhtovp,
.vfs_init = cd9660_init,
.vfs_omount = cd9660_omount,
.vfs_mount = cd9660_mount,
.vfs_cmount = cd9660_cmount,
.vfs_root = cd9660_root,
.vfs_statfs = cd9660_statfs,
.vfs_uninit = cd9660_uninit,
@ -89,140 +91,79 @@ static struct vfsops cd9660_vfsops = {
VFS_SET(cd9660_vfsops, cd9660, VFCF_READONLY);
MODULE_VERSION(cd9660, 1);
/*
* Called by vfs_mountroot when iso is going to be mounted as root.
*/
static int iso_get_ssector(struct cdev *dev, struct thread *td);
static int iso_mountfs(struct vnode *devvp, struct mount *mp,
struct thread *td, struct iso_args *argp);
/*
* Try to find the start of the last data track on this CD-ROM. This
* is used to mount the last session of a multi-session CD. Bail out
* and return 0 if we fail, this is always a safe bet.
*/
static int
iso_get_ssector(dev, td)
struct cdev *dev;
struct thread *td;
{
struct ioc_toc_header h;
struct ioc_read_toc_single_entry t;
int i, error;
struct cdevsw *bd;
d_ioctl_t *ioctlp;
bd = dev_refthread(dev);
if (bd == NULL)
return 0;
ioctlp = bd->d_ioctl;
error = ioctlp(dev, CDIOREADTOCHEADER, (caddr_t)&h, FREAD, td);
if (error) {
dev_relthread(dev);
return 0;
}
for (i = h.ending_track; i >= 0; i--) {
t.address_format = CD_LBA_FORMAT;
t.track = i;
error = ioctlp(dev, CDIOREADTOCENTRY, (caddr_t)&t, FREAD, td);
if (error) {
dev_relthread(dev);
return 0;
}
if ((t.entry.control & 4) != 0)
/* found a data track */
break;
}
dev_relthread(dev);
if (i < 0)
return 0;
return ntohl(t.entry.addr.lba);
}
static int iso_mountroot(struct mount *mp, struct thread *td);
static int
iso_mountroot(mp, td)
struct mount *mp;
struct thread *td;
{
struct iso_args args;
struct vnode *rootvp;
int error;
if ((error = bdevvp(rootdev, &rootvp))) {
printf("iso_mountroot: can't find rootvp\n");
return (error);
}
args.flags = ISOFSMNT_ROOT;
vn_lock(rootvp, LK_EXCLUSIVE | LK_RETRY, td);
error = VOP_OPEN(rootvp, FREAD, FSCRED, td, -1);
VOP_UNLOCK(rootvp, 0, td);
if (error)
return error;
args.ssector = iso_get_ssector(rootdev, td);
(void)VOP_CLOSE(rootvp, FREAD, NOCRED, td);
if (bootverbose)
printf("iso_mountroot(): using session at block %d\n",
args.ssector);
if ((error = iso_mountfs(rootvp, mp, td, &args)) != 0)
return (error);
(void)cd9660_statfs(mp, &mp->mnt_stat, td);
return (0);
}
struct thread *td);
/*
* VFS Operations.
*
* mount system call
*/
static int
cd9660_omount(mp, path, data, td)
struct mount *mp;
char *path;
caddr_t data;
struct thread *td;
cd9660_cmount(struct mntarg *ma, void *data, int flags, struct thread *td)
{
struct iso_args args;
int error;
error = copyin(data, &args, sizeof args);
if (error)
return (error);
ma = mount_argsu(ma, "from", args.fspec, MAXPATHLEN);
ma = mount_arg(ma, "export", &args.export, sizeof args.export);
ma = mount_argsu(ma, "cs_disk", args.cs_disk, 64);
ma = mount_argsu(ma, "cs_local", args.cs_local, 64);
ma = mount_argf(ma, "ssector", "%u", args.ssector);
ma = mount_argb(ma, !(args.flags & ISOFSMNT_NORRIP), "norrip");
ma = mount_argb(ma, args.flags & ISOFSMNT_GENS, "nogens");
ma = mount_argb(ma, args.flags & ISOFSMNT_EXTATT, "noextatt");
ma = mount_argb(ma, !(args.flags & ISOFSMNT_NOJOLIET), "nojoliet");
ma = mount_argb(ma,
args.flags & ISOFSMNT_BROKENJOLIET, "nobrokenjoliet");
ma = mount_argb(ma, args.flags & ISOFSMNT_KICONV, "nokiconv");
ma = mount_argb(ma, args.flags & ISOFSMNT_EXTATT, "nogens");
error = kernel_mount(ma, flags);
return (error);
}
static int
cd9660_mount(struct mount *mp, struct thread *td)
{
struct vnode *devvp;
struct iso_args args;
size_t size;
int error;
struct export_args *export;
char *fspec;
int error, len;
mode_t accessmode;
struct iso_mnt *imp = 0;
struct nameidata ndp;
if (mp->mnt_flag & MNT_ROOTFS)
return (iso_mountroot(mp, td));
if ((error = copyin(data, (caddr_t)&args, sizeof (struct iso_args))))
return (error);
struct iso_mnt *imp = 0;
if ((mp->mnt_flag & MNT_RDONLY) == 0)
return (EROFS);
fspec = vfs_getopts(mp->mnt_optnew, "from", &error);
if (error)
return (error);
imp = VFSTOISOFS(mp);
/*
* If updating, check whether changing from read-only to
* read/write; if there is no device name, that's all we do.
*/
if (mp->mnt_flag & MNT_UPDATE) {
imp = VFSTOISOFS(mp);
if (args.fspec == 0)
return (vfs_export(mp, &args.export));
if (fspec == NULL) {
error = vfs_getopt(mp->mnt_optnew,
"export", (void **)&export, &len);
if (error || len != sizeof *export)
return (EINVAL);
return (vfs_export(mp, export));
}
}
/*
* Not an update, or updating the name: look up the name
* and verify that it refers to a sensible block device.
*/
NDINIT(&ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, td);
NDINIT(&ndp, LOOKUP, FOLLOW, UIO_SYSSPACE, fspec, td);
if ((error = namei(&ndp)))
return (error);
NDFREE(&ndp, NDF_ONLY_PNBUF);
@ -249,7 +190,7 @@ cd9660_omount(mp, path, data, td)
VOP_UNLOCK(devvp, 0, td);
if ((mp->mnt_flag & MNT_UPDATE) == 0) {
error = iso_mountfs(devvp, mp, td, &args);
error = iso_mountfs(devvp, mp, td);
} else {
if (devvp != imp->im_devvp)
error = EINVAL; /* needs translation */
@ -260,11 +201,7 @@ cd9660_omount(mp, path, data, td)
vrele(devvp);
return error;
}
imp = VFSTOISOFS(mp);
(void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
&size);
bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
(void) cd9660_statfs(mp, &mp->mnt_stat, td);
vfs_mountedfrom(mp, fspec);
return 0;
}
@ -272,11 +209,10 @@ cd9660_omount(mp, path, data, td)
* Common code for mount and mountroot
*/
static int
iso_mountfs(devvp, mp, td, argp)
iso_mountfs(devvp, mp, td)
struct vnode *devvp;
struct mount *mp;
struct thread *td;
struct iso_args *argp;
{
struct iso_mnt *isomp = (struct iso_mnt *)0;
struct buf *bp = NULL;
@ -292,12 +228,10 @@ iso_mountfs(devvp, mp, td, argp)
struct iso_sierra_primary_descriptor *pri_sierra = NULL;
struct iso_supplementary_descriptor *sup = NULL;
struct iso_directory_record *rootp;
int logical_block_size;
int logical_block_size, ssector;
struct g_consumer *cp;
struct bufobj *bo;
if (!(mp->mnt_flag & MNT_RDONLY))
return EROFS;
char *cs_local, *cs_disk;
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);
DROP_GIANT();
@ -324,8 +258,10 @@ iso_mountfs(devvp, mp, td, argp)
iso_bsize = ISO_DEFAULT_BLOCK_SIZE;
joliet_level = 0;
for (iso_blknum = 16 + argp->ssector;
iso_blknum < 100 + argp->ssector;
if (1 != vfs_scanopt(mp->mnt_optnew, "ssector", "%d", &ssector))
ssector = 0;
for (iso_blknum = 16 + ssector;
iso_blknum < 100 + ssector;
iso_blknum++) {
if ((error = bread(devvp, iso_blknum * btodb(iso_bsize),
iso_bsize, NOCRED, &bp)) != 0)
@ -357,7 +293,7 @@ iso_mountfs(devvp, mp, td, argp)
bp = NULL;
sup = (struct iso_supplementary_descriptor *)vdp;
if (!(argp->flags & ISOFSMNT_NOJOLIET)) {
if (vfs_flagopt(mp->mnt_optnew, "joliet", NULL, 0)) {
if (bcmp(sup->escape, "%/@", 3) == 0)
joliet_level = 1;
if (bcmp(sup->escape, "%/C", 3) == 0)
@ -366,7 +302,7 @@ iso_mountfs(devvp, mp, td, argp)
joliet_level = 3;
if ((isonum_711 (sup->flags) & 1) &&
(argp->flags & ISOFSMNT_BROKENJOLIET) == 0)
!vfs_flagopt(mp->mnt_optnew, "brokenjoliet", NULL, 0))
joliet_level = 0;
}
}
@ -427,7 +363,7 @@ iso_mountfs(devvp, mp, td, argp)
* can't do much better. This is also important for the NFS
* filehandle validation.
*/
isomp->volume_space_size += argp->ssector;
isomp->volume_space_size += ssector;
bcopy (rootp, isomp->root, sizeof isomp->root);
isomp->root_extent = isonum_733 (rootp->extent);
isomp->root_size = isonum_733 (rootp->size);
@ -448,8 +384,14 @@ iso_mountfs(devvp, mp, td, argp)
isomp->im_dev = dev;
isomp->im_devvp = devvp;
vfs_flagopt(mp->mnt_optnew, "rrip", &isomp->im_flags, ISOFSMNT_NORRIP);
vfs_flagopt(mp->mnt_optnew, "gens", &isomp->im_flags, ISOFSMNT_GENS);
vfs_flagopt(mp->mnt_optnew, "extatt", &isomp->im_flags, ISOFSMNT_EXTATT);
vfs_flagopt(mp->mnt_optnew, "joliet", &isomp->im_flags, ISOFSMNT_NOJOLIET);
vfs_flagopt(mp->mnt_optnew, "kiconv", &isomp->im_flags, ISOFSMNT_KICONV);
isomp->im_flags ^= (ISOFSMNT_NORRIP | ISOFSMNT_NOJOLIET);
/* Check the Rock Ridge Extention support */
if (!(argp->flags & ISOFSMNT_NORRIP)) {
if (vfs_flagopt(mp->mnt_optnew, "rrip", NULL, 0)) {
if ((error = bread(isomp->im_devvp,
(isomp->root_extent + isonum_711(rootp->ext_attr_length)) <<
(isomp->im_bshift - DEV_BSHIFT),
@ -459,9 +401,9 @@ iso_mountfs(devvp, mp, td, argp)
rootp = (struct iso_directory_record *)bp->b_data;
if ((isomp->rr_skip = cd9660_rrip_offset(rootp,isomp)) < 0) {
argp->flags |= ISOFSMNT_NORRIP;
isomp->im_flags |= ISOFSMNT_NORRIP;
} else {
argp->flags &= ~ISOFSMNT_GENS;
isomp->im_flags &= ~ISOFSMNT_GENS;
}
/*
@ -472,13 +414,16 @@ iso_mountfs(devvp, mp, td, argp)
brelse(bp);
bp = NULL;
}
isomp->im_flags = argp->flags & (ISOFSMNT_NORRIP | ISOFSMNT_GENS |
ISOFSMNT_EXTATT | ISOFSMNT_NOJOLIET |
ISOFSMNT_KICONV);
if (isomp->im_flags & ISOFSMNT_KICONV && cd9660_iconv) {
cd9660_iconv->open(argp->cs_local, argp->cs_disk, &isomp->im_d2l);
cd9660_iconv->open(argp->cs_disk, argp->cs_local, &isomp->im_l2d);
cs_local = vfs_getopts(mp->mnt_optnew, "cs_local", &error);
if (error)
goto out;
cs_disk = vfs_getopts(mp->mnt_optnew, "cs_disk", &error);
if (error)
goto out;
cd9660_iconv->open(cs_local, cs_disk, &isomp->im_d2l);
cd9660_iconv->open(cs_disk, cs_local, &isomp->im_l2d);
} else {
isomp->im_d2l = NULL;
isomp->im_l2d = NULL;

View File

@ -512,7 +512,6 @@ start_init(void *dummy)
char *ucp, **uap, *arg0, *arg1;
struct thread *td;
struct proc *p;
int init_does_devfs = 0;
mtx_lock(&Giant);
@ -523,34 +522,10 @@ start_init(void *dummy)
vfs_mountroot();
/* Get the vnode for '/'. Set p->p_fd->fd_cdir to reference it. */
if (VFS_ROOT(TAILQ_FIRST(&mountlist), &rootvnode, td))
panic("cannot find root vnode");
FILEDESC_LOCK(p->p_fd);
p->p_fd->fd_cdir = rootvnode;
VREF(p->p_fd->fd_cdir);
p->p_fd->fd_rdir = rootvnode;
VREF(p->p_fd->fd_rdir);
FILEDESC_UNLOCK(p->p_fd);
VOP_UNLOCK(rootvnode, 0, td);
#ifdef MAC
mac_create_root_mount(td->td_ucred, TAILQ_FIRST(&mountlist));
#endif
/*
* For disk based systems, we probably cannot do this yet
* since the fs will be read-only. But a NFS root
* might be ok. It is worth a shot.
*/
error = kern_mkdir(td, "/dev", UIO_SYSSPACE, 0700);
if (error == EEXIST)
error = 0;
if (error == 0)
error = kernel_vmount(0, "fstype", "devfs",
"fspath", "/dev", NULL);
if (error != 0)
init_does_devfs = 1;
/*
* Need just enough stack to hold the faked-up "execve()" arguments.
*/
@ -598,10 +573,6 @@ start_init(void *dummy)
(void)subyte(--ucp, 'C');
options = 1;
#endif
if (init_does_devfs) {
(void)subyte(--ucp, 'd');
options = 1;
}
if (options == 0)
(void)subyte(--ucp, '-');

View File

@ -216,8 +216,8 @@ vfs_register(struct vfsconf *vfc)
* Check the mount and unmount operations.
*/
vfsops = vfc->vfc_vfsops;
KASSERT(vfsops->vfs_mount != NULL || vfsops->vfs_omount != NULL,
("Filesystem %s has no (o)mount op", vfc->vfc_name));
KASSERT(vfsops->vfs_mount != NULL,
("Filesystem %s has no mount op", vfc->vfc_name));
KASSERT(vfsops->vfs_unmount != NULL,
("Filesystem %s has no unmount op", vfc->vfc_name));

View File

@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/filedesc.h>
#include <sys/reboot.h>
#include <sys/syscallsubr.h>
#include <sys/sysproto.h>
#include <sys/sx.h>
#include <sys/sysctl.h>
@ -73,10 +74,9 @@ __FBSDID("$FreeBSD$");
#define VFS_MOUNTARG_SIZE_MAX (1024 * 64)
static void checkdirs(struct vnode *olddp, struct vnode *newdp);
static struct cdev *getdiskbyname(char *_name);
static void gets(char *cp);
static int vfs_domount(struct thread *td, const char *fstype,
char *fspath, int fsflags, void *fsdata, int compat);
char *fspath, int fsflags, void *fsdata);
static int vfs_mount_alloc(struct vnode *dvp, struct vfsconf *vfsp,
const char *fspath, struct thread *td, struct mount **mpp);
static int vfs_mountroot_ask(void);
@ -144,12 +144,15 @@ static char *cdrom_rootdevnames[] = {
/* legacy find-root code */
char *rootdevnames[2] = {NULL, NULL};
struct cdev *rootdev = NULL;
#ifdef ROOTDEVNAME
const char *ctrootdevname = ROOTDEVNAME;
#else
const char *ctrootdevname = NULL;
#ifndef ROOTDEVNAME
# define ROOTDEVNAME NULL
#endif
const char *ctrootdevname = ROOTDEVNAME;
/*
* ---------------------------------------------------------------------
* Functions for building and sanitizing the mount options
*/
/* Remove one mount option. */
static void
@ -344,7 +347,8 @@ vfs_mergeopts(struct vfsoptlist *toopts, struct vfsoptlist *opts)
}
/*
* New mount API.
* ---------------------------------------------------------------------
* Mount a filesystem
*/
int
nmount(td, uap)
@ -389,6 +393,11 @@ nmount(td, uap)
return (error);
}
/*
* ---------------------------------------------------------------------
* Various utility functions
*/
/*
* Allocate and initialize the mount point struct.
*/
@ -487,7 +496,7 @@ vfs_donmount(struct thread *td, int fsflags, struct uio *fsoptions)
}
mtx_lock(&Giant);
error = vfs_domount(td, fstype, fspath, fsflags, optlist, 0);
error = vfs_domount(td, fstype, fspath, fsflags, optlist);
mtx_unlock(&Giant);
bail:
if (error)
@ -496,6 +505,7 @@ vfs_donmount(struct thread *td, int fsflags, struct uio *fsoptions)
}
/*
* ---------------------------------------------------------------------
* Old mount API.
*/
#ifndef _SYS_SYSPROTO_H_
@ -518,49 +528,42 @@ mount(td, uap)
} */ *uap;
{
char *fstype;
char *fspath;
struct vfsconf *vfsp;
struct vfsconf *vfsp = NULL;
struct mntarg *ma = NULL;
int error;
/* Kick out MNT_ROOTFS early as it is legal internally */
uap->flags &= ~MNT_ROOTFS;
fstype = malloc(MFSNAMELEN, M_TEMP, M_WAITOK);
if (uap->data == NULL)
return (EINVAL);
/*
* vfs_mount() actually takes a kernel string for `type' and
* `path' now, so extract them.
*/
fstype = malloc(MFSNAMELEN, M_TEMP, M_WAITOK);
error = copyinstr(uap->type, fstype, MFSNAMELEN, NULL);
mtx_lock(&Giant); /* XXX ? */
vfsp = vfs_byname_kld(fstype, td, &error);
mtx_unlock(&Giant); /* XXX ? */
if (vfsp == NULL) {
free(fstype, M_TEMP);
return (ENOENT);
}
fspath = malloc(MNAMELEN, M_TEMP, M_WAITOK);
error = copyinstr(uap->path, fspath, MNAMELEN, NULL);
if (error == 0 && vfsp->vfc_vfsops->vfs_cmount != NULL) {
ma = mount_argsu(ma, "fstype", uap->type, MNAMELEN);
ma = mount_argsu(ma, "fspath", uap->path, MNAMELEN);
ma = mount_argb(ma, uap->flags & MNT_RDONLY, "noro");
ma = mount_argb(ma, !(uap->flags & MNT_NOSUID), "nosuid");
ma = mount_argb(ma, !(uap->flags & MNT_NOEXEC), "noexec");
error = vfsp->vfc_vfsops->vfs_cmount(
ma, uap->data, uap->flags, td);
} else if (error == 0) {
mtx_lock(&Giant);
error = vfs_domount(td, fstype, fspath,
uap->flags, uap->data, 1);
if (!error) {
mtx_lock(&Giant); /* XXX ? */
vfsp = vfs_byname_kld(fstype, td, &error);
mtx_unlock(&Giant);
}
free(fstype, M_TEMP);
free(fspath, M_TEMP);
if (error)
return (error);
if (vfsp == NULL)
return (ENOENT);
if (vfsp->vfc_vfsops->vfs_cmount == NULL)
return (EOPNOTSUPP);
ma = mount_argsu(ma, "fstype", uap->type, MNAMELEN);
ma = mount_argsu(ma, "fspath", uap->path, MNAMELEN);
ma = mount_argb(ma, uap->flags & MNT_RDONLY, "noro");
ma = mount_argb(ma, !(uap->flags & MNT_NOSUID), "nosuid");
ma = mount_argb(ma, !(uap->flags & MNT_NOEXEC), "noexec");
error = vfsp->vfc_vfsops->vfs_cmount(ma, uap->data, uap->flags, td);
return (error);
}
/*
* vfs_domount(): actually attempt a filesystem mount.
*/
@ -570,8 +573,7 @@ vfs_domount(
const char *fstype, /* Filesystem type. */
char *fspath, /* Mount path. */
int fsflags, /* Flags common to all filesystems. */
void *fsdata, /* Options local to the filesystem. */
int compat /* Invocation from compat syscall. */
void *fsdata /* Options local to the filesystem. */
)
{
struct vnode *vp;
@ -660,12 +662,10 @@ vfs_domount(
vp->v_iflag |= VI_MOUNT;
VI_UNLOCK(vp);
mp->mnt_flag |= fsflags &
(MNT_RELOAD | MNT_FORCE | MNT_UPDATE | MNT_SNAPSHOT);
(MNT_RELOAD | MNT_FORCE | MNT_UPDATE | MNT_SNAPSHOT | MNT_ROOTFS);
VOP_UNLOCK(vp, 0, td);
if (compat == 0) {
mp->mnt_optnew = fsdata;
vfs_mergeopts(mp->mnt_optnew, mp->mnt_opt);
}
mp->mnt_optnew = fsdata;
vfs_mergeopts(mp->mnt_optnew, mp->mnt_opt);
} else {
/*
* If the user is not root, ensure that they own the directory
@ -682,7 +682,8 @@ vfs_domount(
return (error);
}
}
if ((error = vinvalbuf(vp, V_SAVE, td->td_ucred, td, 0, 0)) != 0) {
error = vinvalbuf(vp, V_SAVE, td->td_ucred, td, 0, 0);
if (error != 0) {
vput(vp);
return (error);
}
@ -716,26 +717,7 @@ vfs_domount(
VOP_UNLOCK(vp, 0, td);
/* XXXMAC: pass to vfs_mount_alloc? */
if (compat == 0)
mp->mnt_optnew = fsdata;
}
/*
* Check if the fs implements the type VFS_[O]MOUNT()
* function we are looking for.
*/
if ((compat && (mp->mnt_op->vfs_omount == NULL)) ||
(!compat && (mp->mnt_op->vfs_mount == NULL))) {
printf("%s doesn't support the %s mount syscall\n",
mp->mnt_vfc->vfc_name, compat ? "old" : "new");
VI_LOCK(vp);
vp->v_iflag &= ~VI_MOUNT;
VI_UNLOCK(vp);
if (mp->mnt_flag & MNT_UPDATE)
vfs_unbusy(mp, td);
else
vfs_mount_destroy(mp, td);
vrele(vp);
return (EOPNOTSUPP);
mp->mnt_optnew = fsdata;
}
/*
@ -743,19 +725,14 @@ vfs_domount(
*/
if (fsflags & MNT_RDONLY)
mp->mnt_flag |= MNT_RDONLY;
else if (mp->mnt_flag & MNT_RDONLY)
mp->mnt_kern_flag |= MNTK_WANTRDWR;
mp->mnt_flag &=~ MNT_UPDATEMASK;
mp->mnt_flag |= fsflags & (MNT_UPDATEMASK | MNT_FORCE);
mp->mnt_flag |= fsflags & (MNT_UPDATEMASK | MNT_FORCE | MNT_ROOTFS);
/*
* Mount the filesystem.
* XXX The final recipients of VFS_MOUNT just overwrite the ndp they
* get. No freeing of cn_pnbuf.
*/
if (compat)
error = VFS_OMOUNT(mp, fspath, fsdata, td);
else
error = VFS_MOUNT(mp, td);
error = VFS_MOUNT(mp, td);
if (!error) {
if (mp->mnt_opt != NULL)
vfs_freeopts(mp->mnt_opt);
@ -768,11 +745,8 @@ vfs_domount(
*/
mp->mnt_optnew = NULL;
if (mp->mnt_flag & MNT_UPDATE) {
if (mp->mnt_kern_flag & MNTK_WANTRDWR)
mp->mnt_flag &= ~MNT_RDONLY;
mp->mnt_flag &=
~(MNT_UPDATE | MNT_RELOAD | MNT_FORCE | MNT_SNAPSHOT);
mp->mnt_kern_flag &= ~MNTK_WANTRDWR;
if (error) {
mp->mnt_flag = flag;
mp->mnt_kern_flag = kern_flag;
@ -877,6 +851,7 @@ checkdirs(olddp, newdp)
}
/*
* ---------------------------------------------------------------------
* Unmount a filesystem.
*
* Note: unmount takes a path to the vnode mounted on as argument,
@ -1063,6 +1038,146 @@ dounmount(mp, flags, td)
return (0);
}
/*
* ---------------------------------------------------------------------
* Mounting of root filesystem
*
*/
static void
set_rootvnode(struct thread *td)
{
struct proc *p;
if (VFS_ROOT(TAILQ_FIRST(&mountlist), &rootvnode, td))
panic("Cannot find root vnode");
p = td->td_proc;
FILEDESC_LOCK(p->p_fd);
if (p->p_fd->fd_cdir != NULL)
vrele(p->p_fd->fd_cdir);
p->p_fd->fd_cdir = rootvnode;
VREF(rootvnode);
if (p->p_fd->fd_rdir != NULL)
vrele(p->p_fd->fd_rdir);
p->p_fd->fd_rdir = rootvnode;
VREF(rootvnode);
FILEDESC_UNLOCK(p->p_fd);
VOP_UNLOCK(rootvnode, 0, td);
}
/*
* Mount /devfs as our root filesystem, but do not put it on the mountlist
* yet. Create a /dev -> / symlink so that absolute pathnames will lookup.
*/
static struct mount *
devfs_first(void)
{
struct thread *td = curthread;
struct vfsconf *vfsp;
struct mount *mp = NULL;
int error;
vfsp = vfs_byname("devfs");
KASSERT(vfsp != NULL, ("Could not find devfs by name"));
if (vfsp == NULL)
return(NULL);
error = vfs_mount_alloc(NULLVP, vfsp, "/dev", td, &mp);
KASSERT(error == 0, ("vfs_mount_alloc failed %d", error));
if (error)
return (NULL);
error = VFS_MOUNT(mp, curthread);
KASSERT(error == 0, ("VFS_MOUNT(devfs) failed %d", error));
if (error)
return (NULL);
VFS_START(mp, 0, td);
mtx_lock(&mountlist_mtx);
TAILQ_INSERT_HEAD(&mountlist, mp, mnt_list);
mtx_unlock(&mountlist_mtx);
set_rootvnode(td);
error = kern_symlink(td, "/", "dev", UIO_SYSSPACE);
printf("kern_symlink = %d\n", error);
return (mp);
}
/*
* Surgically move our devfs to be mounted on /dev.
*/
static void
devfs_fixup(struct thread *td)
{
struct nameidata nd;
int error;
struct vnode *vp, *dvp;
struct mount *mp;
/* Remove our devfs mount from the mountlist and purge the cache */
mtx_lock(&mountlist_mtx);
mp = TAILQ_FIRST(&mountlist);
TAILQ_REMOVE(&mountlist, mp, mnt_list);
mtx_unlock(&mountlist_mtx);
cache_purgevfs(mp);
VFS_ROOT(mp, &dvp, td);
VI_LOCK(dvp);
dvp->v_iflag &= ~VI_MOUNT;
dvp->v_mountedhere = NULL;
VI_UNLOCK(dvp);
/* Set up the real rootvnode, and purge the cache */
TAILQ_FIRST(&mountlist)->mnt_vnodecovered = NULL;
set_rootvnode(td);
cache_purgevfs(rootvnode->v_mount);
#if 0
/* We may have a chance... */
error = kern_mkdir(td, "/dev", UIO_SYSSPACE, 0700);
printf("kern_mkdir = %d\n", error);
#endif
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, "/dev", td);
error = namei(&nd);
if (error) {
printf("Lookup /dev -> %d\n", error);
return;
}
NDFREE(&nd, NDF_ONLY_PNBUF);
vp = nd.ni_vp;
if (vp->v_type != VDIR) {
vput(vp);
}
error = vinvalbuf(vp, V_SAVE, td->td_ucred, td, 0, 0);
if (error) {
vput(vp);
}
cache_purge(vp);
mp->mnt_vnodecovered = vp;
vp->v_mountedhere = mp;
mtx_lock(&mountlist_mtx);
TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
mtx_unlock(&mountlist_mtx);
VOP_UNLOCK(vp, 0, td);
vfs_unbusy(mp, td);
VREF(vp);
vput(vp);
vput(dvp);
}
/*
* Find and mount the root filesystem
*/
@ -1071,7 +1186,7 @@ vfs_mountroot(void)
{
char *cp;
int error, i, asked = 0;
struct mount *mp;
/*
* Wait for GEOM to settle down
@ -1080,6 +1195,8 @@ vfs_mountroot(void)
g_waitidle();
PICKUP_GIANT();
mp = devfs_first();
/*
* We are booted with instructions to prompt for the root filesystem.
*/
@ -1138,7 +1255,6 @@ vfs_mountroot(void)
if (ctrootdevname != NULL)
if (!vfs_mountroot_try(ctrootdevname))
return;
/*
* Everything so far has failed, prompt on the console if we haven't
* already tried that.
@ -1146,6 +1262,7 @@ vfs_mountroot(void)
if (!asked)
if (!vfs_mountroot_ask())
return;
panic("Root mount failed, startup aborted.");
}
@ -1156,8 +1273,6 @@ static int
vfs_mountroot_try(const char *mountfrom)
{
struct mount *mp;
struct thread *td = curthread;
struct vfsconf *vfsp;
char *vfsname, *path;
int error;
char patt[32];
@ -1181,68 +1296,36 @@ vfs_mountroot_try(const char *mountfrom)
vfsname[0] = path[0] = 0;
sprintf(patt, "%%%d[a-z0-9]:%%%ds", MFSNAMELEN, MNAMELEN);
if (sscanf(mountfrom, patt, vfsname, path) < 1)
goto done;
return (error);
if (path[0] == '\0')
strcpy(path, ROOTNAME);
vfsp = vfs_byname(vfsname);
if (vfsp == NULL) {
printf("Can't find filesystem \"%s\"\n", vfsname);
goto done;
}
error = vfs_mount_alloc(NULLVP, vfsp, "/", td, &mp);
if (error) {
printf("Could not alloc mountpoint\n");
goto done;
}
mp->mnt_flag |= MNT_RDONLY | MNT_ROOTFS;
strlcpy(mp->mnt_stat.f_mntfromname, path, MNAMELEN);
/*
* do our best to set rootdev
* XXX: This does not belong here!
*/
if (path[0] != '\0') {
struct cdev *diskdev;
diskdev = getdiskbyname(path);
if (diskdev != NULL)
rootdev = diskdev;
else
printf("setrootbyname failed\n");
}
error = VFS_OMOUNT(mp, path, NULL, curthread);
done:
if (vfsname != NULL)
free(vfsname, M_MOUNT);
if (path != NULL)
free(path, M_MOUNT);
if (error != 0) {
if (mp != NULL)
vfs_mount_destroy(mp, curthread);
printf("Root mount failed: %d\n", error);
} else {
/* register with list of mounted filesystems */
mtx_lock(&mountlist_mtx);
TAILQ_INSERT_HEAD(&mountlist, mp, mnt_list);
mtx_unlock(&mountlist_mtx);
error = kernel_vmount(
MNT_RDONLY | MNT_ROOTFS,
"fstype", vfsname,
"fspath", "/",
"from", path,
NULL);
printf("kernel_vmount = %d\n", error);
if (error == 0) {
mp = TAILQ_FIRST(&mountlist);
/* sanity check system clock against root fs timestamp */
inittodr(mp->mnt_time);
vfs_unbusy(mp, curthread);
error = VFS_START(mp, 0, curthread);
devfs_fixup(curthread);
}
return (error);
}
/*
* Spin prompting on the console for a suitable root filesystem
* ---------------------------------------------------------------------
* Interactive root filesystem selection code.
*/
static int
vfs_mountroot_ask(void)
{
@ -1313,86 +1396,6 @@ gets(char *cp)
}
}
/*
* Convert a given name to the cdev pointer of the device, which is probably
* but not by definition, a disk. Mount a DEVFS (on nothing), look the name
* up, extract the cdev from the vnode and unmount it again. Unfortunately
* we cannot use the vnode directly (because we unmount the DEVFS again)
* so the filesystems still have to do the bdevvp() stunt.
*/
static struct cdev *
getdiskbyname(char *name)
{
char *cp = name;
struct cdev *dev = NULL;
struct thread *td = curthread;
struct vfsconf *vfsp;
struct mount *mp = NULL;
struct vnode *vroot = NULL;
struct nameidata nid;
int error;
if (!bcmp(cp, "/dev/", 5))
cp += 5;
do {
vfsp = vfs_byname("devfs");
if (vfsp == NULL)
break;
error = vfs_mount_alloc(NULLVP, vfsp, "/dev", td, &mp);
if (error)
break;
mp->mnt_flag |= MNT_RDONLY;
error = VFS_MOUNT(mp, curthread);
if (error)
break;
VFS_START(mp, 0, td);
VFS_ROOT(mp, &vroot, td);
VOP_UNLOCK(vroot, 0, td);
NDINIT(&nid, LOOKUP, NOCACHE|FOLLOW,
UIO_SYSSPACE, cp, curthread);
nid.ni_startdir = vroot;
nid.ni_pathlen = strlen(cp);
nid.ni_cnd.cn_cred = curthread->td_ucred;
nid.ni_cnd.cn_nameptr = cp;
error = lookup(&nid);
if (error)
break;
if (nid.ni_vp->v_type != VCHR)
dev = NULL;
else
dev = nid.ni_vp->v_rdev;
NDFREE(&nid, 0);
} while (0);
if (vroot != NULL)
VFS_UNMOUNT(mp, 0, td);
if (mp != NULL)
vfs_mount_destroy(mp, td);
return (dev);
}
/* Show the struct cdev *for a disk specified by name */
#ifdef DDB
DB_SHOW_COMMAND(disk, db_getdiskbyname)
{
struct cdev *dev;
if (modif[0] == '\0') {
db_error("usage: show disk/devicename");
return;
}
dev = getdiskbyname(modif);
if (dev != NULL)
db_printf("struct cdev *= %p\n", dev);
else
db_printf("No disk device matched.\n");
}
#endif
/*
* ---------------------------------------------------------------------
* Functions for querying mount options/arguments from filesystems.
@ -1515,6 +1518,7 @@ vfs_scanopt(struct vfsoptlist *opts, const char *name, const char *fmt, ...)
}
return (0);
}
/*
* Find and copy a mount option.
*
@ -1545,7 +1549,6 @@ vfs_copyopt(opts, name, dest, len)
return (ENOENT);
}
/*
* This is a helper function for filesystems to traverse their
* vnodes. See MNT_VNODE_FOREACH() in sys/mount.h

View File

@ -79,7 +79,6 @@ __FBSDID("$FreeBSD$");
static MALLOC_DEFINE(M_NETADDR, "Export Host", "Export host address structure");
static void addalias(struct vnode *vp, struct cdev *nvp_rdev);
static void delmntque(struct vnode *vp);
static void insmntque(struct vnode *vp, struct mount *mp);
static void vclean(struct vnode *vp, int flags, struct thread *td);
@ -1752,39 +1751,6 @@ reassignbuf(struct buf *bp)
VI_UNLOCK(vp);
}
/*
* Create a vnode for a device.
* Used for mounting the root filesystem.
*/
int
bdevvp(dev, vpp)
struct cdev *dev;
struct vnode **vpp;
{
register struct vnode *vp;
struct vnode *nvp;
int error;
if (dev == NULL) {
*vpp = NULLVP;
return (ENXIO);
}
if (vfinddev(dev, vpp))
return (0);
error = getnewvnode("none", (struct mount *)0, &devfs_specops, &nvp);
if (error) {
*vpp = NULLVP;
return (error);
}
vp = nvp;
vp->v_type = VCHR;
vp->v_bufobj.bo_bsize = DEV_BSIZE;
addalias(vp, dev);
*vpp = vp;
return (0);
}
static void
v_incr_usecount(struct vnode *vp, int delta)
{
@ -1797,86 +1763,6 @@ v_incr_usecount(struct vnode *vp, int delta)
}
}
/*
* Add vnode to the alias list hung off the struct cdev *.
*
* The reason for this gunk is that multiple vnodes can reference
* the same physical device, so checking vp->v_usecount to see
* how many users there are is inadequate; the v_usecount for
* the vnodes need to be accumulated. vcount() does that.
*/
struct vnode *
addaliasu(nvp, nvp_rdev)
struct vnode *nvp;
dev_t nvp_rdev;
{
struct vnode *ovp;
struct vop_vector *ops;
struct cdev *dev;
if (nvp->v_type == VBLK)
return (nvp);
if (nvp->v_type != VCHR)
panic("addaliasu on non-special vnode");
dev = findcdev(nvp_rdev);
if (dev == NULL)
return (nvp);
/*
* Check to see if we have a bdevvp vnode with no associated
* filesystem. If so, we want to associate the filesystem of
* the new newly instigated vnode with the bdevvp vnode and
* discard the newly created vnode rather than leaving the
* bdevvp vnode lying around with no associated filesystem.
*/
if (vfinddev(dev, &ovp) == 0 || ovp->v_data != NULL) {
addalias(nvp, dev);
return (nvp);
}
/*
* Discard unneeded vnode, but save its node specific data.
* Note that if there is a lock, it is carried over in the
* node specific data to the replacement vnode.
*/
vref(ovp);
ovp->v_data = nvp->v_data;
ovp->v_tag = nvp->v_tag;
nvp->v_data = NULL;
lockdestroy(ovp->v_vnlock);
lockinit(ovp->v_vnlock, PVFS, nvp->v_vnlock->lk_wmesg,
nvp->v_vnlock->lk_timo, nvp->v_vnlock->lk_flags & LK_EXTFLG_MASK);
ops = ovp->v_op;
ovp->v_op = nvp->v_op;
if (VOP_ISLOCKED(nvp, curthread)) {
VOP_UNLOCK(nvp, 0, curthread);
vn_lock(ovp, LK_EXCLUSIVE | LK_RETRY, curthread);
}
nvp->v_op = ops;
delmntque(ovp);
insmntque(ovp, nvp->v_mount);
vrele(nvp);
vgone(nvp);
return (ovp);
}
/* This is a local helper function that do the same as addaliasu, but for a
* struct cdev *instead of an dev_t. */
static void
addalias(nvp, dev)
struct vnode *nvp;
struct cdev *dev;
{
KASSERT(nvp->v_type == VCHR, ("addalias on non-special vnode"));
VI_LOCK(nvp);
dev_lock();
dev->si_refcount++;
nvp->v_rdev = dev;
SLIST_INSERT_HEAD(&dev->si_hlist, nvp, v_specnext);
dev->si_usecount += nvp->v_usecount;
dev_unlock();
VI_UNLOCK(nvp);
}
/*
* Grab a particular vnode from the free list, increment its
* reference count and lock it. The vnode lock bit is set if the

View File

@ -101,11 +101,12 @@ SYSCTL_INT(_vfs_nfs, NFS_TPRINTF_DELAY,
downdelayinterval, CTLFLAG_RW, &nfs_tprintf_delay, 0, "");
static int nfs_iosize(struct nfsmount *nmp);
static void nfs_decode_args(struct nfsmount *nmp, struct nfs_args *argp);
static void nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp);
static int mountnfs(struct nfs_args *, struct mount *,
struct sockaddr *, char *, char *, struct vnode **,
struct ucred *cred);
static vfs_omount_t nfs_omount;
static vfs_mount_t nfs_mount;
static vfs_cmount_t nfs_cmount;
static vfs_unmount_t nfs_unmount;
static vfs_root_t nfs_root;
static vfs_statfs_t nfs_statfs;
@ -117,7 +118,8 @@ static vfs_sysctl_t nfs_sysctl;
*/
static struct vfsops nfs_vfsops = {
.vfs_init = nfs_init,
.vfs_omount = nfs_omount,
.vfs_mount = nfs_mount,
.vfs_cmount = nfs_cmount,
.vfs_root = nfs_root,
.vfs_statfs = nfs_statfs,
.vfs_sync = nfs_sync,
@ -519,13 +521,17 @@ nfs_mountdiskless(char *path, char *which, int mountflag,
}
static void
nfs_decode_args(struct nfsmount *nmp, struct nfs_args *argp)
nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp)
{
int s;
int adjsock;
int maxio;
s = splnet();
if (vfs_getopt(mp->mnt_optnew, "ro", NULL, NULL))
mp->mnt_flag &= ~MNT_RDONLY;
else
mp->mnt_flag |= MNT_RDONLY;
/*
* Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes
* no sense in that context.
@ -658,6 +664,8 @@ nfs_decode_args(struct nfsmount *nmp, struct nfs_args *argp)
}
}
static const char *nfs_opts[] = { "from", "nfs_args", NULL };
/*
* VFS Operations.
*
@ -669,7 +677,7 @@ nfs_decode_args(struct nfsmount *nmp, struct nfs_args *argp)
*/
/* ARGSUSED */
static int
nfs_omount(struct mount *mp, char *path, caddr_t data, struct thread *td)
nfs_mount(struct mount *mp, struct thread *td)
{
int error;
struct nfs_args args;
@ -678,27 +686,21 @@ nfs_omount(struct mount *mp, char *path, caddr_t data, struct thread *td)
char hst[MNAMELEN];
size_t len;
u_char nfh[NFSX_V3FHMAX];
char *path = "XXX: foo";
if (vfs_filteropt(mp->mnt_optnew, nfs_opts))
return (EINVAL);
if (mp->mnt_flag & MNT_ROOTFS)
return (nfs_mountroot(mp, td));
error = copyin(data, (caddr_t)&args, sizeof (struct nfs_args));
error = vfs_copyopt(mp->mnt_optnew, "nfs_args", &args, sizeof args);
if (error)
return (error);
if (args.version != NFS_ARGSVERSION) {
#ifdef COMPAT_PRELITE2
/*
* If the argument version is unknown, then assume the
* caller is a pre-lite2 4.4BSD client and convert its
* arguments.
*/
struct onfs_args oargs;
error = copyin(data, (caddr_t)&oargs, sizeof (struct onfs_args));
if (error)
return (error);
nfs_convert_oargs(&args,&oargs);
#else /* !COMPAT_PRELITE2 */
return (EPROGMISMATCH);
#endif /* COMPAT_PRELITE2 */
}
if (mp->mnt_flag & MNT_UPDATE) {
struct nfsmount *nmp = VFSTONFS(mp);
@ -713,7 +715,7 @@ nfs_omount(struct mount *mp, char *path, caddr_t data, struct thread *td)
~(NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) |
(nmp->nm_flag &
(NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/));
nfs_decode_args(nmp, &args);
nfs_decode_args(mp, nmp, &args);
return (0);
}
@ -746,6 +748,34 @@ nfs_omount(struct mount *mp, char *path, caddr_t data, struct thread *td)
return (error);
}
/*
* VFS Operations.
*
* mount system call
* It seems a bit dumb to copyinstr() the host and path here and then
* bcopy() them in mountnfs(), but I wanted to detect errors before
* doing the sockargs() call because sockargs() allocates an mbuf and
* an error after that means that I have to release the mbuf.
*/
/* ARGSUSED */
static int
nfs_cmount(struct mntarg *ma, void *data, int flags, struct thread *td)
{
int error;
struct nfs_args args;
error = copyin(data, &args, sizeof (struct nfs_args));
if (error)
return (error);
ma = mount_arg(ma, "nfs_args", &args, sizeof args);
error = kernel_mount(ma, flags);
return (error);
}
/*
* Common code for mount and mountroot
*/
@ -815,7 +845,7 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
nmp->nm_soproto = argp->proto;
nmp->nm_rpcops = &nfs_rpcops;
nfs_decode_args(nmp, argp);
nfs_decode_args(mp, nmp, argp);
if (nmp->nm_sotype == SOCK_STREAM)
mtx_init(&nmp->nm_nfstcpstate.mtx, "NFS/TCP state lock",

View File

@ -125,6 +125,7 @@ struct ostatfs {
#define MMAXOPTIONLEN 65536 /* maximum length of a mount option */
TAILQ_HEAD(vnodelst, vnode);
struct vfsoptlist;
struct vfsopt;
@ -144,7 +145,7 @@ struct mount {
struct lock mnt_lock; /* mount structure lock */
struct mtx mnt_mtx; /* mount structure interlock */
int mnt_writeopcount; /* write syscalls in progress */
int mnt_flag; /* flags shared with user */
u_int mnt_flag; /* flags shared with user */
struct vfsoptlist *mnt_opt; /* current mount options */
struct vfsoptlist *mnt_optnew; /* new options passed to fs */
int mnt_kern_flag; /* kernel only flags */
@ -264,7 +265,6 @@ struct vnode *__mnt_vnode_next(struct vnode **nvp, struct mount *mp);
#define MNTK_UNMOUNTF 0x00000001 /* forced unmount in progress */
#define MNTK_UNMOUNT 0x01000000 /* unmount in progress */
#define MNTK_MWAIT 0x02000000 /* waiting for unmount to finish */
#define MNTK_WANTRDWR 0x04000000 /* upgrade to read/write requested */
#define MNTK_SUSPEND 0x08000000 /* request write suspension */
#define MNTK_SUSPENDED 0x10000000 /* write operations are suspended */
@ -462,8 +462,6 @@ struct sysctl_req;
struct mntarg;
typedef int vfs_cmount_t(struct mntarg *ma, void *data, int flags, struct thread *td);
typedef int vfs_omount_t(struct mount *mp, char *path, caddr_t data,
struct thread *td);
typedef int vfs_start_t(struct mount *mp, int flags, struct thread *td);
typedef int vfs_unmount_t(struct mount *mp, int mntflags, struct thread *td);
typedef int vfs_root_t(struct mount *mp, struct vnode **vpp, struct thread *td);
@ -490,7 +488,6 @@ typedef int vfs_sysctl_t(struct mount *mp, fsctlop_t op,
struct vfsops {
vfs_mount_t *vfs_mount;
vfs_omount_t *vfs_omount;
vfs_cmount_t *vfs_cmount;
vfs_start_t *vfs_start;
vfs_unmount_t *vfs_unmount;
@ -511,8 +508,6 @@ struct vfsops {
vfs_statfs_t __vfs_statfs;
#define VFS_MOUNT(MP, P) (*(MP)->mnt_op->vfs_mount)(MP, P)
#define VFS_OMOUNT(MP, PATH, DATA, P) \
(*(MP)->mnt_op->vfs_omount)(MP, PATH, DATA, P)
#define VFS_START(MP, FLAGS, P) (*(MP)->mnt_op->vfs_start)(MP, FLAGS, P)
#define VFS_UNMOUNT(MP, FORCE, P) (*(MP)->mnt_op->vfs_unmount)(MP, FORCE, P)
#define VFS_ROOT(MP, VPP, P) (*(MP)->mnt_op->vfs_root)(MP, VPP, P)
@ -559,13 +554,14 @@ extern char *mountrootfsname;
/*
* exported vnode operations
*/
int dounmount(struct mount *, int, struct thread *);
void free_mntarg(struct mntarg *ma);
struct mntarg *mount_argb(struct mntarg *ma, int flag, const char *name);
int kernel_mount(struct mntarg *ma, int flags);
int kernel_vmount(int flags, ...);
struct mntarg *mount_arg(struct mntarg *ma, const char *name, const void *val, int len);
struct mntarg *mount_argb(struct mntarg *ma, int flag, const char *name);
struct mntarg *mount_argf(struct mntarg *ma, const char *name, const char *fmt, ...);
struct mntarg *mount_argsu(struct mntarg *ma, const char *name, const void *val, int len);
struct vfsconf *vfs_byname(const char *);

View File

@ -62,7 +62,6 @@ extern struct cv selwait; /* select conditional variable */
extern long physmem; /* physical memory */
extern struct cdev *rootdev; /* root device */
extern char *rootdevnames[2]; /* names of possible root devices */
extern int boothowto; /* reboot flags, from console subsystem */
@ -298,6 +297,7 @@ void wakeup_one(void *chan) __nonnull(1);
* Common `struct cdev *' stuff are declared here to avoid #include poisoning
*/
struct cdev;
int major(struct cdev *x);
int minor(struct cdev *x);
dev_t dev2udev(struct cdev *x);

View File

@ -564,8 +564,6 @@ extern int (*lease_check_hook)(struct vop_lease_args *);
extern int (*softdep_fsync_hook)(struct vnode *);
extern int (*softdep_process_worklist_hook)(struct mount *);
struct vnode *addaliasu(struct vnode *vp, dev_t nvp_rdev);
int bdevvp(struct cdev *dev, struct vnode **vpp);
/* cache_* may belong in namei.h. */
void cache_enter(struct vnode *dvp, struct vnode *vp,
struct componentname *cnp);

View File

@ -81,13 +81,15 @@ static void ffs_ifree(struct ufsmount *ump, struct inode *ip);
static vfs_init_t ffs_init;
static vfs_uninit_t ffs_uninit;
static vfs_extattrctl_t ffs_extattrctl;
static vfs_omount_t ffs_omount;
static vfs_cmount_t ffs_cmount;
static vfs_mount_t ffs_mount;
static struct vfsops ufs_vfsops = {
.vfs_extattrctl = ffs_extattrctl,
.vfs_fhtovp = ffs_fhtovp,
.vfs_init = ffs_init,
.vfs_omount = ffs_omount,
.vfs_mount = ffs_mount,
.vfs_cmount = ffs_cmount,
.vfs_quotactl = ufs_quotactl,
.vfs_root = ufs_root,
.vfs_statfs = ffs_statfs,
@ -108,55 +110,23 @@ static struct buf_ops ffs_ops = {
.bop_strategy = ffs_geom_strategy,
};
/*
* ffs_omount
*
* Called when mounting local physical media
*
* PARAMETERS:
* mountroot
* mp mount point structure
* path path to mount point
* data <unused>
* ndp <unused>
* p process (user credentials check [statfs])
*
* mount
* mp mount point structure
* path path to mount point
* data pointer to argument struct in user space
* ndp mount point namei() return (used for
* credentials on reload), reused to look
* up block device.
* p process (user credentials check)
*
* RETURNS: 0 Success
* !0 error number (errno.h)
*
* LOCK STATE:
*
* ENTRY
* mount point is locked
* EXIT
* mount point is locked
*
* NOTES:
* A NULL path can be used for a flag since the mount
* system call will fail with EFAULT in copyinstr in
* namei() if it is a genuine NULL from the user.
*/
static const char *ffs_opts[] = { "from", "export", NULL };
static int
ffs_omount(struct mount *mp, char *path, caddr_t data, struct thread *td)
ffs_mount(struct mount *mp, struct thread *td)
{
size_t size;
struct vnode *devvp, *rootvp;
struct ufs_args args;
struct vnode *devvp;
struct ufsmount *ump = 0;
struct fs *fs;
int error, flags;
mode_t accessmode;
struct nameidata ndp;
struct export_args *export;
char *fspec;
int len;
if (vfs_filteropt(mp->mnt_optnew, ffs_opts))
return (EINVAL);
if (uma_inode == NULL) {
uma_inode = uma_zcreate("FFS inode",
sizeof(struct inode), NULL, NULL, NULL, NULL,
@ -168,27 +138,10 @@ ffs_omount(struct mount *mp, char *path, caddr_t data, struct thread *td)
sizeof(struct ufs2_dinode), NULL, NULL, NULL, NULL,
UMA_ALIGN_PTR, 0);
}
if ((mp->mnt_flag & MNT_ROOTFS) && mp->mnt_data == NULL) {
if ((error = bdevvp(rootdev, &rootvp))) {
printf("ffs_mountroot: can't find rootvp\n");
return (error);
}
if ((error = ffs_mountfs(rootvp, mp, td)) != 0)
return (error);
return (0);
}
/*
* Get mount options, if any.
*/
if (data != NULL) {
error = copyin(data, (caddr_t)&args, sizeof args);
if (error)
return (error);
} else {
memset(&args, 0, sizeof args);
}
fspec = vfs_getopts(mp->mnt_optnew, "from", &error);
if (error)
return (error);
/*
* If updating, check whether changing from read-only to
@ -198,7 +151,8 @@ ffs_omount(struct mount *mp, char *path, caddr_t data, struct thread *td)
ump = VFSTOUFS(mp);
fs = ump->um_fs;
devvp = ump->um_devvp;
if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) {
if (fs->fs_ronly == 0 &&
vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0)) {
if ((error = vn_start_write(NULL, &mp, V_WAIT)) != 0)
return (error);
/*
@ -234,7 +188,6 @@ ffs_omount(struct mount *mp, char *path, caddr_t data, struct thread *td)
fs->fs_pendingblocks = 0;
fs->fs_pendinginodes = 0;
}
fs->fs_ronly = 1;
if ((fs->fs_flags & (FS_UNCLEAN | FS_NEEDSFSCK)) == 0)
fs->fs_clean = 1;
if ((error = ffs_sbupdate(ump, MNT_WAIT)) != 0) {
@ -249,11 +202,14 @@ ffs_omount(struct mount *mp, char *path, caddr_t data, struct thread *td)
g_access(ump->um_cp, 0, -1, 0);
g_topology_unlock();
PICKUP_GIANT();
fs->fs_ronly = 1;
mp->mnt_flag |= MNT_RDONLY;
}
if ((mp->mnt_flag & MNT_RELOAD) &&
(error = ffs_reload(mp, td)) != 0)
return (error);
if (fs->fs_ronly && (mp->mnt_kern_flag & MNTK_WANTRDWR)) {
if (fs->fs_ronly &&
!vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0)) {
/*
* If upgrade to read-write by non-root, then verify
* that user has necessary permissions on the device.
@ -299,6 +255,7 @@ ffs_omount(struct mount *mp, char *path, caddr_t data, struct thread *td)
if ((error = vn_start_write(NULL, &mp, V_WAIT)) != 0)
return (error);
fs->fs_ronly = 0;
mp->mnt_flag &= ~MNT_RDONLY;
fs->fs_clean = 0;
if ((error = ffs_sbupdate(ump, MNT_WAIT)) != 0) {
vn_finished_write(mp);
@ -326,20 +283,25 @@ ffs_omount(struct mount *mp, char *path, caddr_t data, struct thread *td)
/*
* If not updating name, process export requests.
*/
if (args.fspec == 0)
return (vfs_export(mp, &args.export));
if (fspec == NULL) {
error = vfs_getopt(mp->mnt_optnew,
"export", (void **)&export, &len);
if (error || len != sizeof *export)
return (EINVAL);
return (vfs_export(mp, export));
}
/*
* If this is a snapshot request, take the snapshot.
*/
if (mp->mnt_flag & MNT_SNAPSHOT)
return (ffs_snapshot(mp, args.fspec));
return (ffs_snapshot(mp, fspec));
}
/*
* Not an update, or updating the name: look up the name
* and verify that it refers to a sensible disk device.
*/
NDINIT(&ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, td);
NDINIT(&ndp, LOOKUP, FOLLOW, UIO_SYSSPACE, fspec, td);
if ((error = namei(&ndp)) != 0)
return (error);
NDFREE(&ndp, NDF_ONLY_PNBUF);
@ -392,14 +354,33 @@ ffs_omount(struct mount *mp, char *path, caddr_t data, struct thread *td)
return (error);
}
}
/*
* Save "mounted from" device name info for mount point (NULL pad).
*/
copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size);
bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
vfs_mountedfrom(mp, fspec);
return (0);
}
/*
* Compatibility with old mount system call.
*/
static int
ffs_cmount(struct mntarg *ma, void *data, int flags, struct thread *td)
{
struct ufs_args args;
int error;
if (data == NULL)
return (EINVAL);
error = copyin(data, &args, sizeof args);
if (error)
return (error);
ma = mount_argsu(ma, "from", args.fspec, MAXPATHLEN);
ma = mount_arg(ma, "export", &args.export, sizeof args.export);
error = kernel_mount(ma, flags);
return (error);
}
/*
* Reload all incore data for a filesystem (used after running fsck on
* the root filesystem and finding things to fix). The filesystem must
@ -572,7 +553,6 @@ ffs_mountfs(devvp, mp, td)
int error, i, blks, size, ronly;
int32_t *lp;
struct ucred *cred;
size_t strsize;
struct g_consumer *cp;
dev = devvp->v_rdev;
@ -580,18 +560,6 @@ ffs_mountfs(devvp, mp, td)
vfs_object_create(devvp, td, td->td_ucred);
ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
#if 0
/*
* XXX: check filesystem permissions, they may be more strict
* XXX: than what geom enforces.
* XXX: But since we're root, they wouldn't matter, would they ?
*/
error = VOP_ACCESS(devvp, ronly ? FREAD : FREAD | FWRITE, FSCRED, td);
if (error) {
VOP_UNLOCK(devvp, 0, td);
return (error);
}
#endif
DROP_GIANT();
g_topology_lock();
error = g_vfs_open(devvp, &cp, "ffs", ronly ? 0 : 1);
@ -770,11 +738,7 @@ ffs_mountfs(devvp, mp, td)
/*
* Set FS local "last mounted on" information (NULL pad)
*/
copystr( mp->mnt_stat.f_mntonname, /* mount point*/
fs->fs_fsmnt, /* copy area*/
sizeof(fs->fs_fsmnt) - 1, /* max size*/
&strsize); /* real size*/
bzero( fs->fs_fsmnt + strsize, sizeof(fs->fs_fsmnt) - strsize);
vfs_mountedfrom(mp, fs->fs_fsmnt);
if( mp->mnt_flag & MNT_ROOTFS) {
/*
@ -800,7 +764,6 @@ ffs_mountfs(devvp, mp, td)
/*
* Initialize filesystem stat information in mount struct.
*/
(void)VFS_STATFS(mp, &mp->mnt_stat, td);
#ifdef UFS_EXTATTR
#ifdef UFS_EXTATTR_AUTOSTART
/*