summaryrefslogtreecommitdiff
path: root/sys/msdosfs/msdosfs_vfsops.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2017-12-11 05:27:41 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2017-12-11 05:27:41 +0000
commitd1538d110d9557ee9f9e4b04b6cba258e4f43d3a (patch)
treefd0c509c4d351be908d5ccc6ae3ffd4b0a61c6a5 /sys/msdosfs/msdosfs_vfsops.c
parent2921b422210353885272232bc38314523b006e06 (diff)
In uvm Chuck decided backing store would not be allocated proactively
for blocks re-fetchable from the filesystem. However at reboot time, filesystems are unmounted, and since processes lack backing store they are killed. Since the scheduler is still running, in some cases init is killed... which drops us to ddb [noted by bluhm]. Solution is to convert filesystems to read-only [proposed by kettenis]. The tale follows: sys_reboot() should pass proc * to MD boot() to vfs_shutdown() which completes current IO with vfs_busy VB_WRITE|VB_WAIT, then calls VFS_MOUNT() with MNT_UPDATE | MNT_RDONLY, soon teaching us that *fs_mount() calls a copyin() late... so store the sizes in vfsconflist[] and move the copyin() to sys_mount()... and notice nfs_mount copyin() is size-variant, so kill legacy struct nfs_args3. Next we learn ffs_mount()'s MNT_UPDATE code is sharp and rusty especially wrt softdep, so fix some bugs adn add ~MNT_SOFTDEP to the downgrade. Some vnodes need a little more help, so tie them to &dead_vnops. ffs_mount calling DIOCCACHESYNC is causing a bit of grief still but this issue is seperate and will be dealt with in time. couple hundred reboots by bluhm and myself, advice from guenther and others at the hut
Diffstat (limited to 'sys/msdosfs/msdosfs_vfsops.c')
-rw-r--r--sys/msdosfs/msdosfs_vfsops.c32
1 files changed, 15 insertions, 17 deletions
diff --git a/sys/msdosfs/msdosfs_vfsops.c b/sys/msdosfs/msdosfs_vfsops.c
index 5c426a2c37e..2a403a9cb59 100644
--- a/sys/msdosfs/msdosfs_vfsops.c
+++ b/sys/msdosfs/msdosfs_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: msdosfs_vfsops.c,v 1.84 2017/05/29 14:07:16 sf Exp $ */
+/* $OpenBSD: msdosfs_vfsops.c,v 1.85 2017/12/11 05:27:40 deraadt Exp $ */
/* $NetBSD: msdosfs_vfsops.c,v 1.48 1997/10/18 02:54:57 briggs Exp $ */
/*-
@@ -101,17 +101,13 @@ msdosfs_mount(struct mount *mp, const char *path, void *data,
struct nameidata *ndp, struct proc *p)
{
struct vnode *devvp; /* vnode for blk device to mount */
- struct msdosfs_args args; /* will hold data from mount request */
+ struct msdosfs_args *args = data; /* will hold data from mount request */
/* msdosfs specific mount control block */
struct msdosfsmount *pmp = NULL;
char fname[MNAMELEN];
char fspec[MNAMELEN];
int error, flags;
- error = copyin(data, &args, sizeof(struct msdosfs_args));
- if (error)
- return (error);
-
/*
* If updating, check whether changing from read-only to
* read/write; if there is no device name, that's all we do.
@@ -147,11 +143,11 @@ msdosfs_mount(struct mount *mp, const char *path, void *data,
(mp->mnt_flag & MNT_WANTRDWR))
pmp->pm_flags &= ~MSDOSFSMNT_RONLY;
- if (args.fspec == NULL) {
+ if (args && args->fspec == NULL) {
#ifdef __notyet__ /* doesn't work correctly with current mountd XXX */
- if (args.flags & MSDOSFSMNT_MNTOPT) {
+ if (args->flags & MSDOSFSMNT_MNTOPT) {
pmp->pm_flags &= ~MSDOSFSMNT_MNTOPT;
- pmp->pm_flags |= args.flags & MSDOSFSMNT_MNTOPT;
+ pmp->pm_flags |= args->flags & MSDOSFSMNT_MNTOPT;
if (pmp->pm_flags & MSDOSFSMNT_NOWIN95)
pmp->pm_flags |= MSDOSFSMNT_SHORTNAME;
}
@@ -160,15 +156,17 @@ msdosfs_mount(struct mount *mp, const char *path, void *data,
* Process export requests.
*/
return (vfs_export(mp, &pmp->pm_export,
- &args.export_info));
+ &args->export_info));
}
+ if (args == NULL)
+ return (0);
}
/*
* Not an update, or updating the name: look up the name
* and verify that it refers to a sensible block device.
*/
- error = copyinstr(args.fspec, fspec, sizeof(fspec), NULL);
+ error = copyinstr(args->fspec, fspec, sizeof(fspec), NULL);
if (error)
goto error;
@@ -191,7 +189,7 @@ msdosfs_mount(struct mount *mp, const char *path, void *data,
}
if ((mp->mnt_flag & MNT_UPDATE) == 0)
- error = msdosfs_mountfs(devvp, mp, p, &args);
+ error = msdosfs_mountfs(devvp, mp, p, args);
else {
if (devvp != pmp->pm_devvp)
error = EINVAL; /* XXX needs translation */
@@ -202,10 +200,10 @@ msdosfs_mount(struct mount *mp, const char *path, void *data,
goto error_devvp;
pmp = VFSTOMSDOSFS(mp);
- pmp->pm_gid = args.gid;
- pmp->pm_uid = args.uid;
- pmp->pm_mask = args.mask;
- pmp->pm_flags |= args.flags & MSDOSFSMNT_MNTOPT;
+ pmp->pm_gid = args->gid;
+ pmp->pm_uid = args->uid;
+ pmp->pm_mask = args->mask;
+ pmp->pm_flags |= args->flags & MSDOSFSMNT_MNTOPT;
if (pmp->pm_flags & MSDOSFSMNT_NOWIN95)
pmp->pm_flags |= MSDOSFSMNT_SHORTNAME;
@@ -241,7 +239,7 @@ msdosfs_mount(struct mount *mp, const char *path, void *data,
strlcpy(mp->mnt_stat.f_mntfromname, fname, MNAMELEN);
bzero(mp->mnt_stat.f_mntfromspec, MNAMELEN);
strlcpy(mp->mnt_stat.f_mntfromspec, fspec, MNAMELEN);
- bcopy(&args, &mp->mnt_stat.mount_info.msdosfs_args, sizeof(args));
+ bcopy(args, &mp->mnt_stat.mount_info.msdosfs_args, sizeof(*args));
#ifdef MSDOSFS_DEBUG
printf("msdosfs_mount(): mp %p, pmp %p, inusemap %p\n", mp,