Loading fs/overlayfs/inode.c +2 −2 Original line number Diff line number Diff line Loading @@ -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) { return ovl_inode_real(inode, NULL) == data; return inode->i_private == 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; } Loading fs/overlayfs/overlayfs.h +1 −12 Original line number Diff line number Diff line Loading @@ -60,8 +60,6 @@ struct ovl_fh { u8 fid[0]; /* file identifier */ } __packed; #define OVL_ISUPPER_MASK 1UL static inline int ovl_do_rmdir(struct inode *dir, struct dentry *dentry) { int err = vfs_rmdir(dir, dentry); Loading Loading @@ -175,16 +173,6 @@ static inline struct dentry *ovl_do_tmpfile(struct dentry *dentry, umode_t mode) 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 */ int ovl_want_write(struct dentry *dentry); void ovl_drop_write(struct dentry *dentry); Loading @@ -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_lower(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); void ovl_set_dir_cache(struct dentry *dentry, struct ovl_dir_cache *cache); bool ovl_dentry_is_opaque(struct dentry *dentry); Loading fs/overlayfs/ovl_entry.h +2 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,8 @@ static inline struct dentry *ovl_upperdentry_dereference(struct ovl_entry *oe) struct ovl_inode { struct inode vfs_inode; struct inode *upper; struct inode *lower; }; static inline struct ovl_inode *OVL_I(struct inode *inode) Loading fs/overlayfs/super.c +3 −0 Original line number Diff line number Diff line Loading @@ -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); oi->upper = NULL; oi->lower = NULL; return &oi->vfs_inode; } Loading fs/overlayfs/util.c +29 −6 Original line number Diff line number Diff line Loading @@ -155,6 +155,22 @@ struct dentry *ovl_dentry_real(struct dentry *dentry) 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_entry *oe = dentry->d_fsdata; Loading Loading @@ -233,10 +249,11 @@ void ovl_dentry_update(struct dentry *dentry, struct dentry *upperdentry) void ovl_inode_init(struct inode *inode, struct dentry *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 | (is_upper ? OVL_ISUPPER_MASK : 0)); if (ovl_dentry_upper(dentry)) OVL_I(inode)->upper = realinode; else OVL_I(inode)->lower = realinode; ovl_copyattr(realinode, inode); } Loading @@ -245,11 +262,17 @@ void ovl_inode_update(struct inode *inode, struct inode *upperinode) { WARN_ON(!upperinode); WARN_ON(!inode_unhashed(inode)); WRITE_ONCE(inode->i_private, (unsigned long) upperinode | OVL_ISUPPER_MASK); if (!S_ISDIR(upperinode->i_mode)) /* * Make sure upperinode is consistent before making it visible to * 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); } } void ovl_dentry_version_inc(struct dentry *dentry) { Loading Loading
fs/overlayfs/inode.c +2 −2 Original line number Diff line number Diff line Loading @@ -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) { return ovl_inode_real(inode, NULL) == data; return inode->i_private == 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; } Loading
fs/overlayfs/overlayfs.h +1 −12 Original line number Diff line number Diff line Loading @@ -60,8 +60,6 @@ struct ovl_fh { u8 fid[0]; /* file identifier */ } __packed; #define OVL_ISUPPER_MASK 1UL static inline int ovl_do_rmdir(struct inode *dir, struct dentry *dentry) { int err = vfs_rmdir(dir, dentry); Loading Loading @@ -175,16 +173,6 @@ static inline struct dentry *ovl_do_tmpfile(struct dentry *dentry, umode_t mode) 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 */ int ovl_want_write(struct dentry *dentry); void ovl_drop_write(struct dentry *dentry); Loading @@ -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_lower(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); void ovl_set_dir_cache(struct dentry *dentry, struct ovl_dir_cache *cache); bool ovl_dentry_is_opaque(struct dentry *dentry); Loading
fs/overlayfs/ovl_entry.h +2 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,8 @@ static inline struct dentry *ovl_upperdentry_dereference(struct ovl_entry *oe) struct ovl_inode { struct inode vfs_inode; struct inode *upper; struct inode *lower; }; static inline struct ovl_inode *OVL_I(struct inode *inode) Loading
fs/overlayfs/super.c +3 −0 Original line number Diff line number Diff line Loading @@ -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); oi->upper = NULL; oi->lower = NULL; return &oi->vfs_inode; } Loading
fs/overlayfs/util.c +29 −6 Original line number Diff line number Diff line Loading @@ -155,6 +155,22 @@ struct dentry *ovl_dentry_real(struct dentry *dentry) 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_entry *oe = dentry->d_fsdata; Loading Loading @@ -233,10 +249,11 @@ void ovl_dentry_update(struct dentry *dentry, struct dentry *upperdentry) void ovl_inode_init(struct inode *inode, struct dentry *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 | (is_upper ? OVL_ISUPPER_MASK : 0)); if (ovl_dentry_upper(dentry)) OVL_I(inode)->upper = realinode; else OVL_I(inode)->lower = realinode; ovl_copyattr(realinode, inode); } Loading @@ -245,11 +262,17 @@ void ovl_inode_update(struct inode *inode, struct inode *upperinode) { WARN_ON(!upperinode); WARN_ON(!inode_unhashed(inode)); WRITE_ONCE(inode->i_private, (unsigned long) upperinode | OVL_ISUPPER_MASK); if (!S_ISDIR(upperinode->i_mode)) /* * Make sure upperinode is consistent before making it visible to * 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); } } void ovl_dentry_version_inc(struct dentry *dentry) { Loading