aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/dir.c
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2005-10-26 12:53:25 +0000
committerMiklos Szeredi <miklos@szeredi.hu>2005-10-26 12:53:25 +0000
commitb0b13d1e5499e20382ad74e202160d49e1792ee8 (patch)
tree77c9dbbceda8149929fed4e66411b49a405808cf /kernel/dir.c
parentc4c12ae295ca6f3fb02e12d3bad8f92fee4dfe3f (diff)
downloadlibfuse-b0b13d1e5499e20382ad74e202160d49e1792ee8.tar.gz
add access operation
Diffstat (limited to 'kernel/dir.c')
-rw-r--r--kernel/dir.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/kernel/dir.c b/kernel/dir.c
index 6753636..20a6aae 100644
--- a/kernel/dir.c
+++ b/kernel/dir.c
@@ -482,6 +482,40 @@ static int fuse_revalidate(struct dentry *entry)
return fuse_do_getattr(inode);
}
+#ifdef KERNEL_2_6
+static int fuse_access(struct inode *inode, int mask)
+{
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_req *req;
+ struct fuse_access_in inarg;
+ int err;
+
+ if (fc->no_access)
+ return 0;
+
+ req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ memset(&inarg, 0, sizeof(inarg));
+ inarg.mask = mask;
+ req->in.h.opcode = FUSE_ACCESS;
+ req->in.h.nodeid = get_node_id(inode);
+ req->inode = inode;
+ req->in.numargs = 1;
+ req->in.args[0].size = sizeof(inarg);
+ req->in.args[0].value = &inarg;
+ request_send(fc, req);
+ err = req->out.h.error;
+ fuse_put_request(fc, req);
+ if (err == -ENOSYS) {
+ fc->no_access = 1;
+ err = 0;
+ }
+ return err;
+}
+#endif
+
static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
{
struct fuse_conn *fc = get_fuse_conn(inode);
@@ -525,6 +559,11 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
return -EROFS;
if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO))
return -EACCES;
+
+#ifdef KERNEL_2_6
+ if (nd && (nd->flags & LOOKUP_ACCESS))
+ return fuse_access(inode, mask);
+#endif
return 0;
}
}