summaryrefslogtreecommitdiff
path: root/usr/src/lib
diff options
context:
space:
mode:
authorcth <none@none>2008-02-22 09:02:16 -0800
committercth <none@none>2008-02-22 09:02:16 -0800
commite37c6c376a1a22a828db3bb5ab40c86cb08f9c86 (patch)
tree4e26a9dc4fb51ae3c275b4a874d16228f566782f /usr/src/lib
parent931293416c5362b3d50b217b4390d1c88f7c7500 (diff)
downloadillumos-joyent-e37c6c376a1a22a828db3bb5ab40c86cb08f9c86.tar.gz
6453345 devfs_getattr violates devfs locking rules
6527396 devfsadm -C taking hours after reconfiguration reboot 6661843 i_ddi_di_cache_invalidate() should only use taskq_dispatch on valid->invalid 6662461 reserved_links_exist() should be optimized
Diffstat (limited to 'usr/src/lib')
-rw-r--r--usr/src/lib/libdevinfo/devinfo_finddev.c61
-rw-r--r--usr/src/lib/libdevinfo/libdevinfo.h3
-rw-r--r--usr/src/lib/libdevinfo/mapfile-vers5
3 files changed, 65 insertions, 4 deletions
diff --git a/usr/src/lib/libdevinfo/devinfo_finddev.c b/usr/src/lib/libdevinfo/devinfo_finddev.c
index 3dfb4467c9..eea252358f 100644
--- a/usr/src/lib/libdevinfo/devinfo_finddev.c
+++ b/usr/src/lib/libdevinfo/devinfo_finddev.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -256,6 +256,65 @@ finddev_readdir(const char *path, finddevhdl_t *handlep)
return (finddev_readdir_alt(path, handlep));
}
+/*
+ * Return true if a directory is empty
+ * Use the standard library readdir to determine if a directory is
+ * empty.
+ */
+static int
+finddev_emptydir_alt(const char *path)
+{
+ DIR *dir;
+ struct dirent *dp;
+
+ if ((dir = opendir(path)) == NULL)
+ return (ENOENT);
+
+ while ((dp = readdir(dir)) != NULL) {
+ if ((strcmp(dp->d_name, ".") == 0) ||
+ (strcmp(dp->d_name, "..") == 0))
+ continue;
+ (void) closedir(dir);
+ return (0); /* not empty */
+ }
+ (void) closedir(dir);
+ return (1); /* empty */
+}
+
+/*
+ * Use of the dev filesystem's private readdir does (not trigger
+ * the implicit device reconfiguration) to determine if a directory
+ * is empty.
+ *
+ * Note: only useable with paths mounted on an instance of the
+ * dev filesystem.
+ *
+ * Does not return the . and .. entries.
+ * Empty directories are returned as an zero-length list.
+ * ENOENT is returned as a NULL list pointer.
+ */
+static int
+finddev_emptydir_devfs(const char *path)
+{
+ int rv;
+ int empty;
+
+ rv = modctl(MODDEVEMPTYDIR, path, strlen(path), &empty);
+ if (rv == 0) {
+ return (empty);
+ }
+ return (0);
+}
+
+int
+finddev_emptydir(const char *path)
+{
+ if (GLOBAL_DEV_PATH(path)) {
+ return (finddev_emptydir_devfs(path));
+ }
+ return (finddev_emptydir_alt(path));
+}
+
void
finddev_close(finddevhdl_t arg)
{
diff --git a/usr/src/lib/libdevinfo/libdevinfo.h b/usr/src/lib/libdevinfo/libdevinfo.h
index 7672b83a7c..2314ee1c9c 100644
--- a/usr/src/lib/libdevinfo/libdevinfo.h
+++ b/usr/src/lib/libdevinfo/libdevinfo.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -473,6 +473,7 @@ typedef struct __finddevhdl *finddevhdl_t;
extern int device_exists(const char *);
extern int finddev_readdir(const char *, finddevhdl_t *);
+extern int finddev_emptydir(const char *);
extern void finddev_close(finddevhdl_t);
extern const char *finddev_next(finddevhdl_t);
diff --git a/usr/src/lib/libdevinfo/mapfile-vers b/usr/src/lib/libdevinfo/mapfile-vers
index 90afb14386..aa49121009 100644
--- a/usr/src/lib/libdevinfo/mapfile-vers
+++ b/usr/src/lib/libdevinfo/mapfile-vers
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -207,9 +207,10 @@ SUNWprivate_1.1 {
di_prom_prop_lookup_slot_names;
di_prop_find;
device_exists;
- finddev_readdir;
finddev_close;
+ finddev_emptydir;
finddev_next;
+ finddev_readdir;
di_flags;
di_retire_device;
di_unretire_device;