autofs-5.1.7 - refactor umount_multi_triggers() From: Ian Kent Refactor umount_multi_triggers() to try the umount of an offset subtree in a seperate function. Signed-off-by: Ian Kent --- CHANGELOG | 1 lib/mounts.c | 187 ++++++++++++++++++++++++++++++++-------------------------- 2 files changed, 104 insertions(+), 84 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 3eda995c..5a3bedc1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -11,6 +11,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(). 25/01/2021 autofs-5.1.7 - make bind mounts propagation slave by default. diff --git a/lib/mounts.c b/lib/mounts.c index 8e88182f..5268ba5b 100644 --- a/lib/mounts.c +++ b/lib/mounts.c @@ -2496,57 +2496,6 @@ static int do_mount_autofs_offset(struct autofs_point *ap, 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; @@ -2582,7 +2531,10 @@ static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe) 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; @@ -2612,7 +2564,6 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root 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; @@ -2632,47 +2583,116 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root 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; @@ -2871,4 +2891,3 @@ int clean_stale_multi_triggers(struct autofs_point *ap, return left; } -