ovl: pass layer mnt to ovl_open_realfile()
Ensure that ovl_open_realfile() takes the mount's idmapping into account. We add a new helper ovl_path_realdata() that can be used to easily retrieve the relevant path which we can pass down. This is needed to support idmapped base layers with overlay. Cc: <linux-unionfs@vger.kernel.org> Tested-by: Giuseppe Scrivano <gscrivan@redhat.com> Reviewed-by: Christian Brauner (Microsoft) <brauner@kernel.org> Signed-off-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
Родитель
5272eaf3a5
Коммит
1248ea4b91
|
@ -38,8 +38,9 @@ static char ovl_whatisit(struct inode *inode, struct inode *realinode)
|
|||
#define OVL_OPEN_FLAGS (O_NOATIME | FMODE_NONOTIFY)
|
||||
|
||||
static struct file *ovl_open_realfile(const struct file *file,
|
||||
struct inode *realinode)
|
||||
struct path *realpath)
|
||||
{
|
||||
struct inode *realinode = d_inode(realpath->dentry);
|
||||
struct inode *inode = file_inode(file);
|
||||
struct file *realfile;
|
||||
const struct cred *old_cred;
|
||||
|
@ -104,21 +105,21 @@ static int ovl_change_flags(struct file *file, unsigned int flags)
|
|||
static int ovl_real_fdget_meta(const struct file *file, struct fd *real,
|
||||
bool allow_meta)
|
||||
{
|
||||
struct inode *inode = file_inode(file);
|
||||
struct inode *realinode;
|
||||
struct dentry *dentry = file_dentry(file);
|
||||
struct path realpath;
|
||||
|
||||
real->flags = 0;
|
||||
real->file = file->private_data;
|
||||
|
||||
if (allow_meta)
|
||||
realinode = ovl_inode_real(inode);
|
||||
ovl_path_real(dentry, &realpath);
|
||||
else
|
||||
realinode = ovl_inode_realdata(inode);
|
||||
ovl_path_realdata(dentry, &realpath);
|
||||
|
||||
/* Has it been copied up since we'd opened it? */
|
||||
if (unlikely(file_inode(real->file) != realinode)) {
|
||||
if (unlikely(file_inode(real->file) != d_inode(realpath.dentry))) {
|
||||
real->flags = FDPUT_FPUT;
|
||||
real->file = ovl_open_realfile(file, realinode);
|
||||
real->file = ovl_open_realfile(file, &realpath);
|
||||
|
||||
return PTR_ERR_OR_ZERO(real->file);
|
||||
}
|
||||
|
@ -144,17 +145,20 @@ static int ovl_real_fdget(const struct file *file, struct fd *real)
|
|||
|
||||
static int ovl_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct dentry *dentry = file_dentry(file);
|
||||
struct file *realfile;
|
||||
struct path realpath;
|
||||
int err;
|
||||
|
||||
err = ovl_maybe_copy_up(file_dentry(file), file->f_flags);
|
||||
err = ovl_maybe_copy_up(dentry, file->f_flags);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* No longer need these flags, so don't pass them on to underlying fs */
|
||||
file->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
|
||||
|
||||
realfile = ovl_open_realfile(file, ovl_inode_realdata(inode));
|
||||
ovl_path_realdata(dentry, &realpath);
|
||||
realfile = ovl_open_realfile(file, &realpath);
|
||||
if (IS_ERR(realfile))
|
||||
return PTR_ERR(realfile);
|
||||
|
||||
|
|
|
@ -320,6 +320,7 @@ void ovl_path_upper(struct dentry *dentry, struct path *path);
|
|||
void ovl_path_lower(struct dentry *dentry, struct path *path);
|
||||
void ovl_path_lowerdata(struct dentry *dentry, struct path *path);
|
||||
enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path);
|
||||
enum ovl_path_type ovl_path_realdata(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_lowerdata(struct dentry *dentry);
|
||||
|
|
|
@ -194,6 +194,20 @@ enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path)
|
|||
return type;
|
||||
}
|
||||
|
||||
enum ovl_path_type ovl_path_realdata(struct dentry *dentry, struct path *path)
|
||||
{
|
||||
enum ovl_path_type type = ovl_path_type(dentry);
|
||||
|
||||
WARN_ON_ONCE(d_is_dir(dentry));
|
||||
|
||||
if (!OVL_TYPE_UPPER(type) || OVL_TYPE_MERGE(type))
|
||||
ovl_path_lowerdata(dentry, path);
|
||||
else
|
||||
ovl_path_upper(dentry, path);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
struct dentry *ovl_dentry_upper(struct dentry *dentry)
|
||||
{
|
||||
return ovl_upperdentry_dereference(OVL_I(d_inode(dentry)));
|
||||
|
|
Загрузка…
Ссылка в новой задаче