[prev in list] [next in list] [prev in thread] [next in thread]
List: fuse-devel
Subject: [fuse-devel] [PATCH] libfuse: allow umask processing in userspace
From: Miklos Szeredi <miklos () szeredi ! hu>
Date: 2009-06-23 10:23:56
Message-ID: E1MJ3AS-00077O-8Y () pomaz-ex ! szeredi ! hu
[Download RAW message or body]
This patch against fuse-2.8.0-pre3 lets filesystems handle masking the
file mode on creation.
fuse_ctx (lowlevel API) and fuse_context (high level API) are extended
with a 'umask' field. If the kernel doesn't send the umask, it is set
to zero.
Introduce a new feature flag FUSE_CAP_DONT_MASK, if the kernel
supports this feature, then this flag will be set in conn->capable in
the ->init() method. If the filesystem sets this flag in in
conn->want, then the create modes will not be masked.
Testing is welcome.
Thanks,
Miklos
---
include/fuse.h | 3 +++
include/fuse_common.h | 2 ++
include/fuse_kernel.h | 20 ++++++++++++++++++--
include/fuse_lowlevel.h | 3 +++
lib/fuse_lowlevel.c | 38 +++++++++++++++++++++++++++++++++++---
lib/fuse_versionscript | 4 ++--
6 files changed, 63 insertions(+), 7 deletions(-)
Index: fuse/include/fuse_lowlevel.h
===================================================================
--- fuse.orig/include/fuse_lowlevel.h 2009-06-23 09:57:22.000000000 +0200
+++ fuse/include/fuse_lowlevel.h 2009-06-23 09:58:14.000000000 +0200
@@ -109,6 +109,9 @@ struct fuse_ctx {
/** Thread ID of the calling process */
pid_t pid;
+
+ /** Umask of the calling process (introduced in version 2.8) */
+ mode_t umask;
};
/* 'to_set' flags in setattr */
Index: fuse/lib/fuse_lowlevel.c
===================================================================
--- fuse.orig/lib/fuse_lowlevel.c 2009-06-23 09:57:22.000000000 +0200
+++ fuse/lib/fuse_lowlevel.c 2009-06-23 10:07:21.000000000 +0200
@@ -606,9 +606,15 @@ static void do_readlink(fuse_req_t req,
static void do_mknod(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
struct fuse_mknod_in *arg = (struct fuse_mknod_in *) inarg;
+ char *name = PARAM(arg);
+
+ if (req->f->conn.proto_minor >= 12)
+ req->ctx.umask = arg->umask;
+ else
+ name = (char *) inarg + FUSE_COMPAT_MKNOD_IN_SIZE;
if (req->f->op.mknod)
- req->f->op.mknod(req, nodeid, PARAM(arg), arg->mode, arg->rdev);
+ req->f->op.mknod(req, nodeid, name, arg->mode, arg->rdev);
else
fuse_reply_err(req, ENOSYS);
}
@@ -617,6 +623,9 @@ static void do_mkdir(fuse_req_t req, fus
{
struct fuse_mkdir_in *arg = (struct fuse_mkdir_in *) inarg;
+ if (req->f->conn.proto_minor >= 12)
+ req->ctx.umask = arg->umask;
+
if (req->f->op.mkdir)
req->f->op.mkdir(req, nodeid, PARAM(arg), arg->mode);
else
@@ -678,15 +687,21 @@ static void do_link(fuse_req_t req, fuse
static void do_create(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_open_in *arg = (struct fuse_open_in *) inarg;
+ struct fuse_create_in *arg = (struct fuse_create_in *) inarg;
if (req->f->op.create) {
struct fuse_file_info fi;
+ char *name = PARAM(arg);
memset(&fi, 0, sizeof(fi));
fi.flags = arg->flags;
- req->f->op.create(req, nodeid, PARAM(arg), arg->mode, &fi);
+ if (req->f->conn.proto_minor >= 12)
+ req->ctx.umask = arg->umask;
+ else
+ name = (char *) inarg + sizeof(struct fuse_open_in);
+
+ req->f->op.create(req, nodeid, name, arg->mode, &fi);
} else
fuse_reply_err(req, ENOSYS);
}
@@ -1168,6 +1183,8 @@ static void do_init(fuse_req_t req, fuse
f->conn.capable |= FUSE_CAP_EXPORT_SUPPORT;
if (arg->flags & FUSE_BIG_WRITES)
f->conn.capable |= FUSE_CAP_BIG_WRITES;
+ if (arg->flags & FUSE_DONT_MASK)
+ f->conn.capable |= FUSE_CAP_DONT_MASK;
} else {
f->conn.async_read = 0;
f->conn.max_readahead = 0;
@@ -1207,6 +1224,8 @@ static void do_init(fuse_req_t req, fuse
outarg.flags |= FUSE_EXPORT_SUPPORT;
if (f->conn.want & FUSE_CAP_BIG_WRITES)
outarg.flags |= FUSE_BIG_WRITES;
+ if (f->conn.want & FUSE_CAP_DONT_MASK)
+ outarg.flags |= FUSE_DONT_MASK;
outarg.max_readahead = f->conn.max_readahead;
outarg.max_write = f->conn.max_write;
@@ -1280,6 +1299,19 @@ const struct fuse_ctx *fuse_req_ctx(fuse
return &req->ctx;
}
+/*
+ * The size of fuse_ctx got extended, so need to be careful about
+ * incompatibility (i.e. a new binary cannot work with an old
+ * library).
+ */
+const struct fuse_ctx *fuse_req_ctx_compat24(fuse_req_t req);
+const struct fuse_ctx *fuse_req_ctx_compat24(fuse_req_t req)
+{
+ return fuse_req_ctx(req);
+}
+FUSE_SYMVER(".symver fuse_req_ctx_compat24,fuse_req_ctx@FUSE_2.4");
+
+
void fuse_req_interrupt_func(fuse_req_t req, fuse_interrupt_func_t func,
void *data)
{
Index: fuse/lib/fuse_versionscript
===================================================================
--- fuse.orig/lib/fuse_versionscript 2009-06-23 09:57:22.000000000 +0200
+++ fuse/lib/fuse_versionscript 2009-06-23 09:58:14.000000000 +0200
@@ -3,7 +3,6 @@ FUSE_2.2 {
fuse_destroy;
fuse_exit;
fuse_exited;
- fuse_get_context;
fuse_invalidate;
fuse_is_lib_option;
fuse_loop;
@@ -43,7 +42,6 @@ FUSE_2.4 {
fuse_reply_readlink;
fuse_reply_write;
fuse_reply_xattr;
- fuse_req_ctx;
fuse_req_userdata;
fuse_session_add_chan;
fuse_session_destroy;
@@ -176,6 +174,8 @@ FUSE_2.8 {
fuse_reply_poll;
fuse_req_getgroups;
fuse_getgroups;
+ fuse_req_ctx;
+ fuse_get_context;
local:
*;
Index: fuse/include/fuse.h
===================================================================
--- fuse.orig/include/fuse.h 2009-06-23 09:57:22.000000000 +0200
+++ fuse/include/fuse.h 2009-06-23 09:58:14.000000000 +0200
@@ -518,6 +518,9 @@ struct fuse_context {
/** Private filesystem data */
void *private_data;
+
+ /** Umask of the calling process (introduced in version 2.8) */
+ mode_t umask;
};
/**
Index: fuse/include/fuse_common.h
===================================================================
--- fuse.orig/include/fuse_common.h 2009-06-23 09:57:22.000000000 +0200
+++ fuse/include/fuse_common.h 2009-06-23 09:58:14.000000000 +0200
@@ -88,12 +88,14 @@ struct fuse_file_info {
* FUSE_CAP_ATOMIC_O_TRUNC: filesystem handles the O_TRUNC open flag
* FUSE_CAP_EXPORT_SUPPORT: filesystem handles lookups of "." and ".."
* FUSE_CAP_BIG_WRITES: filesystem can handle write size larger than 4kB
+ * FUSE_CAP_DONT_MASK: don't apply umask to file mode on create operations
*/
#define FUSE_CAP_ASYNC_READ (1 << 0)
#define FUSE_CAP_POSIX_LOCKS (1 << 1)
#define FUSE_CAP_ATOMIC_O_TRUNC (1 << 3)
#define FUSE_CAP_EXPORT_SUPPORT (1 << 4)
#define FUSE_CAP_BIG_WRITES (1 << 5)
+#define FUSE_CAP_DONT_MASK (1 << 6)
/**
* Ioctl flags
Index: fuse/include/fuse_kernel.h
===================================================================
--- fuse.orig/include/fuse_kernel.h 2009-06-23 09:57:22.000000000 +0200
+++ fuse/include/fuse_kernel.h 2009-06-23 10:06:10.000000000 +0200
@@ -51,6 +51,9 @@
* - add IOCTL message
* - add unsolicited notification support
* - add POLL message and NOTIFY_POLL notification
+ *
+ * 7.12
+ * - add umask flag to input argument of open, mknod and mkdir
*/
#ifndef _LINUX_FUSE_H
@@ -65,7 +68,7 @@
#define FUSE_KERNEL_VERSION 7
/** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 11
+#define FUSE_KERNEL_MINOR_VERSION 12
/** The node ID of the root inode */
#define FUSE_ROOT_ID 1
@@ -141,6 +144,7 @@ struct fuse_file_lock {
* INIT request/reply flags
*
* FUSE_EXPORT_SUPPORT: filesystem handles lookups of "." and ".."
+ * FUSE_DONT_MASK: don't apply umask to file mode on create operations
*/
#define FUSE_ASYNC_READ (1 << 0)
#define FUSE_POSIX_LOCKS (1 << 1)
@@ -148,6 +152,7 @@ struct fuse_file_lock {
#define FUSE_ATOMIC_O_TRUNC (1 << 3)
#define FUSE_EXPORT_SUPPORT (1 << 4)
#define FUSE_BIG_WRITES (1 << 5)
+#define FUSE_DONT_MASK (1 << 6)
/**
* CUSE INIT request/reply flags
@@ -291,14 +296,18 @@ struct fuse_attr_out {
struct fuse_attr attr;
};
+#define FUSE_COMPAT_MKNOD_IN_SIZE 8
+
struct fuse_mknod_in {
__u32 mode;
__u32 rdev;
+ __u32 umask;
+ __u32 padding;
};
struct fuse_mkdir_in {
__u32 mode;
- __u32 padding;
+ __u32 umask;
};
struct fuse_rename_in {
@@ -330,7 +339,14 @@ struct fuse_setattr_in {
struct fuse_open_in {
__u32 flags;
+ __u32 unused;
+};
+
+struct fuse_create_in {
+ __u32 flags;
__u32 mode;
+ __u32 umask;
+ __u32 padding;
};
struct fuse_open_out {
------------------------------------------------------------------------------
Are you an open source citizen? Join us for the Open Source Bridge conference!
Portland, OR, June 17-19. Two days of sessions, one day of unconference: $250.
Need another reason to go? 24-hour hacker lounge. Register today!
http://ad.doubleclick.net/clk;215844324;13503038;v?http://opensourcebridge.org
_______________________________________________
fuse-devel mailing list
fuse-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/fuse-devel
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic