summaryrefslogtreecommitdiff
path: root/usr/src/uts/common
diff options
context:
space:
mode:
authorMike Gerdts <mike.gerdts@joyent.com>2019-11-22 21:18:51 +0000
committerMike Gerdts <mike.gerdts@joyent.com>2019-12-02 15:24:17 +0000
commit90c832de103bf8a88947637500243fa256e75b31 (patch)
tree626653d4d37231efdffb7cc05f650a0322e1addd /usr/src/uts/common
parent98860832862cef20612fd5b10b324f5eba1b4015 (diff)
downloadillumos-joyent-OS-8054.tar.gz
OS-8054 inotify watches lead to EBUSY during zfs mountOS-8054
Diffstat (limited to 'usr/src/uts/common')
-rw-r--r--usr/src/uts/common/fs/fem.c31
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_vfsops.c5
-rw-r--r--usr/src/uts/common/sys/fem.h3
3 files changed, 34 insertions, 5 deletions
diff --git a/usr/src/uts/common/fs/fem.c b/usr/src/uts/common/fs/fem.c
index 50633859ce..e5c318c6d7 100644
--- a/usr/src/uts/common/fs/fem.c
+++ b/usr/src/uts/common/fs/fem.c
@@ -24,7 +24,7 @@
*/
/*
- * Copyright (c) 2015, Joyent, Inc. All rights reserved.
+ * Copyright 2019 Joyent, Inc.
*/
#include <sys/types.h>
@@ -3977,6 +3977,35 @@ fem_getvnops(vnode_t *v)
return (r);
}
+/*
+ * Returns the number of vnode refs that are not associated with fem.
+ */
+int
+fem_getvnrefs(vnode_t *v)
+{
+ int val;
+ struct fem_list *fl;
+
+ ASSERT(MUTEX_HELD(&v->v_lock));
+ if (v->v_femhead == NULL) {
+ return (v->v_count);
+ }
+
+ if ((fl = fem_lock(v->v_femhead)) == NULL) {
+ val = v->v_count;
+ } else {
+ ASSERT3S(fl->feml_tos, >, 0);
+ ASSERT3S(fl->feml_tos, <=, v->v_count);
+ /*
+ * The first item on the list is a guard entry that does not
+ * have a vnode ref.
+ */
+ val = fl->feml_tos - v->v_count + 1;
+ }
+ fem_unlock(v->v_femhead);
+
+ return (val);
+}
/*
* VFS interposition
diff --git a/usr/src/uts/common/fs/zfs/zfs_vfsops.c b/usr/src/uts/common/fs/zfs/zfs_vfsops.c
index 6b61cd7a84..cb542f1037 100644
--- a/usr/src/uts/common/fs/zfs/zfs_vfsops.c
+++ b/usr/src/uts/common/fs/zfs/zfs_vfsops.c
@@ -20,11 +20,10 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright 2019 Joyent, Inc.
* Copyright (c) 2012, 2015 by Delphix. All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
* Copyright 2016 Nexenta Systems, Inc. All rights reserved.
- * Copyright 2019 Joyent, Inc.
*/
/* Portions Copyright 2010 Robert Milkowski */
@@ -1832,7 +1831,7 @@ zfs_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr)
mutex_enter(&mvp->v_lock);
if ((uap->flags & MS_REMOUNT) == 0 &&
(uap->flags & MS_OVERLAY) == 0 &&
- (mvp->v_count != 1 || (mvp->v_flag & VROOT))) {
+ (fem_getvnrefs(mvp) != 1 || (mvp->v_flag & VROOT))) {
mutex_exit(&mvp->v_lock);
return (SET_ERROR(EBUSY));
}
diff --git a/usr/src/uts/common/sys/fem.h b/usr/src/uts/common/sys/fem.h
index beb838fdfa..f606c47e3b 100644
--- a/usr/src/uts/common/sys/fem.h
+++ b/usr/src/uts/common/sys/fem.h
@@ -23,6 +23,7 @@
* Use is subject to license terms.
*
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2019 Joyent, Inc.
*/
#ifndef _SYS_FEM_H
@@ -427,7 +428,7 @@ extern int fem_is_installed(struct vnode *v, fem_t *mon, void *arg);
extern int fem_uninstall(struct vnode *v, fem_t *mon, void *arg);
extern vnodeops_t *fem_getvnops(struct vnode *v);
extern void fem_setvnops(struct vnode *v, struct vnodeops *nops);
-
+extern int fem_getvnrefs(vnode_t *);
extern int fsem_create(char *name, const struct fs_operation_def *templ,
fsem_t **actual);