[Cluster-devel] [PATCH RHEL6] mount.gfs2: Fix mounting of regular files with -o loop
Andrew Price
anprice at redhat.com
Wed Aug 17 16:25:35 UTC 2011
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];
--
1.7.1
More information about the Cluster-devel
mailing list