256 lines
6.8 KiB
Diff
256 lines
6.8 KiB
Diff
autofs-5.1.7 - refactor umount_multi_triggers()
|
|
|
|
From: Ian Kent <raven@themaw.net>
|
|
|
|
Refactor umount_multi_triggers() to try the umount of an offset subtree
|
|
in a seperate function.
|
|
|
|
Signed-off-by: Ian Kent <raven@themaw.net>
|
|
---
|
|
CHANGELOG | 1
|
|
lib/mounts.c | 187 ++++++++++++++++++++++++++++++++---------------------------
|
|
2 files changed, 104 insertions(+), 84 deletions(-)
|
|
|
|
--- autofs-5.1.4.orig/CHANGELOG
|
|
+++ autofs-5.1.4/CHANGELOG
|
|
@@ -10,6 +10,7 @@
|
|
- set offset parent in update_offset_entry().
|
|
- remove redundant variables from mount_autofs_offset().
|
|
- remove unused parameter form do_mount_autofs_offset().
|
|
+- refactor umount_multi_triggers().
|
|
|
|
xx/xx/2018 autofs-5.1.5
|
|
- fix flag file permission.
|
|
--- autofs-5.1.4.orig/lib/mounts.c
|
|
+++ autofs-5.1.4/lib/mounts.c
|
|
@@ -2490,57 +2490,6 @@ static int do_mount_autofs_offset(struct
|
|
return mounted;
|
|
}
|
|
|
|
-int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
|
|
- const char *root, unsigned int start, const char *base)
|
|
-{
|
|
- char path[PATH_MAX + 1];
|
|
- char *offset = path;
|
|
- struct mapent *oe;
|
|
- struct list_head *pos = NULL;
|
|
- unsigned int root_len = strlen(root);
|
|
- int mounted;
|
|
-
|
|
- mounted = 0;
|
|
- offset = cache_get_offset(base, offset, start, &me->multi_list, &pos);
|
|
- while (offset) {
|
|
- char key[PATH_MAX + 1];
|
|
- int key_len = root_len + strlen(offset);
|
|
-
|
|
- if (key_len > PATH_MAX) {
|
|
- warn(ap->logopt, "path loo long");
|
|
- goto cont;
|
|
- }
|
|
-
|
|
- /* The root offset is always mounted seperately so the
|
|
- * offset path will always be root + offset.
|
|
- */
|
|
- strcpy(key, root);
|
|
- strcat(key, offset);
|
|
-
|
|
- oe = cache_lookup_distinct(me->mc, key);
|
|
- if (!oe || !oe->mapent)
|
|
- goto cont;
|
|
-
|
|
- mounted += do_mount_autofs_offset(ap, oe, root);
|
|
-
|
|
- /*
|
|
- * If re-constructing a multi-mount it's necessary to walk
|
|
- * into nested mounts, unlike the usual "mount only what's
|
|
- * needed as you go" behavior.
|
|
- */
|
|
- if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) {
|
|
- if (oe->ioctlfd != -1 ||
|
|
- is_mounted(oe->key, MNTS_REAL))
|
|
- mount_multi_triggers(ap, oe, key, strlen(key), base);
|
|
- }
|
|
-cont:
|
|
- offset = cache_get_offset(base,
|
|
- offset, start, &me->multi_list, &pos);
|
|
- }
|
|
-
|
|
- return mounted;
|
|
-}
|
|
-
|
|
static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe)
|
|
{
|
|
char *dir, *path;
|
|
@@ -2576,7 +2525,10 @@ static int rmdir_path_offset(struct auto
|
|
return ret;
|
|
}
|
|
|
|
-int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root, const char *base)
|
|
+static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const char *root);
|
|
+
|
|
+static int do_umount_multi_triggers(struct autofs_point *ap,
|
|
+ struct mapent *me, const char *root, const char *base)
|
|
{
|
|
char path[PATH_MAX + 1];
|
|
char *offset;
|
|
@@ -2606,7 +2558,6 @@ int umount_multi_triggers(struct autofs_
|
|
while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
|
|
char key[PATH_MAX + 1];
|
|
int key_len = root_len + strlen(offset);
|
|
- char *oe_base;
|
|
|
|
if (mm_base_len > 1)
|
|
key_len += mm_base_len;
|
|
@@ -2626,47 +2577,116 @@ int umount_multi_triggers(struct autofs_
|
|
if (!oe || (strlen(oe->key) - start) == 1)
|
|
continue;
|
|
|
|
+ left += do_umount_offset(ap, oe, root);
|
|
+ }
|
|
+
|
|
+ return left;
|
|
+}
|
|
+
|
|
+static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const char *root)
|
|
+{
|
|
+ char *oe_base;
|
|
+ int left = 0;
|
|
+
|
|
+ /*
|
|
+ * Check for and umount subtree offsets resulting from
|
|
+ * nonstrict mount fail.
|
|
+ */
|
|
+ oe_base = oe->key + strlen(root);
|
|
+ left += do_umount_multi_triggers(ap, oe, root, oe_base);
|
|
+
|
|
+ if (oe->ioctlfd != -1 ||
|
|
+ is_mounted(oe->key, MNTS_REAL)) {
|
|
+ left++;
|
|
+ return left;
|
|
+ }
|
|
+
|
|
+ debug(ap->logopt, "umount offset %s", oe->key);
|
|
+
|
|
+ if (umount_autofs_offset(ap, oe)) {
|
|
+ warn(ap->logopt, "failed to umount offset");
|
|
+ left++;
|
|
+ } else {
|
|
+ struct stat st;
|
|
+ int ret;
|
|
+
|
|
+ if (!(oe->flags & MOUNT_FLAG_DIR_CREATED))
|
|
+ return left;
|
|
+
|
|
/*
|
|
- * Check for and umount subtree offsets resulting from
|
|
- * nonstrict mount fail.
|
|
+ * An error due to partial directory removal is
|
|
+ * ok so only try and remount the offset if the
|
|
+ * actual mount point still exists.
|
|
*/
|
|
- oe_base = oe->key + strlen(root);
|
|
- left += umount_multi_triggers(ap, oe, root, oe_base);
|
|
+ ret = rmdir_path_offset(ap, oe);
|
|
+ if (ret == -1 && !stat(oe->key, &st)) {
|
|
+ ret = do_mount_autofs_offset(ap, oe, root);
|
|
+ if (ret)
|
|
+ left++;
|
|
+ /* But we did origianlly create this */
|
|
+ oe->flags |= MOUNT_FLAG_DIR_CREATED;
|
|
+ }
|
|
+ }
|
|
+ return left;
|
|
+}
|
|
|
|
- if (oe->ioctlfd != -1 ||
|
|
- is_mounted(oe->key, MNTS_REAL)) {
|
|
- left++;
|
|
- continue;
|
|
+int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
|
|
+ const char *root, unsigned int start, const char *base)
|
|
+{
|
|
+ char path[PATH_MAX + 1];
|
|
+ char *offset = path;
|
|
+ struct mapent *oe;
|
|
+ struct list_head *pos = NULL;
|
|
+ unsigned int root_len = strlen(root);
|
|
+ int mounted;
|
|
+
|
|
+ mounted = 0;
|
|
+ offset = cache_get_offset(base, offset, start, &me->multi_list, &pos);
|
|
+ while (offset) {
|
|
+ char key[PATH_MAX + 1];
|
|
+ int key_len = root_len + strlen(offset);
|
|
+
|
|
+ if (key_len > PATH_MAX) {
|
|
+ warn(ap->logopt, "path loo long");
|
|
+ goto cont;
|
|
}
|
|
|
|
- debug(ap->logopt, "umount offset %s", oe->key);
|
|
+ /* The root offset is always mounted seperately so the
|
|
+ * offset path will always be root + offset.
|
|
+ */
|
|
+ strcpy(key, root);
|
|
+ strcat(key, offset);
|
|
|
|
- if (umount_autofs_offset(ap, oe)) {
|
|
- warn(ap->logopt, "failed to umount offset");
|
|
- left++;
|
|
- } else {
|
|
- struct stat st;
|
|
- int ret;
|
|
+ oe = cache_lookup_distinct(me->mc, key);
|
|
+ if (!oe || !oe->mapent)
|
|
+ goto cont;
|
|
|
|
- if (!(oe->flags & MOUNT_FLAG_DIR_CREATED))
|
|
- continue;
|
|
+ mounted += do_mount_autofs_offset(ap, oe, root);
|
|
|
|
- /*
|
|
- * An error due to partial directory removal is
|
|
- * ok so only try and remount the offset if the
|
|
- * actual mount point still exists.
|
|
- */
|
|
- ret = rmdir_path_offset(ap, oe);
|
|
- if (ret == -1 && !stat(oe->key, &st)) {
|
|
- ret = do_mount_autofs_offset(ap, oe, root);
|
|
- if (ret)
|
|
- left++;
|
|
- /* But we did origianlly create this */
|
|
- oe->flags |= MOUNT_FLAG_DIR_CREATED;
|
|
- }
|
|
+ /*
|
|
+ * If re-constructing a multi-mount it's necessary to walk
|
|
+ * into nested mounts, unlike the usual "mount only what's
|
|
+ * needed as you go" behavior.
|
|
+ */
|
|
+ if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) {
|
|
+ if (oe->ioctlfd != -1 ||
|
|
+ is_mounted(oe->key, MNTS_REAL))
|
|
+ mount_multi_triggers(ap, oe, key, strlen(key), base);
|
|
}
|
|
+cont:
|
|
+ offset = cache_get_offset(base,
|
|
+ offset, start, &me->multi_list, &pos);
|
|
}
|
|
|
|
+ return mounted;
|
|
+}
|
|
+
|
|
+int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root, const char *base)
|
|
+{
|
|
+ int left;
|
|
+
|
|
+ left = do_umount_multi_triggers(ap, me, root, base);
|
|
+
|
|
if (!left && me->multi == me) {
|
|
struct mapent_cache *mc = me->mc;
|
|
int status;
|
|
@@ -2865,4 +2885,3 @@ int clean_stale_multi_triggers(struct au
|
|
|
|
return left;
|
|
}
|
|
-
|