diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/dev.c | 1 | ||||
-rw-r--r-- | kernel/dir.c | 34 | ||||
-rw-r--r-- | kernel/file.c | 15 | ||||
-rw-r--r-- | kernel/fuse_i.h | 18 |
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 */ |