summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--contrib/fuse-include/fuse-mount.h3
-rw-r--r--contrib/fuse-lib/mount-gluster-compat.h42
-rw-r--r--contrib/fuse-lib/mount.c119
-rw-r--r--contrib/macfuse/mount_darwin.c3
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c9
5 files changed, 151 insertions, 25 deletions
diff --git a/contrib/fuse-include/fuse-mount.h b/contrib/fuse-include/fuse-mount.h
index 9358ac810e1..7a3756d92b8 100644
--- a/contrib/fuse-include/fuse-mount.h
+++ b/contrib/fuse-include/fuse-mount.h
@@ -8,6 +8,5 @@
*/
void gf_fuse_unmount (const char *mountpoint, int fd);
-int gf_fuse_mount (const char *mountpoint, char *fsname,
- unsigned long mountflags, char *mnt_param,
+int gf_fuse_mount (const char *mountpoint, char *fsname, char *mnt_param,
pid_t *mtab_pid, int status_fd);
diff --git a/contrib/fuse-lib/mount-gluster-compat.h b/contrib/fuse-lib/mount-gluster-compat.h
index 562f089dd1f..a16103e0fbb 100644
--- a/contrib/fuse-lib/mount-gluster-compat.h
+++ b/contrib/fuse-lib/mount-gluster-compat.h
@@ -30,17 +30,59 @@
#include <sys/wait.h>
#include <sys/mount.h>
+#ifdef GF_LINUX_HOST_OS
+typedef unsigned long mount_flag_t;
+#endif
+
#if defined(__NetBSD__)
#include <perfuse.h>
#define umount2(dir, flags) unmount(dir, ((flags) != 0) ? MNT_FORCE : 0)
#define MS_RDONLY MNT_RDONLY
+#define MS_NOSUID MNT_NOSUID
+#define MS_NODEV MNT_NODEV
+#define MS_NOATIME MNT_NOATIME
+#define MS_NOEXEC MNT_NOEXEC
+typedef int mount_flag_t;
#endif
#if defined(GF_DARWIN_HOST_OS) || defined(__FreeBSD__)
#include <sys/param.h>
#include <sys/mount.h>
#define umount2(dir, flags) unmount(dir, ((flags) != 0) ? MNT_FORCE : 0)
+#endif
+
+#if defined(__FreeBSD__)
#define MS_RDONLY MNT_RDONLY
+#define MS_NOSUID MNT_NOSUID
+/* "nodev"/MNT_NODEV was removed from FreBSD, as it became unneeded because "As
+ * of FreeBSD 6.0 device nodes may be created in regular file systems but such
+ * nodes cannot be used to access devices." (See
+ * https://freebsd.org/cgi/man.cgi?query=mknod&sektion=8 .
+ * Also see:
+ * - https://github.com/freebsd/freebsd/commit/266790a
+ * - https://github.com/freebsd/freebsd/commit/a5e716d
+ * - 700008 in
+ * https://www.freebsd.org/doc/en/books/porters-handbook/versions-7.html .)
+ */
+#if __FreeBSD_version < 700008
+#define MS_NODEV MNT_NODEV
+#else
+#define MS_NODEV 0
+#endif
+#define MS_NOATIME MNT_NOATIME
+#define MS_NOEXEC MNT_NOEXEC
+#if __FreeBSD_version < 1000715
+typedef int mount_flag_t;
+#else
+/* __FreeBSD_version was not bumped for this type change. Anyway, see
+ * https://github.com/freebsd/freebsd/commit/e8d76f8
+ * and respective __FreeBSD_version:
+ * https://github.com/freebsd/freebsd/blob/e8d76f8/sys/sys/param.h#L61 .
+ * We use the subsequent value, 1000715, to switch. (Also see:
+ * https://www.freebsd.org/doc/en/books/porters-handbook/versions-10.html .)
+ */
+typedef long long mount_flag_t;
+#endif
#endif
#ifdef GF_LINUX_HOST_OS
diff --git a/contrib/fuse-lib/mount.c b/contrib/fuse-lib/mount.c
index bfe28d3a26a..1dfd2a71c05 100644
--- a/contrib/fuse-lib/mount.c
+++ b/contrib/fuse-lib/mount.c
@@ -106,8 +106,7 @@ escape (char *s)
static int
fuse_mount_fusermount (const char *mountpoint, char *fsname,
- unsigned long mountflags, char *mnt_param,
- int fd)
+ char *mnt_param, int fd)
{
int pid = -1;
int res = 0;
@@ -130,8 +129,7 @@ fuse_mount_fusermount (const char *mountpoint, char *fsname,
return -1;
}
ret = asprintf (&fm_mnt_params,
- "%s%s,fsname=%s,nonempty,subtype=glusterfs",
- (mountflags & MS_RDONLY) ? "ro," : "",
+ "%s,fsname=%s,nonempty,subtype=glusterfs",
mnt_param, efsname);
FREE (efsname);
if (ret == -1) {
@@ -224,19 +222,112 @@ build_iovec_argf(struct iovec **iov, int *iovlen, const char *name,
}
#endif /* __FreeBSD__ */
+struct mount_flags {
+ const char *opt;
+ mount_flag_t flag;
+ int on;
+} mount_flags[] = {
+ /* We provide best effort cross platform support for mount flags by
+ * defining the ones which are commonly used in Unix-like OS-es.
+ */
+ {"ro", MS_RDONLY, 1},
+ {"nosuid", MS_NOSUID, 1},
+ {"nodev", MS_NODEV, 1},
+ {"noatime", MS_NOATIME, 1},
+ {"noexec", MS_NOEXEC, 1},
+#ifdef GF_LINUX_HOST_OS
+ {"rw", MS_RDONLY, 0},
+ {"suid", MS_NOSUID, 0},
+ {"dev", MS_NODEV, 0},
+ {"exec", MS_NOEXEC, 0},
+ {"async", MS_SYNCHRONOUS, 0},
+ {"sync", MS_SYNCHRONOUS, 1},
+ {"atime", MS_NOATIME, 0},
+ {"dirsync", MS_DIRSYNC, 1},
+#endif
+ {NULL, 0, 0}
+};
+
+static int
+mount_param_to_flag (char *mnt_param, mount_flag_t *mntflags,
+ char **mnt_param_new)
+{
+ int i = 0;
+ int j = 0;
+ char *p = NULL;
+ gf_boolean_t found = _gf_false;
+ struct mount_flags *flag = NULL;
+
+ /* Allocate a buffer that will hold the mount parameters remaining
+ * after the ones corresponding to mount flags are processed and
+ * removed.The length of the original params are a good upper bound
+ * of the size needed.
+ */
+ *mnt_param_new = CALLOC (1, strlen (mnt_param) + 1);
+ if (!*mnt_param_new)
+ return -1;
+ p = *mnt_param_new;
+
+ while (mnt_param[j]) {
+ if (j > 0)
+ i = j+1;
+ j = i;
+
+ /* Seek the delimiters. */
+ while (mnt_param[j] != ',' && mnt_param[j] != '\0')
+ j++;
+
+ found = _gf_false;
+ for (flag = mount_flags; flag->opt; flag++) {
+ /* Compare the mount flag name to the param
+ * name at hand (from i to j in mnt_param).
+ */
+ if (strlen (flag->opt) == j - i &&
+ memcmp (flag->opt, mnt_param + i, j - i) == 0) {
+ /* If there is a match, adjust mntflags
+ * accordingly and break.
+ */
+ if (flag->on) {
+ *mntflags |= flag->flag;
+ } else {
+ *mntflags &= ~flag->flag;
+ }
+ found = _gf_true;
+ break;
+ }
+ }
+ /* If the param did't match any flag name, retain it (ie. copy
+ * over to the new param buffer).
+ */
+ if (!found) {
+ if (p != *mnt_param_new)
+ *p++ = ',';
+ memcpy (p, mnt_param + i, j - i);
+ p += j - i;
+ }
+ }
+
+ return 0;
+}
+
static int
fuse_mount_sys (const char *mountpoint, char *fsname,
- unsigned long mountflags, char *mnt_param, int fd)
+ char *mnt_param, int fd)
{
int ret = -1;
unsigned mounted = 0;
char *mnt_param_mnt = NULL;
char *fstype = "fuse.glusterfs";
char *source = fsname;
-
- ret = asprintf (&mnt_param_mnt,
- "%s,fd=%i,rootmode=%o,user_id=%i,group_id=%i",
- mnt_param, fd, S_IFDIR, getuid (), getgid ());
+ mount_flag_t mountflags = 0;
+ char *mnt_param_new = NULL;
+
+ ret = mount_param_to_flag (mnt_param, &mountflags, &mnt_param_new);
+ if (ret == 0)
+ ret = asprintf (&mnt_param_mnt,
+ "%s,fd=%i,rootmode=%o,user_id=%i,group_id=%i",
+ mnt_param_new, fd, S_IFDIR, getuid (),
+ getgid ());
if (ret == -1) {
GFFUSE_LOGERR ("Out of memory");
@@ -295,7 +386,7 @@ fuse_mount_sys (const char *mountpoint, char *fsname,
ret = asprintf (&mnt_param_mtab, "%s%s",
mountflags & MS_RDONLY ? "ro," : "",
- mnt_param);
+ mnt_param_new);
if (ret == -1)
GFFUSE_LOGERR ("Out of memory");
else {
@@ -320,6 +411,7 @@ out:
umount2 (mountpoint, 2); /* lazy umount */
}
FREE (mnt_param_mnt);
+ FREE (mnt_param_new);
if (source != fsname)
FREE (source);
@@ -328,8 +420,7 @@ out:
int
gf_fuse_mount (const char *mountpoint, char *fsname,
- unsigned long mountflags, char *mnt_param,
- pid_t *mnt_pid, int status_fd)
+ char *mnt_param, pid_t *mnt_pid, int status_fd)
{
int fd = -1;
pid_t pid = -1;
@@ -356,8 +447,7 @@ gf_fuse_mount (const char *mountpoint, char *fsname,
exit (pid == -1 ? 1 : 0);
}
- ret = fuse_mount_sys (mountpoint, fsname, mountflags, mnt_param,
- fd);
+ ret = fuse_mount_sys (mountpoint, fsname, mnt_param, fd);
if (ret == -1) {
gf_log ("glusterfs-fuse", GF_LOG_INFO,
"direct mount failed (%s) errno %d",
@@ -368,7 +458,6 @@ gf_fuse_mount (const char *mountpoint, char *fsname,
"retry to mount via fusermount");
ret = fuse_mount_fusermount (mountpoint, fsname,
- mountflags,
mnt_param, fd);
}
}
diff --git a/contrib/macfuse/mount_darwin.c b/contrib/macfuse/mount_darwin.c
index 10eff204bc6..f4ecacad86a 100644
--- a/contrib/macfuse/mount_darwin.c
+++ b/contrib/macfuse/mount_darwin.c
@@ -42,8 +42,7 @@
gf_log ("glusterfs-fuse", GF_LOG_ERROR, ## __VA_ARGS__)
int
-gf_fuse_mount (const char *mountpoint, char *fsname,
- unsigned long mountflags, char *mnt_param,
+gf_fuse_mount (const char *mountpoint, char *fsname, char *mnt_param,
pid_t *mnt_pid, int status_fd) /* Not used on OS X */
{
int fd = 0;
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index 6e5cd63a818..7056b6fd164 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -10,7 +10,6 @@
#include <sys/wait.h>
#include "fuse-bridge.h"
-#include "mount-gluster-compat.h"
#include "glusterfs.h"
#include "byte-order.h"
#include "compat-errno.h"
@@ -5481,7 +5480,6 @@ init (xlator_t *this_xl)
glusterfs_ctx_t *ctx = NULL;
gf_boolean_t sync_to_mount = _gf_false;
gf_boolean_t fopen_keep_cache = _gf_false;
- unsigned long mntflags = 0;
char *mnt_args = NULL;
eh_t *event = NULL;
@@ -5717,10 +5715,9 @@ init (xlator_t *this_xl)
goto cleanup_exit;
}
- if (priv->read_only)
- mntflags |= MS_RDONLY;
- gf_asprintf (&mnt_args, "%s%s%sallow_other,max_read=131072",
+ gf_asprintf (&mnt_args, "%s%s%s%sallow_other,max_read=131072",
priv->acl ? "" : "default_permissions,",
+ priv->read_only ? "ro," : "",
priv->fuse_mountopts ? priv->fuse_mountopts : "",
priv->fuse_mountopts ? "," : "");
if (!mnt_args)
@@ -5732,7 +5729,7 @@ init (xlator_t *this_xl)
goto cleanup_exit;
}
- priv->fd = gf_fuse_mount (priv->mount_point, fsname, mntflags, mnt_args,
+ priv->fd = gf_fuse_mount (priv->mount_point, fsname, mnt_args,
sync_to_mount ? &ctx->mnt_pid : NULL,
priv->status_pipe[1]);
if (priv->fd == -1)