import autofs-5.1.4-69.el8

This commit is contained in:
CentOS Sources 2021-05-29 04:11:24 +00:00 committed by Andrew Lukoshko
parent f719b745d3
commit cb3938c254
6 changed files with 830 additions and 1 deletions

View File

@ -0,0 +1,82 @@
autofs-5.1.7 - eliminate redundant cache lookup in tree_mapent_add_node()
From: Ian Kent <raven@themaw.net>
Since we need to create the offset tree after adding the offset entries
to the mapent cache (from a list.h list) there's no need to lookup the
mapent in tree_mapent_add_node() and validate it. Just use it directly
when calling tree_mapent_add_node() and avoid a cache lookup on every
node addition.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
include/mounts.h | 2 +-
lib/mounts.c | 13 ++-----------
modules/parse_sun.c | 2 +-
4 files changed, 5 insertions(+), 13 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -70,6 +70,7 @@
- fix amd hosts mount expire.
- fix offset entries order.
- use mapent tree root for tree_mapent_add_node().
+- eliminate redundant cache lookup in tree_mapent_add_node().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -170,7 +170,7 @@ void mnts_get_expire_list(struct list_he
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_mapent_root(struct mapent *me);
-int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, const char *key);
+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);
void tree_mapent_cleanup_offsets(struct mapent *oe);
int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict);
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1519,19 +1519,10 @@ static void tree_mapent_free(struct tree
}
int tree_mapent_add_node(struct mapent_cache *mc,
- struct tree_node *root, const char *key)
+ struct tree_node *root, struct mapent *me)
{
- unsigned int logopt = mc->ap->logopt;
struct tree_node *n;
struct mapent *parent;
- struct mapent *me;
-
- me = cache_lookup_distinct(mc, key);
- if (!me) {
- error(logopt,
- "failed to find key %s of multi-mount", key);
- return 0;
- }
n = tree_add_node(root, me);
if (!n)
@@ -1540,7 +1531,7 @@ int tree_mapent_add_node(struct mapent_c
MAPENT_SET_ROOT(me, root)
/* Set the subtree parent */
- parent = cache_get_offset_parent(mc, key);
+ parent = cache_get_offset_parent(mc, me->key);
if (!parent)
MAPENT_SET_PARENT(me, root)
else
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -1548,7 +1548,7 @@ dont_expand:
return 1;
}
list_for_each_entry_safe(oe, tmp, &offsets, work) {
- if (!tree_mapent_add_node(mc, MAPENT_ROOT(me), oe->key))
+ if (!tree_mapent_add_node(mc, MAPENT_ROOT(me), oe))
error(ap->logopt, "failed to add offset %s to tree", oe->key);
list_del_init(&oe->work);
}

View File

@ -0,0 +1,129 @@
autofs-5.1.7 - fix direct mount deadlock
From: Ian Kent <raven@themaw.net>
When umounting direct mounts at exit or when umounting mounts no
longer in the map on re-load a deadlock can occur.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 22 +++++++++++++++++++++-
daemon/state.c | 14 +++++++++-----
3 files changed, 31 insertions(+), 6 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -72,6 +72,7 @@
- use mapent tree root for tree_mapent_add_node().
- eliminate redundant cache lookup in tree_mapent_add_node().
- fix hosts map offset order.
+- fix direct mount deadlock.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/direct.c
+++ autofs-5.1.4/daemon/direct.c
@@ -84,11 +84,27 @@ static void mnts_cleanup(void *arg)
int do_umount_autofs_direct(struct autofs_point *ap, struct mapent *me)
{
struct ioctl_ops *ops = get_ioctl_ops();
+ struct mapent_cache *mc = me->mc;
char buf[MAX_ERR_BUF];
int ioctlfd = -1, rv, left, retries;
+ char key[PATH_MAX + 1];
+ struct mapent *tmp;
int opened = 0;
- left = umount_multi(ap, me->key, 0);
+ if (me->len > PATH_MAX) {
+ error(ap->logopt, "path too long");
+ return 1;
+ }
+ strcpy(key, me->key);
+
+ cache_unlock(mc);
+ left = umount_multi(ap, key, 0);
+ cache_readlock(mc);
+ tmp = cache_lookup_distinct(mc, key);
+ if (tmp != me) {
+ error(ap->logopt, "key %s no longer in mapent cache", key);
+ return -1;
+ }
if (left) {
warn(ap->logopt, "could not unmount %d dirs under %s",
left, me->key);
@@ -213,6 +229,7 @@ int umount_autofs_direct(struct autofs_p
mc = map->mc;
pthread_cleanup_push(cache_lock_cleanup, mc);
cache_readlock(mc);
+restart:
me = cache_enumerate(mc, NULL);
while (me) {
int error;
@@ -230,6 +247,9 @@ int umount_autofs_direct(struct autofs_p
* failed umount.
*/
error = do_umount_autofs_direct(ap, me);
+ /* cache became invalid, restart */
+ if (error == -1)
+ goto restart;
if (!error)
goto done;
--- autofs-5.1.4.orig/daemon/state.c
+++ autofs-5.1.4/daemon/state.c
@@ -348,11 +348,12 @@ static void do_readmap_cleanup(void *arg
return;
}
-static void do_readmap_mount(struct autofs_point *ap,
+static int do_readmap_mount(struct autofs_point *ap,
struct map_source *map, struct mapent *me, time_t now)
{
struct mapent_cache *nc;
struct mapent *ne, *nested, *valid;
+ int ret = 0;
nc = ap->entry->master->nc;
@@ -411,7 +412,7 @@ static void do_readmap_mount(struct auto
cache_unlock(vmc);
error(ap->logopt,
"failed to find expected existing valid map entry");
- return;
+ return ret;
}
/* Take over the mount if there is one */
valid->ioctlfd = me->ioctlfd;
@@ -430,14 +431,14 @@ static void do_readmap_mount(struct auto
ap->exp_runfreq = runfreq;
}
} else if (!is_mounted(me->key, MNTS_REAL))
- do_umount_autofs_direct(ap, me);
+ ret = do_umount_autofs_direct(ap, me);
else
debug(ap->logopt,
"%s is mounted", me->key);
} else
do_mount_autofs_direct(ap, me, get_exp_timeout(ap, map));
- return;
+ return ret;
}
static void *do_readmap(void *arg)
@@ -504,9 +505,12 @@ static void *do_readmap(void *arg)
mc = map->mc;
pthread_cleanup_push(cache_lock_cleanup, mc);
cache_readlock(mc);
+restart:
me = cache_enumerate(mc, NULL);
while (me) {
- do_readmap_mount(ap, map, me, now);
+ int ret = do_readmap_mount(ap, map, me, now);
+ if (ret == -1)
+ goto restart;
me = cache_enumerate(mc, me);
}
lookup_prune_one_cache(ap, map->mc, now);

View File

@ -0,0 +1,289 @@
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);

View File

@ -0,0 +1,199 @@
autofs-5.1.7 - fix offset entries order
From: Ian Kent <raven@themaw.net>
While it's rare it's possible that a mapent entry might not have
it's offsets in shortest to longest path order.
If this happens adding an entry to the mapent tree can result in
an incorrect tree topology that doesn't work. That's because adding
tree entries ensures that nodes in a sub-tree are placed below the
containing node so the containing node must be present for that to
work. This topology is critical to the performance of map entries
that have a very large number of offsets such as an NFS server with
many exports.
There's no other choice but make a traversal after the offset entries
have all been added to create the mapent tree.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
include/automount.h | 1
lib/cache.c | 1
modules/parse_sun.c | 74 +++++++++++++++++++++++++++++++++++++++++-----------
4 files changed, 62 insertions(+), 15 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -68,6 +68,7 @@
- add ext_mount_hash_mutex lock helpers.
- fix amd section mounts map reload.
- fix amd hosts mount expire.
+- fix offset entries 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
@@ -169,6 +169,7 @@ struct mapent {
/* Parent nesting point within multi-mount */
struct tree_node *mm_parent;
struct tree_node node;
+ struct list_head work;
char *key;
size_t len;
char *mapent;
--- autofs-5.1.4.orig/lib/cache.c
+++ autofs-5.1.4/lib/cache.c
@@ -559,6 +559,7 @@ int cache_add(struct mapent_cache *mc, s
me->mm_parent = NULL;
INIT_TREE_NODE(&me->node);
INIT_LIST_HEAD(&me->ino_index);
+ INIT_LIST_HEAD(&me->work);
me->ioctlfd = -1;
me->dev = (dev_t) -1;
me->ino = (ino_t) -1;
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -791,14 +791,15 @@ static int check_is_multi(const char *ma
static int
update_offset_entry(struct autofs_point *ap,
- struct mapent_cache *mc, const char *name,
- const char *m_root, int m_root_len,
+ struct mapent_cache *mc, struct list_head *offsets,
+ const char *name, const char *m_root, int m_root_len,
const char *m_offset, const char *myoptions,
const char *loc, time_t age)
{
char m_key[PATH_MAX + 1];
char m_mapent[MAPENT_MAX_LEN + 1];
int o_len, m_key_len, m_options_len, m_mapent_len;
+ struct mapent *me;
int ret;
memset(m_mapent, 0, MAPENT_MAX_LEN + 1);
@@ -864,8 +865,29 @@ update_offset_entry(struct autofs_point
cache_writelock(mc);
ret = cache_update_offset(mc, name, m_key, m_mapent, age);
- if (!tree_mapent_add_node(mc, name, m_key))
- error(ap->logopt, "failed to add offset %s to tree", m_key);
+ me = cache_lookup_distinct(mc, m_key);
+ if (me && list_empty(&me->work)) {
+ struct list_head *last;
+
+ /* Offset entries really need to be in shortest to
+ * longest path order. If not and the list of offsets
+ * is large there will be a performace hit.
+ */
+ list_for_each_prev(last, offsets) {
+ struct mapent *this;
+
+ this = list_entry(last, struct mapent, work);
+ if (me->len >= this->len) {
+ if (last->next == offsets)
+ list_add_tail(&me->work, offsets);
+ else
+ list_add_tail(&me->work, last);
+ break;
+ }
+ }
+ if (list_empty(&me->work))
+ list_add(&me->work, offsets);
+ }
cache_unlock(mc);
if (ret == CHE_DUPLICATE) {
@@ -1211,6 +1233,25 @@ static char *do_expandsunent(const char
return mapent;
}
+static void cleanup_offset_entries(struct autofs_point *ap,
+ struct mapent_cache *mc,
+ struct list_head *offsets)
+{
+ struct mapent *me, *tmp;
+ int ret;
+
+ if (list_empty(offsets))
+ return;
+ cache_writelock(mc);
+ list_for_each_entry_safe(me, tmp, offsets, work) {
+ list_del(&me->work);
+ ret = cache_delete(mc, me->key);
+ if (ret != CHE_OK)
+ crit(ap->logopt, "failed to delete offset %s", me->key);
+ }
+ cache_unlock(mc);
+}
+
/*
* syntax is:
* [-options] location [location] ...
@@ -1230,7 +1271,8 @@ int parse_mount(struct autofs_point *ap,
char buf[MAX_ERR_BUF];
struct map_source *source;
struct mapent_cache *mc;
- struct mapent *me;
+ struct mapent *me, *oe, *tmp;
+ LIST_HEAD(offsets);
char *pmapent, *options;
const char *p;
int mapent_len, rv = 0;
@@ -1446,9 +1488,7 @@ dont_expand:
if (!m_offset) {
warn(ap->logopt, MODPREFIX "null path or out of memory");
- cache_writelock(mc);
- tree_mapent_delete_offsets(mc, name);
- cache_unlock(mc);
+ cleanup_offset_entries(ap, mc, &offsets);
free(options);
free(pmapent);
pthread_setcancelstate(cur_state, NULL);
@@ -1463,9 +1503,7 @@ dont_expand:
l = parse_mapent(p, options, &myoptions, &loc, ap->logopt);
if (!l) {
- cache_writelock(mc);
- tree_mapent_delete_offsets(mc, name);
- cache_unlock(mc);
+ cleanup_offset_entries(ap, mc, &offsets);
free(m_offset);
free(options);
free(pmapent);
@@ -1476,15 +1514,13 @@ dont_expand:
p += l;
p = skipspace(p);
- status = update_offset_entry(ap, mc,
+ status = update_offset_entry(ap, mc, &offsets,
name, m_root, m_root_len,
m_offset, myoptions, loc, age);
if (status != CHE_OK) {
warn(ap->logopt, MODPREFIX "error adding multi-mount");
- cache_writelock(mc);
- tree_mapent_delete_offsets(mc, name);
- cache_unlock(mc);
+ cleanup_offset_entries(ap, mc, &offsets);
free(m_offset);
free(options);
free(pmapent);
@@ -1501,6 +1537,14 @@ dont_expand:
free(myoptions);
} while (*p == '/' || (*p == '"' && *(p + 1) == '/'));
+ cache_writelock(mc);
+ list_for_each_entry_safe(oe, tmp, &offsets, work) {
+ if (!tree_mapent_add_node(mc, name, oe->key))
+ error(ap->logopt, "failed to add offset %s to tree", oe->key);
+ list_del_init(&oe->work);
+ }
+ cache_unlock(mc);
+
rv = mount_subtree(ap, mc, name, NULL, options, ctxt);
free(options);

View File

@ -0,0 +1,111 @@
autofs-5.1.7 - use mapent tree root for tree_mapent_add_node()
From: Ian Kent <raven@themaw.net>
Since we need to create the offset tree after adding the offset entries
to the mapent cache lookup the root mapent once and use it when calling
tree_mapent_add_node() instread of doing a cache lookup on every node
addition.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
include/mounts.h | 2 +-
lib/mounts.c | 24 +++++-------------------
modules/parse_sun.c | 11 ++++++++++-
4 files changed, 17 insertions(+), 21 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -69,6 +69,7 @@
- fix amd section mounts map reload.
- fix amd hosts mount expire.
- fix offset entries order.
+- use mapent tree root for tree_mapent_add_node().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -170,7 +170,7 @@ void mnts_get_expire_list(struct list_he
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_mapent_root(struct mapent *me);
-int tree_mapent_add_node(struct mapent_cache *mc, const char *base, const char *key);
+int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, const char *key);
int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key);
void tree_mapent_cleanup_offsets(struct mapent *oe);
int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict);
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1519,27 +1519,13 @@ static void tree_mapent_free(struct tree
}
int tree_mapent_add_node(struct mapent_cache *mc,
- const char *root, const char *key)
+ struct tree_node *root, const char *key)
{
unsigned int logopt = mc->ap->logopt;
- struct tree_node *tree, *n;
- struct mapent *base;
+ struct tree_node *n;
struct mapent *parent;
struct mapent *me;
- base = cache_lookup_distinct(mc, root);
- if (!base) {
- error(logopt,
- "failed to find multi-mount root for key %s", key);
- return 0;
- }
-
- if (MAPENT_ROOT(base) != MAPENT_NODE(base)) {
- error(logopt, "key %s is not multi-mount root", root);
- return 0;
- }
- tree = MAPENT_ROOT(base);
-
me = cache_lookup_distinct(mc, key);
if (!me) {
error(logopt,
@@ -1547,16 +1533,16 @@ int tree_mapent_add_node(struct mapent_c
return 0;
}
- n = tree_add_node(tree, me);
+ n = tree_add_node(root, me);
if (!n)
return 0;
- MAPENT_SET_ROOT(me, tree)
+ MAPENT_SET_ROOT(me, root)
/* Set the subtree parent */
parent = cache_get_offset_parent(mc, key);
if (!parent)
- MAPENT_SET_PARENT(me, tree)
+ MAPENT_SET_PARENT(me, root)
else
MAPENT_SET_PARENT(me, MAPENT_NODE(parent))
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -1538,8 +1538,17 @@ dont_expand:
} while (*p == '/' || (*p == '"' && *(p + 1) == '/'));
cache_writelock(mc);
+ me = cache_lookup_distinct(mc, name);
+ if (!me) {
+ cache_unlock(mc);
+ free(options);
+ free(pmapent);
+ cleanup_offset_entries(ap, mc, &offsets);
+ pthread_setcancelstate(cur_state, NULL);
+ return 1;
+ }
list_for_each_entry_safe(oe, tmp, &offsets, work) {
- if (!tree_mapent_add_node(mc, name, oe->key))
+ if (!tree_mapent_add_node(mc, MAPENT_ROOT(me), oe->key))
error(ap->logopt, "failed to add offset %s to tree", oe->key);
list_del_init(&oe->work);
}

View File

@ -8,7 +8,7 @@
Summary: A tool for automatically mounting and unmounting filesystems
Name: autofs
Version: 5.1.4
Release: 68%{?dist}
Release: 69%{?dist}
Epoch: 1
License: GPLv2+
Group: System Environment/Daemons
@ -234,6 +234,11 @@ Patch211: autofs-5.1.7-add-ext_mount_hash_mutex-lock-helpers.patch
Patch212: autofs-5.1.7-fix-amd-section-mounts-map-reload.patch
Patch213: autofs-5.1.7-fix-amd-hosts-mount-expire.patch
Patch214: autofs-5.1.7-fix-offset-entries-order.patch
Patch215: autofs-5.1.7-use-mapent-tree-root-for-tree_mapent_add_node.patch
Patch216: autofs-5.1.7-eliminate-redundant-cache-lookup-in-tree_mapent_add_node.patch
Patch217: autofs-5.1.7-fix-hosts-map-offset-order.patch
Patch218: autofs-5.1.7-fix-direct-mount-deadlock.patch
%if %{with_systemd}
BuildRequires: systemd-units
@ -510,6 +515,11 @@ echo %{version}-%{release} > .version
%patch212 -p1
%patch213 -p1
%patch214 -p1
%patch215 -p1
%patch216 -p1
%patch217 -p1
%patch218 -p1
%build
LDFLAGS=-Wl,-z,now
@ -605,6 +615,15 @@ fi
%dir /etc/auto.master.d
%changelog
* Wed May 19 2021 Ian Kent <ikent@redhat.com> - 5.1.4-69
- bz1961492 - autofs: regression in offset ordering
- 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.
- fix direct mount deadlock.
- Resolves: rhbz#1961492
* Mon May 10 2021 Ian Kent <ikent@redhat.com> - 5.1.4-68
- bz1958487 - autofs amd mounts present in the configuration get umounted
on reload