[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