Skip to content

Commit 87a8a76

Browse files
committed
ovl: allocate a container struct ovl_file for ovl private context
Instead of using ->private_data to point at realfile directly, so that we can add more context per ovl open file. Signed-off-by: Amir Goldstein <amir73il@gmail.com>
1 parent c2c54b5 commit 87a8a76

File tree

3 files changed

+48
-9
lines changed

3 files changed

+48
-9
lines changed

fs/overlayfs/dir.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,6 +1323,7 @@ static int ovl_create_tmpfile(struct file *file, struct dentry *dentry,
13231323
const struct cred *old_cred, *new_cred = NULL;
13241324
struct path realparentpath;
13251325
struct file *realfile;
1326+
struct ovl_file *of;
13261327
struct dentry *newdentry;
13271328
/* It's okay to set O_NOATIME, since the owner will be current fsuid */
13281329
int flags = file->f_flags | OVL_OPEN_FLAGS;
@@ -1344,14 +1345,21 @@ static int ovl_create_tmpfile(struct file *file, struct dentry *dentry,
13441345
if (err)
13451346
goto out_revert_creds;
13461347

1348+
of = ovl_file_alloc(realfile);
1349+
if (!of) {
1350+
fput(realfile);
1351+
err = -ENOMEM;
1352+
goto out_revert_creds;
1353+
}
1354+
13471355
/* ovl_instantiate() consumes the newdentry reference on success */
13481356
newdentry = dget(realfile->f_path.dentry);
13491357
err = ovl_instantiate(dentry, inode, newdentry, false, file);
13501358
if (!err) {
1351-
file->private_data = realfile;
1359+
file->private_data = of;
13521360
} else {
13531361
dput(newdentry);
1354-
fput(realfile);
1362+
ovl_file_free(of);
13551363
}
13561364
out_revert_creds:
13571365
ovl_revert_creds(old_cred);
@@ -1407,7 +1415,7 @@ static int ovl_tmpfile(struct mnt_idmap *idmap, struct inode *dir,
14071415
put_realfile:
14081416
/* Without FMODE_OPENED ->release() won't be called on @file */
14091417
if (!(file->f_mode & FMODE_OPENED))
1410-
fput(file->private_data);
1418+
ovl_file_free(file->private_data);
14111419
put_inode:
14121420
iput(inode);
14131421
drop_write:

fs/overlayfs/file.c

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,32 @@ static int ovl_change_flags(struct file *file, unsigned int flags)
8989
return 0;
9090
}
9191

92+
struct ovl_file {
93+
struct file *realfile;
94+
};
95+
96+
struct ovl_file *ovl_file_alloc(struct file *realfile)
97+
{
98+
struct ovl_file *of = kzalloc(sizeof(struct ovl_file), GFP_KERNEL);
99+
100+
if (unlikely(!of))
101+
return NULL;
102+
103+
of->realfile = realfile;
104+
return of;
105+
}
106+
107+
void ovl_file_free(struct ovl_file *of)
108+
{
109+
fput(of->realfile);
110+
kfree(of);
111+
}
112+
92113
static int ovl_real_fdget_path(const struct file *file, struct fd *real,
93114
struct path *realpath)
94115
{
95-
struct file *realfile = file->private_data;
116+
struct ovl_file *of = file->private_data;
117+
struct file *realfile = of->realfile;
96118

97119
real->word = (unsigned long)realfile;
98120

@@ -144,6 +166,7 @@ static int ovl_open(struct inode *inode, struct file *file)
144166
struct dentry *dentry = file_dentry(file);
145167
struct file *realfile;
146168
struct path realpath;
169+
struct ovl_file *of;
147170
int err;
148171

149172
/* lazy lookup and verify lowerdata */
@@ -166,15 +189,20 @@ static int ovl_open(struct inode *inode, struct file *file)
166189
if (IS_ERR(realfile))
167190
return PTR_ERR(realfile);
168191

169-
file->private_data = realfile;
192+
of = ovl_file_alloc(realfile);
193+
if (!of) {
194+
fput(realfile);
195+
return -ENOMEM;
196+
}
197+
198+
file->private_data = of;
170199

171200
return 0;
172201
}
173202

174203
static int ovl_release(struct inode *inode, struct file *file)
175204
{
176-
fput(file->private_data);
177-
205+
ovl_file_free(file->private_data);
178206
return 0;
179207
}
180208

@@ -426,13 +454,13 @@ static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync)
426454

427455
static int ovl_mmap(struct file *file, struct vm_area_struct *vma)
428456
{
429-
struct file *realfile = file->private_data;
457+
struct ovl_file *of = file->private_data;
430458
struct backing_file_ctx ctx = {
431459
.cred = ovl_creds(file_inode(file)->i_sb),
432460
.accessed = ovl_file_accessed,
433461
};
434462

435-
return backing_file_mmap(realfile, vma, &ctx);
463+
return backing_file_mmap(of->realfile, vma, &ctx);
436464
}
437465

438466
static long ovl_fallocate(struct file *file, int mode, loff_t offset, loff_t len)

fs/overlayfs/overlayfs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,9 @@ int ovl_real_fileattr_set(const struct path *realpath, struct fileattr *fa);
863863
int ovl_fileattr_get(struct dentry *dentry, struct fileattr *fa);
864864
int ovl_fileattr_set(struct mnt_idmap *idmap,
865865
struct dentry *dentry, struct fileattr *fa);
866+
struct ovl_file;
867+
struct ovl_file *ovl_file_alloc(struct file *realfile);
868+
void ovl_file_free(struct ovl_file *of);
866869

867870
/* copy_up.c */
868871
int ovl_copy_up(struct dentry *dentry);

0 commit comments

Comments
 (0)