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

Commit b22d55b6 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "fs:fuse: Ensure update of fuse inode attributes in shortcircuit"

parents 4cd59b62 820c88f5
Loading
Loading
Loading
Loading
+5 −9
Original line number Diff line number Diff line
@@ -1210,15 +1210,6 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
	loff_t endbyte = 0;
	loff_t pos = iocb->ki_pos;

	if (ff && ff->rw_lower_file) {
		/* Update size (EOF optimization) and mode (SUID clearing) */
		err = fuse_update_attributes(mapping->host, NULL, file, NULL);
		if (err)
			return err;

		return fuse_shortcircuit_write_iter(iocb, from);
	}

	if (get_fuse_conn(inode)->writeback_cache) {
		/* Update size (EOF optimization) and mode (SUID clearing) */
		err = fuse_update_attributes(mapping->host, NULL, file, NULL);
@@ -1249,6 +1240,11 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
	if (err)
		goto out;

	if (ff && ff->rw_lower_file) {
		written = fuse_shortcircuit_write_iter(iocb, from);
		goto out;
	}

	if (file->f_flags & O_DIRECT) {
		written = generic_file_direct_write(iocb, from, pos);
		if (written < 0 || !iov_iter_count(from))
+2 −0
Original line number Diff line number Diff line
@@ -908,6 +908,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
			if (arg->flags & FUSE_SHORTCIRCUIT) {
				fc->writeback_cache = 0;
				fc->shortcircuit_io = 1;
				pr_info("FUSE: SHORTCIRCUIT enabled [%s : %d]!\n",
					current->comm, current->pid);
			}
			if (arg->time_gran && arg->time_gran <= 1000000000)
				fc->sb->s_time_gran = arg->time_gran;
+13 −1
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#include "fuse_shortcircuit.h"

#include <linux/aio.h>
#include <linux/fs_stack.h>

void fuse_setup_shortcircuit(struct fuse_conn *fc, struct fuse_req *req)
{
@@ -54,24 +55,35 @@ static ssize_t fuse_shortcircuit_read_write_iter(struct kiocb *iocb,
						 int do_write)
{
	ssize_t ret_val;
	struct fuse_file *ff = iocb->ki_filp->private_data;
	struct fuse_file *ff;
	struct file *fuse_file, *lower_file;
	struct inode *fuse_inode, *lower_inode;

	ff = iocb->ki_filp->private_data;
	fuse_file = iocb->ki_filp;
	lower_file = ff->rw_lower_file;

	/* lock lower file to prevent it from being released */
	get_file(lower_file);
	iocb->ki_filp = lower_file;
	fuse_inode = fuse_file->f_path.dentry->d_inode;
	lower_inode = file_inode(lower_file);

	if (do_write) {
		if (!lower_file->f_op->write_iter)
			return -EIO;
		ret_val = lower_file->f_op->write_iter(iocb, iter);

		if (ret_val >= 0 || ret_val == -EIOCBQUEUED) {
			fsstack_copy_inode_size(fuse_inode, lower_inode);
			fsstack_copy_attr_times(fuse_inode, lower_inode);
		}
	} else {
		if (!lower_file->f_op->read_iter)
			return -EIO;
		ret_val = lower_file->f_op->read_iter(iocb, iter);
		if (ret_val >= 0 || ret_val == -EIOCBQUEUED)
			fsstack_copy_attr_atime(fuse_inode, lower_inode);
	}

	iocb->ki_filp = fuse_file;