aboutsummaryrefslogtreecommitdiff
path: root/sys/fs/autofs
diff options
context:
space:
mode:
authorEdward Tomasz Napierala <trasz@FreeBSD.org>2016-03-24 13:34:39 +0000
committerEdward Tomasz Napierala <trasz@FreeBSD.org>2016-03-24 13:34:39 +0000
commit42ed64e39b68fd79bee65cefc623fd37ede12616 (patch)
tree7882da830a69ced59d0b10d9c854d71aff4b4cda /sys/fs/autofs
parentf379b4636a915f0f4c93c1c0c5944d4345a40f42 (diff)
downloadsrc-42ed64e39b68fd79bee65cefc623fd37ede12616.tar.gz
src-42ed64e39b68fd79bee65cefc623fd37ede12616.zip
Notes
Diffstat (limited to 'sys/fs/autofs')
-rw-r--r--sys/fs/autofs/autofs.c10
-rw-r--r--sys/fs/autofs/autofs.h7
-rw-r--r--sys/fs/autofs/autofs_vfsops.c9
-rw-r--r--sys/fs/autofs/autofs_vnops.c38
4 files changed, 40 insertions, 24 deletions
diff --git a/sys/fs/autofs/autofs.c b/sys/fs/autofs/autofs.c
index c4b1ec331dce..eee74ea43fa0 100644
--- a/sys/fs/autofs/autofs.c
+++ b/sys/fs/autofs/autofs.c
@@ -77,6 +77,7 @@
#include <sys/sysctl.h>
#include <sys/syscallsubr.h>
#include <sys/taskqueue.h>
+#include <sys/tree.h>
#include <sys/vnode.h>
#include <machine/atomic.h>
#include <vm/uma.h>
@@ -149,6 +150,15 @@ TUNABLE_INT("vfs.autofs.interruptible", &autofs_interruptible);
SYSCTL_INT(_vfs_autofs, OID_AUTO, interruptible, CTLFLAG_RWTUN,
&autofs_interruptible, 1, "Allow requests to be interrupted by signal");
+static int
+autofs_node_cmp(const struct autofs_node *a, const struct autofs_node *b)
+{
+
+ return (strcmp(a->an_name, b->an_name));
+}
+
+RB_GENERATE(autofs_node_tree, autofs_node, an_link, autofs_node_cmp);
+
int
autofs_init(struct vfsconf *vfsp)
{
diff --git a/sys/fs/autofs/autofs.h b/sys/fs/autofs/autofs.h
index 27e380bd9bb7..bab22825b6e5 100644
--- a/sys/fs/autofs/autofs.h
+++ b/sys/fs/autofs/autofs.h
@@ -65,11 +65,12 @@ extern int autofs_mount_on_stat;
#define AUTOFS_ASSERT_UNLOCKED(X) sx_assert(&X->am_lock, SA_UNLOCKED)
struct autofs_node {
- TAILQ_ENTRY(autofs_node) an_next;
+ RB_ENTRY(autofs_node) an_link;
char *an_name;
int an_fileno;
struct autofs_node *an_parent;
- TAILQ_HEAD(, autofs_node) an_children;
+ RB_HEAD(autofs_node_tree,
+ autofs_node) an_children;
struct autofs_mount *an_mount;
struct vnode *an_vnode;
struct sx an_vnode_lock;
@@ -136,4 +137,6 @@ void autofs_node_delete(struct autofs_node *anp);
int autofs_node_vn(struct autofs_node *anp, struct mount *mp,
int flags, struct vnode **vpp);
+RB_PROTOTYPE(autofs_node_tree, autofs_node, an_link, autofs_node_cmp);
+
#endif /* !AUTOFS_H */
diff --git a/sys/fs/autofs/autofs_vfsops.c b/sys/fs/autofs/autofs_vfsops.c
index 722ff24fb362..b427a7fa70d7 100644
--- a/sys/fs/autofs/autofs_vfsops.c
+++ b/sys/fs/autofs/autofs_vfsops.c
@@ -42,6 +42,7 @@
#include <sys/stat.h>
#include <sys/sx.h>
#include <sys/taskqueue.h>
+#include <sys/tree.h>
#include <sys/vnode.h>
#include <fs/autofs/autofs.h>
@@ -158,10 +159,10 @@ autofs_unmount(struct mount *mp, int mntflags)
/*
* Not terribly efficient, but at least not recursive.
*/
- while (!TAILQ_EMPTY(&amp->am_root->an_children)) {
- anp = TAILQ_FIRST(&amp->am_root->an_children);
- while (!TAILQ_EMPTY(&anp->an_children))
- anp = TAILQ_FIRST(&anp->an_children);
+ while (!RB_EMPTY(&amp->am_root->an_children)) {
+ anp = RB_MIN(autofs_node_tree, &amp->am_root->an_children);
+ while (!RB_EMPTY(&anp->an_children))
+ anp = RB_MIN(autofs_node_tree, &anp->an_children);
autofs_node_delete(anp);
}
autofs_node_delete(amp->am_root);
diff --git a/sys/fs/autofs/autofs_vnops.c b/sys/fs/autofs/autofs_vnops.c
index dda886d68f63..0ab6ec113e7c 100644
--- a/sys/fs/autofs/autofs_vnops.c
+++ b/sys/fs/autofs/autofs_vnops.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <sys/stat.h>
#include <sys/systm.h>
#include <sys/taskqueue.h>
+#include <sys/tree.h>
#include <sys/vnode.h>
#include <machine/atomic.h>
#include <vm/uma.h>
@@ -450,7 +451,7 @@ autofs_readdir(struct vop_readdir_args *ap)
* Write out the directory entries for subdirectories.
*/
AUTOFS_SLOCK(amp);
- TAILQ_FOREACH(child, &anp->an_children, an_next) {
+ RB_FOREACH(child, autofs_node_tree, &anp->an_children) {
/*
* Check the offset to skip entries returned by previous
* calls to getdents().
@@ -575,8 +576,8 @@ autofs_node_new(struct autofs_node *parent, struct autofs_mount *amp,
anp->an_parent = parent;
anp->an_mount = amp;
if (parent != NULL)
- TAILQ_INSERT_TAIL(&parent->an_children, anp, an_next);
- TAILQ_INIT(&anp->an_children);
+ RB_INSERT(autofs_node_tree, &parent->an_children, anp);
+ RB_INIT(&anp->an_children);
*anpp = anp;
return (0);
@@ -586,27 +587,28 @@ int
autofs_node_find(struct autofs_node *parent, const char *name,
int namelen, struct autofs_node **anpp)
{
- struct autofs_node *anp;
+ struct autofs_node *anp, find;
+ int error;
AUTOFS_ASSERT_LOCKED(parent->an_mount);
- TAILQ_FOREACH(anp, &parent->an_children, an_next) {
- if (namelen >= 0) {
- if (strlen(anp->an_name) != namelen)
- continue;
- if (strncmp(anp->an_name, name, namelen) != 0)
- continue;
- } else {
- if (strcmp(anp->an_name, name) != 0)
- continue;
- }
+ if (namelen >= 0)
+ find.an_name = strndup(name, namelen, M_AUTOFS);
+ else
+ find.an_name = strdup(name, M_AUTOFS);
+ anp = RB_FIND(autofs_node_tree, &parent->an_children, &find);
+ if (anp != NULL) {
+ error = 0;
if (anpp != NULL)
*anpp = anp;
- return (0);
+ } else {
+ error = ENOENT;
}
- return (ENOENT);
+ free(find.an_name, M_AUTOFS);
+
+ return (error);
}
void
@@ -615,13 +617,13 @@ autofs_node_delete(struct autofs_node *anp)
struct autofs_node *parent;
AUTOFS_ASSERT_XLOCKED(anp->an_mount);
- KASSERT(TAILQ_EMPTY(&anp->an_children), ("have children"));
+ KASSERT(RB_EMPTY(&anp->an_children), ("have children"));
callout_drain(&anp->an_callout);
parent = anp->an_parent;
if (parent != NULL)
- TAILQ_REMOVE(&parent->an_children, anp, an_next);
+ RB_REMOVE(autofs_node_tree, &parent->an_children, anp);
sx_destroy(&anp->an_vnode_lock);
free(anp->an_name, M_AUTOFS);
uma_zfree(autofs_node_zone, anp);