Merge in 2.0.2.
This commit is contained in:
@@ -82,6 +82,9 @@ struct knowndev {
|
||||
struct fs *kd_fs;
|
||||
};
|
||||
|
||||
/* A placeholder for kd_fs for devices used as swap */
|
||||
#define SWAP_FS ((struct fs *)-1)
|
||||
|
||||
DECLARRAY(knowndev, static __UNUSED inline);
|
||||
DEFARRAY(knowndev, static __UNUSED inline);
|
||||
|
||||
@@ -160,7 +163,7 @@ vfs_sync(void)
|
||||
num = knowndevarray_num(knowndevs);
|
||||
for (i=0; i<num; i++) {
|
||||
dev = knowndevarray_get(knowndevs, i);
|
||||
if (dev->kd_fs != NULL) {
|
||||
if (dev->kd_fs != NULL && dev->kd_fs != SWAP_FS) {
|
||||
/*result =*/ FSOP_SYNC(dev->kd_fs);
|
||||
}
|
||||
}
|
||||
@@ -195,7 +198,7 @@ vfs_getroot(const char *devname, struct vnode **ret)
|
||||
* and DEVNAME names the device, return ENXIO.
|
||||
*/
|
||||
|
||||
if (kd->kd_fs!=NULL) {
|
||||
if (kd->kd_fs != NULL && kd->kd_fs != SWAP_FS) {
|
||||
const char *volname;
|
||||
volname = FSOP_GETVOLNAME(kd->kd_fs);
|
||||
|
||||
@@ -344,7 +347,7 @@ badnames(const char *n1, const char *n2, const char *n3)
|
||||
for (i=0; i<num; i++) {
|
||||
kd = knowndevarray_get(knowndevs, i);
|
||||
|
||||
if (kd->kd_fs) {
|
||||
if (kd->kd_fs != NULL && kd->kd_fs != SWAP_FS) {
|
||||
volname = FSOP_GETVOLNAME(kd->kd_fs);
|
||||
if (samestring3(volname, n1, n2, n3)) {
|
||||
return 1;
|
||||
@@ -542,6 +545,7 @@ vfs_mount(const char *devname, void *data,
|
||||
}
|
||||
|
||||
KASSERT(fs != NULL);
|
||||
KASSERT(fs != SWAP_FS);
|
||||
|
||||
kd->kd_fs = fs;
|
||||
|
||||
@@ -553,6 +557,59 @@ vfs_mount(const char *devname, void *data,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Like mount, but for attaching swap. Hands back the raw device
|
||||
* vnode. Unlike mount tolerates a trailing colon on the device name,
|
||||
* to avoid student-facing confusion.
|
||||
*/
|
||||
int
|
||||
vfs_swapon(const char *devname, struct vnode **ret)
|
||||
{
|
||||
char *myname = NULL;
|
||||
size_t len;
|
||||
struct knowndev *kd;
|
||||
int result;
|
||||
|
||||
len = strlen(devname);
|
||||
if (len > 0 && devname[len - 1] == ':') {
|
||||
/* tolerate trailing :, e.g. lhd0: rather than lhd0 */
|
||||
myname = kstrdup(devname);
|
||||
if (myname == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
myname[len - 1] = 0;
|
||||
devname = myname;
|
||||
}
|
||||
|
||||
vfs_biglock_acquire();
|
||||
|
||||
result = findmount(devname, &kd);
|
||||
if (result) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (kd->kd_fs != NULL) {
|
||||
result = EBUSY;
|
||||
goto out;
|
||||
}
|
||||
KASSERT(kd->kd_rawname != NULL);
|
||||
KASSERT(kd->kd_device != NULL);
|
||||
|
||||
kprintf("vfs: Swap attached to %s\n", kd->kd_name);
|
||||
|
||||
kd->kd_fs = SWAP_FS;
|
||||
VOP_INCREF(kd->kd_vnode);
|
||||
*ret = kd->kd_vnode;
|
||||
|
||||
out:
|
||||
vfs_biglock_release();
|
||||
if (myname != NULL) {
|
||||
kfree(myname);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unmount a filesystem/device by name.
|
||||
* First calls FSOP_SYNC on the filesystem; then calls FSOP_UNMOUNT.
|
||||
@@ -570,7 +627,7 @@ vfs_unmount(const char *devname)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (kd->kd_fs == NULL) {
|
||||
if (kd->kd_fs == NULL || kd->kd_fs == SWAP_FS) {
|
||||
result = EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
@@ -600,6 +657,43 @@ vfs_unmount(const char *devname)
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Detach swap. Like unmount.
|
||||
*
|
||||
* (Provided for completeness; there is no real need to remove swap
|
||||
* explicitly prior to shutting down, except perhaps when swapping to
|
||||
* things that themselves want a clean shutdown, like RAIDs.)
|
||||
*/
|
||||
int
|
||||
vfs_swapoff(const char *devname)
|
||||
{
|
||||
struct knowndev *kd;
|
||||
int result;
|
||||
|
||||
vfs_biglock_acquire();
|
||||
|
||||
result = findmount(devname, &kd);
|
||||
if (result) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (kd->kd_fs != SWAP_FS) {
|
||||
result = EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
kprintf("vfs: Swap detached from %s:\n", kd->kd_name);
|
||||
|
||||
/* drop it */
|
||||
kd->kd_fs = NULL;
|
||||
|
||||
KASSERT(result==0);
|
||||
|
||||
fail:
|
||||
vfs_biglock_release();
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Global unmount function.
|
||||
*/
|
||||
@@ -623,6 +717,11 @@ vfs_unmountall(void)
|
||||
/* not mounted */
|
||||
continue;
|
||||
}
|
||||
if (dev->kd_fs == SWAP_FS) {
|
||||
/* just drop it */
|
||||
dev->kd_fs = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
kprintf("vfs: Unmounting %s:\n", dev->kd_name);
|
||||
|
||||
|
@@ -129,7 +129,8 @@ vnode_decref(struct vnode *vn)
|
||||
void
|
||||
vnode_check(struct vnode *v, const char *opstr)
|
||||
{
|
||||
vfs_biglock_acquire();
|
||||
/* not safe, and not really needed to check constant fields */
|
||||
/*vfs_biglock_acquire();*/
|
||||
|
||||
if (v == NULL) {
|
||||
panic("vnode_check: vop_%s: null vnode\n", opstr);
|
||||
@@ -173,5 +174,5 @@ vnode_check(struct vnode *v, const char *opstr)
|
||||
}
|
||||
|
||||
spinlock_release(&v->vn_countlock);
|
||||
vfs_biglock_release();
|
||||
/*vfs_biglock_release();*/
|
||||
}
|
||||
|
Reference in New Issue
Block a user