Commit b9d54c6f authored by Miklos Szeredi's avatar Miklos Szeredi
Browse files

fuse: add internal open/release helpers



Clean out 'struct file' from internal helpers.

Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent 54d601cb
Loading
Loading
Loading
Loading
+33 −17
Original line number Original line Diff line number Diff line
@@ -19,14 +19,15 @@
#include <linux/uio.h>
#include <linux/uio.h>
#include <linux/fs.h>
#include <linux/fs.h>


static int fuse_send_open(struct fuse_mount *fm, u64 nodeid, struct file *file,
static int fuse_send_open(struct fuse_mount *fm, u64 nodeid,
			  int opcode, struct fuse_open_out *outargp)
			  unsigned int open_flags, int opcode,
			  struct fuse_open_out *outargp)
{
{
	struct fuse_open_in inarg;
	struct fuse_open_in inarg;
	FUSE_ARGS(args);
	FUSE_ARGS(args);


	memset(&inarg, 0, sizeof(inarg));
	memset(&inarg, 0, sizeof(inarg));
	inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY);
	inarg.flags = open_flags & ~(O_CREAT | O_EXCL | O_NOCTTY);
	if (!fm->fc->atomic_o_trunc)
	if (!fm->fc->atomic_o_trunc)
		inarg.flags &= ~O_TRUNC;
		inarg.flags &= ~O_TRUNC;


@@ -123,8 +124,8 @@ static void fuse_file_put(struct fuse_file *ff, bool sync, bool isdir)
	}
	}
}
}


int fuse_do_open(struct fuse_mount *fm, u64 nodeid, struct file *file,
struct fuse_file *fuse_file_open(struct fuse_mount *fm, u64 nodeid,
		 bool isdir)
				 unsigned int open_flags, bool isdir)
{
{
	struct fuse_conn *fc = fm->fc;
	struct fuse_conn *fc = fm->fc;
	struct fuse_file *ff;
	struct fuse_file *ff;
@@ -132,7 +133,7 @@ int fuse_do_open(struct fuse_mount *fm, u64 nodeid, struct file *file,


	ff = fuse_file_alloc(fm);
	ff = fuse_file_alloc(fm);
	if (!ff)
	if (!ff)
		return -ENOMEM;
		return ERR_PTR(-ENOMEM);


	ff->fh = 0;
	ff->fh = 0;
	/* Default for no-open */
	/* Default for no-open */
@@ -141,14 +142,14 @@ int fuse_do_open(struct fuse_mount *fm, u64 nodeid, struct file *file,
		struct fuse_open_out outarg;
		struct fuse_open_out outarg;
		int err;
		int err;


		err = fuse_send_open(fm, nodeid, file, opcode, &outarg);
		err = fuse_send_open(fm, nodeid, open_flags, opcode, &outarg);
		if (!err) {
		if (!err) {
			ff->fh = outarg.fh;
			ff->fh = outarg.fh;
			ff->open_flags = outarg.open_flags;
			ff->open_flags = outarg.open_flags;


		} else if (err != -ENOSYS) {
		} else if (err != -ENOSYS) {
			fuse_file_free(ff);
			fuse_file_free(ff);
			return err;
			return ERR_PTR(err);
		} else {
		} else {
			if (isdir)
			if (isdir)
				fc->no_opendir = 1;
				fc->no_opendir = 1;
@@ -161,9 +162,19 @@ int fuse_do_open(struct fuse_mount *fm, u64 nodeid, struct file *file,
		ff->open_flags &= ~FOPEN_DIRECT_IO;
		ff->open_flags &= ~FOPEN_DIRECT_IO;


	ff->nodeid = nodeid;
	ff->nodeid = nodeid;

	return ff;
}

int fuse_do_open(struct fuse_mount *fm, u64 nodeid, struct file *file,
		 bool isdir)
{
	struct fuse_file *ff = fuse_file_open(fm, nodeid, file->f_flags, isdir);

	if (!IS_ERR(ff))
		file->private_data = ff;
		file->private_data = ff;


	return 0;
	return PTR_ERR_OR_ZERO(ff);
}
}
EXPORT_SYMBOL_GPL(fuse_do_open);
EXPORT_SYMBOL_GPL(fuse_do_open);


@@ -284,22 +295,21 @@ static void fuse_prepare_release(struct fuse_inode *fi, struct fuse_file *ff,
	ra->args.nocreds = true;
	ra->args.nocreds = true;
}
}


void fuse_release_common(struct file *file, bool isdir)
void fuse_file_release(struct inode *inode, struct fuse_file *ff,
		       unsigned int open_flags, fl_owner_t id, bool isdir)
{
{
	struct fuse_inode *fi = get_fuse_inode(file_inode(file));
	struct fuse_inode *fi = get_fuse_inode(inode);
	struct fuse_file *ff = file->private_data;
	struct fuse_release_args *ra = ff->release_args;
	struct fuse_release_args *ra = ff->release_args;
	int opcode = isdir ? FUSE_RELEASEDIR : FUSE_RELEASE;
	int opcode = isdir ? FUSE_RELEASEDIR : FUSE_RELEASE;


	fuse_prepare_release(fi, ff, file->f_flags, opcode);
	fuse_prepare_release(fi, ff, open_flags, opcode);


	if (ff->flock) {
	if (ff->flock) {
		ra->inarg.release_flags |= FUSE_RELEASE_FLOCK_UNLOCK;
		ra->inarg.release_flags |= FUSE_RELEASE_FLOCK_UNLOCK;
		ra->inarg.lock_owner = fuse_lock_owner_id(ff->fm->fc,
		ra->inarg.lock_owner = fuse_lock_owner_id(ff->fm->fc, id);
							  (fl_owner_t) file);
	}
	}
	/* Hold inode until release is finished */
	/* Hold inode until release is finished */
	ra->inode = igrab(file_inode(file));
	ra->inode = igrab(inode);


	/*
	/*
	 * Normally this will send the RELEASE request, however if
	 * Normally this will send the RELEASE request, however if
@@ -313,6 +323,12 @@ void fuse_release_common(struct file *file, bool isdir)
	fuse_file_put(ff, ff->fm->fc->destroy, isdir);
	fuse_file_put(ff, ff->fm->fc->destroy, isdir);
}
}


void fuse_release_common(struct file *file, bool isdir)
{
	fuse_file_release(file_inode(file), file->private_data, file->f_flags,
			  (fl_owner_t) file, isdir);
}

static int fuse_open(struct inode *inode, struct file *file)
static int fuse_open(struct inode *inode, struct file *file)
{
{
	return fuse_open_common(inode, file, false);
	return fuse_open_common(inode, file, false);
+7 −0
Original line number Original line Diff line number Diff line
@@ -1242,4 +1242,11 @@ long fuse_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
long fuse_file_compat_ioctl(struct file *file, unsigned int cmd,
long fuse_file_compat_ioctl(struct file *file, unsigned int cmd,
			    unsigned long arg);
			    unsigned long arg);


/* file.c */

struct fuse_file *fuse_file_open(struct fuse_mount *fm, u64 nodeid,
				 unsigned int open_flags, bool isdir);
void fuse_file_release(struct inode *inode, struct fuse_file *ff,
		       unsigned int open_flags, fl_owner_t id, bool isdir);

#endif /* _FS_FUSE_I_H */
#endif /* _FS_FUSE_I_H */