mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-19 11:43:40 +00:00
overlayfs update for 6.2
-----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQSQHSd0lITzzeNWNm3h3BK/laaZPAUCY5b3+gAKCRDh3BK/laaZ PIPxAQCPgyV/X/yJFd3wVgKa3/JxcHl5qdPbwHXFuYiJCBd69QEA9LYQEeEoTLCY veGiQPkl6Sp8ZqmTbDBxqw5OaBTSMwM= =7TiE -----END PGP SIGNATURE----- Merge tag 'ovl-update-6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs Pull overlayfs update from Miklos Szeredi: - Fix a couple of bugs found by syzbot - Don't ingore some open flags set by fcntl(F_SETFL) - Fix failure to create a hard link in certain cases - Use type safe helpers for some mnt_userns transformations - Improve performance of mount - Misc cleanups * tag 'ovl-update-6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs: ovl: Kconfig: Fix spelling mistake "undelying" -> "underlying" ovl: use inode instead of dentry where possible ovl: Add comment on upperredirect reassignment ovl: use plain list filler in indexdir and workdir cleanup ovl: do not reconnect upper index records in ovl_indexdir_cleanup() ovl: fix comment typos ovl: port to vfs{g,u}id_t and associated helpers ovl: Use ovl mounter's fsuid and fsgid in ovl_link() ovl: Use "buf" flexible array for memcpy() destination ovl: update ->f_iocb_flags when ovl_change_flags() modifies ->f_flags ovl: fix use inode directly in rcu-walk mode
This commit is contained in:
commit
6df7cc2268
@ -96,7 +96,7 @@ config OVERLAY_FS_XINO_AUTO
|
|||||||
depends on 64BIT
|
depends on 64BIT
|
||||||
help
|
help
|
||||||
If this config option is enabled then overlay filesystems will use
|
If this config option is enabled then overlay filesystems will use
|
||||||
unused high bits in undelying filesystem inode numbers to map all
|
unused high bits in underlying filesystem inode numbers to map all
|
||||||
inodes to a unified address space. The mapped 64bit inode numbers
|
inodes to a unified address space. The mapped 64bit inode numbers
|
||||||
might not be compatible with applications that expect 32bit inodes.
|
might not be compatible with applications that expect 32bit inodes.
|
||||||
|
|
||||||
|
@ -576,28 +576,42 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode,
|
|||||||
goto out_revert_creds;
|
goto out_revert_creds;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = -ENOMEM;
|
if (!attr->hardlink) {
|
||||||
override_cred = prepare_creds();
|
err = -ENOMEM;
|
||||||
if (override_cred) {
|
override_cred = prepare_creds();
|
||||||
|
if (!override_cred)
|
||||||
|
goto out_revert_creds;
|
||||||
|
/*
|
||||||
|
* In the creation cases(create, mkdir, mknod, symlink),
|
||||||
|
* ovl should transfer current's fs{u,g}id to underlying
|
||||||
|
* fs. Because underlying fs want to initialize its new
|
||||||
|
* inode owner using current's fs{u,g}id. And in this
|
||||||
|
* case, the @inode is a new inode that is initialized
|
||||||
|
* in inode_init_owner() to current's fs{u,g}id. So use
|
||||||
|
* the inode's i_{u,g}id to override the cred's fs{u,g}id.
|
||||||
|
*
|
||||||
|
* But in the other hardlink case, ovl_link() does not
|
||||||
|
* create a new inode, so just use the ovl mounter's
|
||||||
|
* fs{u,g}id.
|
||||||
|
*/
|
||||||
override_cred->fsuid = inode->i_uid;
|
override_cred->fsuid = inode->i_uid;
|
||||||
override_cred->fsgid = inode->i_gid;
|
override_cred->fsgid = inode->i_gid;
|
||||||
if (!attr->hardlink) {
|
err = security_dentry_create_files_as(dentry,
|
||||||
err = security_dentry_create_files_as(dentry,
|
attr->mode, &dentry->d_name, old_cred,
|
||||||
attr->mode, &dentry->d_name, old_cred,
|
override_cred);
|
||||||
override_cred);
|
if (err) {
|
||||||
if (err) {
|
put_cred(override_cred);
|
||||||
put_cred(override_cred);
|
goto out_revert_creds;
|
||||||
goto out_revert_creds;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
put_cred(override_creds(override_cred));
|
put_cred(override_creds(override_cred));
|
||||||
put_cred(override_cred);
|
put_cred(override_cred);
|
||||||
|
|
||||||
if (!ovl_dentry_is_whiteout(dentry))
|
|
||||||
err = ovl_create_upper(dentry, inode, attr);
|
|
||||||
else
|
|
||||||
err = ovl_create_over_whiteout(dentry, inode, attr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ovl_dentry_is_whiteout(dentry))
|
||||||
|
err = ovl_create_upper(dentry, inode, attr);
|
||||||
|
else
|
||||||
|
err = ovl_create_over_whiteout(dentry, inode, attr);
|
||||||
|
|
||||||
out_revert_creds:
|
out_revert_creds:
|
||||||
revert_creds(old_cred);
|
revert_creds(old_cred);
|
||||||
return err;
|
return err;
|
||||||
|
@ -339,7 +339,7 @@ out_iput:
|
|||||||
return dentry;
|
return dentry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the upper or lower dentry in stach whose on layer @idx */
|
/* Get the upper or lower dentry in stack whose on layer @idx */
|
||||||
static struct dentry *ovl_dentry_real_at(struct dentry *dentry, int idx)
|
static struct dentry *ovl_dentry_real_at(struct dentry *dentry, int idx)
|
||||||
{
|
{
|
||||||
struct ovl_entry *oe = dentry->d_fsdata;
|
struct ovl_entry *oe = dentry->d_fsdata;
|
||||||
@ -463,7 +463,7 @@ static struct dentry *ovl_lookup_real_inode(struct super_block *sb,
|
|||||||
|
|
||||||
/* Get connected upper overlay dir from index */
|
/* Get connected upper overlay dir from index */
|
||||||
if (index) {
|
if (index) {
|
||||||
struct dentry *upper = ovl_index_upper(ofs, index);
|
struct dentry *upper = ovl_index_upper(ofs, index, true);
|
||||||
|
|
||||||
dput(index);
|
dput(index);
|
||||||
if (IS_ERR_OR_NULL(upper))
|
if (IS_ERR_OR_NULL(upper))
|
||||||
@ -739,7 +739,7 @@ static struct dentry *ovl_lower_fh_to_d(struct super_block *sb,
|
|||||||
|
|
||||||
/* Then try to get a connected upper dir by index */
|
/* Then try to get a connected upper dir by index */
|
||||||
if (index && d_is_dir(index)) {
|
if (index && d_is_dir(index)) {
|
||||||
struct dentry *upper = ovl_index_upper(ofs, index);
|
struct dentry *upper = ovl_index_upper(ofs, index, true);
|
||||||
|
|
||||||
err = PTR_ERR(upper);
|
err = PTR_ERR(upper);
|
||||||
if (IS_ERR_OR_NULL(upper))
|
if (IS_ERR_OR_NULL(upper))
|
||||||
@ -796,7 +796,7 @@ static struct ovl_fh *ovl_fid_to_fh(struct fid *fid, int buflen, int fh_type)
|
|||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
/* Copy unaligned inner fh into aligned buffer */
|
/* Copy unaligned inner fh into aligned buffer */
|
||||||
memcpy(&fh->fb, fid, buflen - OVL_FH_WIRE_OFFSET);
|
memcpy(fh->buf, fid, buflen - OVL_FH_WIRE_OFFSET);
|
||||||
return fh;
|
return fh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ static char ovl_whatisit(struct inode *inode, struct inode *realinode)
|
|||||||
return 'm';
|
return 'm';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No atime modificaton nor notify on underlying */
|
/* No atime modification nor notify on underlying */
|
||||||
#define OVL_OPEN_FLAGS (O_NOATIME | FMODE_NONOTIFY)
|
#define OVL_OPEN_FLAGS (O_NOATIME | FMODE_NONOTIFY)
|
||||||
|
|
||||||
static struct file *ovl_open_realfile(const struct file *file,
|
static struct file *ovl_open_realfile(const struct file *file,
|
||||||
@ -96,6 +96,7 @@ static int ovl_change_flags(struct file *file, unsigned int flags)
|
|||||||
|
|
||||||
spin_lock(&file->f_lock);
|
spin_lock(&file->f_lock);
|
||||||
file->f_flags = (file->f_flags & ~OVL_SETFL_MASK) | flags;
|
file->f_flags = (file->f_flags & ~OVL_SETFL_MASK) | flags;
|
||||||
|
file->f_iocb_flags = iocb_flags(file);
|
||||||
spin_unlock(&file->f_lock);
|
spin_unlock(&file->f_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -487,7 +487,8 @@ fail:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get upper dentry from index */
|
/* Get upper dentry from index */
|
||||||
struct dentry *ovl_index_upper(struct ovl_fs *ofs, struct dentry *index)
|
struct dentry *ovl_index_upper(struct ovl_fs *ofs, struct dentry *index,
|
||||||
|
bool connected)
|
||||||
{
|
{
|
||||||
struct ovl_fh *fh;
|
struct ovl_fh *fh;
|
||||||
struct dentry *upper;
|
struct dentry *upper;
|
||||||
@ -499,7 +500,7 @@ struct dentry *ovl_index_upper(struct ovl_fs *ofs, struct dentry *index)
|
|||||||
if (IS_ERR_OR_NULL(fh))
|
if (IS_ERR_OR_NULL(fh))
|
||||||
return ERR_CAST(fh);
|
return ERR_CAST(fh);
|
||||||
|
|
||||||
upper = ovl_decode_real_fh(ofs, fh, ovl_upper_mnt(ofs), true);
|
upper = ovl_decode_real_fh(ofs, fh, ovl_upper_mnt(ofs), connected);
|
||||||
kfree(fh);
|
kfree(fh);
|
||||||
|
|
||||||
if (IS_ERR_OR_NULL(upper))
|
if (IS_ERR_OR_NULL(upper))
|
||||||
@ -572,7 +573,7 @@ int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index)
|
|||||||
* directly from the index dentry, but for dir index we first need to
|
* directly from the index dentry, but for dir index we first need to
|
||||||
* decode the upper directory.
|
* decode the upper directory.
|
||||||
*/
|
*/
|
||||||
upper = ovl_index_upper(ofs, index);
|
upper = ovl_index_upper(ofs, index, false);
|
||||||
if (IS_ERR_OR_NULL(upper)) {
|
if (IS_ERR_OR_NULL(upper)) {
|
||||||
err = PTR_ERR(upper);
|
err = PTR_ERR(upper);
|
||||||
/*
|
/*
|
||||||
@ -1085,6 +1086,11 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
|
|||||||
.mnt = ovl_upper_mnt(ofs),
|
.mnt = ovl_upper_mnt(ofs),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* It's safe to assign upperredirect here: the previous
|
||||||
|
* assignment of happens only if upperdentry is non-NULL, and
|
||||||
|
* this one only if upperdentry is NULL.
|
||||||
|
*/
|
||||||
upperredirect = ovl_get_redirect_xattr(ofs, &upperpath, 0);
|
upperredirect = ovl_get_redirect_xattr(ofs, &upperpath, 0);
|
||||||
if (IS_ERR(upperredirect)) {
|
if (IS_ERR(upperredirect)) {
|
||||||
err = PTR_ERR(upperredirect);
|
err = PTR_ERR(upperredirect);
|
||||||
|
@ -110,7 +110,7 @@ struct ovl_fh {
|
|||||||
u8 padding[3]; /* make sure fb.fid is 32bit aligned */
|
u8 padding[3]; /* make sure fb.fid is 32bit aligned */
|
||||||
union {
|
union {
|
||||||
struct ovl_fb fb;
|
struct ovl_fb fb;
|
||||||
u8 buf[0];
|
DECLARE_FLEX_ARRAY(u8, buf);
|
||||||
};
|
};
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
@ -415,7 +415,7 @@ const char *ovl_dentry_get_redirect(struct dentry *dentry);
|
|||||||
void ovl_dentry_set_redirect(struct dentry *dentry, const char *redirect);
|
void ovl_dentry_set_redirect(struct dentry *dentry, const char *redirect);
|
||||||
void ovl_inode_update(struct inode *inode, struct dentry *upperdentry);
|
void ovl_inode_update(struct inode *inode, struct dentry *upperdentry);
|
||||||
void ovl_dir_modified(struct dentry *dentry, bool impurity);
|
void ovl_dir_modified(struct dentry *dentry, bool impurity);
|
||||||
u64 ovl_dentry_version_get(struct dentry *dentry);
|
u64 ovl_inode_version_get(struct inode *inode);
|
||||||
bool ovl_is_whiteout(struct dentry *dentry);
|
bool ovl_is_whiteout(struct dentry *dentry);
|
||||||
struct file *ovl_path_open(const struct path *path, int flags);
|
struct file *ovl_path_open(const struct path *path, int flags);
|
||||||
int ovl_copy_up_start(struct dentry *dentry, int flags);
|
int ovl_copy_up_start(struct dentry *dentry, int flags);
|
||||||
@ -539,7 +539,8 @@ int ovl_check_origin_fh(struct ovl_fs *ofs, struct ovl_fh *fh, bool connected,
|
|||||||
int ovl_verify_set_fh(struct ovl_fs *ofs, struct dentry *dentry,
|
int ovl_verify_set_fh(struct ovl_fs *ofs, struct dentry *dentry,
|
||||||
enum ovl_xattr ox, struct dentry *real, bool is_upper,
|
enum ovl_xattr ox, struct dentry *real, bool is_upper,
|
||||||
bool set);
|
bool set);
|
||||||
struct dentry *ovl_index_upper(struct ovl_fs *ofs, struct dentry *index);
|
struct dentry *ovl_index_upper(struct ovl_fs *ofs, struct dentry *index,
|
||||||
|
bool connected);
|
||||||
int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index);
|
int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index);
|
||||||
int ovl_get_index_name(struct ovl_fs *ofs, struct dentry *origin,
|
int ovl_get_index_name(struct ovl_fs *ofs, struct dentry *origin,
|
||||||
struct qstr *name);
|
struct qstr *name);
|
||||||
@ -584,9 +585,9 @@ int ovl_indexdir_cleanup(struct ovl_fs *ofs);
|
|||||||
* lower dir was removed under it and possibly before it was rotated from upper
|
* lower dir was removed under it and possibly before it was rotated from upper
|
||||||
* to lower layer.
|
* to lower layer.
|
||||||
*/
|
*/
|
||||||
static inline bool ovl_dir_is_real(struct dentry *dir)
|
static inline bool ovl_dir_is_real(struct inode *dir)
|
||||||
{
|
{
|
||||||
return !ovl_test_flag(OVL_WHITEOUTS, d_inode(dir));
|
return !ovl_test_flag(OVL_WHITEOUTS, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* inode.c */
|
/* inode.c */
|
||||||
|
@ -235,15 +235,15 @@ void ovl_dir_cache_free(struct inode *inode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ovl_cache_put(struct ovl_dir_file *od, struct dentry *dentry)
|
static void ovl_cache_put(struct ovl_dir_file *od, struct inode *inode)
|
||||||
{
|
{
|
||||||
struct ovl_dir_cache *cache = od->cache;
|
struct ovl_dir_cache *cache = od->cache;
|
||||||
|
|
||||||
WARN_ON(cache->refcount <= 0);
|
WARN_ON(cache->refcount <= 0);
|
||||||
cache->refcount--;
|
cache->refcount--;
|
||||||
if (!cache->refcount) {
|
if (!cache->refcount) {
|
||||||
if (ovl_dir_cache(d_inode(dentry)) == cache)
|
if (ovl_dir_cache(inode) == cache)
|
||||||
ovl_set_dir_cache(d_inode(dentry), NULL);
|
ovl_set_dir_cache(inode, NULL);
|
||||||
|
|
||||||
ovl_cache_free(&cache->entries);
|
ovl_cache_free(&cache->entries);
|
||||||
kfree(cache);
|
kfree(cache);
|
||||||
@ -323,15 +323,15 @@ static void ovl_dir_reset(struct file *file)
|
|||||||
{
|
{
|
||||||
struct ovl_dir_file *od = file->private_data;
|
struct ovl_dir_file *od = file->private_data;
|
||||||
struct ovl_dir_cache *cache = od->cache;
|
struct ovl_dir_cache *cache = od->cache;
|
||||||
struct dentry *dentry = file->f_path.dentry;
|
struct inode *inode = file_inode(file);
|
||||||
bool is_real;
|
bool is_real;
|
||||||
|
|
||||||
if (cache && ovl_dentry_version_get(dentry) != cache->version) {
|
if (cache && ovl_inode_version_get(inode) != cache->version) {
|
||||||
ovl_cache_put(od, dentry);
|
ovl_cache_put(od, inode);
|
||||||
od->cache = NULL;
|
od->cache = NULL;
|
||||||
od->cursor = NULL;
|
od->cursor = NULL;
|
||||||
}
|
}
|
||||||
is_real = ovl_dir_is_real(dentry);
|
is_real = ovl_dir_is_real(inode);
|
||||||
if (od->is_real != is_real) {
|
if (od->is_real != is_real) {
|
||||||
/* is_real can only become false when dir is copied up */
|
/* is_real can only become false when dir is copied up */
|
||||||
if (WARN_ON(is_real))
|
if (WARN_ON(is_real))
|
||||||
@ -394,9 +394,10 @@ static struct ovl_dir_cache *ovl_cache_get(struct dentry *dentry)
|
|||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
struct ovl_dir_cache *cache;
|
struct ovl_dir_cache *cache;
|
||||||
|
struct inode *inode = d_inode(dentry);
|
||||||
|
|
||||||
cache = ovl_dir_cache(d_inode(dentry));
|
cache = ovl_dir_cache(inode);
|
||||||
if (cache && ovl_dentry_version_get(dentry) == cache->version) {
|
if (cache && ovl_inode_version_get(inode) == cache->version) {
|
||||||
WARN_ON(!cache->refcount);
|
WARN_ON(!cache->refcount);
|
||||||
cache->refcount++;
|
cache->refcount++;
|
||||||
return cache;
|
return cache;
|
||||||
@ -418,8 +419,8 @@ static struct ovl_dir_cache *ovl_cache_get(struct dentry *dentry)
|
|||||||
return ERR_PTR(res);
|
return ERR_PTR(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
cache->version = ovl_dentry_version_get(dentry);
|
cache->version = ovl_inode_version_get(inode);
|
||||||
ovl_set_dir_cache(d_inode(dentry), cache);
|
ovl_set_dir_cache(inode, cache);
|
||||||
|
|
||||||
return cache;
|
return cache;
|
||||||
}
|
}
|
||||||
@ -596,16 +597,17 @@ static struct ovl_dir_cache *ovl_cache_get_impure(const struct path *path)
|
|||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
struct dentry *dentry = path->dentry;
|
struct dentry *dentry = path->dentry;
|
||||||
|
struct inode *inode = d_inode(dentry);
|
||||||
struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
|
struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
|
||||||
struct ovl_dir_cache *cache;
|
struct ovl_dir_cache *cache;
|
||||||
|
|
||||||
cache = ovl_dir_cache(d_inode(dentry));
|
cache = ovl_dir_cache(inode);
|
||||||
if (cache && ovl_dentry_version_get(dentry) == cache->version)
|
if (cache && ovl_inode_version_get(inode) == cache->version)
|
||||||
return cache;
|
return cache;
|
||||||
|
|
||||||
/* Impure cache is not refcounted, free it here */
|
/* Impure cache is not refcounted, free it here */
|
||||||
ovl_dir_cache_free(d_inode(dentry));
|
ovl_dir_cache_free(inode);
|
||||||
ovl_set_dir_cache(d_inode(dentry), NULL);
|
ovl_set_dir_cache(inode, NULL);
|
||||||
|
|
||||||
cache = kzalloc(sizeof(struct ovl_dir_cache), GFP_KERNEL);
|
cache = kzalloc(sizeof(struct ovl_dir_cache), GFP_KERNEL);
|
||||||
if (!cache)
|
if (!cache)
|
||||||
@ -627,13 +629,13 @@ static struct ovl_dir_cache *ovl_cache_get_impure(const struct path *path)
|
|||||||
OVL_XATTR_IMPURE);
|
OVL_XATTR_IMPURE);
|
||||||
ovl_drop_write(dentry);
|
ovl_drop_write(dentry);
|
||||||
}
|
}
|
||||||
ovl_clear_flag(OVL_IMPURE, d_inode(dentry));
|
ovl_clear_flag(OVL_IMPURE, inode);
|
||||||
kfree(cache);
|
kfree(cache);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
cache->version = ovl_dentry_version_get(dentry);
|
cache->version = ovl_inode_version_get(inode);
|
||||||
ovl_set_dir_cache(d_inode(dentry), cache);
|
ovl_set_dir_cache(inode, cache);
|
||||||
|
|
||||||
return cache;
|
return cache;
|
||||||
}
|
}
|
||||||
@ -675,7 +677,7 @@ static bool ovl_fill_real(struct dir_context *ctx, const char *name,
|
|||||||
static bool ovl_is_impure_dir(struct file *file)
|
static bool ovl_is_impure_dir(struct file *file)
|
||||||
{
|
{
|
||||||
struct ovl_dir_file *od = file->private_data;
|
struct ovl_dir_file *od = file->private_data;
|
||||||
struct inode *dir = d_inode(file->f_path.dentry);
|
struct inode *dir = file_inode(file);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Only upper dir can be impure, but if we are in the middle of
|
* Only upper dir can be impure, but if we are in the middle of
|
||||||
@ -893,7 +895,7 @@ static int ovl_dir_fsync(struct file *file, loff_t start, loff_t end,
|
|||||||
struct file *realfile;
|
struct file *realfile;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = ovl_sync_status(OVL_FS(file->f_path.dentry->d_sb));
|
err = ovl_sync_status(OVL_FS(file_inode(file)->i_sb));
|
||||||
if (err <= 0)
|
if (err <= 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@ -913,7 +915,7 @@ static int ovl_dir_release(struct inode *inode, struct file *file)
|
|||||||
|
|
||||||
if (od->cache) {
|
if (od->cache) {
|
||||||
inode_lock(inode);
|
inode_lock(inode);
|
||||||
ovl_cache_put(od, file->f_path.dentry);
|
ovl_cache_put(od, inode);
|
||||||
inode_unlock(inode);
|
inode_unlock(inode);
|
||||||
}
|
}
|
||||||
fput(od->realfile);
|
fput(od->realfile);
|
||||||
@ -942,7 +944,7 @@ static int ovl_dir_open(struct inode *inode, struct file *file)
|
|||||||
return PTR_ERR(realfile);
|
return PTR_ERR(realfile);
|
||||||
}
|
}
|
||||||
od->realfile = realfile;
|
od->realfile = realfile;
|
||||||
od->is_real = ovl_dir_is_real(file->f_path.dentry);
|
od->is_real = ovl_dir_is_real(inode);
|
||||||
od->is_upper = OVL_TYPE_UPPER(type);
|
od->is_upper = OVL_TYPE_UPPER(type);
|
||||||
file->private_data = od;
|
file->private_data = od;
|
||||||
|
|
||||||
@ -1071,14 +1073,10 @@ static int ovl_workdir_cleanup_recurse(struct ovl_fs *ofs, const struct path *pa
|
|||||||
int err;
|
int err;
|
||||||
struct inode *dir = path->dentry->d_inode;
|
struct inode *dir = path->dentry->d_inode;
|
||||||
LIST_HEAD(list);
|
LIST_HEAD(list);
|
||||||
struct rb_root root = RB_ROOT;
|
|
||||||
struct ovl_cache_entry *p;
|
struct ovl_cache_entry *p;
|
||||||
struct ovl_readdir_data rdd = {
|
struct ovl_readdir_data rdd = {
|
||||||
.ctx.actor = ovl_fill_merge,
|
.ctx.actor = ovl_fill_plain,
|
||||||
.dentry = NULL,
|
|
||||||
.list = &list,
|
.list = &list,
|
||||||
.root = &root,
|
|
||||||
.is_lowest = false,
|
|
||||||
};
|
};
|
||||||
bool incompat = false;
|
bool incompat = false;
|
||||||
|
|
||||||
@ -1159,14 +1157,10 @@ int ovl_indexdir_cleanup(struct ovl_fs *ofs)
|
|||||||
struct inode *dir = indexdir->d_inode;
|
struct inode *dir = indexdir->d_inode;
|
||||||
struct path path = { .mnt = ovl_upper_mnt(ofs), .dentry = indexdir };
|
struct path path = { .mnt = ovl_upper_mnt(ofs), .dentry = indexdir };
|
||||||
LIST_HEAD(list);
|
LIST_HEAD(list);
|
||||||
struct rb_root root = RB_ROOT;
|
|
||||||
struct ovl_cache_entry *p;
|
struct ovl_cache_entry *p;
|
||||||
struct ovl_readdir_data rdd = {
|
struct ovl_readdir_data rdd = {
|
||||||
.ctx.actor = ovl_fill_merge,
|
.ctx.actor = ovl_fill_plain,
|
||||||
.dentry = NULL,
|
|
||||||
.list = &list,
|
.list = &list,
|
||||||
.root = &root,
|
|
||||||
.is_lowest = false,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
err = ovl_dir_read(&path, &rdd);
|
err = ovl_dir_read(&path, &rdd);
|
||||||
|
@ -139,11 +139,16 @@ static int ovl_dentry_revalidate_common(struct dentry *dentry,
|
|||||||
unsigned int flags, bool weak)
|
unsigned int flags, bool weak)
|
||||||
{
|
{
|
||||||
struct ovl_entry *oe = dentry->d_fsdata;
|
struct ovl_entry *oe = dentry->d_fsdata;
|
||||||
|
struct inode *inode = d_inode_rcu(dentry);
|
||||||
struct dentry *upper;
|
struct dentry *upper;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
|
|
||||||
upper = ovl_dentry_upper(dentry);
|
/* Careful in RCU mode */
|
||||||
|
if (!inode)
|
||||||
|
return -ECHILD;
|
||||||
|
|
||||||
|
upper = ovl_i_dentry_upper(inode);
|
||||||
if (upper)
|
if (upper)
|
||||||
ret = ovl_revalidate_real(upper, flags, weak);
|
ret = ovl_revalidate_real(upper, flags, weak);
|
||||||
|
|
||||||
|
@ -463,7 +463,7 @@ static void ovl_dir_version_inc(struct dentry *dentry, bool impurity)
|
|||||||
* which have been copied up and have origins), so only need to note
|
* which have been copied up and have origins), so only need to note
|
||||||
* changes to impure entries.
|
* changes to impure entries.
|
||||||
*/
|
*/
|
||||||
if (!ovl_dir_is_real(dentry) || impurity)
|
if (!ovl_dir_is_real(inode) || impurity)
|
||||||
OVL_I(inode)->version++;
|
OVL_I(inode)->version++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -475,10 +475,8 @@ void ovl_dir_modified(struct dentry *dentry, bool impurity)
|
|||||||
ovl_dir_version_inc(dentry, impurity);
|
ovl_dir_version_inc(dentry, impurity);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 ovl_dentry_version_get(struct dentry *dentry)
|
u64 ovl_inode_version_get(struct inode *inode)
|
||||||
{
|
{
|
||||||
struct inode *inode = d_inode(dentry);
|
|
||||||
|
|
||||||
WARN_ON(!inode_is_locked(inode));
|
WARN_ON(!inode_is_locked(inode));
|
||||||
return OVL_I(inode)->version;
|
return OVL_I(inode)->version;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user