[Cluster-devel] [PATCH RHEL6] mount.gfs2: Fix mounting of regular files with -o loop

Steven Whitehouse swhiteho at redhat.com
Wed Aug 17 16:32:59 UTC 2011


Hi,

Looks good to me. Did you test it with -o remount to be sure it does the
right thing for that too?

Steve.

On Wed, 2011-08-17 at 17:25 +0100, Andrew Price wrote:
> When we use -o loop, mount(8) sets up the loop device and passes
> loop=/dev/loopN to mount.gfs2, which currently naively passes this option to
> mount(2). As gfs2 doesn't recognise the loop option, mounting fails with
> EINVAL.
> 
> This patch stops mount.gfs2 from passing loop=/dev/loopN to mount(2) to fix
> this problem and also makes sure this option appears in /etc/mtab so that
> umount(8) can automatically free up the loop device on unmount.
> 
> rhbz#729071
> 
> Signed-off-by: Andrew Price <anprice at redhat.com>
> ---
>  gfs2/mount/util.c |   29 ++++++++++++++++++++++++++---
>  gfs2/mount/util.h |    1 +
>  2 files changed, 27 insertions(+), 3 deletions(-)
> 
> diff --git a/gfs2/mount/util.c b/gfs2/mount/util.c
> index 5a1f999..3884389 100644
> --- a/gfs2/mount/util.c
> +++ b/gfs2/mount/util.c
> @@ -150,6 +150,16 @@ void parse_opts(struct mount_options *mo)
>  			continue;
>  		}
>  
> +		/* mount(8) will have already set up the loop device for us so
> +		   we can safely ignore the loop= option it provides and avoid
> +		   getting an EINVAL from gfs2. However, we still need to make
> +		   sure the option appears in mtab so that umount(8) can
> +		   automatically free up the loop device. */
> +		if (!strncmp("loop", o, 4)) {
> +			strncpy(mo->loopopt, o, PATH_MAX);
> +			continue;
> +		}
> +
>  		if (extra_len + 1 + strlen(o) > PATH_MAX)
>  			die("extra options string is too long\n");
>  
> @@ -261,6 +271,8 @@ void read_proc_mounts(struct mount_options *mo)
>  	char save_opts[PATH_MAX];
>  	char save_device[PATH_MAX];
>  	int found = 0;
> +	int freq = 0;
> +	int passno = 0;
>  	struct stat st_mo_dev, st_mounts_dev;
>  
>  	file = fopen("/proc/mounts", "r");
> @@ -274,8 +286,14 @@ void read_proc_mounts(struct mount_options *mo)
>  	}
>  
>  	while (fgets(line, PATH_MAX, file)) {
> -		if (sscanf(line, "%s %s %s %s", device, path, type, opts) != 4)
> -			continue;
> +		if (mo->loopopt[0] == '\0') {
> +			if (sscanf(line, "%s %s %s %s", device, path, type, opts) != 4)
> +				continue;
> +		} else {
> +			if (sscanf(line, "%s %s %s %s %d %d",
> +			           device, path, type, opts, &freq, &passno) != 6)
> +				continue;
> +		}
>  		if (strcmp(path, mo->dir)) {
>  			if (!strchr(path, '\\'))
>  				continue;
> @@ -301,7 +319,11 @@ void read_proc_mounts(struct mount_options *mo)
>  
>  		strncpy(save_device, device, PATH_MAX);
>  		strncpy(save_opts, opts, PATH_MAX);
> -		strncpy(save_line, line, PATH_MAX);
> +		if (mo->loopopt[0] != '\0')
> +			snprintf(save_line, PATH_MAX, "%s %s %s %s,%s %d %d\n",
> +			         device, path, type, opts, mo->loopopt, freq, passno);
> +		else
> +			strncpy(save_line, line, PATH_MAX);
>  		found = 1;
>  	}
>  
> @@ -318,6 +340,7 @@ void read_proc_mounts(struct mount_options *mo)
>  	log_debug("read_proc_mounts: device = \"%s\"", mo->specified_dev);
>  	log_debug("read_proc_mounts: dm device = \"%s\"", mo->dev);
>  	log_debug("read_proc_mounts: opts = \"%s\"", mo->opts);
> +	log_debug("read_proc_mounts: proc_entry = \"%s\"", mo->proc_entry);
>  }
>  
>  static void gfs2_inum_in(struct gfs2_inum *no, char *buf)
> diff --git a/gfs2/mount/util.h b/gfs2/mount/util.h
> index e866cd4..8b05aa5 100644
> --- a/gfs2/mount/util.h
> +++ b/gfs2/mount/util.h
> @@ -50,6 +50,7 @@ struct mount_options {
>  	char dev[PATH_MAX+1];
>  	char dir[PATH_MAX+1];
>  	char opts[PATH_MAX+1];
> +	char loopopt[PATH_MAX+1];
>  	char hostdata[PATH_MAX+1];
>  	char extra[PATH_MAX+1];
>  	char extra_plus[PATH_MAX+1];





More information about the Cluster-devel mailing list