mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2024-12-28 16:53:49 +00:00
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>
This commit is contained in:
parent
c2c54b5f34
commit
87a8a76c34
@ -1323,6 +1323,7 @@ static int ovl_create_tmpfile(struct file *file, struct dentry *dentry,
|
||||
const struct cred *old_cred, *new_cred = NULL;
|
||||
struct path realparentpath;
|
||||
struct file *realfile;
|
||||
struct ovl_file *of;
|
||||
struct dentry *newdentry;
|
||||
/* It's okay to set O_NOATIME, since the owner will be current fsuid */
|
||||
int flags = file->f_flags | OVL_OPEN_FLAGS;
|
||||
@ -1344,14 +1345,21 @@ static int ovl_create_tmpfile(struct file *file, struct dentry *dentry,
|
||||
if (err)
|
||||
goto out_revert_creds;
|
||||
|
||||
of = ovl_file_alloc(realfile);
|
||||
if (!of) {
|
||||
fput(realfile);
|
||||
err = -ENOMEM;
|
||||
goto out_revert_creds;
|
||||
}
|
||||
|
||||
/* ovl_instantiate() consumes the newdentry reference on success */
|
||||
newdentry = dget(realfile->f_path.dentry);
|
||||
err = ovl_instantiate(dentry, inode, newdentry, false, file);
|
||||
if (!err) {
|
||||
file->private_data = realfile;
|
||||
file->private_data = of;
|
||||
} else {
|
||||
dput(newdentry);
|
||||
fput(realfile);
|
||||
ovl_file_free(of);
|
||||
}
|
||||
out_revert_creds:
|
||||
ovl_revert_creds(old_cred);
|
||||
@ -1407,7 +1415,7 @@ static int ovl_tmpfile(struct mnt_idmap *idmap, struct inode *dir,
|
||||
put_realfile:
|
||||
/* Without FMODE_OPENED ->release() won't be called on @file */
|
||||
if (!(file->f_mode & FMODE_OPENED))
|
||||
fput(file->private_data);
|
||||
ovl_file_free(file->private_data);
|
||||
put_inode:
|
||||
iput(inode);
|
||||
drop_write:
|
||||
|
@ -89,10 +89,32 @@ static int ovl_change_flags(struct file *file, unsigned int flags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ovl_file {
|
||||
struct file *realfile;
|
||||
};
|
||||
|
||||
struct ovl_file *ovl_file_alloc(struct file *realfile)
|
||||
{
|
||||
struct ovl_file *of = kzalloc(sizeof(struct ovl_file), GFP_KERNEL);
|
||||
|
||||
if (unlikely(!of))
|
||||
return NULL;
|
||||
|
||||
of->realfile = realfile;
|
||||
return of;
|
||||
}
|
||||
|
||||
void ovl_file_free(struct ovl_file *of)
|
||||
{
|
||||
fput(of->realfile);
|
||||
kfree(of);
|
||||
}
|
||||
|
||||
static int ovl_real_fdget_path(const struct file *file, struct fd *real,
|
||||
struct path *realpath)
|
||||
{
|
||||
struct file *realfile = file->private_data;
|
||||
struct ovl_file *of = file->private_data;
|
||||
struct file *realfile = of->realfile;
|
||||
|
||||
real->word = (unsigned long)realfile;
|
||||
|
||||
@ -144,6 +166,7 @@ static int ovl_open(struct inode *inode, struct file *file)
|
||||
struct dentry *dentry = file_dentry(file);
|
||||
struct file *realfile;
|
||||
struct path realpath;
|
||||
struct ovl_file *of;
|
||||
int err;
|
||||
|
||||
/* lazy lookup and verify lowerdata */
|
||||
@ -166,15 +189,20 @@ static int ovl_open(struct inode *inode, struct file *file)
|
||||
if (IS_ERR(realfile))
|
||||
return PTR_ERR(realfile);
|
||||
|
||||
file->private_data = realfile;
|
||||
of = ovl_file_alloc(realfile);
|
||||
if (!of) {
|
||||
fput(realfile);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
file->private_data = of;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ovl_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
fput(file->private_data);
|
||||
|
||||
ovl_file_free(file->private_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -426,13 +454,13 @@ static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync)
|
||||
|
||||
static int ovl_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
{
|
||||
struct file *realfile = file->private_data;
|
||||
struct ovl_file *of = file->private_data;
|
||||
struct backing_file_ctx ctx = {
|
||||
.cred = ovl_creds(file_inode(file)->i_sb),
|
||||
.accessed = ovl_file_accessed,
|
||||
};
|
||||
|
||||
return backing_file_mmap(realfile, vma, &ctx);
|
||||
return backing_file_mmap(of->realfile, vma, &ctx);
|
||||
}
|
||||
|
||||
static long ovl_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
|
||||
|
@ -863,6 +863,9 @@ int ovl_real_fileattr_set(const struct path *realpath, struct fileattr *fa);
|
||||
int ovl_fileattr_get(struct dentry *dentry, struct fileattr *fa);
|
||||
int ovl_fileattr_set(struct mnt_idmap *idmap,
|
||||
struct dentry *dentry, struct fileattr *fa);
|
||||
struct ovl_file;
|
||||
struct ovl_file *ovl_file_alloc(struct file *realfile);
|
||||
void ovl_file_free(struct ovl_file *of);
|
||||
|
||||
/* copy_up.c */
|
||||
int ovl_copy_up(struct dentry *dentry);
|
||||
|
Loading…
Reference in New Issue
Block a user