summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan Cantrill <bryan@joyent.com>2011-11-10 09:09:20 +0000
committerRobert Mustacchi <rm@joyent.com>2013-08-15 10:06:11 -0700
commit8d3cb697ab50bcbe6fdf24afdb4243a7367d164e (patch)
treebdbbb877abfcf50e13402d5ac94e83d804330987
parenta7027df17fad220a20367b9d1eb251bc6300d203 (diff)
downloadillumos-joyent-8d3cb697ab50bcbe6fdf24afdb4243a7367d164e.tar.gz
3976 sdev_readdir() recursively acquires sdev_contents as reader
Reviewed by: Gordon Ross <gwr@nexenta.com> Reviewed by: Richard Lowe <richlowe@richlowe.net> Approved by: Garrett D'Amore <garrett@damore.org>
-rw-r--r--usr/src/uts/common/fs/dev/sdev_vnops.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/usr/src/uts/common/fs/dev/sdev_vnops.c b/usr/src/uts/common/fs/dev/sdev_vnops.c
index fb1d93d06b..89c5decbf0 100644
--- a/usr/src/uts/common/fs/dev/sdev_vnops.c
+++ b/usr/src/uts/common/fs/dev/sdev_vnops.c
@@ -1142,9 +1142,21 @@ sdev_readdir(struct vnode *dvp, struct uio *uiop, struct cred *cred, int *eofp,
struct sdev_node *parent = VTOSDEV(dvp);
int error;
- /* execute access is required to search the directory */
- if ((error = VOP_ACCESS(dvp, VEXEC, 0, cred, ct)) != 0)
- return (error);
+ /*
+ * We must check that we have execute access to search the directory --
+ * but because our sdev_contents lock is already held as a reader (the
+ * caller must have done a VOP_RWLOCK()), we call directly into the
+ * underlying access routine if sdev_attr is non-NULL.
+ */
+ if (parent->sdev_attr != NULL) {
+ VERIFY(RW_READ_HELD(&parent->sdev_contents));
+
+ if (sdev_unlocked_access(parent, VEXEC, cred) != 0)
+ return (EACCES);
+ } else {
+ if ((error = VOP_ACCESS(dvp, VEXEC, 0, cred, ct)) != 0)
+ return (error);
+ }
ASSERT(parent);
if (!SDEV_IS_GLOBAL(parent))