aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/dev.c1
-rw-r--r--kernel/dir.c34
-rw-r--r--kernel/file.c15
-rw-r--r--kernel/fuse_i.h18
4 files changed, 65 insertions, 3 deletions
diff --git a/kernel/dev.c b/kernel/dev.c
index afc9f4c..af20de8 100644
--- a/kernel/dev.c
+++ b/kernel/dev.c
@@ -543,6 +543,7 @@ static struct fuse_conn *new_conn(void)
fc = kmalloc(sizeof(*fc), GFP_KERNEL);
if (fc != NULL) {
+ memset(fc, 0, sizeof(*fc));
fc->sb = NULL;
fc->file = NULL;
fc->flags = 0;
diff --git a/kernel/dir.c b/kernel/dir.c
index 110a472..e941e3e 100644
--- a/kernel/dir.c
+++ b/kernel/dir.c
@@ -783,6 +783,9 @@ static int fuse_setxattr(struct dentry *entry, const char *name,
if (size > FUSE_XATTR_SIZE_MAX)
return -E2BIG;
+ if (fc->no_setxattr)
+ return -EOPNOTSUPP;
+
memset(&inarg, 0, sizeof(inarg));
inarg.size = size;
inarg.flags = flags;
@@ -797,6 +800,10 @@ static int fuse_setxattr(struct dentry *entry, const char *name,
in.args[2].size = size;
in.args[2].value = value;
request_send(fc, &in, &out);
+ if (out.h.error == -ENOSYS) {
+ fc->no_setxattr = 1;
+ return -EOPNOTSUPP;
+ }
return out.h.error;
}
@@ -810,6 +817,9 @@ static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
struct fuse_getxattr_in inarg;
struct fuse_getxattr_out outarg;
+ if (fc->no_getxattr)
+ return -EOPNOTSUPP;
+
memset(&inarg, 0, sizeof(inarg));
inarg.size = size;
@@ -833,8 +843,13 @@ static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
request_send(fc, &in, &out);
if (!out.h.error)
return size ? out.args[0].size : outarg.size;
- else
+ else {
+ if (out.h.error == -ENOSYS) {
+ fc->no_getxattr = 1;
+ return -EOPNOTSUPP;
+ }
return out.h.error;
+ }
}
static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
@@ -846,6 +861,9 @@ static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
struct fuse_getxattr_in inarg;
struct fuse_getxattr_out outarg;
+ if (fc->no_listxattr)
+ return -EOPNOTSUPP;
+
memset(&inarg, 0, sizeof(inarg));
inarg.size = size;
@@ -867,8 +885,13 @@ static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
request_send(fc, &in, &out);
if (!out.h.error)
return size ? out.args[0].size : outarg.size;
- else
+ else {
+ if (out.h.error == -ENOSYS) {
+ fc->no_listxattr = 1;
+ return -EOPNOTSUPP;
+ }
return out.h.error;
+ }
}
static int fuse_removexattr(struct dentry *entry, const char *name)
@@ -878,12 +901,19 @@ static int fuse_removexattr(struct dentry *entry, const char *name)
struct fuse_in in = FUSE_IN_INIT;
struct fuse_out out = FUSE_OUT_INIT;
+ if (fc->no_removexattr)
+ return -EOPNOTSUPP;
+
in.h.opcode = FUSE_REMOVEXATTR;
in.h.ino = inode->i_ino;
in.numargs = 1;
in.args[0].size = strlen(name) + 1;
in.args[0].value = name;
request_send(fc, &in, &out);
+ if (out.h.error == -ENOSYS) {
+ fc->no_removexattr = 1;
+ return -EOPNOTSUPP;
+ }
return out.h.error;
}
diff --git a/kernel/file.c b/kernel/file.c
index c9a44fd..2067bd7 100644
--- a/kernel/file.c
+++ b/kernel/file.c
@@ -99,11 +99,16 @@ static int fuse_flush(struct file *file)
struct fuse_in in = FUSE_IN_INIT;
struct fuse_out out = FUSE_OUT_INIT;
+ if (fc->no_flush)
+ return 0;
+
in.h.opcode = FUSE_FLUSH;
in.h.ino = inode->i_ino;
request_send(fc, &in, &out);
- if (out.h.error == -ENOSYS)
+ if (out.h.error == -ENOSYS) {
+ fc->no_flush = 1;
return 0;
+ }
else
return out.h.error;
}
@@ -116,6 +121,9 @@ static int fuse_fsync(struct file *file, struct dentry *de, int datasync)
struct fuse_out out = FUSE_OUT_INIT;
struct fuse_fsync_in inarg;
+ if (fc->no_fsync)
+ return 0;
+
memset(&inarg, 0, sizeof(inarg));
inarg.datasync = datasync;
@@ -125,6 +133,11 @@ static int fuse_fsync(struct file *file, struct dentry *de, int datasync)
in.args[0].size = sizeof(inarg);
in.args[0].value = &inarg;
request_send(fc, &in, &out);
+
+ if (out.h.error == -ENOSYS) {
+ fc->no_fsync = 1;
+ return 0;
+ }
return out.h.error;
/* FIXME: need to ensure, that all write requests issued
diff --git a/kernel/fuse_i.h b/kernel/fuse_i.h
index 1299139..d5943a9 100644
--- a/kernel/fuse_i.h
+++ b/kernel/fuse_i.h
@@ -96,6 +96,24 @@ struct fuse_conn {
/** The next unique request id */
int reqctr;
+
+ /** Is fsync not implemented by fs? */
+ unsigned int no_fsync : 1;
+
+ /** Is flush not implemented by fs? */
+ unsigned int no_flush : 1;
+
+ /** Is setxattr not implemented by fs? */
+ unsigned int no_setxattr : 1;
+
+ /** Is getxattr not implemented by fs? */
+ unsigned int no_getxattr : 1;
+
+ /** Is listxattr not implemented by fs? */
+ unsigned int no_listxattr : 1;
+
+ /** Is removexattr not implemented by fs? */
+ unsigned int no_removexattr : 1;
};
/** One input argument of a request */