Re: [PATCH v3 9/9] fuse: implement ->tmpfile()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Sep 20, 2022 at 09:36:32PM +0200, Miklos Szeredi wrote:
> This is basically equivalent to the FUSE_CREATE operation which creates and
> opens a regular file.
> 
> Add a new FUSE_TMPFILE operation, otherwise just reuse the protocol and the
> code for FUSE_CREATE.
> 
> Signed-off-by: Miklos Szeredi <mszeredi@xxxxxxxxxx>
> ---
>  fs/fuse/dir.c             | 25 ++++++++++++++++++++++---
>  fs/fuse/fuse_i.h          |  3 +++
>  include/uapi/linux/fuse.h |  6 +++++-
>  3 files changed, 30 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
> index b585b04e815e..01b2d5c5a64a 100644
> --- a/fs/fuse/dir.c
> +++ b/fs/fuse/dir.c
> @@ -529,7 +529,7 @@ static int get_security_context(struct dentry *entry, umode_t mode,
>   */
>  static int fuse_create_open(struct inode *dir, struct dentry *entry,
>  			    struct file *file, unsigned int flags,
> -			    umode_t mode)
> +			    umode_t mode, u32 opcode)
>  {
>  	int err;
>  	struct inode *inode;
> @@ -573,7 +573,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry,
>  		inarg.open_flags |= FUSE_OPEN_KILL_SUIDGID;
>  	}
>  
> -	args.opcode = FUSE_CREATE;
> +	args.opcode = opcode;
>  	args.nodeid = get_node_id(dir);
>  	args.in_numargs = 2;
>  	args.in_args[0].size = sizeof(inarg);
> @@ -676,7 +676,7 @@ static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
>  	if (fc->no_create)
>  		goto mknod;
>  
> -	err = fuse_create_open(dir, entry, file, flags, mode);
> +	err = fuse_create_open(dir, entry, file, flags, mode, FUSE_CREATE);
>  	if (err == -ENOSYS) {
>  		fc->no_create = 1;
>  		goto mknod;
> @@ -802,6 +802,24 @@ static int fuse_create(struct user_namespace *mnt_userns, struct inode *dir,
>  	return fuse_mknod(&init_user_ns, dir, entry, mode, 0);
>  }
>  
> +static int fuse_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
> +			struct file *file, umode_t mode)
> +{
> +	struct fuse_conn *fc = get_fuse_conn(dir);
> +	int err;
> +
> +	if (fc->no_tmpfile)
> +		goto no_tmpfile;
> +
> +	err = fuse_create_open(dir, file->f_path.dentry, file, file->f_flags, mode, FUSE_TMPFILE);
> +	if (err == -ENOSYS) {
> +		fc->no_tmpfile = 1;
> +no_tmpfile:
> +		err = -EOPNOTSUPP;
> +	}
> +	return err;
> +}

Hm, seems like this could avoid the goto into an if-block:

static int fuse_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
			struct file *file, umode_t mode)
{
	struct fuse_conn *fc = get_fuse_conn(dir);
	int err;

	if (fc->no_tmpfile)
		return -EOPNOTSUPP;

	err = fuse_create_open(dir, file->f_path.dentry, file, file->f_flags, mode, FUSE_TMPFILE);
	if (err == -ENOSYS) {
		fc->no_tmpfile = 1;
		err = -EOPNOTSUPP;
	}
	return err;
}

> +
>  static int fuse_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
>  		      struct dentry *entry, umode_t mode)
>  {
> @@ -1913,6 +1931,7 @@ static const struct inode_operations fuse_dir_inode_operations = {
>  	.setattr	= fuse_setattr,
>  	.create		= fuse_create,
>  	.atomic_open	= fuse_atomic_open,
> +	.tmpfile	= fuse_tmpfile,
>  	.mknod		= fuse_mknod,
>  	.permission	= fuse_permission,
>  	.getattr	= fuse_getattr,
> diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
> index 488b460e046f..98a9cf531873 100644
> --- a/fs/fuse/fuse_i.h
> +++ b/fs/fuse/fuse_i.h
> @@ -784,6 +784,9 @@ struct fuse_conn {
>  	/* Does the filesystem support per inode DAX? */
>  	unsigned int inode_dax:1;
>  
> +	/* Is tmpfile not implemented by fs? */
> +	unsigned int no_tmpfile:1;

Just a nit, it might be nicer to turn this into a positive, i.e.,
unsigned int has_tmpfile:1. Easier to understand as people usually
aren't great at processing negations.

> +
>  	/** The number of requests waiting for completion */
>  	atomic_t num_waiting;
>  
> diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h
> index d6ccee961891..76ee8f9e024a 100644
> --- a/include/uapi/linux/fuse.h
> +++ b/include/uapi/linux/fuse.h
> @@ -194,6 +194,9 @@
>   *  - add FUSE_SECURITY_CTX init flag
>   *  - add security context to create, mkdir, symlink, and mknod requests
>   *  - add FUSE_HAS_INODE_DAX, FUSE_ATTR_DAX
> + *
> + *  7.37
> + *  - add FUSE_TMPFILE
>   */
>  
>  #ifndef _LINUX_FUSE_H
> @@ -229,7 +232,7 @@
>  #define FUSE_KERNEL_VERSION 7
>  
>  /** Minor version number of this interface */
> -#define FUSE_KERNEL_MINOR_VERSION 36
> +#define FUSE_KERNEL_MINOR_VERSION 37
>  
>  /** The node ID of the root inode */
>  #define FUSE_ROOT_ID 1
> @@ -537,6 +540,7 @@ enum fuse_opcode {
>  	FUSE_SETUPMAPPING	= 48,
>  	FUSE_REMOVEMAPPING	= 49,
>  	FUSE_SYNCFS		= 50,
> +	FUSE_TMPFILE		= 51,
>  
>  	/* CUSE specific operations */
>  	CUSE_INIT		= 4096,
> -- 
> 2.37.3
> 



[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux