Skip to content

Commit

Permalink
fuse: don't use ->d_time
Browse files Browse the repository at this point in the history
Store in memory pointed to by ->d_fsdata.  Use ->d_init() to allocate the
storage.  Need to use RCU freeing because the data is used in RCU lookup
mode.

We could cast ->d_fsdata directly on 64bit archs, but I don't think this is
worth the extra complexity.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
  • Loading branch information
Miklos Szeredi committed Oct 1, 2016
1 parent 60bcc88 commit f75fdf2
Showing 1 changed file with 23 additions and 20 deletions.
43 changes: 23 additions & 20 deletions fs/fuse/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,37 +39,25 @@ static void fuse_advise_use_readdirplus(struct inode *dir)
set_bit(FUSE_I_ADVISE_RDPLUS, &fi->state);
}

#if BITS_PER_LONG >= 64
union fuse_dentry {
u64 time;
struct rcu_head rcu;
};

static inline void fuse_dentry_settime(struct dentry *entry, u64 time)
{
entry->d_time = time;
((union fuse_dentry *) entry->d_fsdata)->time = time;
}

static inline u64 fuse_dentry_time(struct dentry *entry)
{
return entry->d_time;
}
#else
/*
* On 32 bit archs store the high 32 bits of time in d_fsdata
*/
static void fuse_dentry_settime(struct dentry *entry, u64 time)
{
entry->d_time = time;
entry->d_fsdata = (void *) (unsigned long) (time >> 32);
}

static u64 fuse_dentry_time(struct dentry *entry)
{
return (u64) entry->d_time +
((u64) (unsigned long) entry->d_fsdata << 32);
return ((union fuse_dentry *) entry->d_fsdata)->time;
}
#endif

/*
* FUSE caches dentries and attributes with separate timeout. The
* time in jiffies until the dentry/attributes are valid is stored in
* dentry->d_time and fuse_inode->i_time respectively.
* dentry->d_fsdata and fuse_inode->i_time respectively.
*/

/*
Expand Down Expand Up @@ -275,8 +263,23 @@ static int invalid_nodeid(u64 nodeid)
return !nodeid || nodeid == FUSE_ROOT_ID;
}

static int fuse_dentry_init(struct dentry *dentry)
{
dentry->d_fsdata = kzalloc(sizeof(union fuse_dentry), GFP_KERNEL);

return dentry->d_fsdata ? 0 : -ENOMEM;
}
static void fuse_dentry_release(struct dentry *dentry)
{
union fuse_dentry *fd = dentry->d_fsdata;

kfree_rcu(fd, rcu);
}

const struct dentry_operations fuse_dentry_operations = {
.d_revalidate = fuse_dentry_revalidate,
.d_init = fuse_dentry_init,
.d_release = fuse_dentry_release,
};

int fuse_valid_type(int m)
Expand Down

0 comments on commit f75fdf2

Please sign in to comment.