Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 106038
b: refs/heads/master
c: dbd561d
h: refs/heads/master
v: v3
  • Loading branch information
Miklos Szeredi authored and Linus Torvalds committed Jul 25, 2008
1 parent 7d61d29 commit 1e60967
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 3 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: 0de6256daafa3a97a269995e9b29f956bd419bbf
refs/heads/master: dbd561d236ff16f8143bc727d91758ddd190e8cb
4 changes: 2 additions & 2 deletions trunk/fs/fuse/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ void fuse_invalidate_attr(struct inode *inode)
* timeout is unknown (unlink, rmdir, rename and in some cases
* lookup)
*/
static void fuse_invalidate_entry_cache(struct dentry *entry)
void fuse_invalidate_entry_cache(struct dentry *entry)
{
fuse_dentry_settime(entry, 0);
}
Expand Down Expand Up @@ -225,7 +225,7 @@ static int invalid_nodeid(u64 nodeid)
return !nodeid || nodeid == FUSE_ROOT_ID;
}

static struct dentry_operations fuse_dentry_operations = {
struct dentry_operations fuse_dentry_operations = {
.d_revalidate = fuse_dentry_revalidate,
};

Expand Down
4 changes: 4 additions & 0 deletions trunk/fs/fuse/fuse_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,8 @@ static inline u64 get_node_id(struct inode *inode)
/** Device operations */
extern const struct file_operations fuse_dev_operations;

extern struct dentry_operations fuse_dentry_operations;

/**
* Get a filled in inode
*/
Expand Down Expand Up @@ -604,6 +606,8 @@ void fuse_abort_conn(struct fuse_conn *fc);
*/
void fuse_invalidate_attr(struct inode *inode);

void fuse_invalidate_entry_cache(struct dentry *entry);

/**
* Acquire reference to fuse_conn
*/
Expand Down
115 changes: 115 additions & 0 deletions trunk/fs/fuse/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <linux/statfs.h>
#include <linux/random.h>
#include <linux/sched.h>
#include <linux/exportfs.h>

MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>");
MODULE_DESCRIPTION("Filesystem in Userspace");
Expand Down Expand Up @@ -552,6 +553,119 @@ static struct inode *get_root_inode(struct super_block *sb, unsigned mode)
return fuse_iget(sb, 1, 0, &attr, 0, 0);
}

struct fuse_inode_handle
{
u64 nodeid;
u32 generation;
};

static struct dentry *fuse_get_dentry(struct super_block *sb,
struct fuse_inode_handle *handle)
{
struct inode *inode;
struct dentry *entry;
int err = -ESTALE;

if (handle->nodeid == 0)
goto out_err;

inode = ilookup5(sb, handle->nodeid, fuse_inode_eq, &handle->nodeid);
if (!inode)
goto out_err;
err = -ESTALE;
if (inode->i_generation != handle->generation)
goto out_iput;

entry = d_alloc_anon(inode);
err = -ENOMEM;
if (!entry)
goto out_iput;

if (get_node_id(inode) != FUSE_ROOT_ID) {
entry->d_op = &fuse_dentry_operations;
fuse_invalidate_entry_cache(entry);
}

return entry;

out_iput:
iput(inode);
out_err:
return ERR_PTR(err);
}

static int fuse_encode_fh(struct dentry *dentry, u32 *fh, int *max_len,
int connectable)
{
struct inode *inode = dentry->d_inode;
bool encode_parent = connectable && !S_ISDIR(inode->i_mode);
int len = encode_parent ? 6 : 3;
u64 nodeid;
u32 generation;

if (*max_len < len)
return 255;

nodeid = get_fuse_inode(inode)->nodeid;
generation = inode->i_generation;

fh[0] = (u32)(nodeid >> 32);
fh[1] = (u32)(nodeid & 0xffffffff);
fh[2] = generation;

if (encode_parent) {
struct inode *parent;

spin_lock(&dentry->d_lock);
parent = dentry->d_parent->d_inode;
nodeid = get_fuse_inode(parent)->nodeid;
generation = parent->i_generation;
spin_unlock(&dentry->d_lock);

fh[3] = (u32)(nodeid >> 32);
fh[4] = (u32)(nodeid & 0xffffffff);
fh[5] = generation;
}

*max_len = len;
return encode_parent ? 0x82 : 0x81;
}

static struct dentry *fuse_fh_to_dentry(struct super_block *sb,
struct fid *fid, int fh_len, int fh_type)
{
struct fuse_inode_handle handle;

if ((fh_type != 0x81 && fh_type != 0x82) || fh_len < 3)
return NULL;

handle.nodeid = (u64) fid->raw[0] << 32;
handle.nodeid |= (u64) fid->raw[1];
handle.generation = fid->raw[2];
return fuse_get_dentry(sb, &handle);
}

static struct dentry *fuse_fh_to_parent(struct super_block *sb,
struct fid *fid, int fh_len, int fh_type)
{
struct fuse_inode_handle parent;

if (fh_type != 0x82 || fh_len < 6)
return NULL;

parent.nodeid = (u64) fid->raw[3] << 32;
parent.nodeid |= (u64) fid->raw[4];
parent.generation = fid->raw[5];
return fuse_get_dentry(sb, &parent);
}


static const struct export_operations fuse_export_operations = {
.fh_to_dentry = fuse_fh_to_dentry,
.fh_to_parent = fuse_fh_to_parent,
.encode_fh = fuse_encode_fh,
};

static const struct super_operations fuse_super_operations = {
.alloc_inode = fuse_alloc_inode,
.destroy_inode = fuse_destroy_inode,
Expand Down Expand Up @@ -652,6 +766,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
sb->s_magic = FUSE_SUPER_MAGIC;
sb->s_op = &fuse_super_operations;
sb->s_maxbytes = MAX_LFS_FILESIZE;
sb->s_export_op = &fuse_export_operations;

file = fget(d.fd);
if (!file)
Expand Down

0 comments on commit 1e60967

Please sign in to comment.