vfs: add vfs_tmpfile_open() helper
This helper unifies tmpfile creation with opening. Existing vfs_tmpfile() callers outside of fs/namei.c will be converted to using this helper. There are two such callers: cachefile and overlayfs. The cachefiles code currently uses the open_with_fake_path() helper to open the tmpfile, presumably to disable accounting of the open file. Overlayfs uses tmpfile for copy_up, which means these struct file instances will be short lived, hence it doesn't really matter if they are accounted or not. Disable accounting in this helper too, which should be okay for both callers. Add MAY_OPEN permission checking for consistency. Like for create(2) read/write permissions are not checked. Reviewed-by: Christian Brauner (Microsoft) <brauner@kernel.org> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
parent
521a547ced
commit
22873deac9
41
fs/namei.c
41
fs/namei.c
|
@ -3624,6 +3624,47 @@ out_err:
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(vfs_tmpfile);
|
EXPORT_SYMBOL(vfs_tmpfile);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vfs_tmpfile_open - open a tmpfile for kernel internal use
|
||||||
|
* @mnt_userns: user namespace of the mount the inode was found from
|
||||||
|
* @parentpath: path of the base directory
|
||||||
|
* @mode: mode of the new tmpfile
|
||||||
|
* @open_flag: flags
|
||||||
|
* @cred: credentials for open
|
||||||
|
*
|
||||||
|
* Create and open a temporary file. The file is not accounted in nr_files,
|
||||||
|
* hence this is only for kernel internal use, and must not be installed into
|
||||||
|
* file tables or such.
|
||||||
|
*/
|
||||||
|
struct file *vfs_tmpfile_open(struct user_namespace *mnt_userns,
|
||||||
|
const struct path *parentpath,
|
||||||
|
umode_t mode, int open_flag, const struct cred *cred)
|
||||||
|
{
|
||||||
|
struct file *file;
|
||||||
|
int error;
|
||||||
|
struct path path = { .mnt = parentpath->mnt };
|
||||||
|
|
||||||
|
path.dentry = vfs_tmpfile(mnt_userns, parentpath->dentry, mode, open_flag);
|
||||||
|
if (IS_ERR(path.dentry))
|
||||||
|
return ERR_CAST(path.dentry);
|
||||||
|
|
||||||
|
error = may_open(mnt_userns, &path, 0, open_flag);
|
||||||
|
file = ERR_PTR(error);
|
||||||
|
if (error)
|
||||||
|
goto out_dput;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This relies on the "noaccount" property of fake open, otherwise
|
||||||
|
* equivalent to dentry_open().
|
||||||
|
*/
|
||||||
|
file = open_with_fake_path(&path, open_flag, d_inode(path.dentry), cred);
|
||||||
|
out_dput:
|
||||||
|
dput(path.dentry);
|
||||||
|
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(vfs_tmpfile_open);
|
||||||
|
|
||||||
static int do_tmpfile(struct nameidata *nd, unsigned flags,
|
static int do_tmpfile(struct nameidata *nd, unsigned flags,
|
||||||
const struct open_flags *op,
|
const struct open_flags *op,
|
||||||
struct file *file)
|
struct file *file)
|
||||||
|
|
|
@ -2007,6 +2007,10 @@ static inline int vfs_whiteout(struct user_namespace *mnt_userns,
|
||||||
struct dentry *vfs_tmpfile(struct user_namespace *mnt_userns,
|
struct dentry *vfs_tmpfile(struct user_namespace *mnt_userns,
|
||||||
struct dentry *dentry, umode_t mode, int open_flag);
|
struct dentry *dentry, umode_t mode, int open_flag);
|
||||||
|
|
||||||
|
struct file *vfs_tmpfile_open(struct user_namespace *mnt_userns,
|
||||||
|
const struct path *parentpath,
|
||||||
|
umode_t mode, int open_flag, const struct cred *cred);
|
||||||
|
|
||||||
int vfs_mkobj(struct dentry *, umode_t,
|
int vfs_mkobj(struct dentry *, umode_t,
|
||||||
int (*f)(struct dentry *, umode_t, void *),
|
int (*f)(struct dentry *, umode_t, void *),
|
||||||
void *);
|
void *);
|
||||||
|
|
Loading…
Reference in New Issue