diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2017-12-11 05:27:41 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2017-12-11 05:27:41 +0000 |
commit | d1538d110d9557ee9f9e4b04b6cba258e4f43d3a (patch) | |
tree | fd0c509c4d351be908d5ccc6ae3ffd4b0a61c6a5 /sys/nfs/nfs_vfsops.c | |
parent | 2921b422210353885272232bc38314523b006e06 (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/nfs/nfs_vfsops.c')
-rw-r--r-- | sys/nfs/nfs_vfsops.c | 41 |
1 files changed, 15 insertions, 26 deletions
diff --git a/sys/nfs/nfs_vfsops.c b/sys/nfs/nfs_vfsops.c index 7a7c5a1cbdc..65874a1e2b1 100644 --- a/sys/nfs/nfs_vfsops.c +++ b/sys/nfs/nfs_vfsops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_vfsops.c,v 1.114 2017/05/17 08:59:05 mpi Exp $ */ +/* $OpenBSD: nfs_vfsops.c,v 1.115 2017/12/11 05:27:40 deraadt Exp $ */ /* $NetBSD: nfs_vfsops.c,v 1.46.4.1 1996/05/25 22:40:35 fvdl Exp $ */ /* @@ -554,27 +554,14 @@ nfs_mount(struct mount *mp, const char *path, void *data, struct nameidata *ndp, struct proc *p) { int error; - struct nfs_args args; + struct nfs_args *args = data; struct mbuf *nam; char hst[MNAMELEN]; size_t len; u_char nfh[NFSX_V3FHMAX]; - error = copyin(data, &args, sizeof(args.version)); - if (error) - return (error); - if (args.version == 3) { - error = copyin(data, &args, sizeof(struct nfs_args3)); - args.flags &= ~(NFSMNT_INTERNAL|NFSMNT_NOAC); - } else if (args.version == NFS_ARGSVERSION) { - error = copyin(data, &args, sizeof(struct nfs_args)); - args.flags &= ~NFSMNT_NOAC; /* XXX - compatibility */ - } else - return (EPROGMISMATCH); - if (error) - return (error); - - if ((args.flags & (NFSMNT_NFSV3|NFSMNT_RDIRPLUS)) == NFSMNT_RDIRPLUS) + if (args && + (args->flags & (NFSMNT_NFSV3|NFSMNT_RDIRPLUS)) == NFSMNT_RDIRPLUS) return (EINVAL); if (nfs_niothreads < 0) { @@ -591,26 +578,28 @@ nfs_mount(struct mount *mp, const char *path, void *data, * When doing an update, we can't change from or to * v3. */ - args.flags = (args.flags & ~(NFSMNT_NFSV3)) | - (nmp->nm_flag & (NFSMNT_NFSV3)); - nfs_decode_args(nmp, &args, &mp->mnt_stat.mount_info.nfs_args); + if (args) { + args->flags = (args->flags & ~(NFSMNT_NFSV3)) | + (nmp->nm_flag & (NFSMNT_NFSV3)); + nfs_decode_args(nmp, args, &mp->mnt_stat.mount_info.nfs_args); + } return (0); } - if (args.fhsize < 0 || args.fhsize > NFSX_V3FHMAX) + if (args->fhsize < 0 || args->fhsize > NFSX_V3FHMAX) return (EINVAL); - error = copyin(args.fh, nfh, args.fhsize); + error = copyin(args->fh, nfh, args->fhsize); if (error) return (error); - error = copyinstr(args.hostname, hst, MNAMELEN-1, &len); + error = copyinstr(args->hostname, hst, MNAMELEN-1, &len); if (error) return (error); memset(&hst[len], 0, MNAMELEN - len); /* sockargs() call must be after above copyin() calls */ - error = sockargs(&nam, args.addr, args.addrlen, MT_SONAME); + error = sockargs(&nam, args->addr, args->addrlen, MT_SONAME); if (error) return (error); - args.fh = nfh; - error = mountnfs(&args, mp, nam, path, hst); + args->fh = nfh; + error = mountnfs(args, mp, nam, path, hst); return (error); } |