All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <djwong@kernel.org>
To: bernd@bsbernd.com
Cc: neal@gompa.dev, fuse-devel@lists.linux.dev
Subject: Re: [PATCH 3/4] mount_util: share the mtab flag-option builder
Date: Wed, 30 Sep 2026 08:20:58 -0700	[thread overview]
Message-ID: <20260930152058.GP6253@frogsfrogsfrogs> (raw)
In-Reply-To: <20260930-mount-service-use-mount-fsmount-v1-3-d585598896ee@bsbernd.com>

On Wed, Sep 30, 2026 at 03:44:35PM +0200, Bernd Schubert via B4 Relay wrote:
> From: Bernd Schubert <bernd@bsbernd.com>
> 
> The loop over mount_flags[] that builds the rw/nosuid/nodev mirrors of
> an mtab record existed twice, in lib/mount.c and util/fusermount.c;
> both feed the same record, so a change to one silently diverges.
> fusermount3 does not link libfuse and cannot call fuse_opt_add_opt(),
> so fuse_mnt_add_opt() moves to lib/mount_util.c next to mount_flags[].
> 
> fuse_mnt_add_opt() now has one realloc and one snprintf, because
> realloc(NULL) is the malloc. The empty-list path reserves expand as
> well, which strdup could not do. No caller pairs an empty list with a
> non-zero expand, so nothing changes today.
> 
> Signed-off-by: Bernd Schubert <bernd@bsbernd.com>

This looks like a pretty simple refactoring to hoist common code so
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>

--D

> ---
>  lib/mount.c         | 21 +--------------------
>  lib/mount_fsmount.c | 12 ++----------
>  lib/mount_util.c    | 33 +++++++++++++++++++++++++++++++++
>  lib/mount_util.h    | 20 ++++++++++++++++++++
>  util/fusermount.c   | 33 +++------------------------------
>  5 files changed, 59 insertions(+), 60 deletions(-)
> 
> diff --git a/lib/mount.c b/lib/mount.c
> index a6dd5013ea80..4d03ef4b848f 100644
> --- a/lib/mount.c
> +++ b/lib/mount.c
> @@ -995,25 +995,6 @@ static int fuse_mount_sys(const char *mnt, struct mount_opts *mo,
>  	return fd;
>  }
>  
> -/*
> - * Append the flag-mirror prefix (rw/nosuid/nodev/...) of the mtab record
> - * to @mtab_optsp, derived from the MS_* bitmask in @flags.
> - */
> -static int get_mtab_flag_opts(char **mtab_optsp, int flags)
> -{
> -	int i;
> -
> -	if (!(flags & MS_RDONLY) && fuse_opt_add_opt(mtab_optsp, "rw") == -1)
> -		return -1;
> -
> -	for (i = 0; mount_flags[i].opt != NULL; i++) {
> -		if (mount_flags[i].on && (flags & mount_flags[i].flag) &&
> -		    fuse_opt_add_opt(mtab_optsp, mount_flags[i].opt) == -1)
> -			return -1;
> -	}
> -	return 0;
> -}
> -
>  struct mount_opts *parse_mount_opts(struct fuse_args *args)
>  {
>  	struct mount_opts *mo;
> @@ -1057,7 +1038,7 @@ void destroy_mount_opts(struct mount_opts *mo)
>  int fuse_kern_mount_get_base_mtab_opts(const struct mount_opts *mo,
>  				       char **mtab_optsp)
>  {
> -	if (get_mtab_flag_opts(mtab_optsp, mo->flags) == -1)
> +	if (fuse_mnt_get_mtab_flag_opts(mtab_optsp, mo->flags) == -1)
>  		return -1;
>  	if (mo->kernel_opts && fuse_opt_add_opt(mtab_optsp, mo->kernel_opts) == -1)
>  		return -1;
> diff --git a/lib/mount_fsmount.c b/lib/mount_fsmount.c
> index 0b1fd4300d2d..730071206fc7 100644
> --- a/lib/mount_fsmount.c
> +++ b/lib/mount_fsmount.c
> @@ -446,16 +446,8 @@ int apply_fsconfig_mount_opts(int fsfd, const char *opts)
>  			continue;
>  		/*
>  		 * Skip mount attributes, they're handled by fsmount()
> -		 * not fsconfig().
> -		 *
> -		 * These string options (nosuid, nodev, etc.) are reconstructed
> -		 * from MS_* flags by get_mtab_flag_opts() in lib/mount.c and
> -		 * get_mtab_opts() in util/fusermount.c. Both the library path
> -		 * (via fuse_kern_mount_get_base_mtab_opts) and fusermount3 path
> -		 * rebuild these strings from the flags bitmask and pass them in
> -		 * mtab_opts. They must be filtered here because they are mount
> -		 * attributes (passed to fsmount via MOUNT_ATTR_*), not
> -		 * filesystem parameters (which would be passed to fsconfig).
> +		 * not fsconfig(). Callers rebuild them as strings from the
> +		 * MS_* bitmask for the mtab record, so they do show up here.
>  		 *
>  		 * Also skip mtab-only options - they're for /run/mount/utab, not kernel
>  		 */
> diff --git a/lib/mount_util.c b/lib/mount_util.c
> index 2f763fe1218e..72ed17c93f47 100644
> --- a/lib/mount_util.c
> +++ b/lib/mount_util.c
> @@ -140,6 +140,39 @@ const struct mount_flags mount_flags[] = {
>  {NULL,           0,                0,  0,    0,        0}
>  };
>  
> +int fuse_mnt_add_opt(char **optsp, const char *opt, unsigned int expand)
> +{
> +	/* an empty list gets no separator, and realloc(NULL) is the malloc */
> +	const char *sep = *optsp ? "," : "";
> +	size_t oldsize = *optsp ? strlen(*optsp) : 0;
> +	size_t newsize = oldsize + strlen(sep) + strlen(opt) + expand + 1;
> +	char *newopts = (char *) realloc(*optsp, newsize);
> +
> +	if (newopts == NULL) {
> +		fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate memory\n");
> +		return -1;
> +	}
> +
> +	snprintf(newopts + oldsize, newsize - oldsize, "%s%s", sep, opt);
> +	*optsp = newopts;
> +	return 0;
> +}
> +
> +int fuse_mnt_get_mtab_flag_opts(char **mtab_optsp, int flags)
> +{
> +	int i;
> +
> +	if (!(flags & MS_RDONLY) && fuse_mnt_add_opt(mtab_optsp, "rw", 0) == -1)
> +		return -1;
> +
> +	for (i = 0; mount_flags[i].opt != NULL; i++) {
> +		if (mount_flags[i].on && (flags & mount_flags[i].flag) &&
> +		    fuse_mnt_add_opt(mtab_optsp, mount_flags[i].opt, 0) == -1)
> +			return -1;
> +	}
> +	return 0;
> +}
> +
>  #ifdef IGNORE_MTAB
>  #define mtab_needs_update(mnt) 0
>  #else
> diff --git a/lib/mount_util.h b/lib/mount_util.h
> index b20a428d99c7..4485d8a29f93 100644
> --- a/lib/mount_util.h
> +++ b/lib/mount_util.h
> @@ -24,6 +24,26 @@ struct mount_flags {
>  };
>  extern const struct mount_flags mount_flags[];
>  
> +/**
> + * @brief Append @opt to the comma-separated option list @optsp.
> + *
> + * @param[in,out] optsp   list to extend, NULL for an empty list.
> + * @param[in]     opt     option to append.
> + * @param[in]     expand  extra bytes to reserve for a value the caller
> + *                        appends itself.
> + * @return 0 on success, -1 on failure.
> + */
> +int fuse_mnt_add_opt(char **optsp, const char *opt, unsigned int expand);
> +
> +/**
> + * @brief Append the flag-mirror part of an mtab record (rw/nosuid/nodev/...).
> + *
> + * @param[in,out] mtab_optsp  option list to extend.
> + * @param[in]     flags       MS_* bitmask the mirrors are derived from.
> + * @return 0 on success, -1 on failure.
> + */
> +int fuse_mnt_get_mtab_flag_opts(char **mtab_optsp, int flags);
> +
>  int fuse_mnt_add_mount(const char *progname, const char *fsname,
>  		       const char *mnt, const char *type, const char *opts);
>  int fuse_mnt_remove_mount(const char *progname, const char *mnt);
> diff --git a/util/fusermount.c b/util/fusermount.c
> index 3031b282a7a6..c7de86f4b12e 100644
> --- a/util/fusermount.c
> +++ b/util/fusermount.c
> @@ -556,26 +556,6 @@ static int find_mount_flag(const char *s, unsigned len, int *on, int *flag)
>  	return 0;
>  }
>  
> -static int add_option(char **optsp, const char *opt, unsigned expand)
> -{
> -	char *newopts;
> -	if (*optsp == NULL)
> -		newopts = strdup(opt);
> -	else {
> -		unsigned oldsize = strlen(*optsp);
> -		unsigned newsize = oldsize + 1 + strlen(opt) + expand + 1;
> -		newopts = (char *) realloc(*optsp, newsize);
> -		if (newopts)
> -			sprintf(newopts + oldsize, ",%s", opt);
> -	}
> -	if (newopts == NULL) {
> -		fprintf(stderr, "%s: failed to allocate memory\n", progname);
> -		return -1;
> -	}
> -	*optsp = newopts;
> -	return 0;
> -}
> -
>  /*
>   * Build the mtab/utab record string for this mount: flag-mirrors of MS_*
>   * (rw/nosuid/nodev/...) + the kernel-bound -o options + "user=<n>" when
> @@ -585,19 +565,12 @@ static int add_option(char **optsp, const char *opt, unsigned expand)
>   */
>  static int get_mtab_opts(int flags, const char *opts, char **mtab_optsp)
>  {
> -	int i;
>  	int l;
>  
> -	if (!(flags & MS_RDONLY) && add_option(mtab_optsp, "rw", 0) == -1)
> +	if (fuse_mnt_get_mtab_flag_opts(mtab_optsp, flags) == -1)
>  		return -1;
>  
> -	for (i = 0; mount_flags[i].opt != NULL; i++) {
> -		if (mount_flags[i].on && (flags & mount_flags[i].flag) &&
> -		    add_option(mtab_optsp, mount_flags[i].opt, 0) == -1)
> -			return -1;
> -	}
> -
> -	if (add_option(mtab_optsp, opts, 0) == -1)
> +	if (fuse_mnt_add_opt(mtab_optsp, opts, 0) == -1)
>  		return -1;
>  	/* remove comma from end of opts*/
>  	l = strlen(*mtab_optsp);
> @@ -608,7 +581,7 @@ static int get_mtab_opts(int flags, const char *opts, char **mtab_optsp)
>  		if (user == NULL)
>  			return -1;
>  
> -		if (add_option(mtab_optsp, "user=", strlen(user)) == -1)
> +		if (fuse_mnt_add_opt(mtab_optsp, "user=", strlen(user)) == -1)
>  			return -1;
>  		strcat(*mtab_optsp, user);
>  	}
> 
> -- 
> 2.53.0
> 
> 
> 

  reply	other threads:[~2026-09-30 15:21 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-30 13:44 [PATCH 0/4] libfuse: Avoid mount API code dup between mount-service and libfuse Bernd Schubert
2026-09-30 13:44 ` Bernd Schubert via B4 Relay
2026-09-30 13:44 ` [PATCH 1/4] mount_fsmount: split superblock creation and move_mount into a helper Bernd Schubert
2026-09-30 13:44   ` Bernd Schubert via B4 Relay
2026-09-30 15:13   ` Darrick J. Wong
2026-09-30 13:44 ` [PATCH 2/4] mount_service: mount via the shared fsmount helper Bernd Schubert
2026-09-30 13:44   ` Bernd Schubert via B4 Relay
2026-09-30 15:16   ` Darrick J. Wong
2026-09-30 13:44 ` [PATCH 3/4] mount_util: share the mtab flag-option builder Bernd Schubert
2026-09-30 13:44   ` Bernd Schubert via B4 Relay
2026-09-30 15:20   ` Darrick J. Wong [this message]
2026-09-30 13:44 ` [PATCH 4/4] mount/fuse_service: share the service socket helpers Bernd Schubert
2026-09-30 13:44   ` Bernd Schubert via B4 Relay
2026-09-30 15:23   ` Darrick J. Wong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260930152058.GP6253@frogsfrogsfrogs \
    --to=djwong@kernel.org \
    --cc=bernd@bsbernd.com \
    --cc=fuse-devel@lists.linux.dev \
    --cc=neal@gompa.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.