Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2c48b9c4 authored by Al Viro's avatar Al Viro
Browse files

switch alloc_file() to passing struct path



... and have the caller grab both mnt and dentry; kill
leak in infiniband, while we are at it.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent a95161aa
Loading
Loading
Loading
Loading
+8 −7
Original line number Diff line number Diff line
@@ -2200,7 +2200,7 @@ pfm_alloc_file(pfm_context_t *ctx)
{
	struct file *file;
	struct inode *inode;
	struct dentry *dentry;
	struct path path;
	char name[32];
	struct qstr this;

@@ -2225,18 +2225,19 @@ pfm_alloc_file(pfm_context_t *ctx)
	/*
	 * allocate a new dcache entry
	 */
	dentry = d_alloc(pfmfs_mnt->mnt_sb->s_root, &this);
	if (!dentry) {
	path.dentry = d_alloc(pfmfs_mnt->mnt_sb->s_root, &this);
	if (!path.dentry) {
		iput(inode);
		return ERR_PTR(-ENOMEM);
	}
	path.mnt = mntget(pfmfs_mnt);

	dentry->d_op = &pfmfs_dentry_operations;
	d_add(dentry, inode);
	path.dentry->d_op = &pfmfs_dentry_operations;
	d_add(path.dentry, inode);

	file = alloc_file(pfmfs_mnt, dentry, FMODE_READ, &pfm_file_ops);
	file = alloc_file(&path, FMODE_READ, &pfm_file_ops);
	if (!file) {
		dput(dentry);
		path_put(&path);
		return ERR_PTR(-ENFILE);
	}

+7 −2
Original line number Diff line number Diff line
@@ -492,6 +492,7 @@ struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
					int is_async, int *fd)
{
	struct ib_uverbs_event_file *ev_file;
	struct path path;
	struct file *filp;
	int ret;

@@ -519,8 +520,10 @@ struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
	 * system call on a uverbs file, which will already have a
	 * module reference.
	 */
	filp = alloc_file(uverbs_event_mnt, dget(uverbs_event_mnt->mnt_root),
			  FMODE_READ, fops_get(&uverbs_event_fops));
	path.mnt = uverbs_event_mnt;
	path.dentry = uverbs_event_mnt->mnt_root;
	path_get(&path);
	filp = alloc_file(&path, FMODE_READ, fops_get(&uverbs_event_fops));
	if (!filp) {
		ret = -ENFILE;
		goto err_fd;
@@ -531,6 +534,8 @@ struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
	return filp;

err_fd:
	fops_put(&uverbs_event_fops);
	path_put(&path);
	put_unused_fd(*fd);

err:
+9 −9
Original line number Diff line number Diff line
@@ -88,7 +88,7 @@ struct file *anon_inode_getfile(const char *name,
				void *priv, int flags)
{
	struct qstr this;
	struct dentry *dentry;
	struct path path;
	struct file *file;
	int error;

@@ -106,10 +106,11 @@ struct file *anon_inode_getfile(const char *name,
	this.name = name;
	this.len = strlen(name);
	this.hash = 0;
	dentry = d_alloc(anon_inode_mnt->mnt_sb->s_root, &this);
	if (!dentry)
	path.dentry = d_alloc(anon_inode_mnt->mnt_sb->s_root, &this);
	if (!path.dentry)
		goto err_module;

	path.mnt = mntget(anon_inode_mnt);
	/*
	 * We know the anon_inode inode count is always greater than zero,
	 * so we can avoid doing an igrab() and we can use an open-coded
@@ -117,14 +118,13 @@ struct file *anon_inode_getfile(const char *name,
	 */
	atomic_inc(&anon_inode_inode->i_count);

	dentry->d_op = &anon_inodefs_dentry_operations;
	path.dentry->d_op = &anon_inodefs_dentry_operations;
	/* Do not publish this dentry inside the global dentry hash table */
	dentry->d_flags &= ~DCACHE_UNHASHED;
	d_instantiate(dentry, anon_inode_inode);
	path.dentry->d_flags &= ~DCACHE_UNHASHED;
	d_instantiate(path.dentry, anon_inode_inode);

	error = -ENFILE;
	file = alloc_file(anon_inode_mnt, dentry,
			  FMODE_READ | FMODE_WRITE, fops);
	file = alloc_file(&path, FMODE_READ | FMODE_WRITE, fops);
	if (!file)
		goto err_dput;
	file->f_mapping = anon_inode_inode->i_mapping;
@@ -137,7 +137,7 @@ struct file *anon_inode_getfile(const char *name,
	return file;

err_dput:
	dput(dentry);
	path_put(&path);
err_module:
	module_put(fops->owner);
	return ERR_PTR(error);
+6 −7
Original line number Diff line number Diff line
@@ -162,8 +162,8 @@ struct file *get_empty_filp(void)
 * If all the callers of init_file() are eliminated, its
 * code should be moved into this function.
 */
struct file *alloc_file(struct vfsmount *mnt, struct dentry *dentry,
		fmode_t mode, const struct file_operations *fop)
struct file *alloc_file(struct path *path, fmode_t mode,
		const struct file_operations *fop)
{
	struct file *file;

@@ -171,9 +171,8 @@ struct file *alloc_file(struct vfsmount *mnt, struct dentry *dentry,
	if (!file)
		return NULL;

	file->f_path.dentry = dentry;
	file->f_path.mnt = mntget(mnt);
	file->f_mapping = dentry->d_inode->i_mapping;
	file->f_path = *path;
	file->f_mapping = path->dentry->d_inode->i_mapping;
	file->f_mode = mode;
	file->f_op = fop;

@@ -183,10 +182,10 @@ struct file *alloc_file(struct vfsmount *mnt, struct dentry *dentry,
	 * visible.  We do this for consistency, and so
	 * that we can do debugging checks at __fput()
	 */
	if ((mode & FMODE_WRITE) && !special_file(dentry->d_inode->i_mode)) {
	if ((mode & FMODE_WRITE) && !special_file(path->dentry->d_inode->i_mode)) {
		int error = 0;
		file_take_write(file);
		error = mnt_clone_write(mnt);
		error = mnt_clone_write(path->mnt);
		WARN_ON(error);
	}
	return file;
+8 −7
Original line number Diff line number Diff line
@@ -922,7 +922,8 @@ struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag,
	int error = -ENOMEM;
	struct file *file;
	struct inode *inode;
	struct dentry *dentry, *root;
	struct path path;
	struct dentry *root;
	struct qstr quick_string;

	*user = NULL;
@@ -944,10 +945,11 @@ struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag,
	quick_string.name = name;
	quick_string.len = strlen(quick_string.name);
	quick_string.hash = 0;
	dentry = d_alloc(root, &quick_string);
	if (!dentry)
	path.dentry = d_alloc(root, &quick_string);
	if (!path.dentry)
		goto out_shm_unlock;

	path.mnt = mntget(hugetlbfs_vfsmount);
	error = -ENOSPC;
	inode = hugetlbfs_get_inode(root->d_sb, current_fsuid(),
				current_fsgid(), S_IFREG | S_IRWXUGO, 0);
@@ -960,13 +962,12 @@ struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag,
			acctflag))
		goto out_inode;

	d_instantiate(dentry, inode);
	d_instantiate(path.dentry, inode);
	inode->i_size = size;
	inode->i_nlink = 0;

	error = -ENFILE;
	file = alloc_file(hugetlbfs_vfsmount, dentry,
			FMODE_WRITE | FMODE_READ,
	file = alloc_file(&path, FMODE_WRITE | FMODE_READ,
			&hugetlbfs_file_operations);
	if (!file)
		goto out_dentry; /* inode is already attached */
@@ -977,7 +978,7 @@ struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag,
out_inode:
	iput(inode);
out_dentry:
	dput(dentry);
	path_put(&path);
out_shm_unlock:
	if (*user) {
		user_shm_unlock(size, *user);
Loading