Fix BOOTP root FS mounts. Also cleanup vfs_getnewfsid() and collapse
addaliasu() into addalias() (no operational change) and clarify comments relating to a trick that vclean() uses. The fix to BOOTP is yet another hack. Actually, rootfsid handling is already a major hack. The whole thing needs to be cleaned up. Reviewed by: David Greenman <dg@root.com>, Alan Cox <alc@cs.rice.edu>
This commit is contained in:
parent
31fd514730
commit
d813e119cd
@ -136,7 +136,27 @@ vfs_mountrootfs(void *unused)
|
||||
mp->mnt_flag |= MNT_ROOTFS;
|
||||
|
||||
/*
|
||||
* Attempt the mount
|
||||
* If we have no idea what the device is because the VFS root mount
|
||||
* initialization code couldn't figure it out, take a guess by
|
||||
* assuming that vfs_getnewfsid() will be called when we try the
|
||||
* mount. For the moment this is necessary for NFS-baesd BOOTP
|
||||
* boots. Ultimately we would like to get rid of 'rootdev' entirely
|
||||
* and go with a linked list of possible roots and device-specific
|
||||
* auxillary data that we do not try to interpret ourselves.
|
||||
*/
|
||||
if (rootdev == NODEV && rootdevs[0] == NODEV)
|
||||
rootdev = vfs_getrootfsid(mp);
|
||||
|
||||
/*
|
||||
* Attempt the mount. This is rather messy due to many historical
|
||||
* layers. Basically what it comes down to is that 'rootdev' is an
|
||||
* override to the rootdevs[] array. The rootdevs[] array itself
|
||||
* cannot normally be accessed directly by other modules, but FFS
|
||||
* plays with it. NFS, on the otherhand, has no clue what the
|
||||
* device assignment for a mount will be until it actually does it.
|
||||
*
|
||||
* During the loop we set rootdev to rootdevs[i]. This is used
|
||||
* by FFS and a few other modules. It is ignored by NFS.
|
||||
*/
|
||||
err = ENXIO;
|
||||
orootdev = rootdev;
|
||||
|
@ -333,35 +333,54 @@ vfs_getvfs(fsid)
|
||||
|
||||
/*
|
||||
* Get a new unique fsid
|
||||
*
|
||||
* Keep in mind that several mounts may be running in parallel,
|
||||
* so always increment mntid_base even if lower numbers are available.
|
||||
*/
|
||||
|
||||
static u_short mntid_base;
|
||||
|
||||
void
|
||||
vfs_getnewfsid(mp)
|
||||
struct mount *mp;
|
||||
{
|
||||
static u_short xxxfs_mntid;
|
||||
|
||||
fsid_t tfsid;
|
||||
int mtype;
|
||||
|
||||
simple_lock(&mntid_slock);
|
||||
|
||||
mtype = mp->mnt_vfc->vfc_typenum;
|
||||
mp->mnt_stat.f_fsid.val[0] = makeudev(255, mtype);
|
||||
mp->mnt_stat.f_fsid.val[1] = mtype;
|
||||
if (xxxfs_mntid == 0)
|
||||
++xxxfs_mntid;
|
||||
tfsid.val[0] = makeudev(255, mtype + (xxxfs_mntid << 16));
|
||||
tfsid.val[1] = mtype;
|
||||
if (mountlist.cqh_first != (void *)&mountlist) {
|
||||
while (vfs_getvfs(&tfsid)) {
|
||||
xxxfs_mntid++;
|
||||
tfsid.val[0] = makeudev(255,
|
||||
mtype + (xxxfs_mntid << 16));
|
||||
}
|
||||
for (;;) {
|
||||
tfsid.val[0] = makeudev(255, mtype + (mntid_base << 16));
|
||||
tfsid.val[1] = mtype;
|
||||
++mntid_base;
|
||||
if (vfs_getvfs(&tfsid) == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
mp->mnt_stat.f_fsid.val[0] = tfsid.val[0];
|
||||
mp->mnt_stat.f_fsid.val[1] = tfsid.val[1];
|
||||
|
||||
simple_unlock(&mntid_slock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get what should become the root fsid.
|
||||
*
|
||||
* This is somewhat of a hack. If the rootdev is not known we
|
||||
* assume that vfs_getnewfsid() will be called momentarily to
|
||||
* allocate it, and we return what vfs_getnewfsid() will return.
|
||||
*/
|
||||
|
||||
dev_t
|
||||
vfs_getrootfsid(struct mount *mp)
|
||||
{
|
||||
int mtype;
|
||||
|
||||
mtype = mp->mnt_vfc->vfc_typenum;
|
||||
return(makedev(255, mtype + (mntid_base << 16)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Knob to control the precision of file timestamps:
|
||||
*
|
||||
@ -1303,11 +1322,7 @@ addaliasu(nvp, nvp_rdev)
|
||||
|
||||
if (nvp->v_type != VBLK && nvp->v_type != VCHR)
|
||||
panic("addaliasu on non-special vnode");
|
||||
|
||||
nvp->v_rdev = udev2dev(nvp_rdev, nvp->v_type == VBLK ? 1 : 0);
|
||||
simple_lock(&spechash_slock);
|
||||
SLIST_INSERT_HEAD(&nvp->v_rdev->si_hlist, nvp, v_specnext);
|
||||
simple_unlock(&spechash_slock);
|
||||
addalias(nvp, udev2dev(nvp_rdev, nvp->v_type == VBLK ? 1 : 0));
|
||||
}
|
||||
|
||||
void
|
||||
@ -1650,8 +1665,9 @@ vclean(vp, flags, p)
|
||||
if ((obj = vp->v_object) != NULL) {
|
||||
if (obj->ref_count == 0) {
|
||||
/*
|
||||
* This is a normal way of shutting down the object/vnode
|
||||
* association.
|
||||
* vclean() may be called twice. The first time removes the
|
||||
* primary reference to the object, the second time goes
|
||||
* one further and is a special-case to terminate the object.
|
||||
*/
|
||||
vm_object_terminate(obj);
|
||||
} else {
|
||||
|
@ -136,7 +136,27 @@ vfs_mountrootfs(void *unused)
|
||||
mp->mnt_flag |= MNT_ROOTFS;
|
||||
|
||||
/*
|
||||
* Attempt the mount
|
||||
* If we have no idea what the device is because the VFS root mount
|
||||
* initialization code couldn't figure it out, take a guess by
|
||||
* assuming that vfs_getnewfsid() will be called when we try the
|
||||
* mount. For the moment this is necessary for NFS-baesd BOOTP
|
||||
* boots. Ultimately we would like to get rid of 'rootdev' entirely
|
||||
* and go with a linked list of possible roots and device-specific
|
||||
* auxillary data that we do not try to interpret ourselves.
|
||||
*/
|
||||
if (rootdev == NODEV && rootdevs[0] == NODEV)
|
||||
rootdev = vfs_getrootfsid(mp);
|
||||
|
||||
/*
|
||||
* Attempt the mount. This is rather messy due to many historical
|
||||
* layers. Basically what it comes down to is that 'rootdev' is an
|
||||
* override to the rootdevs[] array. The rootdevs[] array itself
|
||||
* cannot normally be accessed directly by other modules, but FFS
|
||||
* plays with it. NFS, on the otherhand, has no clue what the
|
||||
* device assignment for a mount will be until it actually does it.
|
||||
*
|
||||
* During the loop we set rootdev to rootdevs[i]. This is used
|
||||
* by FFS and a few other modules. It is ignored by NFS.
|
||||
*/
|
||||
err = ENXIO;
|
||||
orootdev = rootdev;
|
||||
|
@ -333,35 +333,54 @@ vfs_getvfs(fsid)
|
||||
|
||||
/*
|
||||
* Get a new unique fsid
|
||||
*
|
||||
* Keep in mind that several mounts may be running in parallel,
|
||||
* so always increment mntid_base even if lower numbers are available.
|
||||
*/
|
||||
|
||||
static u_short mntid_base;
|
||||
|
||||
void
|
||||
vfs_getnewfsid(mp)
|
||||
struct mount *mp;
|
||||
{
|
||||
static u_short xxxfs_mntid;
|
||||
|
||||
fsid_t tfsid;
|
||||
int mtype;
|
||||
|
||||
simple_lock(&mntid_slock);
|
||||
|
||||
mtype = mp->mnt_vfc->vfc_typenum;
|
||||
mp->mnt_stat.f_fsid.val[0] = makeudev(255, mtype);
|
||||
mp->mnt_stat.f_fsid.val[1] = mtype;
|
||||
if (xxxfs_mntid == 0)
|
||||
++xxxfs_mntid;
|
||||
tfsid.val[0] = makeudev(255, mtype + (xxxfs_mntid << 16));
|
||||
tfsid.val[1] = mtype;
|
||||
if (mountlist.cqh_first != (void *)&mountlist) {
|
||||
while (vfs_getvfs(&tfsid)) {
|
||||
xxxfs_mntid++;
|
||||
tfsid.val[0] = makeudev(255,
|
||||
mtype + (xxxfs_mntid << 16));
|
||||
}
|
||||
for (;;) {
|
||||
tfsid.val[0] = makeudev(255, mtype + (mntid_base << 16));
|
||||
tfsid.val[1] = mtype;
|
||||
++mntid_base;
|
||||
if (vfs_getvfs(&tfsid) == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
mp->mnt_stat.f_fsid.val[0] = tfsid.val[0];
|
||||
mp->mnt_stat.f_fsid.val[1] = tfsid.val[1];
|
||||
|
||||
simple_unlock(&mntid_slock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get what should become the root fsid.
|
||||
*
|
||||
* This is somewhat of a hack. If the rootdev is not known we
|
||||
* assume that vfs_getnewfsid() will be called momentarily to
|
||||
* allocate it, and we return what vfs_getnewfsid() will return.
|
||||
*/
|
||||
|
||||
dev_t
|
||||
vfs_getrootfsid(struct mount *mp)
|
||||
{
|
||||
int mtype;
|
||||
|
||||
mtype = mp->mnt_vfc->vfc_typenum;
|
||||
return(makedev(255, mtype + (mntid_base << 16)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Knob to control the precision of file timestamps:
|
||||
*
|
||||
@ -1303,11 +1322,7 @@ addaliasu(nvp, nvp_rdev)
|
||||
|
||||
if (nvp->v_type != VBLK && nvp->v_type != VCHR)
|
||||
panic("addaliasu on non-special vnode");
|
||||
|
||||
nvp->v_rdev = udev2dev(nvp_rdev, nvp->v_type == VBLK ? 1 : 0);
|
||||
simple_lock(&spechash_slock);
|
||||
SLIST_INSERT_HEAD(&nvp->v_rdev->si_hlist, nvp, v_specnext);
|
||||
simple_unlock(&spechash_slock);
|
||||
addalias(nvp, udev2dev(nvp_rdev, nvp->v_type == VBLK ? 1 : 0));
|
||||
}
|
||||
|
||||
void
|
||||
@ -1650,8 +1665,9 @@ vclean(vp, flags, p)
|
||||
if ((obj = vp->v_object) != NULL) {
|
||||
if (obj->ref_count == 0) {
|
||||
/*
|
||||
* This is a normal way of shutting down the object/vnode
|
||||
* association.
|
||||
* vclean() may be called twice. The first time removes the
|
||||
* primary reference to the object, the second time goes
|
||||
* one further and is a special-case to terminate the object.
|
||||
*/
|
||||
vm_object_terminate(obj);
|
||||
} else {
|
||||
|
@ -391,6 +391,7 @@ struct netcred *vfs_export_lookup /* lookup host in fs export list */
|
||||
__P((struct mount *, struct netexport *, struct sockaddr *));
|
||||
int vfs_allocate_syncvnode __P((struct mount *));
|
||||
void vfs_getnewfsid __P((struct mount *));
|
||||
dev_t vfs_getrootfsid __P((struct mount *));
|
||||
struct mount *vfs_getvfs __P((fsid_t *)); /* return vfs given fsid */
|
||||
int vfs_modevent __P((module_t, int, void *));
|
||||
int vfs_mountedon __P((struct vnode *)); /* is a vfs mounted on vp */
|
||||
|
Loading…
Reference in New Issue
Block a user