290 lines
7.9 KiB
Diff
290 lines
7.9 KiB
Diff
autofs-5.1.7 - fix hosts map offset order
|
|
|
|
From: Ian Kent <raven@themaw.net>
|
|
|
|
Map entry offset paths to be in shortest to longest order but exports
|
|
from a server could come in any order. If there are a large number of
|
|
exports this can result in a lot of overhead when adding the offset
|
|
to the ordered list use to mount the offset during parsing since the
|
|
path length of exports can cary a lot.
|
|
|
|
So leverage the tree implemention to sort the export offsets into
|
|
shortest to longest order as we go when constructing the mapent from
|
|
the exports list.
|
|
|
|
Signed-off-by: Ian Kent <raven@themaw.net>
|
|
---
|
|
CHANGELOG | 1
|
|
include/automount.h | 2 -
|
|
include/mounts.h | 8 +++++
|
|
include/rpc_subs.h | 3 ++
|
|
lib/mounts.c | 57 +++++++++++++++++++++++++++++++++++++--
|
|
modules/lookup_hosts.c | 71 ++++++++++++++++++++++++++++++++++++++-----------
|
|
6 files changed, 124 insertions(+), 18 deletions(-)
|
|
|
|
--- autofs-5.1.4.orig/CHANGELOG
|
|
+++ autofs-5.1.4/CHANGELOG
|
|
@@ -71,6 +71,7 @@
|
|
- fix offset entries order.
|
|
- use mapent tree root for tree_mapent_add_node().
|
|
- eliminate redundant cache lookup in tree_mapent_add_node().
|
|
+- fix hosts map offset order.
|
|
|
|
xx/xx/2018 autofs-5.1.5
|
|
- fix flag file permission.
|
|
--- autofs-5.1.4.orig/include/automount.h
|
|
+++ autofs-5.1.4/include/automount.h
|
|
@@ -31,9 +31,9 @@
|
|
#include "master.h"
|
|
#include "macros.h"
|
|
#include "log.h"
|
|
+#include "mounts.h"
|
|
#include "rpc_subs.h"
|
|
#include "parse_subs.h"
|
|
-#include "mounts.h"
|
|
#include "dev-ioctl-lib.h"
|
|
#include "parse_amd.h"
|
|
|
|
--- autofs-5.1.4.orig/include/mounts.h
|
|
+++ autofs-5.1.4/include/mounts.h
|
|
@@ -52,6 +52,7 @@ extern const unsigned int t_direct;
|
|
extern const unsigned int t_offset;
|
|
|
|
struct mnt_list;
|
|
+struct exportinfo;
|
|
struct mapent;
|
|
|
|
struct tree_ops;
|
|
@@ -66,6 +67,9 @@ struct tree_node {
|
|
#define MNT_LIST(n) (container_of(n, struct mnt_list, node))
|
|
#define MNT_LIST_NODE(ptr) ((struct tree_node *) &((struct mnt_list *) ptr)->node)
|
|
|
|
+#define EXPORTINFO(n) (container_of(n, struct exportinfo, node))
|
|
+#define EXPORT_NODE(ptr) ((struct tree_node *) &((struct exportinfo *) ptr)->node)
|
|
+
|
|
#define MAPENT(n) (container_of(n, struct mapent, node))
|
|
#define MAPENT_NODE(p) ((struct tree_node *) &((struct mapent *) p)->node)
|
|
#define MAPENT_ROOT(p) ((struct tree_node *) ((struct mapent *) p)->mm_root)
|
|
@@ -166,9 +170,13 @@ struct mnt_list *mnts_add_mount(struct a
|
|
void mnts_remove_mount(const char *mp, unsigned int flags);
|
|
struct mnt_list *get_mnt_list(const char *path, int include);
|
|
unsigned int mnts_has_mounted_mounts(struct autofs_point *ap);
|
|
+int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr);
|
|
+void tree_free(struct tree_node *root);
|
|
void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap);
|
|
void mnts_put_expire_list(struct list_head *mnts);
|
|
void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags);
|
|
+struct tree_node *tree_host_root(struct exportinfo *exp);
|
|
+struct tree_node *tree_host_add_node(struct tree_node *root, struct exportinfo *exp);
|
|
struct tree_node *tree_mapent_root(struct mapent *me);
|
|
int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, struct mapent *me);
|
|
int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key);
|
|
--- autofs-5.1.4.orig/include/rpc_subs.h
|
|
+++ autofs-5.1.4/include/rpc_subs.h
|
|
@@ -23,6 +23,8 @@
|
|
#include <linux/nfs2.h>
|
|
#include <linux/nfs3.h>
|
|
|
|
+#include "automount.h"
|
|
+
|
|
#define NFS4_VERSION 4
|
|
|
|
/* rpc helper subs */
|
|
@@ -57,6 +59,7 @@ struct exportinfo {
|
|
char *dir;
|
|
struct hostinfo *hosts;
|
|
struct exportinfo *next;
|
|
+ struct tree_node node;
|
|
};
|
|
|
|
struct conn_info {
|
|
--- autofs-5.1.4.orig/lib/mounts.c
|
|
+++ autofs-5.1.4/lib/mounts.c
|
|
@@ -79,6 +79,17 @@ static struct tree_ops mnt_ops = {
|
|
};
|
|
static struct tree_ops *tree_mnt_ops = &mnt_ops;
|
|
|
|
+static struct tree_node *tree_host_new(void *ptr);
|
|
+static int tree_host_cmp(struct tree_node *n, void *ptr);
|
|
+static void tree_host_free(struct tree_node *n);
|
|
+
|
|
+static struct tree_ops host_ops = {
|
|
+ .new = tree_host_new,
|
|
+ .cmp = tree_host_cmp,
|
|
+ .free = tree_host_free,
|
|
+};
|
|
+static struct tree_ops *tree_host_ops = &host_ops;
|
|
+
|
|
static struct tree_node *tree_mapent_new(void *ptr);
|
|
static int tree_mapent_cmp(struct tree_node *n, void *ptr);
|
|
static void tree_mapent_free(struct tree_node *n);
|
|
@@ -1341,7 +1352,7 @@ static struct tree_node *tree_add_node(s
|
|
return NULL;
|
|
}
|
|
|
|
-static void tree_free(struct tree_node *root)
|
|
+void tree_free(struct tree_node *root)
|
|
{
|
|
struct tree_ops *ops = root->ops;
|
|
|
|
@@ -1352,7 +1363,7 @@ static void tree_free(struct tree_node *
|
|
ops->free(root);
|
|
}
|
|
|
|
-static int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr)
|
|
+int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr)
|
|
{
|
|
int ret;
|
|
|
|
@@ -1479,6 +1490,48 @@ void mnts_put_expire_list(struct list_he
|
|
mnts_hash_mutex_unlock();
|
|
}
|
|
|
|
+struct tree_node *tree_host_root(struct exportinfo *exp)
|
|
+{
|
|
+ return tree_root(tree_host_ops, exp);
|
|
+}
|
|
+
|
|
+static struct tree_node *tree_host_new(void *ptr)
|
|
+{
|
|
+ struct tree_node *n = EXPORT_NODE(ptr);
|
|
+
|
|
+ n->ops = tree_host_ops;
|
|
+ n->left = NULL;
|
|
+ n->right = NULL;
|
|
+
|
|
+ return n;
|
|
+}
|
|
+
|
|
+static int tree_host_cmp(struct tree_node *n, void *ptr)
|
|
+{
|
|
+ struct exportinfo *n_exp = EXPORTINFO(n);
|
|
+ size_t n_exp_len = strlen(n_exp->dir);
|
|
+ struct exportinfo *exp = ptr;
|
|
+ size_t exp_len = strlen(exp->dir);
|
|
+ int eq;
|
|
+
|
|
+ eq = strcmp(exp->dir, n_exp->dir);
|
|
+ if (!eq)
|
|
+ return 0;
|
|
+ return (exp_len < n_exp_len) ? -1 : 1;
|
|
+}
|
|
+
|
|
+static void tree_host_free(struct tree_node *n)
|
|
+{
|
|
+ n->ops = NULL;
|
|
+ n->left = NULL;
|
|
+ n->right = NULL;
|
|
+}
|
|
+
|
|
+struct tree_node *tree_host_add_node(struct tree_node *root, struct exportinfo *exp)
|
|
+{
|
|
+ return tree_add_node(root, exp);
|
|
+}
|
|
+
|
|
struct tree_node *tree_mapent_root(struct mapent *me)
|
|
{
|
|
return tree_root(tree_mapent_ops, me);
|
|
--- autofs-5.1.4.orig/modules/lookup_hosts.c
|
|
+++ autofs-5.1.4/modules/lookup_hosts.c
|
|
@@ -84,14 +84,38 @@ int lookup_read_master(struct master *ma
|
|
return NSS_STATUS_UNKNOWN;
|
|
}
|
|
|
|
+struct work_info {
|
|
+ char *mapent;
|
|
+ const char *host;
|
|
+ int pos;
|
|
+};
|
|
+
|
|
+static int tree_host_work(struct tree_node *n, void *ptr)
|
|
+{
|
|
+ struct exportinfo *exp = EXPORTINFO(n);
|
|
+ struct work_info *wi = ptr;
|
|
+ int len;
|
|
+
|
|
+ if (!wi->pos)
|
|
+ len = sprintf(wi->mapent, "\"%s\" \"%s:%s\"",
|
|
+ exp->dir, wi->host, exp->dir);
|
|
+ else
|
|
+ len = sprintf(wi->mapent + wi->pos, " \"%s\" \"%s:%s\"",
|
|
+ exp->dir, wi->host, exp->dir);
|
|
+ wi->pos += len;
|
|
+
|
|
+ return 1;
|
|
+}
|
|
+
|
|
static char *get_exports(struct autofs_point *ap, const char *host)
|
|
{
|
|
char buf[MAX_ERR_BUF];
|
|
char *mapent;
|
|
struct exportinfo *exp, *this;
|
|
+ struct tree_node *tree = NULL;
|
|
+ struct work_info wi;
|
|
size_t hostlen = strlen(host);
|
|
size_t mapent_len;
|
|
- int len, pos;
|
|
|
|
debug(ap->logopt, MODPREFIX "fetchng export list for %s", host);
|
|
|
|
@@ -100,7 +124,28 @@ static char *get_exports(struct autofs_p
|
|
this = exp;
|
|
mapent_len = 0;
|
|
while (this) {
|
|
+ struct tree_node *n;
|
|
+
|
|
mapent_len += hostlen + 2*(strlen(this->dir) + 2) + 3;
|
|
+
|
|
+ if (!tree) {
|
|
+ tree = tree_host_root(this);
|
|
+ if (!tree) {
|
|
+ error(ap->logopt, "failed to create exports tree root");
|
|
+ rpc_exports_free(exp);
|
|
+ return NULL;
|
|
+ }
|
|
+ goto next;
|
|
+ }
|
|
+
|
|
+ n = tree_host_add_node(tree, this);
|
|
+ if (!n) {
|
|
+ error(ap->logopt, "failed to add exports tree node");
|
|
+ tree_free(tree);
|
|
+ rpc_exports_free(exp);
|
|
+ return NULL;
|
|
+ }
|
|
+next:
|
|
this = this->next;
|
|
}
|
|
|
|
@@ -115,20 +160,16 @@ static char *get_exports(struct autofs_p
|
|
}
|
|
*mapent = 0;
|
|
|
|
- pos = 0;
|
|
- this = exp;
|
|
- if (this) {
|
|
- len = sprintf(mapent, "\"%s\" \"%s:%s\"",
|
|
- this->dir, host, this->dir);
|
|
- pos += len;
|
|
- this = this->next;
|
|
- }
|
|
-
|
|
- while (this) {
|
|
- len = sprintf(mapent + pos, " \"%s\" \"%s:%s\"",
|
|
- this->dir, host, this->dir);
|
|
- pos += len;
|
|
- this = this->next;
|
|
+ wi.mapent = mapent;
|
|
+ wi.host = host;
|
|
+ wi.pos = 0;
|
|
+
|
|
+ if (!tree) {
|
|
+ free(mapent);
|
|
+ mapent = NULL;
|
|
+ } else {
|
|
+ tree_traverse_inorder(tree, tree_host_work, &wi);
|
|
+ tree_free(tree);
|
|
}
|
|
rpc_exports_free(exp);
|
|
|