Skip to content

Commit 1248ea4

Browse files
amir73ilMiklos Szeredi
authored andcommitted
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>
1 parent 5272eaf commit 1248ea4

3 files changed

Lines changed: 28 additions & 9 deletions

File tree

fs/overlayfs/file.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@ static char ovl_whatisit(struct inode *inode, struct inode *realinode)
3838
#define OVL_OPEN_FLAGS (O_NOATIME | FMODE_NONOTIFY)
3939

4040
static struct file *ovl_open_realfile(const struct file *file,
41-
struct inode *realinode)
41+
struct path *realpath)
4242
{
43+
struct inode *realinode = d_inode(realpath->dentry);
4344
struct inode *inode = file_inode(file);
4445
struct file *realfile;
4546
const struct cred *old_cred;
@@ -104,21 +105,21 @@ static int ovl_change_flags(struct file *file, unsigned int flags)
104105
static int ovl_real_fdget_meta(const struct file *file, struct fd *real,
105106
bool allow_meta)
106107
{
107-
struct inode *inode = file_inode(file);
108-
struct inode *realinode;
108+
struct dentry *dentry = file_dentry(file);
109+
struct path realpath;
109110

110111
real->flags = 0;
111112
real->file = file->private_data;
112113

113114
if (allow_meta)
114-
realinode = ovl_inode_real(inode);
115+
ovl_path_real(dentry, &realpath);
115116
else
116-
realinode = ovl_inode_realdata(inode);
117+
ovl_path_realdata(dentry, &realpath);
117118

118119
/* Has it been copied up since we'd opened it? */
119-
if (unlikely(file_inode(real->file) != realinode)) {
120+
if (unlikely(file_inode(real->file) != d_inode(realpath.dentry))) {
120121
real->flags = FDPUT_FPUT;
121-
real->file = ovl_open_realfile(file, realinode);
122+
real->file = ovl_open_realfile(file, &realpath);
122123

123124
return PTR_ERR_OR_ZERO(real->file);
124125
}
@@ -144,17 +145,20 @@ static int ovl_real_fdget(const struct file *file, struct fd *real)
144145

145146
static int ovl_open(struct inode *inode, struct file *file)
146147
{
148+
struct dentry *dentry = file_dentry(file);
147149
struct file *realfile;
150+
struct path realpath;
148151
int err;
149152

150-
err = ovl_maybe_copy_up(file_dentry(file), file->f_flags);
153+
err = ovl_maybe_copy_up(dentry, file->f_flags);
151154
if (err)
152155
return err;
153156

154157
/* No longer need these flags, so don't pass them on to underlying fs */
155158
file->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
156159

157-
realfile = ovl_open_realfile(file, ovl_inode_realdata(inode));
160+
ovl_path_realdata(dentry, &realpath);
161+
realfile = ovl_open_realfile(file, &realpath);
158162
if (IS_ERR(realfile))
159163
return PTR_ERR(realfile);
160164

fs/overlayfs/overlayfs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ void ovl_path_upper(struct dentry *dentry, struct path *path);
320320
void ovl_path_lower(struct dentry *dentry, struct path *path);
321321
void ovl_path_lowerdata(struct dentry *dentry, struct path *path);
322322
enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path);
323+
enum ovl_path_type ovl_path_realdata(struct dentry *dentry, struct path *path);
323324
struct dentry *ovl_dentry_upper(struct dentry *dentry);
324325
struct dentry *ovl_dentry_lower(struct dentry *dentry);
325326
struct dentry *ovl_dentry_lowerdata(struct dentry *dentry);

fs/overlayfs/util.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,20 @@ enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path)
194194
return type;
195195
}
196196

197+
enum ovl_path_type ovl_path_realdata(struct dentry *dentry, struct path *path)
198+
{
199+
enum ovl_path_type type = ovl_path_type(dentry);
200+
201+
WARN_ON_ONCE(d_is_dir(dentry));
202+
203+
if (!OVL_TYPE_UPPER(type) || OVL_TYPE_MERGE(type))
204+
ovl_path_lowerdata(dentry, path);
205+
else
206+
ovl_path_upper(dentry, path);
207+
208+
return type;
209+
}
210+
197211
struct dentry *ovl_dentry_upper(struct dentry *dentry)
198212
{
199213
return ovl_upperdentry_dereference(OVL_I(d_inode(dentry)));

0 commit comments

Comments
 (0)