changeset 14138:489a49e3fc33

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>
author Bryan Cantrill <bryan@joyent.com>
date Thu, 10 Nov 2011 09:09:20 +0000
parents f7523d207d74
children c3f8a4690b1f
files usr/src/uts/common/fs/dev/sdev_vnops.c
diffstat 1 files changed, 15 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/fs/dev/sdev_vnops.c	Wed Aug 14 11:42:31 2013 -0800
+++ b/usr/src/uts/common/fs/dev/sdev_vnops.c	Thu Nov 10 09:09:20 2011 +0000
@@ -1142,9 +1142,21 @@
 	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))