Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 71221
b: refs/heads/master
c: c79e322
h: refs/heads/master
i:
  71219: d41ef17
v: v3
  • Loading branch information
Miklos Szeredi authored and Linus Torvalds committed Oct 18, 2007
1 parent 180df87 commit 699c365
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 16 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1fb69e7817296da8a6824804bb206ca1e7f31425
refs/heads/master: c79e322f63592c00b25b17af6a1782fad6c6fe6e
37 changes: 25 additions & 12 deletions trunk/fs/fuse/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -705,10 +705,12 @@ static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
stat->blksize = (1 << inode->i_blkbits);
}

static int fuse_do_getattr(struct inode *inode, struct kstat *stat)
static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
struct file *file)
{
int err;
struct fuse_attr_out arg;
struct fuse_getattr_in inarg;
struct fuse_attr_out outarg;
struct fuse_conn *fc = get_fuse_conn(inode);
struct fuse_req *req;
u64 attr_version;
Expand All @@ -721,24 +723,35 @@ static int fuse_do_getattr(struct inode *inode, struct kstat *stat)
attr_version = fc->attr_version;
spin_unlock(&fc->lock);

memset(&inarg, 0, sizeof(inarg));
/* Directories have separate file-handle space */
if (file && S_ISREG(inode->i_mode)) {
struct fuse_file *ff = file->private_data;

inarg.getattr_flags |= FUSE_GETATTR_FH;
inarg.fh = ff->fh;
}
req->in.h.opcode = FUSE_GETATTR;
req->in.h.nodeid = get_node_id(inode);
req->in.numargs = 1;
req->in.args[0].size = sizeof(inarg);
req->in.args[0].value = &inarg;
req->out.numargs = 1;
req->out.args[0].size = sizeof(arg);
req->out.args[0].value = &arg;
req->out.args[0].size = sizeof(outarg);
req->out.args[0].value = &outarg;
request_send(fc, req);
err = req->out.h.error;
fuse_put_request(fc, req);
if (!err) {
if ((inode->i_mode ^ arg.attr.mode) & S_IFMT) {
if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
make_bad_inode(inode);
err = -EIO;
} else {
fuse_change_attributes(inode, &arg.attr,
attr_timeout(&arg),
fuse_change_attributes(inode, &outarg.attr,
attr_timeout(&outarg),
attr_version);
if (stat)
fuse_fillattr(inode, &arg.attr, stat);
fuse_fillattr(inode, &outarg.attr, stat);
}
}
return err;
Expand Down Expand Up @@ -833,7 +846,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
struct fuse_inode *fi = get_fuse_inode(inode);
if (fi->i_time < get_jiffies_64()) {
err = fuse_do_getattr(inode, NULL);
err = fuse_do_getattr(inode, NULL, NULL);
if (err)
return err;

Expand All @@ -848,7 +861,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
attributes. This is also needed, because the root
node will at first have no permissions */
if (err == -EACCES && !refreshed) {
err = fuse_do_getattr(inode, NULL);
err = fuse_do_getattr(inode, NULL, NULL);
if (!err)
err = generic_permission(inode, mask, NULL);
}
Expand All @@ -864,7 +877,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
if (refreshed)
return -EACCES;

err = fuse_do_getattr(inode, NULL);
err = fuse_do_getattr(inode, NULL, NULL);
if (!err && !(inode->i_mode & S_IXUGO))
return -EACCES;
}
Expand Down Expand Up @@ -1107,7 +1120,7 @@ static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
return -EACCES;

if (fi->i_time < get_jiffies_64())
err = fuse_do_getattr(inode, stat);
err = fuse_do_getattr(inode, stat, NULL);
else {
err = 0;
generic_fillattr(inode, stat);
Expand Down
2 changes: 1 addition & 1 deletion trunk/fs/fuse/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
arg->major = FUSE_KERNEL_VERSION;
arg->minor = FUSE_KERNEL_MINOR_VERSION;
arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE;
arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS;
arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_FILE_OPS;
req->in.h.opcode = FUSE_INIT;
req->in.numargs = 1;
req->in.args[0].size = sizeof(*arg);
Expand Down
23 changes: 21 additions & 2 deletions trunk/include/linux/fuse.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,14 @@
See the file COPYING.
*/

/* This file defines the kernel interface of FUSE */
/*
* This file defines the kernel interface of FUSE
*
* Protocol changelog:
*
* 7.9:
* - new fuse_getattr_in input argument of GETATTR
*/

#include <asm/types.h>
#include <linux/major.h>
Expand All @@ -15,7 +22,7 @@
#define FUSE_KERNEL_VERSION 7

/** Minor version number of this interface */
#define FUSE_KERNEL_MINOR_VERSION 8
#define FUSE_KERNEL_MINOR_VERSION 9

/** The node ID of the root inode */
#define FUSE_ROOT_ID 1
Expand Down Expand Up @@ -91,12 +98,18 @@ struct fuse_file_lock {
*/
#define FUSE_ASYNC_READ (1 << 0)
#define FUSE_POSIX_LOCKS (1 << 1)
#define FUSE_FILE_OPS (1 << 2)

/**
* Release flags
*/
#define FUSE_RELEASE_FLUSH (1 << 0)

/**
* Getattr flags
*/
#define FUSE_GETATTR_FH (1 << 0)

enum fuse_opcode {
FUSE_LOOKUP = 1,
FUSE_FORGET = 2, /* no reply */
Expand Down Expand Up @@ -154,6 +167,12 @@ struct fuse_forget_in {
__u64 nlookup;
};

struct fuse_getattr_in {
__u32 getattr_flags;
__u32 dummy;
__u64 fh;
};

struct fuse_attr_out {
__u64 attr_valid; /* Cache timeout for the attributes */
__u32 attr_valid_nsec;
Expand Down

0 comments on commit 699c365

Please sign in to comment.