From: deraadt Date: Mon, 11 Dec 2017 05:27:40 +0000 (+0000) Subject: In uvm Chuck decided backing store would not be allocated proactively X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=7efda1a11d8bf31499aa02da4d14eddf1b5293ae;p=openbsd 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 --- diff --git a/sys/arch/alpha/alpha/machdep.c b/sys/arch/alpha/alpha/machdep.c index 57c7d0f2721..b17a184ec4a 100644 --- a/sys/arch/alpha/alpha/machdep.c +++ b/sys/arch/alpha/alpha/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.181 2017/05/29 14:19:49 mpi Exp $ */ +/* $OpenBSD: machdep.c,v 1.182 2017/12/11 05:27:40 deraadt Exp $ */ /* $NetBSD: machdep.c,v 1.210 2000/06/01 17:12:38 thorpej Exp $ */ /*- @@ -977,7 +977,7 @@ boot(int howto) boothowto = howto; if ((howto & RB_NOSYNC) == 0 && waittime < 0) { waittime = 0; - vfs_shutdown(); + vfs_shutdown(curproc); if ((howto & RB_TIMEBAD) == 0) { resettodr(); diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index a5011d72f32..33bef001d4f 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.235 2017/10/27 06:48:13 yasuoka Exp $ */ +/* $OpenBSD: machdep.c,v 1.236 2017/12/11 05:27:40 deraadt Exp $ */ /* $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */ /*- @@ -725,7 +725,7 @@ boot(int howto) boothowto = howto; if ((howto & RB_NOSYNC) == 0 && waittime < 0) { waittime = 0; - vfs_shutdown(); + vfs_shutdown(curproc); if ((howto & RB_TIMEBAD) == 0) { resettodr(); diff --git a/sys/arch/arm/arm/arm32_machdep.c b/sys/arch/arm/arm/arm32_machdep.c index 2eb86cded27..f528dc49997 100644 --- a/sys/arch/arm/arm/arm32_machdep.c +++ b/sys/arch/arm/arm/arm32_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: arm32_machdep.c,v 1.54 2017/08/12 13:18:48 tedu Exp $ */ +/* $OpenBSD: arm32_machdep.c,v 1.55 2017/12/11 05:27:40 deraadt Exp $ */ /* $NetBSD: arm32_machdep.c,v 1.42 2003/12/30 12:33:15 pk Exp $ */ /* @@ -206,7 +206,7 @@ bootsync(int howto) printf("Warning IRQ's disabled during boot()\n"); } - vfs_shutdown(); + vfs_shutdown(curproc); if ((howto & RB_TIMEBAD) == 0) { resettodr(); diff --git a/sys/arch/arm64/arm64/machdep.c b/sys/arch/arm64/arm64/machdep.c index db259e9c265..d1d5a673849 100644 --- a/sys/arch/arm64/arm64/machdep.c +++ b/sys/arch/arm64/arm64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.22 2017/09/08 05:36:51 deraadt Exp $ */ +/* $OpenBSD: machdep.c,v 1.23 2017/12/11 05:27:40 deraadt Exp $ */ /* * Copyright (c) 2014 Patrick Wildt * @@ -336,7 +336,7 @@ boot(int howto) boothowto = howto; if ((howto & RB_NOSYNC) == 0 && waittime < 0) { waittime = 0; - vfs_shutdown(); + vfs_shutdown(curproc); if ((howto & RB_TIMEBAD) == 0) { resettodr(); diff --git a/sys/arch/hppa/hppa/machdep.c b/sys/arch/hppa/hppa/machdep.c index 3a1f4888238..9247b5d28d1 100644 --- a/sys/arch/hppa/hppa/machdep.c +++ b/sys/arch/hppa/hppa/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.248 2017/05/18 15:41:59 kettenis Exp $ */ +/* $OpenBSD: machdep.c,v 1.249 2017/12/11 05:27:40 deraadt Exp $ */ /* * Copyright (c) 1999-2003 Michael Shalayeff @@ -902,7 +902,7 @@ boot(int howto) if ((howto & RB_NOSYNC) == 0) { waittime = 0; - vfs_shutdown(); + vfs_shutdown(curproc); if ((howto & RB_TIMEBAD) == 0) { resettodr(); diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index 91ba126fef0..89ac87cc4a5 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.606 2017/09/03 07:00:53 mlarkin Exp $ */ +/* $OpenBSD: machdep.c,v 1.607 2017/12/11 05:27:40 deraadt Exp $ */ /* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */ /*- @@ -2641,7 +2641,7 @@ boot(int howto) boothowto = howto; if ((howto & RB_NOSYNC) == 0 && waittime < 0) { waittime = 0; - vfs_shutdown(); + vfs_shutdown(curproc); if ((howto & RB_TIMEBAD) == 0) { resettodr(); diff --git a/sys/arch/landisk/landisk/machdep.c b/sys/arch/landisk/landisk/machdep.c index b4baca5c86a..9df9c4ee79a 100644 --- a/sys/arch/landisk/landisk/machdep.c +++ b/sys/arch/landisk/landisk/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.45 2017/04/30 16:45:45 mpi Exp $ */ +/* $OpenBSD: machdep.c,v 1.46 2017/12/11 05:27:40 deraadt Exp $ */ /* $NetBSD: machdep.c,v 1.1 2006/09/01 21:26:18 uwe Exp $ */ /*- @@ -202,7 +202,7 @@ boot(int howto) boothowto = howto; if ((howto & RB_NOSYNC) == 0) { - vfs_shutdown(); + vfs_shutdown(curproc); if ((howto & RB_TIMEBAD) == 0) { resettodr(); diff --git a/sys/arch/loongson/loongson/machdep.c b/sys/arch/loongson/loongson/machdep.c index 74aeb1a6da3..2e797fcba9d 100644 --- a/sys/arch/loongson/loongson/machdep.c +++ b/sys/arch/loongson/loongson/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.80 2017/08/26 13:53:46 visa Exp $ */ +/* $OpenBSD: machdep.c,v 1.81 2017/12/11 05:27:40 deraadt Exp $ */ /* * Copyright (c) 2009, 2010, 2014 Miodrag Vallat. @@ -1061,7 +1061,7 @@ boot(int howto) boothowto = howto; if ((howto & RB_NOSYNC) == 0 && waittime < 0) { waittime = 0; - vfs_shutdown(); + vfs_shutdown(curproc); if ((howto & RB_TIMEBAD) == 0) { resettodr(); diff --git a/sys/arch/luna88k/luna88k/machdep.c b/sys/arch/luna88k/luna88k/machdep.c index 65884df7195..89bc6e4d497 100644 --- a/sys/arch/luna88k/luna88k/machdep.c +++ b/sys/arch/luna88k/luna88k/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.126 2017/11/03 09:07:54 aoyama Exp $ */ +/* $OpenBSD: machdep.c,v 1.127 2017/12/11 05:27:40 deraadt Exp $ */ /* * Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr. * Copyright (c) 1996 Nivas Madhur @@ -429,7 +429,7 @@ boot(int howto) boothowto = howto; if ((howto & RB_NOSYNC) == 0) { - vfs_shutdown(); + vfs_shutdown(curproc); if ((howto & RB_TIMEBAD) == 0) { resettodr(); diff --git a/sys/arch/macppc/macppc/machdep.c b/sys/arch/macppc/macppc/machdep.c index 18ed83f1a52..6aaae3cb1cb 100644 --- a/sys/arch/macppc/macppc/machdep.c +++ b/sys/arch/macppc/macppc/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.181 2017/06/13 01:42:12 deraadt Exp $ */ +/* $OpenBSD: machdep.c,v 1.182 2017/12/11 05:27:40 deraadt Exp $ */ /* $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $ */ /* @@ -743,7 +743,7 @@ boot(int howto) boothowto = howto; if ((howto & RB_NOSYNC) == 0 && !syncing) { syncing = 1; - vfs_shutdown(); + vfs_shutdown(curproc); if ((howto & RB_TIMEBAD) == 0) { resettodr(); diff --git a/sys/arch/octeon/octeon/machdep.c b/sys/arch/octeon/octeon/machdep.c index 433ff9ec2ca..6b7f5bc916d 100644 --- a/sys/arch/octeon/octeon/machdep.c +++ b/sys/arch/octeon/octeon/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.101 2017/11/01 14:43:01 visa Exp $ */ +/* $OpenBSD: machdep.c,v 1.102 2017/12/11 05:27:40 deraadt Exp $ */ /* * Copyright (c) 2009, 2010 Miodrag Vallat. @@ -760,7 +760,7 @@ boot(int howto) boothowto = howto; if ((howto & RB_NOSYNC) == 0 && waittime < 0) { waittime = 0; - vfs_shutdown(); + vfs_shutdown(curproc); if ((howto & RB_TIMEBAD) == 0) { resettodr(); diff --git a/sys/arch/sgi/sgi/machdep.c b/sys/arch/sgi/sgi/machdep.c index db43e7bbf15..295c0fc6ee1 100644 --- a/sys/arch/sgi/sgi/machdep.c +++ b/sys/arch/sgi/sgi/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.156 2017/04/30 16:45:45 mpi Exp $ */ +/* $OpenBSD: machdep.c,v 1.157 2017/12/11 05:27:40 deraadt Exp $ */ /* * Copyright (c) 2003-2004 Opsycon AB (www.opsycon.se / www.opsycon.com) @@ -835,7 +835,7 @@ boot(int howto) boothowto = howto; if ((howto & RB_NOSYNC) == 0 && waittime < 0) { waittime = 0; - vfs_shutdown(); + vfs_shutdown(curproc); if ((howto & RB_TIMEBAD) == 0) { resettodr(); diff --git a/sys/arch/socppc/socppc/machdep.c b/sys/arch/socppc/socppc/machdep.c index 0e149caebd3..bf0b0228074 100644 --- a/sys/arch/socppc/socppc/machdep.c +++ b/sys/arch/socppc/socppc/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.72 2017/04/30 16:45:45 mpi Exp $ */ +/* $OpenBSD: machdep.c,v 1.73 2017/12/11 05:27:40 deraadt Exp $ */ /* $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $ */ /* @@ -658,7 +658,7 @@ boot(int howto) boothowto = howto; if ((howto & RB_NOSYNC) == 0 && !syncing) { syncing = 1; - vfs_shutdown(); + vfs_shutdown(curproc); if ((howto & RB_TIMEBAD) == 0) { resettodr(); diff --git a/sys/arch/sparc64/sparc64/machdep.c b/sys/arch/sparc64/sparc64/machdep.c index 94fc8cd25a8..e369e96ad2f 100644 --- a/sys/arch/sparc64/sparc64/machdep.c +++ b/sys/arch/sparc64/sparc64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.185 2017/10/23 18:38:33 kettenis Exp $ */ +/* $OpenBSD: machdep.c,v 1.186 2017/12/11 05:27:40 deraadt Exp $ */ /* $NetBSD: machdep.c,v 1.108 2001/07/24 19:30:14 eeh Exp $ */ /*- @@ -626,7 +626,7 @@ boot(int howto) extern int sparc_clock_time_is_ok; waittime = 0; - vfs_shutdown(); + vfs_shutdown(curproc); /* * XXX diff --git a/sys/ddb/db_command.c b/sys/ddb/db_command.c index 8acff8d345e..6069e2a5ebc 100644 --- a/sys/ddb/db_command.c +++ b/sys/ddb/db_command.c @@ -1,4 +1,4 @@ -/* $OpenBSD: db_command.c,v 1.80 2017/11/27 09:23:44 mpi Exp $ */ +/* $OpenBSD: db_command.c,v 1.81 2017/12/11 05:27:40 deraadt Exp $ */ /* $NetBSD: db_command.c,v 1.20 1996/03/30 22:30:05 christos Exp $ */ /* @@ -769,40 +769,49 @@ db_fncall(db_expr_t addr, int have_addr, db_expr_t count, char *modif) DB_FORMAT_N, 1, 0)); } +void +db_reboot(int howto) +{ + spl0(); + if (!curproc) + curproc = &proc0; + reboot(howto); +} + void db_boot_sync_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif) { - reboot(RB_AUTOBOOT | RB_TIMEBAD | RB_USERREQ); + db_reboot(RB_AUTOBOOT | RB_TIMEBAD | RB_USERREQ); } void db_boot_crash_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif) { - reboot(RB_NOSYNC | RB_DUMP | RB_TIMEBAD | RB_USERREQ); + db_reboot(RB_NOSYNC | RB_DUMP | RB_TIMEBAD | RB_USERREQ); } void db_boot_dump_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif) { - reboot(RB_DUMP | RB_TIMEBAD | RB_USERREQ); + db_reboot(RB_DUMP | RB_TIMEBAD | RB_USERREQ); } void db_boot_halt_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif) { - reboot(RB_NOSYNC | RB_HALT | RB_TIMEBAD | RB_USERREQ); + db_reboot(RB_NOSYNC | RB_HALT | RB_TIMEBAD | RB_USERREQ); } void db_boot_reboot_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif) { - reboot(RB_AUTOBOOT | RB_NOSYNC | RB_TIMEBAD | RB_USERREQ); + db_reboot(RB_AUTOBOOT | RB_NOSYNC | RB_TIMEBAD | RB_USERREQ); } void db_boot_poweroff_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif) { - reboot(RB_NOSYNC | RB_HALT | RB_POWERDOWN | RB_TIMEBAD | RB_USERREQ); + db_reboot(RB_NOSYNC | RB_HALT | RB_POWERDOWN | RB_TIMEBAD | RB_USERREQ); } void diff --git a/sys/isofs/cd9660/cd9660_vfsops.c b/sys/isofs/cd9660/cd9660_vfsops.c index 1dcc256a580..1f4bb0e55a4 100644 --- a/sys/isofs/cd9660/cd9660_vfsops.c +++ b/sys/isofs/cd9660/cd9660_vfsops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cd9660_vfsops.c,v 1.84 2017/04/20 14:13:00 visa Exp $ */ +/* $OpenBSD: cd9660_vfsops.c,v 1.85 2017/12/11 05:27:40 deraadt Exp $ */ /* $NetBSD: cd9660_vfsops.c,v 1.26 1997/06/13 15:38:58 pk Exp $ */ /*- @@ -135,7 +135,7 @@ cd9660_mount(mp, path, data, ndp, p) struct proc *p; { struct iso_mnt *imp = NULL; - struct iso_args args; + struct iso_args *args = data; struct vnode *devvp; char fspec[MNAMELEN]; int error; @@ -143,26 +143,23 @@ cd9660_mount(mp, path, data, ndp, p) if ((mp->mnt_flag & MNT_RDONLY) == 0) return (EROFS); - error = copyin(data, &args, sizeof(struct iso_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. */ if (mp->mnt_flag & MNT_UPDATE) { imp = VFSTOISOFS(mp); - if (args.fspec == NULL) + if (args && args->fspec == NULL) return (vfs_export(mp, &imp->im_export, - &args.export_info)); + &args->export_info)); + 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) return (error); NDINIT(ndp, LOOKUP, FOLLOW, UIO_SYSSPACE, fspec, p); @@ -180,7 +177,7 @@ cd9660_mount(mp, path, data, ndp, p) } if ((mp->mnt_flag & MNT_UPDATE) == 0) - error = iso_mountfs(devvp, mp, p, &args); + error = iso_mountfs(devvp, mp, p, args); else { if (devvp != imp->im_devvp) error = EINVAL; /* needs translation */ @@ -198,7 +195,7 @@ cd9660_mount(mp, path, data, ndp, p) strlcpy(mp->mnt_stat.f_mntfromname, fspec, MNAMELEN); bzero(mp->mnt_stat.f_mntfromspec, MNAMELEN); strlcpy(mp->mnt_stat.f_mntfromspec, fspec, MNAMELEN); - bcopy(&args, &mp->mnt_stat.mount_info.iso_args, sizeof(args)); + bcopy(args, &mp->mnt_stat.mount_info.iso_args, sizeof(*args)); cd9660_statfs(mp, &mp->mnt_stat, p); diff --git a/sys/isofs/udf/udf_vfsops.c b/sys/isofs/udf/udf_vfsops.c index 562ee1eec13..56ef21fa34f 100644 --- a/sys/isofs/udf/udf_vfsops.c +++ b/sys/isofs/udf/udf_vfsops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: udf_vfsops.c,v 1.60 2017/09/08 05:36:53 deraadt Exp $ */ +/* $OpenBSD: udf_vfsops.c,v 1.61 2017/12/11 05:27:40 deraadt Exp $ */ /* * Copyright (c) 2001, 2002 Scott Long @@ -122,7 +122,7 @@ udf_mount(struct mount *mp, const char *path, void *data, struct nameidata *ndp, struct proc *p) { struct vnode *devvp; /* vnode of the mount device */ - struct udf_args args; + struct udf_args *args = data; char fspec[MNAMELEN]; int error; @@ -140,14 +140,15 @@ udf_mount(struct mount *mp, const char *path, void *data, if (mp->mnt_flag & MNT_ROOTFS) return (EOPNOTSUPP); - error = copyin(data, &args, sizeof(struct udf_args)); - if (error) - return (error); - - if (args.fspec == NULL) - return (EINVAL); + /* + * 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) { + return (0); + } - error = copyinstr(args.fspec, fspec, sizeof(fspec), NULL); + error = copyinstr(args->fspec, fspec, sizeof(fspec), NULL); if (error) return (error); @@ -166,7 +167,7 @@ udf_mount(struct mount *mp, const char *path, void *data, return (ENXIO); } - if ((error = udf_mountfs(devvp, mp, args.lastblock, p))) { + if ((error = udf_mountfs(devvp, mp, args->lastblock, p))) { vrele(devvp); return (error); } diff --git a/sys/kern/vfs_init.c b/sys/kern/vfs_init.c index 25f7a6cccf4..ae66c783aad 100644 --- a/sys/kern/vfs_init.c +++ b/sys/kern/vfs_init.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_init.c,v 1.38 2016/09/15 02:00:16 dlg Exp $ */ +/* $OpenBSD: vfs_init.c,v 1.39 2017/12/11 05:27:40 deraadt Exp $ */ /* $NetBSD: vfs_init.c,v 1.6 1996/02/09 19:00:58 christos Exp $ */ /* @@ -92,43 +92,53 @@ extern const struct vfsops tmpfs_vfsops; /* Set up the filesystem operations for vnodes. */ static struct vfsconf vfsconflist[] = { #ifdef FFS - { &ffs_vfsops, MOUNT_FFS, 1, 0, MNT_LOCAL, NULL }, + { &ffs_vfsops, MOUNT_FFS, 1, 0, MNT_LOCAL, NULL, + sizeof(struct ufs_args) }, #endif #ifdef MFS - { &mfs_vfsops, MOUNT_MFS, 3, 0, MNT_LOCAL, NULL }, + { &mfs_vfsops, MOUNT_MFS, 3, 0, MNT_LOCAL, NULL, + sizeof(struct mfs_args) }, #endif #ifdef EXT2FS - { &ext2fs_vfsops, MOUNT_EXT2FS, 17, 0, MNT_LOCAL, NULL }, + { &ext2fs_vfsops, MOUNT_EXT2FS, 17, 0, MNT_LOCAL, NULL, + sizeof(struct ufs_args) }, #endif #ifdef CD9660 - { &cd9660_vfsops, MOUNT_CD9660, 14, 0, MNT_LOCAL, NULL }, + { &cd9660_vfsops, MOUNT_CD9660, 14, 0, MNT_LOCAL, NULL, + sizeof(struct iso_args) }, #endif #ifdef MSDOSFS - { &msdosfs_vfsops, MOUNT_MSDOS, 4, 0, MNT_LOCAL, NULL }, + { &msdosfs_vfsops, MOUNT_MSDOS, 4, 0, MNT_LOCAL, NULL, + sizeof(struct msdosfs_args) }, #endif #ifdef NFSCLIENT - { &nfs_vfsops, MOUNT_NFS, 2, 0, 0, NULL }, + { &nfs_vfsops, MOUNT_NFS, 2, 0, 0, NULL, + sizeof(struct nfs_args) }, #endif #ifdef NTFS - { &ntfs_vfsops, MOUNT_NTFS, 6, 0, MNT_LOCAL, NULL }, + { &ntfs_vfsops, MOUNT_NTFS, 6, 0, MNT_LOCAL, NULL, + sizeof(struct ntfs_args) }, #endif #ifdef UDF - { &udf_vfsops, MOUNT_UDF, 13, 0, MNT_LOCAL, NULL }, + { &udf_vfsops, MOUNT_UDF, 13, 0, MNT_LOCAL, NULL, + sizeof(struct iso_args) }, #endif #ifdef FUSE - { &fusefs_vfsops, MOUNT_FUSEFS, 18, 0, MNT_LOCAL, NULL }, + { &fusefs_vfsops, MOUNT_FUSEFS, 18, 0, MNT_LOCAL, NULL, + sizeof(struct fusefs_args) }, #endif #ifdef TMPFS - { &tmpfs_vfsops, MOUNT_TMPFS, 19, 0, MNT_LOCAL, NULL }, + { &tmpfs_vfsops, MOUNT_TMPFS, 19, 0, MNT_LOCAL, NULL, + sizeof(struct tmpfs_args) }, #endif }; diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 5dc5a7813be..705ceb4b8b3 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_subr.c,v 1.261 2017/12/04 09:38:20 mpi Exp $ */ +/* $OpenBSD: vfs_subr.c,v 1.262 2017/12/11 05:27:40 deraadt Exp $ */ /* $NetBSD: vfs_subr.c,v 1.53 1996/04/22 01:39:13 christos Exp $ */ /* @@ -857,7 +857,8 @@ struct vflush_args { }; int -vflush_vnode(struct vnode *vp, void *arg) { +vflush_vnode(struct vnode *vp, void *arg) +{ struct vflush_args *va = arg; struct proc *p = curproc; @@ -903,6 +904,12 @@ vflush_vnode(struct vnode *vp, void *arg) { return (0); } + if (va->flags & WRITEDEMOTE) { + vp->v_op = &dead_vops; + vp->v_tag = VT_NON; + return (0); + } + #ifdef DEBUG if (busyprt) vprint("vflush: busy vnode", vp); @@ -1572,37 +1579,53 @@ vaccess(enum vtype type, mode_t file_mode, uid_t uid, gid_t gid, return (file_mode & mask) == mask ? 0 : EACCES; } +int +vfs_readonly(struct mount *mp, struct proc *p) +{ + int error; + + error = vfs_busy(mp, VB_WRITE|VB_WAIT); + if (error) { + printf("%s: busy\n", mp->mnt_stat.f_mntonname); + return (error); + } + uvm_vnp_sync(mp); + error = VFS_SYNC(mp, MNT_WAIT, p->p_ucred, p); + if (error) { + printf("%s: failed to sync\n", mp->mnt_stat.f_mntonname); + vfs_unbusy(mp); + return (error); + } + + mp->mnt_flag |= MNT_UPDATE | MNT_RDONLY; + mp->mnt_flag &= ~MNT_SOFTDEP; + error = VFS_MOUNT(mp, mp->mnt_stat.f_mntonname, NULL, NULL, curproc); + if (error) { + printf("%s: failed to remount rdonly, error %d\n", + mp->mnt_stat.f_mntonname, error); + vfs_unbusy(mp); + return (error); + } + if (mp->mnt_syncer != NULL) + vgone(mp->mnt_syncer); + mp->mnt_syncer = NULL; + vfs_unbusy(mp); + return (error); +} + /* - * Unmount all file systems. + * Read-only all file systems. * We traverse the list in reverse order under the assumption that doing so * will avoid needing to worry about dependencies. */ void -vfs_unmountall(void) +vfs_rofs(struct proc *p) { struct mount *mp, *nmp; - int allerror, error, again = 1; - retry: - allerror = 0; TAILQ_FOREACH_REVERSE_SAFE(mp, &mountlist, mntlist, mnt_list, nmp) { - if (vfs_busy(mp, VB_WRITE|VB_NOWAIT)) - continue; /* XXX Here is a race, the next pointer is not locked. */ - if ((error = dounmount(mp, MNT_FORCE, curproc)) != 0) { - printf("unmount of %s failed with error %d\n", - mp->mnt_stat.f_mntonname, error); - allerror = 1; - } - } - - if (allerror) { - printf("WARNING: some file systems would not unmount\n"); - if (again) { - printf("retrying\n"); - again = 0; - goto retry; - } + (void) vfs_readonly(mp, p); } } @@ -1610,26 +1633,21 @@ vfs_unmountall(void) * Sync and unmount file systems before shutting down. */ void -vfs_shutdown(void) +vfs_shutdown(struct proc *p) { #ifdef ACCOUNTING acct_shutdown(); #endif - /* XXX Should suspend scheduling. */ - (void) spl0(); - printf("syncing disks... "); if (panicstr == 0) { - /* Sync before unmount, in case we hang on something. */ - sys_sync(&proc0, NULL, NULL); - - /* Unmount file systems. */ - vfs_unmountall(); + /* Take all filesystems to read-only */ + sys_sync(p, NULL, NULL); + vfs_rofs(p); } - if (vfs_syncwait(1)) + if (vfs_syncwait(p, 1)) printf("giving up\n"); else printf("done\n"); @@ -1641,20 +1659,16 @@ vfs_shutdown(void) /* * perform sync() operation and wait for buffers to flush. - * assumptions: called w/ scheduler disabled and physical io enabled - * for now called at spl0() XXX */ int -vfs_syncwait(int verbose) +vfs_syncwait(struct proc *p, int verbose) { struct buf *bp; int iter, nbusy, dcount, s; - struct proc *p; #ifdef MULTIPROCESSOR int hold_count; #endif - p = curproc? curproc : &proc0; sys_sync(p, NULL, NULL); /* Wait for sync to finish. */ diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index b41c4a24b96..83bfe6a94e3 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_syscalls.c,v 1.272 2017/04/15 13:56:43 bluhm Exp $ */ +/* $OpenBSD: vfs_syscalls.c,v 1.273 2017/12/11 05:27:40 deraadt Exp $ */ /* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */ /* @@ -114,6 +114,7 @@ sys_mount(struct proc *p, void *v, register_t *retval) struct nameidata nd; struct vfsconf *vfsp; int flags = SCARG(uap, flags); + void *args = NULL; if ((error = suser(p, 0))) return (error); @@ -130,15 +131,24 @@ sys_mount(struct proc *p, void *v, register_t *retval) */ NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, fspath, p); if ((error = namei(&nd)) != 0) - return (error); + goto fail; vp = nd.ni_vp; if (flags & MNT_UPDATE) { if ((vp->v_flag & VROOT) == 0) { vput(vp); - return (EINVAL); + error = EINVAL; + goto fail; } mp = vp->v_mount; vfsp = mp->mnt_vfc; + + args = malloc(vfsp->vfc_datasize, M_TEMP, M_WAITOK | M_ZERO); + error = copyin(SCARG(uap, data), args, vfsp->vfc_datasize); + if (error) { + vput(vp); + goto fail; + } + mntflag = mp->mnt_flag; /* * We only allow the filesystem to be reloaded if it @@ -147,12 +157,13 @@ sys_mount(struct proc *p, void *v, register_t *retval) if ((flags & MNT_RELOAD) && ((mp->mnt_flag & MNT_RDONLY) == 0)) { vput(vp); - return (EOPNOTSUPP); /* Needs translation */ + error = EOPNOTSUPP; /* Needs translation */ + goto fail; } if ((error = vfs_busy(mp, VB_READ|VB_NOWAIT)) != 0) { vput(vp); - return (error); + goto fail; } mp->mnt_flag |= flags & (MNT_RELOAD | MNT_UPDATE); goto update; @@ -164,20 +175,21 @@ sys_mount(struct proc *p, void *v, register_t *retval) if ((flags & MNT_NOPERM) && (flags & (MNT_NODEV | MNT_NOEXEC)) != (MNT_NODEV | MNT_NOEXEC)) { vput(vp); - return (EPERM); + error = EPERM; + goto fail; } if ((error = vinvalbuf(vp, V_SAVE, p->p_ucred, p, 0, 0)) != 0) { vput(vp); - return (error); + goto fail; } if (vp->v_type != VDIR) { vput(vp); - return (ENOTDIR); + goto fail; } error = copyinstr(SCARG(uap, type), fstypename, MFSNAMELEN, NULL); if (error) { vput(vp); - return (error); + goto fail; } for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) { if (!strcmp(vfsp->vfc_name, fstypename)) @@ -186,12 +198,21 @@ sys_mount(struct proc *p, void *v, register_t *retval) if (vfsp == NULL) { vput(vp); - return (EOPNOTSUPP); + error = EOPNOTSUPP; + goto fail; + } + + args = malloc(vfsp->vfc_datasize, M_TEMP, M_WAITOK | M_ZERO); + error = copyin(SCARG(uap, data), args, vfsp->vfc_datasize); + if (error) { + vput(vp); + goto fail; } if (vp->v_mountedhere != NULL) { vput(vp); - return (EBUSY); + error = EBUSY; + goto fail; } /* @@ -218,7 +239,7 @@ update: free(mp, M_MOUNT, sizeof(*mp)); } vput(vp); - return (error); + goto fail; } /* @@ -237,7 +258,7 @@ update: /* * Mount the filesystem. */ - error = VFS_MOUNT(mp, fspath, SCARG(uap, data), &nd, p); + error = VFS_MOUNT(mp, fspath, args, &nd, p); if (!error) { mp->mnt_stat.f_ctime = time_second; } @@ -261,7 +282,7 @@ update: } vfs_unbusy(mp); - return (error); + goto fail; } vp->v_mountedhere = mp; @@ -289,6 +310,9 @@ update: vfs_unbusy(vp->v_mount); vput(vp); } +fail: + if (args) + free(args, M_TEMP, vfsp->vfc_datasize); return (error); } diff --git a/sys/miscfs/fuse/fuse_vfsops.c b/sys/miscfs/fuse/fuse_vfsops.c index 16bac9615b5..e4affbf5888 100644 --- a/sys/miscfs/fuse/fuse_vfsops.c +++ b/sys/miscfs/fuse/fuse_vfsops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fuse_vfsops.c,v 1.29 2017/04/20 14:13:00 visa Exp $ */ +/* $OpenBSD: fuse_vfsops.c,v 1.30 2017/12/11 05:27:40 deraadt Exp $ */ /* * Copyright (c) 2012-2013 Sylvestre Gallon * @@ -74,19 +74,14 @@ fusefs_mount(struct mount *mp, const char *path, void *data, { struct fusefs_mnt *fmp; struct fusebuf *fbuf; - struct fusefs_args args; + struct fusefs_args *args = data; struct vnode *vp; struct file *fp; - int error; if (mp->mnt_flag & MNT_UPDATE) return (EOPNOTSUPP); - error = copyin(data, &args, sizeof(struct fusefs_args)); - if (error) - return (error); - - if ((fp = fd_getfile(p->p_fd, args.fd)) == NULL) + if ((fp = fd_getfile(p->p_fd, args->fd)) == NULL) return (EBADF); if (fp->f_type != DTYPE_VNODE) @@ -100,8 +95,8 @@ fusefs_mount(struct mount *mp, const char *path, void *data, fmp->mp = mp; fmp->sess_init = 0; fmp->dev = vp->v_rdev; - if (args.max_read > 0) - fmp->max_read = MIN(args.max_read, FUSEBUFMAXSIZE); + if (args->max_read > 0) + fmp->max_read = MIN(args->max_read, FUSEBUFMAXSIZE); else fmp->max_read = FUSEBUFMAXSIZE; 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, 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); } diff --git a/sys/ntfs/ntfs_vfsops.c b/sys/ntfs/ntfs_vfsops.c index 2083d51ccdc..6ceac5b3288 100644 --- a/sys/ntfs/ntfs_vfsops.c +++ b/sys/ntfs/ntfs_vfsops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ntfs_vfsops.c,v 1.56 2017/03/20 16:44:03 jca Exp $ */ +/* $OpenBSD: ntfs_vfsops.c,v 1.57 2017/12/11 05:27:40 deraadt Exp $ */ /* $NetBSD: ntfs_vfsops.c,v 1.7 2003/04/24 07:50:19 christos Exp $ */ /*- @@ -119,7 +119,7 @@ ntfs_mount(struct mount *mp, const char *path, void *data, { int err = 0; struct vnode *devvp; - struct ntfs_args args; + struct ntfs_args *args = data; char fname[MNAMELEN]; char fspec[MNAMELEN]; @@ -131,24 +131,19 @@ ntfs_mount(struct mount *mp, const char *path, void *data, *** */ - /* copy in user arguments*/ - err = copyin(data, (caddr_t)&args, sizeof (struct ntfs_args)); - if (err) - goto error_1; /* can't get arguments*/ - /* * 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) { /* if not updating name...*/ - if (args.fspec == NULL) { + if (args && args->fspec == NULL) { /* * Process export requests. Jumping to "success" * will return the vfs_export() error code. */ struct ntfsmount *ntm = VFSTONTFS(mp); - err = vfs_export(mp, &ntm->ntm_export, &args.export_info); + err = vfs_export(mp, &ntm->ntm_export, &args->export_info); goto success; } @@ -161,7 +156,7 @@ ntfs_mount(struct mount *mp, const char *path, void *data, * Not an update, or updating the name: look up the name * and verify that it refers to a sensible block device. */ - err = copyinstr(args.fspec, fspec, sizeof(fspec), NULL); + err = copyinstr(args->fspec, fspec, sizeof(fspec), NULL); if (err) goto error_1; @@ -203,7 +198,7 @@ ntfs_mount(struct mount *mp, const char *path, void *data, * Update device name only on success */ if( !err) { - err = set_statfs_info(NULL, UIO_USERSPACE, args.fspec, + err = set_statfs_info(NULL, UIO_USERSPACE, args->fspec, UIO_USERSPACE, mp, p); } #endif @@ -227,9 +222,9 @@ ntfs_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.ntfs_args, sizeof(args)); + bcopy(args, &mp->mnt_stat.mount_info.ntfs_args, sizeof(*args)); if ( !err) { - err = ntfs_mountfs(devvp, mp, &args, p); + err = ntfs_mountfs(devvp, mp, args, p); } } if (err) { diff --git a/sys/sys/mount.h b/sys/sys/mount.h index f71ce3e852f..d0783229211 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mount.h,v 1.131 2017/10/06 18:44:22 bluhm Exp $ */ +/* $OpenBSD: mount.h,v 1.132 2017/12/11 05:27:40 deraadt Exp $ */ /* $NetBSD: mount.h,v 1.48 1996/02/18 11:55:47 fvdl Exp $ */ /* @@ -131,27 +131,6 @@ struct nfs_args { int acdirmin; /* ac for dir recently modified */ int acdirmax; /* ac for dir not recently modified */ }; -/* NFS args version 3 (for backwards compatibility) */ -struct nfs_args3 { - int version; /* args structure version number */ - struct sockaddr *addr; /* file server address */ - int addrlen; /* length of address */ - int sotype; /* Socket type */ - int proto; /* and Protocol */ - u_char *fh; /* File handle to be mounted */ - int fhsize; /* Size, in bytes, of fh */ - int flags; /* flags */ - int wsize; /* write size in bytes */ - int rsize; /* read size in bytes */ - int readdirsize; /* readdir size in bytes */ - int timeo; /* initial timeout in .1 secs */ - int retrans; /* times to retry send */ - int maxgrouplist; /* Max. size of group list */ - int readahead; /* # of blocks to readahead */ - int leaseterm; /* Term (sec) of lease */ - int deadthresh; /* Retrans threshold */ - char *hostname; /* server's name */ -}; /* * NFS mount option flags @@ -468,6 +447,7 @@ struct vfsconf { int vfc_refcount; /* number mounted of this type */ int vfc_flags; /* permanent flags */ struct vfsconf *vfc_next; /* next in list */ + size_t vfc_datasize; /* size of data args */ }; /* buffer cache statistics */ @@ -592,7 +572,6 @@ struct mount *vfs_getvfs(fsid_t *); int vfs_mountedon(struct vnode *); int vfs_rootmountalloc(char *, char *, struct mount **); void vfs_unbusy(struct mount *); -void vfs_unmountall(void); extern TAILQ_HEAD(mntlist, mount) mountlist; struct mount *getvfs(fsid_t *); /* return vfs given fsid */ @@ -604,8 +583,8 @@ struct netcred *vfs_export_lookup(struct mount *, struct netexport *, int vfs_allocate_syncvnode(struct mount *); int speedup_syncer(void); -int vfs_syncwait(int); /* sync and wait for complete */ -void vfs_shutdown(void); /* unmount and sync file systems */ +int vfs_syncwait(struct proc *, int); /* sync and wait for complete */ +void vfs_shutdown(struct proc *); /* unmount and sync file systems */ int dounmount(struct mount *, int, struct proc *); void vfsinit(void); int vfs_register(struct vfsconf *); diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 7c59472c9a1..6578c6d54ff 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -1,4 +1,4 @@ -/* $OpenBSD: vnode.h,v 1.140 2017/08/13 22:02:22 beck Exp $ */ +/* $OpenBSD: vnode.h,v 1.141 2017/12/11 05:27:40 deraadt Exp $ */ /* $NetBSD: vnode.h,v 1.38 1996/02/29 20:59:05 cgd Exp $ */ /* @@ -227,6 +227,7 @@ extern int vttoif_tab[]; #define FORCECLOSE 0x0002 /* vflush: force file closeure */ #define WRITECLOSE 0x0004 /* vflush: only close writeable files */ #define DOCLOSE 0x0008 /* vclean: close active files */ +#define WRITEDEMOTE 0x0010 /* vflush: ok if some writes remain */ #define V_SAVE 0x0001 /* vinvalbuf: sync file first */ #define V_SAVEMETA 0x0002 /* vinvalbuf: leave indirect blocks */ diff --git a/sys/tmpfs/tmpfs_vfsops.c b/sys/tmpfs/tmpfs_vfsops.c index 9a17e74ae63..28b757230a0 100644 --- a/sys/tmpfs/tmpfs_vfsops.c +++ b/sys/tmpfs/tmpfs_vfsops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tmpfs_vfsops.c,v 1.13 2017/09/08 05:36:53 deraadt Exp $ */ +/* $OpenBSD: tmpfs_vfsops.c,v 1.14 2017/12/11 05:27:40 deraadt Exp $ */ /* $NetBSD: tmpfs_vfsops.c,v 1.52 2011/09/27 01:10:43 christos Exp $ */ /* @@ -84,7 +84,7 @@ int tmpfs_mount(struct mount *mp, const char *path, void *data, struct nameidata *ndp, struct proc *p) { - struct tmpfs_args args; + struct tmpfs_args *args = data; tmpfs_mount_t *tmp; tmpfs_node_t *root; uint64_t memlimit; @@ -121,25 +121,25 @@ tmpfs_mount(struct mount *mp, const char *path, void *data, if (tmpfs_mem_info(1) < TMPFS_PAGES_RESERVED) return EINVAL; - error = copyin(data, &args, sizeof(struct tmpfs_args)); + error = copyin(data, args, sizeof(struct tmpfs_args)); if (error) return error; - if (args.ta_root_uid == VNOVAL || args.ta_root_gid == VNOVAL || - args.ta_root_mode == VNOVAL) + if (args->ta_root_uid == VNOVAL || args->ta_root_gid == VNOVAL || + args->ta_root_mode == VNOVAL) return EINVAL; /* Get the memory usage limit for this file-system. */ - if (args.ta_size_max < PAGE_SIZE) { + if (args->ta_size_max < PAGE_SIZE) { memlimit = UINT64_MAX; } else { - memlimit = args.ta_size_max; + memlimit = args->ta_size_max; } KASSERT(memlimit > 0); - if (args.ta_nodes_max <= 3) { + if (args->ta_nodes_max <= 3) { nodes = 3 + (memlimit / 1024); } else { - nodes = args.ta_nodes_max; + nodes = args->ta_nodes_max; } nodes = MIN(nodes, INT_MAX); KASSERT(nodes >= 3); @@ -156,8 +156,8 @@ tmpfs_mount(struct mount *mp, const char *path, void *data, tmpfs_mntmem_init(tmp, memlimit); /* Allocate the root node. */ - error = tmpfs_alloc_node(tmp, VDIR, args.ta_root_uid, - args.ta_root_gid, args.ta_root_mode & ALLPERMS, NULL, + error = tmpfs_alloc_node(tmp, VDIR, args->ta_root_uid, + args->ta_root_gid, args->ta_root_mode & ALLPERMS, NULL, VNOVAL, &root); KASSERT(error == 0 && root != NULL); @@ -180,7 +180,7 @@ tmpfs_mount(struct mount *mp, const char *path, void *data, #endif vfs_getnewfsid(mp); - mp->mnt_stat.mount_info.tmpfs_args = args; + mp->mnt_stat.mount_info.tmpfs_args = *args; bzero(&mp->mnt_stat.f_mntonname, sizeof(mp->mnt_stat.f_mntonname)); bzero(&mp->mnt_stat.f_mntfromname, sizeof(mp->mnt_stat.f_mntfromname)); diff --git a/sys/ufs/ext2fs/ext2fs_vfsops.c b/sys/ufs/ext2fs/ext2fs_vfsops.c index c99cfc78b38..365f01e15ad 100644 --- a/sys/ufs/ext2fs/ext2fs_vfsops.c +++ b/sys/ufs/ext2fs/ext2fs_vfsops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ext2fs_vfsops.c,v 1.99 2017/05/30 10:32:53 sf Exp $ */ +/* $OpenBSD: ext2fs_vfsops.c,v 1.100 2017/12/11 05:27:40 deraadt Exp $ */ /* $NetBSD: ext2fs_vfsops.c,v 1.1 1997/06/11 09:34:07 bouyer Exp $ */ /* @@ -162,17 +162,13 @@ ext2fs_mount(struct mount *mp, const char *path, void *data, struct nameidata *ndp, struct proc *p) { struct vnode *devvp; - struct ufs_args args; + struct ufs_args *args = data; struct ufsmount *ump = NULL; struct m_ext2fs *fs; char fname[MNAMELEN]; char fspec[MNAMELEN]; int error, flags; - error = copyin(data, &args, sizeof(struct ufs_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. @@ -208,19 +204,21 @@ ext2fs_mount(struct mount *mp, const char *path, void *data, fs->e2fs.e2fs_state = E2FS_ERRORS; fs->e2fs_fmod = 1; } - if (args.fspec == NULL) { + if (args && args->fspec == NULL) { /* * Process export requests. */ return (vfs_export(mp, &ump->um_export, - &args.export_info)); + &args->export_info)); } + if (args == NULL) + goto success; } /* * 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; @@ -265,7 +263,7 @@ ext2fs_mount(struct mount *mp, const char *path, void *data, strlcpy(mp->mnt_stat.f_mntfromname, fname, MNAMELEN); memset(mp->mnt_stat.f_mntfromspec, 0, MNAMELEN); strlcpy(mp->mnt_stat.f_mntfromspec, fspec, MNAMELEN); - memcpy(&mp->mnt_stat.mount_info.ufs_args, &args, sizeof(args)); + memcpy(&mp->mnt_stat.mount_info.ufs_args, args, sizeof(*args)); if (fs->e2fs_fmod != 0) { /* XXX */ fs->e2fs_fmod = 0; diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index d0894ffb408..fb56e0de556 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ffs_vfsops.c,v 1.166 2017/05/29 14:07:16 sf Exp $ */ +/* $OpenBSD: ffs_vfsops.c,v 1.167 2017/12/11 05:27:40 deraadt Exp $ */ /* $NetBSD: ffs_vfsops.c,v 1.19 1996/02/09 22:22:26 christos Exp $ */ /* @@ -206,7 +206,7 @@ ffs_mount(struct mount *mp, const char *path, void *data, struct nameidata *ndp, struct proc *p) { struct vnode *devvp; - struct ufs_args args; + struct ufs_args *args = data; struct ufsmount *ump = NULL; struct fs *fs; char fname[MNAMELEN]; @@ -214,10 +214,6 @@ ffs_mount(struct mount *mp, const char *path, void *data, int error = 0, flags; int ronly; - error = copyin(data, &args, sizeof(struct ufs_args)); - if (error) - return (error); - #ifndef FFS_SOFTUPDATES if (mp->mnt_flag & MNT_SOFTDEP) { printf("WARNING: soft updates isn't compiled in\n"); @@ -255,6 +251,8 @@ ffs_mount(struct mount *mp, const char *path, void *data, * Get rid of files open for writing. */ flags = WRITECLOSE; + if (args == NULL) + flags |= WRITEDEMOTE; if (mp->mnt_flag & MNT_FORCE) flags |= FORCECLOSE; if (fs->fs_flags & FS_DOSOFTDEP) { @@ -342,12 +340,14 @@ ffs_mount(struct mount *mp, const char *path, void *data, ronly = 0; } - if (args.fspec == NULL) { + if (args == NULL) + goto success; + if (args->fspec == NULL) { /* * Process export requests. */ error = vfs_export(mp, &ump->um_export, - &args.export_info); + &args->export_info); if (error) goto error_1; else @@ -359,7 +359,7 @@ ffs_mount(struct mount *mp, const char *path, void *data, * 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_1; @@ -435,7 +435,8 @@ ffs_mount(struct mount *mp, const char *path, void *data, * * This code is common to root and non-root mounts */ - memcpy(&mp->mnt_stat.mount_info.ufs_args, &args, sizeof(args)); + if (args) + memcpy(&mp->mnt_stat.mount_info.ufs_args, args, sizeof(*args)); VFS_STATFS(mp, &mp->mnt_stat, p); success: diff --git a/sys/ufs/mfs/mfs_vfsops.c b/sys/ufs/mfs/mfs_vfsops.c index 42a3013cc9d..cb4ca90a741 100644 --- a/sys/ufs/mfs/mfs_vfsops.c +++ b/sys/ufs/mfs/mfs_vfsops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mfs_vfsops.c,v 1.54 2017/01/10 19:48:32 bluhm Exp $ */ +/* $OpenBSD: mfs_vfsops.c,v 1.55 2017/12/11 05:27:40 deraadt Exp $ */ /* $NetBSD: mfs_vfsops.c,v 1.10 1996/02/09 22:31:28 christos Exp $ */ /* @@ -85,17 +85,13 @@ mfs_mount(struct mount *mp, const char *path, void *data, struct nameidata *ndp, struct proc *p) { struct vnode *devvp; - struct mfs_args args; + struct mfs_args *args = data; struct ufsmount *ump; struct fs *fs; struct mfsnode *mfsp; char fspec[MNAMELEN]; int flags, error; - error = copyin(data, &args, sizeof(struct mfs_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. @@ -114,13 +110,13 @@ mfs_mount(struct mount *mp, const char *path, void *data, if (fs->fs_ronly && (mp->mnt_flag & MNT_WANTRDWR)) fs->fs_ronly = 0; #ifdef EXPORTMFS - if (args.fspec == NULL) + if (args && args->fspec == NULL) return (vfs_export(mp, &ump->um_export, - &args.export_info)); + &args->export_info)); #endif return (0); } - error = copyinstr(args.fspec, fspec, sizeof(fspec), NULL); + error = copyinstr(args->fspec, fspec, sizeof(fspec), NULL); if (error) return (error); error = getnewvnode(VT_MFS, NULL, &mfs_vops, &devvp); @@ -132,8 +128,8 @@ mfs_mount(struct mount *mp, const char *path, void *data, mfs_minor++; mfsp = malloc(sizeof *mfsp, M_MFSNODE, M_WAITOK | M_ZERO); devvp->v_data = mfsp; - mfsp->mfs_baseoff = args.base; - mfsp->mfs_size = args.size; + mfsp->mfs_baseoff = args->base; + mfsp->mfs_size = args->size; mfsp->mfs_vnode = devvp; mfsp->mfs_tid = p->p_tid; bufq_init(&mfsp->mfs_bufq, BUFQ_FIFO); @@ -152,7 +148,7 @@ mfs_mount(struct mount *mp, const char *path, void *data, strlcpy(mp->mnt_stat.f_mntfromname, fspec, MNAMELEN); memset(mp->mnt_stat.f_mntfromspec, 0, MNAMELEN); strlcpy(mp->mnt_stat.f_mntfromspec, fspec, MNAMELEN); - memcpy(&mp->mnt_stat.mount_info.mfs_args, &args, sizeof(args)); + memcpy(&mp->mnt_stat.mount_info.mfs_args, args, sizeof(*args)); return (0); }