summaryrefslogtreecommitdiffstats
path: root/fs/overlayfs/dir.c
diff options
context:
space:
mode:
authorAmir Goldstein <amir73il@gmail.com>2024-10-07 15:22:29 +0200
committerAmir Goldstein <amir73il@gmail.com>2024-11-15 08:56:48 +0100
commit87a8a76c34a2ae6f667cc33249dc99705e363d1f (patch)
tree7b027644d0b4f252aa90e3b468eba00845de8e7b /fs/overlayfs/dir.c
parentovl: do not open non-data lower file for fsync (diff)
downloadlinux-87a8a76c34a2ae6f667cc33249dc99705e363d1f.tar.xz
linux-87a8a76c34a2ae6f667cc33249dc99705e363d1f.zip
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>
Diffstat (limited to 'fs/overlayfs/dir.c')
-rw-r--r--fs/overlayfs/dir.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
index 5cf529482a8a..08e683917d12 100644
--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -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: