Page MenuHomeFreeBSD

D7047.id18123.diff
No OneTemporary

D7047.id18123.diff

Index: sbin/umount/umount.8
===================================================================
--- sbin/umount/umount.8
+++ sbin/umount/umount.8
@@ -36,12 +36,12 @@
.Nd unmount file systems
.Sh SYNOPSIS
.Nm
-.Op Fl fv
+.Op Fl fnv
.Ar special ... | node ... | fsid ...
.Nm
.Fl a | A
.Op Fl F Ar fstab
-.Op Fl fv
+.Op Fl fnv
.Op Fl h Ar host
.Op Fl t Ar type
.Sh DESCRIPTION
@@ -94,6 +94,15 @@
option, will only unmount
.Tn NFS
file systems.
+.It Fl n
+Unless the
+.Fl f
+is used, the
+.Nm
+will not unmount an active file system.
+It will, however, perform a flush.
+This flag disables this behaviour, preventing the flush
+if there are any files open.
.It Fl t Ar type
Is used to indicate the actions should only be taken on
file systems of the specified type.
Index: sbin/umount/umount.c
===================================================================
--- sbin/umount/umount.c
+++ sbin/umount/umount.c
@@ -91,7 +91,7 @@
struct addrinfo hints;
all = errs = 0;
- while ((ch = getopt(argc, argv, "AaF:fh:t:v")) != -1)
+ while ((ch = getopt(argc, argv, "AaF:fh:nt:v")) != -1)
switch (ch) {
case 'A':
all = 2;
@@ -103,12 +103,15 @@
setfstab(optarg);
break;
case 'f':
- fflag = MNT_FORCE;
+ fflag |= MNT_FORCE;
break;
case 'h': /* -h implies -A. */
all = 2;
nfshost = optarg;
break;
+ case 'n':
+ fflag |= MNT_NONBUSY;
+ break;
case 't':
if (typelist != NULL)
err(1, "only one -t option may be specified");
@@ -124,8 +127,11 @@
argc -= optind;
argv += optind;
+ if ((fflag & MNT_FORCE) != 0 && (fflag & MNT_NONBUSY) != 0)
+ err(1, "-f and -n are mutually exclusive");
+
/* Start disks transferring immediately. */
- if ((fflag & MNT_FORCE) == 0)
+ if ((fflag & (MNT_FORCE | MNT_NONBUSY)) == 0)
sync();
if ((argc == 0 && !all) || (argc != 0 && all))
@@ -609,7 +615,7 @@
{
(void)fprintf(stderr, "%s\n%s\n",
- "usage: umount [-fv] special ... | node ... | fsid ...",
- " umount -a | -A [-F fstab] [-fv] [-h host] [-t type]");
+ "usage: umount [-fnv] special ... | node ... | fsid ...",
+ " umount -a | -A [-F fstab] [-fnv] [-h host] [-t type]");
exit(1);
}
Index: sys/kern/vfs_mount.c
===================================================================
--- sys/kern/vfs_mount.c
+++ sys/kern/vfs_mount.c
@@ -1205,6 +1205,28 @@
}
/*
+ * Return error if any of the vnodes, ignoring the root vnode
+ * and the syncer vnode, have non-zero usecount.
+ */
+static int
+vfs_check_usecounts(struct mount *mp)
+{
+ struct vnode *vp, *mvp;
+
+ MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
+ if ((vp->v_vflag & VV_ROOT) == 0 && vp->v_type != VNON &&
+ vp->v_usecount != 0) {
+ VI_UNLOCK(vp);
+ MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
+ return (EBUSY);
+ }
+ VI_UNLOCK(vp);
+ }
+
+ return (0);
+}
+
+/*
* Do the actual filesystem unmount.
*/
int
@@ -1247,6 +1269,18 @@
return (error);
}
+ if (flags & MNT_NONBUSY) {
+ error = vfs_check_usecounts(mp);
+ if (error != 0) {
+ if (coveredvp != NULL) {
+ VOP_UNLOCK(coveredvp, 0);
+ vdrop(coveredvp);
+ }
+ vfs_rel(mp);
+ return (error);
+ }
+ }
+
vn_start_write(NULL, &mp, V_WAIT | V_MNTREF);
MNT_ILOCK(mp);
if ((mp->mnt_kern_flag & MNTK_UNMOUNT) != 0 ||
Index: sys/sys/mount.h
===================================================================
--- sys/sys/mount.h
+++ sys/sys/mount.h
@@ -312,17 +312,21 @@
* External filesystem command modifier flags.
* Unmount can use the MNT_FORCE flag.
* XXX: These are not STATES and really should be somewhere else.
- * XXX: MNT_BYFSID collides with MNT_ACLS, but because MNT_ACLS is only used for
- * mount(2) and MNT_BYFSID is only used for unmount(2) it's harmless.
+ * XXX: MNT_BYFSID and MNT_NONBUSY collide with MNT_ACLS and MNT_MULTILABEL,
+ * but because MNT_ACLS and MNT_MULTILABEL are only used for mount(2),
+ * and MNT_BYFSID and MNT_NONBUSY are only used for unmount(2),
+ * it's harmless.
*/
#define MNT_UPDATE 0x0000000000010000ULL /* not real mount, just update */
#define MNT_DELEXPORT 0x0000000000020000ULL /* delete export host lists */
#define MNT_RELOAD 0x0000000000040000ULL /* reload filesystem data */
#define MNT_FORCE 0x0000000000080000ULL /* force unmount or readonly */
#define MNT_SNAPSHOT 0x0000000001000000ULL /* snapshot the filesystem */
+#define MNT_NONBUSY 0x0000000004000000ULL /* check vnode use counts. */
#define MNT_BYFSID 0x0000000008000000ULL /* specify filesystem by ID. */
#define MNT_CMDFLAGS (MNT_UPDATE | MNT_DELEXPORT | MNT_RELOAD | \
- MNT_FORCE | MNT_SNAPSHOT | MNT_BYFSID)
+ MNT_FORCE | MNT_SNAPSHOT | MNT_NONBUSY | \
+ MNT_BYFSID)
/*
* Internal filesystem control flags stored in mnt_kern_flag.
*
Index: usr.sbin/autofs/autounmountd.c
===================================================================
--- usr.sbin/autofs/autounmountd.c
+++ usr.sbin/autofs/autounmountd.c
@@ -161,7 +161,7 @@
if (ret < 0)
log_err(1, "asprintf");
- error = unmount(fsid_str, MNT_BYFSID);
+ error = unmount(fsid_str, MNT_NONBUSY | MNT_BYFSID);
if (error != 0) {
if (errno == EBUSY) {
log_debugx("cannot unmount %s (%s): %s",

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 29, 2:51 AM (15 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26315062
Default Alt Text
D7047.id18123.diff (5 KB)

Event Timeline