Skip to content

Commit

Permalink
fuse: implement ->tmpfile()
Browse files Browse the repository at this point in the history
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.

Acked-by: Christian Brauner (Microsoft) <brauner@kernel.org>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
  • Loading branch information
Miklos Szeredi committed Sep 24, 2022
1 parent 863f144 commit 7d37539
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 4 deletions.
24 changes: 21 additions & 3 deletions fs/fuse/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -802,6 +802,23 @@ 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)
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)
{
Expand Down Expand Up @@ -1913,6 +1930,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,
Expand Down
3 changes: 3 additions & 0 deletions fs/fuse/fuse_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/** The number of requests waiting for completion */
atomic_t num_waiting;

Expand Down
6 changes: 5 additions & 1 deletion include/uapi/linux/fuse.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 7d37539

Please sign in to comment.