diff mbox series

[v3,4/9] cachefiles: use tmpfile_open() helper

Message ID 20220920193632.2215598-5-mszeredi@redhat.com (mailing list archive)
State New, archived
Headers show
Series fuse tmpfile | expand

Commit Message

Miklos Szeredi Sept. 20, 2022, 7:36 p.m. UTC
Use the tmpfile_open() helper instead of doing tmpfile creation and opening
separately.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
---
 fs/cachefiles/namei.c | 26 ++++++++++----------------
 1 file changed, 10 insertions(+), 16 deletions(-)

Comments

Christian Brauner Sept. 21, 2022, 8:26 a.m. UTC | #1
On Tue, Sep 20, 2022 at 09:36:27PM +0200, Miklos Szeredi wrote:
> Use the tmpfile_open() helper instead of doing tmpfile creation and opening
> separately.
> 
> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
> ---
>  fs/cachefiles/namei.c | 26 ++++++++++----------------
>  1 file changed, 10 insertions(+), 16 deletions(-)
> 
> diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
> index d3a5884fe5c9..44f575328af4 100644
> --- a/fs/cachefiles/namei.c
> +++ b/fs/cachefiles/namei.c
> @@ -451,18 +451,19 @@ struct file *cachefiles_create_tmpfile(struct cachefiles_object *object)
>  	const struct cred *saved_cred;
>  	struct dentry *fan = volume->fanout[(u8)object->cookie->key_hash];
>  	struct file *file;
> -	struct path path;
> +	struct path path = { .mnt = cache->mnt, .dentry = fan };
>  	uint64_t ni_size;
>  	long ret;

Maybe we shouldn't use struct path to first refer to the parent path and
then to the tmp path to avoid any potential confusion and instead rely
on a compount initializer for the tmpfile_open() call (__not tested__)?:

diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
index 44f575328af4..979b2f173ac3 100644
--- a/fs/cachefiles/namei.c
+++ b/fs/cachefiles/namei.c
@@ -451,7 +451,7 @@ struct file *cachefiles_create_tmpfile(struct cachefiles_object *object)
        const struct cred *saved_cred;
        struct dentry *fan = volume->fanout[(u8)object->cookie->key_hash];
        struct file *file;
-       struct path path = { .mnt = cache->mnt, .dentry = fan };
+       struct path path;
        uint64_t ni_size;
        long ret;

@@ -460,8 +460,10 @@ struct file *cachefiles_create_tmpfile(struct cachefiles_object *object)

        ret = cachefiles_inject_write_error();
        if (ret == 0) {
-               file = tmpfile_open(&init_user_ns, &path, S_IFREG,
-                                   O_RDWR | O_LARGEFILE | O_DIRECT,
+               file = tmpfile_open(&init_user_ns,
+                                   &{const struct path} {.mnt = cache->mnt,
+                                                         .dentry = fan},
+                                   S_IFREG, O_RDWR | O_LARGEFILE | O_DIRECT,
                                    cache->cache_cred);
                ret = PTR_ERR_OR_ZERO(file);
        }
@@ -472,7 +474,9 @@ struct file *cachefiles_create_tmpfile(struct cachefiles_object *object)
                        cachefiles_io_error_obj(object, "Failed to create tmpfile");
                goto err;
        }
-       /* From now path refers to the tmpfile */
+
+       /* prepare tmp path */
+       path.mnt = cache->mnt;
        path.dentry = file->f_path.dentry;

        trace_cachefiles_tmpfile(object, d_backing_inode(path.dentry));
Miklos Szeredi Sept. 21, 2022, 2:44 p.m. UTC | #2
On Wed, 21 Sept 2022 at 10:27, Christian Brauner <brauner@kernel.org> wrote:
>
> On Tue, Sep 20, 2022 at 09:36:27PM +0200, Miklos Szeredi wrote:
> > Use the tmpfile_open() helper instead of doing tmpfile creation and opening
> > separately.
> >
> > Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
> > ---
> >  fs/cachefiles/namei.c | 26 ++++++++++----------------
> >  1 file changed, 10 insertions(+), 16 deletions(-)
> >
> > diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
> > index d3a5884fe5c9..44f575328af4 100644
> > --- a/fs/cachefiles/namei.c
> > +++ b/fs/cachefiles/namei.c
> > @@ -451,18 +451,19 @@ struct file *cachefiles_create_tmpfile(struct cachefiles_object *object)
> >       const struct cred *saved_cred;
> >       struct dentry *fan = volume->fanout[(u8)object->cookie->key_hash];
> >       struct file *file;
> > -     struct path path;
> > +     struct path path = { .mnt = cache->mnt, .dentry = fan };
> >       uint64_t ni_size;
> >       long ret;
>
> Maybe we shouldn't use struct path to first refer to the parent path and
> then to the tmp path to avoid any potential confusion and instead rely
> on a compount initializer for the tmpfile_open() call (__not tested__)?:
>
> diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
> index 44f575328af4..979b2f173ac3 100644
> --- a/fs/cachefiles/namei.c
> +++ b/fs/cachefiles/namei.c
> @@ -451,7 +451,7 @@ struct file *cachefiles_create_tmpfile(struct cachefiles_object *object)
>         const struct cred *saved_cred;
>         struct dentry *fan = volume->fanout[(u8)object->cookie->key_hash];
>         struct file *file;
> -       struct path path = { .mnt = cache->mnt, .dentry = fan };
> +       struct path path;
>         uint64_t ni_size;
>         long ret;
>
> @@ -460,8 +460,10 @@ struct file *cachefiles_create_tmpfile(struct cachefiles_object *object)
>
>         ret = cachefiles_inject_write_error();
>         if (ret == 0) {
> -               file = tmpfile_open(&init_user_ns, &path, S_IFREG,
> -                                   O_RDWR | O_LARGEFILE | O_DIRECT,
> +               file = tmpfile_open(&init_user_ns,
> +                                   &{const struct path} {.mnt = cache->mnt,
> +                                                         .dentry = fan},

This doesn't look nice.   I fixed it with a separate "parentpath" variable.

Thanks,
Miklos
Al Viro Sept. 21, 2022, 7:46 p.m. UTC | #3
On Wed, Sep 21, 2022 at 10:26:12AM +0200, Christian Brauner wrote:
> -       /* From now path refers to the tmpfile */
> +
> +       /* prepare tmp path */
> +       path.mnt = cache->mnt;
>         path.dentry = file->f_path.dentry;

Do we even want that struct path from that point on?  Look:

	d_backing_inode(path.dentry) is a weird way to spell file_inode(file).

	cachefiles_mark_inode_in_use() is an overkill here - it *can't* fail
here, so all we want is
	inode_lock(inode);
	inode->i_flags |= S_KERNEL_FILE;
	trace_cachefiles_mark_active(object, inode);
	inode_unlock(inode);
where inode is, again, file_inode(file).

	cachefiles_do_unmark_inode_in_use() uses only inode.

	vfs_truncate() could use &file->f_path, but there's a potentially
nastier problem - theoretically, there are filesystems where we might
want struct file available for operation, especially for opened-and-unlinked
equivalents.  In any case, &file->f_path would do just as well as its copy.
Christian Brauner Sept. 22, 2022, 8:04 a.m. UTC | #4
On Wed, Sep 21, 2022 at 08:46:20PM +0100, Al Viro wrote:
> On Wed, Sep 21, 2022 at 10:26:12AM +0200, Christian Brauner wrote:
> > -       /* From now path refers to the tmpfile */
> > +
> > +       /* prepare tmp path */
> > +       path.mnt = cache->mnt;
> >         path.dentry = file->f_path.dentry;
> 
> Do we even want that struct path from that point on?  Look:
> 
> 	d_backing_inode(path.dentry) is a weird way to spell file_inode(file).
> 
> 	cachefiles_mark_inode_in_use() is an overkill here - it *can't* fail
> here, so all we want is
> 	inode_lock(inode);
> 	inode->i_flags |= S_KERNEL_FILE;
> 	trace_cachefiles_mark_active(object, inode);
> 	inode_unlock(inode);
> where inode is, again, file_inode(file).
> 
> 	cachefiles_do_unmark_inode_in_use() uses only inode.
> 
> 	vfs_truncate() could use &file->f_path, but there's a potentially
> nastier problem - theoretically, there are filesystems where we might
> want struct file available for operation, especially for opened-and-unlinked
> equivalents.  In any case, &file->f_path would do just as well as its copy.

Yeah, sounds reasonable.
diff mbox series

Patch

diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
index d3a5884fe5c9..44f575328af4 100644
--- a/fs/cachefiles/namei.c
+++ b/fs/cachefiles/namei.c
@@ -451,18 +451,19 @@  struct file *cachefiles_create_tmpfile(struct cachefiles_object *object)
 	const struct cred *saved_cred;
 	struct dentry *fan = volume->fanout[(u8)object->cookie->key_hash];
 	struct file *file;
-	struct path path;
+	struct path path = { .mnt = cache->mnt, .dentry = fan };
 	uint64_t ni_size;
 	long ret;
 
 
 	cachefiles_begin_secure(cache, &saved_cred);
 
-	path.mnt = cache->mnt;
 	ret = cachefiles_inject_write_error();
 	if (ret == 0) {
-		path.dentry = vfs_tmpfile(&init_user_ns, fan, S_IFREG, O_RDWR);
-		ret = PTR_ERR_OR_ZERO(path.dentry);
+		file = tmpfile_open(&init_user_ns, &path, S_IFREG,
+				    O_RDWR | O_LARGEFILE | O_DIRECT,
+				    cache->cache_cred);
+		ret = PTR_ERR_OR_ZERO(file);
 	}
 	if (ret) {
 		trace_cachefiles_vfs_error(object, d_inode(fan), ret,
@@ -471,12 +472,14 @@  struct file *cachefiles_create_tmpfile(struct cachefiles_object *object)
 			cachefiles_io_error_obj(object, "Failed to create tmpfile");
 		goto err;
 	}
+	/* From now path refers to the tmpfile */
+	path.dentry = file->f_path.dentry;
 
 	trace_cachefiles_tmpfile(object, d_backing_inode(path.dentry));
 
 	ret = -EBUSY;
 	if (!cachefiles_mark_inode_in_use(object, path.dentry))
-		goto err_dput;
+		goto err_fput;
 
 	ret = cachefiles_ondemand_init_object(object);
 	if (ret < 0)
@@ -499,14 +502,6 @@  struct file *cachefiles_create_tmpfile(struct cachefiles_object *object)
 		}
 	}
 
-	file = open_with_fake_path(&path, O_RDWR | O_LARGEFILE | O_DIRECT,
-				   d_backing_inode(path.dentry), cache->cache_cred);
-	ret = PTR_ERR(file);
-	if (IS_ERR(file)) {
-		trace_cachefiles_vfs_error(object, d_backing_inode(path.dentry),
-					   ret, cachefiles_trace_open_error);
-		goto err_unuse;
-	}
 	ret = -EINVAL;
 	if (unlikely(!file->f_op->read_iter) ||
 	    unlikely(!file->f_op->write_iter)) {
@@ -514,15 +509,14 @@  struct file *cachefiles_create_tmpfile(struct cachefiles_object *object)
 		pr_notice("Cache does not support read_iter and write_iter\n");
 		goto err_unuse;
 	}
-	dput(path.dentry);
 out:
 	cachefiles_end_secure(cache, saved_cred);
 	return file;
 
 err_unuse:
 	cachefiles_do_unmark_inode_in_use(object, path.dentry);
-err_dput:
-	dput(path.dentry);
+err_fput:
+	fput(file);
 err:
 	file = ERR_PTR(ret);
 	goto out;