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