Commit 25b7713a authored by Miklos Szeredi's avatar Miklos Szeredi

ovl: use i_private only as a key

Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent e6d2ebdd
...@@ -453,12 +453,12 @@ struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, dev_t rdev) ...@@ -453,12 +453,12 @@ struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, dev_t rdev)
static int ovl_inode_test(struct inode *inode, void *data) static int ovl_inode_test(struct inode *inode, void *data)
{ {
return ovl_inode_real(inode, NULL) == data; return inode->i_private == data;
} }
static int ovl_inode_set(struct inode *inode, void *data) static int ovl_inode_set(struct inode *inode, void *data)
{ {
inode->i_private = (void *) (((unsigned long) data) | OVL_ISUPPER_MASK); inode->i_private = data;
return 0; return 0;
} }
......
...@@ -60,8 +60,6 @@ struct ovl_fh { ...@@ -60,8 +60,6 @@ struct ovl_fh {
u8 fid[0]; /* file identifier */ u8 fid[0]; /* file identifier */
} __packed; } __packed;
#define OVL_ISUPPER_MASK 1UL
static inline int ovl_do_rmdir(struct inode *dir, struct dentry *dentry) static inline int ovl_do_rmdir(struct inode *dir, struct dentry *dentry)
{ {
int err = vfs_rmdir(dir, dentry); int err = vfs_rmdir(dir, dentry);
...@@ -175,16 +173,6 @@ static inline struct dentry *ovl_do_tmpfile(struct dentry *dentry, umode_t mode) ...@@ -175,16 +173,6 @@ static inline struct dentry *ovl_do_tmpfile(struct dentry *dentry, umode_t mode)
return ret; return ret;
} }
static inline struct inode *ovl_inode_real(struct inode *inode, bool *is_upper)
{
unsigned long x = (unsigned long) READ_ONCE(inode->i_private);
if (is_upper)
*is_upper = x & OVL_ISUPPER_MASK;
return (struct inode *) (x & ~OVL_ISUPPER_MASK);
}
/* util.c */ /* util.c */
int ovl_want_write(struct dentry *dentry); int ovl_want_write(struct dentry *dentry);
void ovl_drop_write(struct dentry *dentry); void ovl_drop_write(struct dentry *dentry);
...@@ -201,6 +189,7 @@ enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path); ...@@ -201,6 +189,7 @@ enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path);
struct dentry *ovl_dentry_upper(struct dentry *dentry); struct dentry *ovl_dentry_upper(struct dentry *dentry);
struct dentry *ovl_dentry_lower(struct dentry *dentry); struct dentry *ovl_dentry_lower(struct dentry *dentry);
struct dentry *ovl_dentry_real(struct dentry *dentry); struct dentry *ovl_dentry_real(struct dentry *dentry);
struct inode *ovl_inode_real(struct inode *inode, bool *is_upper);
struct ovl_dir_cache *ovl_dir_cache(struct dentry *dentry); struct ovl_dir_cache *ovl_dir_cache(struct dentry *dentry);
void ovl_set_dir_cache(struct dentry *dentry, struct ovl_dir_cache *cache); void ovl_set_dir_cache(struct dentry *dentry, struct ovl_dir_cache *cache);
bool ovl_dentry_is_opaque(struct dentry *dentry); bool ovl_dentry_is_opaque(struct dentry *dentry);
......
...@@ -61,6 +61,8 @@ static inline struct dentry *ovl_upperdentry_dereference(struct ovl_entry *oe) ...@@ -61,6 +61,8 @@ static inline struct dentry *ovl_upperdentry_dereference(struct ovl_entry *oe)
struct ovl_inode { struct ovl_inode {
struct inode vfs_inode; struct inode vfs_inode;
struct inode *upper;
struct inode *lower;
}; };
static inline struct ovl_inode *OVL_I(struct inode *inode) static inline struct ovl_inode *OVL_I(struct inode *inode)
......
...@@ -171,6 +171,9 @@ static struct inode *ovl_alloc_inode(struct super_block *sb) ...@@ -171,6 +171,9 @@ static struct inode *ovl_alloc_inode(struct super_block *sb)
{ {
struct ovl_inode *oi = kmem_cache_alloc(ovl_inode_cachep, GFP_KERNEL); struct ovl_inode *oi = kmem_cache_alloc(ovl_inode_cachep, GFP_KERNEL);
oi->upper = NULL;
oi->lower = NULL;
return &oi->vfs_inode; return &oi->vfs_inode;
} }
......
...@@ -155,6 +155,22 @@ struct dentry *ovl_dentry_real(struct dentry *dentry) ...@@ -155,6 +155,22 @@ struct dentry *ovl_dentry_real(struct dentry *dentry)
return realdentry; return realdentry;
} }
struct inode *ovl_inode_real(struct inode *inode, bool *is_upper)
{
struct inode *realinode = lockless_dereference(OVL_I(inode)->upper);
bool isup = false;
if (!realinode)
realinode = OVL_I(inode)->lower;
else
isup = true;
if (is_upper)
*is_upper = isup;
return realinode;
}
struct ovl_dir_cache *ovl_dir_cache(struct dentry *dentry) struct ovl_dir_cache *ovl_dir_cache(struct dentry *dentry)
{ {
struct ovl_entry *oe = dentry->d_fsdata; struct ovl_entry *oe = dentry->d_fsdata;
...@@ -233,10 +249,11 @@ void ovl_dentry_update(struct dentry *dentry, struct dentry *upperdentry) ...@@ -233,10 +249,11 @@ void ovl_dentry_update(struct dentry *dentry, struct dentry *upperdentry)
void ovl_inode_init(struct inode *inode, struct dentry *dentry) void ovl_inode_init(struct inode *inode, struct dentry *dentry)
{ {
struct inode *realinode = d_inode(ovl_dentry_real(dentry)); struct inode *realinode = d_inode(ovl_dentry_real(dentry));
bool is_upper = ovl_dentry_upper(dentry);
WRITE_ONCE(inode->i_private, (unsigned long) realinode | if (ovl_dentry_upper(dentry))
(is_upper ? OVL_ISUPPER_MASK : 0)); OVL_I(inode)->upper = realinode;
else
OVL_I(inode)->lower = realinode;
ovl_copyattr(realinode, inode); ovl_copyattr(realinode, inode);
} }
...@@ -245,10 +262,16 @@ void ovl_inode_update(struct inode *inode, struct inode *upperinode) ...@@ -245,10 +262,16 @@ void ovl_inode_update(struct inode *inode, struct inode *upperinode)
{ {
WARN_ON(!upperinode); WARN_ON(!upperinode);
WARN_ON(!inode_unhashed(inode)); WARN_ON(!inode_unhashed(inode));
WRITE_ONCE(inode->i_private, /*
(unsigned long) upperinode | OVL_ISUPPER_MASK); * Make sure upperinode is consistent before making it visible to
if (!S_ISDIR(upperinode->i_mode)) * ovl_inode_real();
*/
smp_wmb();
OVL_I(inode)->upper = upperinode;
if (!S_ISDIR(upperinode->i_mode)) {
inode->i_private = upperinode;
__insert_inode_hash(inode, (unsigned long) upperinode); __insert_inode_hash(inode, (unsigned long) upperinode);
}
} }
void ovl_dentry_version_inc(struct dentry *dentry) void ovl_dentry_version_inc(struct dentry *dentry)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment