VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700    1) /*
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700    2)   FUSE: Filesystem in Userspace
1729a16c2c92b (Miklos Szeredi          2008-11-26 12:03:54 +0100    3)   Copyright (C) 2001-2008  Miklos Szeredi <miklos@szeredi.hu>
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700    4) 
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700    5)   This program can be distributed under the terms of the GNU GPL.
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700    6)   See the file COPYING.
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700    7) */
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700    8) 
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700    9) #include "fuse_i.h"
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700   10) 
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700   11) #include <linux/pagemap.h>
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700   12) #include <linux/slab.h>
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700   13) #include <linux/kernel.h>
e8edc6e03a5c8 (Alexey Dobriyan         2007-05-21 01:22:52 +0400   14) #include <linux/sched.h>
7a36094d61bfe (Eric W. Biederman       2017-09-26 12:45:33 -0500   15) #include <linux/sched/signal.h>
08cbf542bf24f (Tejun Heo               2009-04-14 10:54:53 +0900   16) #include <linux/module.h>
478e0841b3dce (Johannes Weiner         2011-07-25 22:35:35 +0200   17) #include <linux/swap.h>
3634a6327815d (Brian Foster            2013-05-17 09:30:32 -0400   18) #include <linux/falloc.h>
e2e40f2c1ed43 (Christoph Hellwig       2015-02-22 08:58:50 -0800   19) #include <linux/uio.h>
31070f6ccec09 (Chirantan Ekbote        2020-07-14 19:26:39 +0900   20) #include <linux/fs.h>
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700   21) 
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200   22) static int fuse_send_open(struct fuse_mount *fm, u64 nodeid,
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200   23) 			  unsigned int open_flags, int opcode,
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200   24) 			  struct fuse_open_out *outargp)
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700   25) {
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700   26) 	struct fuse_open_in inarg;
7078187a795f8 (Miklos Szeredi          2014-12-12 09:49:05 +0100   27) 	FUSE_ARGS(args);
fd72faac95d7e (Miklos Szeredi          2005-11-07 00:59:51 -0800   28) 
fd72faac95d7e (Miklos Szeredi          2005-11-07 00:59:51 -0800   29) 	memset(&inarg, 0, sizeof(inarg));
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200   30) 	inarg.flags = open_flags & ~(O_CREAT | O_EXCL | O_NOCTTY);
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200   31) 	if (!fm->fc->atomic_o_trunc)
6ff958edbf39c (Miklos Szeredi          2007-10-18 03:07:02 -0700   32) 		inarg.flags &= ~O_TRUNC;
643a666a89c35 (Vivek Goyal             2020-10-09 14:15:11 -0400   33) 
643a666a89c35 (Vivek Goyal             2020-10-09 14:15:11 -0400   34) 	if (fm->fc->handle_killpriv_v2 &&
643a666a89c35 (Vivek Goyal             2020-10-09 14:15:11 -0400   35) 	    (inarg.flags & O_TRUNC) && !capable(CAP_FSETID)) {
643a666a89c35 (Vivek Goyal             2020-10-09 14:15:11 -0400   36) 		inarg.open_flags |= FUSE_OPEN_KILL_SUIDGID;
643a666a89c35 (Vivek Goyal             2020-10-09 14:15:11 -0400   37) 	}
643a666a89c35 (Vivek Goyal             2020-10-09 14:15:11 -0400   38) 
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200   39) 	args.opcode = opcode;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200   40) 	args.nodeid = nodeid;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200   41) 	args.in_numargs = 1;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200   42) 	args.in_args[0].size = sizeof(inarg);
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200   43) 	args.in_args[0].value = &inarg;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200   44) 	args.out_numargs = 1;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200   45) 	args.out_args[0].size = sizeof(*outargp);
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200   46) 	args.out_args[0].value = outargp;
fd72faac95d7e (Miklos Szeredi          2005-11-07 00:59:51 -0800   47) 
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200   48) 	return fuse_simple_request(fm, &args);
fd72faac95d7e (Miklos Szeredi          2005-11-07 00:59:51 -0800   49) }
fd72faac95d7e (Miklos Szeredi          2005-11-07 00:59:51 -0800   50) 
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200   51) struct fuse_release_args {
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200   52) 	struct fuse_args args;
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200   53) 	struct fuse_release_in inarg;
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200   54) 	struct inode *inode;
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200   55) };
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200   56) 
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200   57) struct fuse_file *fuse_file_alloc(struct fuse_mount *fm)
fd72faac95d7e (Miklos Szeredi          2005-11-07 00:59:51 -0800   58) {
fd72faac95d7e (Miklos Szeredi          2005-11-07 00:59:51 -0800   59) 	struct fuse_file *ff;
6b2db28a7a2da (Tejun Heo               2009-04-14 10:54:49 +0900   60) 
dc69e98c241e1 (Khazhismel Kumykov      2019-09-17 12:35:33 -0700   61) 	ff = kzalloc(sizeof(struct fuse_file), GFP_KERNEL_ACCOUNT);
6b2db28a7a2da (Tejun Heo               2009-04-14 10:54:49 +0900   62) 	if (unlikely(!ff))
6b2db28a7a2da (Tejun Heo               2009-04-14 10:54:49 +0900   63) 		return NULL;
6b2db28a7a2da (Tejun Heo               2009-04-14 10:54:49 +0900   64) 
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200   65) 	ff->fm = fm;
dc69e98c241e1 (Khazhismel Kumykov      2019-09-17 12:35:33 -0700   66) 	ff->release_args = kzalloc(sizeof(*ff->release_args),
dc69e98c241e1 (Khazhismel Kumykov      2019-09-17 12:35:33 -0700   67) 				   GFP_KERNEL_ACCOUNT);
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200   68) 	if (!ff->release_args) {
6b2db28a7a2da (Tejun Heo               2009-04-14 10:54:49 +0900   69) 		kfree(ff);
6b2db28a7a2da (Tejun Heo               2009-04-14 10:54:49 +0900   70) 		return NULL;
fd72faac95d7e (Miklos Szeredi          2005-11-07 00:59:51 -0800   71) 	}
6b2db28a7a2da (Tejun Heo               2009-04-14 10:54:49 +0900   72) 
6b2db28a7a2da (Tejun Heo               2009-04-14 10:54:49 +0900   73) 	INIT_LIST_HEAD(&ff->write_entry);
5d7bc7e8680c7 (Miklos Szeredi          2018-10-01 10:07:04 +0200   74) 	mutex_init(&ff->readdir.lock);
4e8c2eb54327a (Elena Reshetova         2017-03-03 11:04:03 +0200   75) 	refcount_set(&ff->count, 1);
6b2db28a7a2da (Tejun Heo               2009-04-14 10:54:49 +0900   76) 	RB_CLEAR_NODE(&ff->polled_node);
6b2db28a7a2da (Tejun Heo               2009-04-14 10:54:49 +0900   77) 	init_waitqueue_head(&ff->poll_wait);
6b2db28a7a2da (Tejun Heo               2009-04-14 10:54:49 +0900   78) 
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200   79) 	ff->kh = atomic64_inc_return(&fm->fc->khctr);
6b2db28a7a2da (Tejun Heo               2009-04-14 10:54:49 +0900   80) 
fd72faac95d7e (Miklos Szeredi          2005-11-07 00:59:51 -0800   81) 	return ff;
fd72faac95d7e (Miklos Szeredi          2005-11-07 00:59:51 -0800   82) }
fd72faac95d7e (Miklos Szeredi          2005-11-07 00:59:51 -0800   83) 
fd72faac95d7e (Miklos Szeredi          2005-11-07 00:59:51 -0800   84) void fuse_file_free(struct fuse_file *ff)
fd72faac95d7e (Miklos Szeredi          2005-11-07 00:59:51 -0800   85) {
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200   86) 	kfree(ff->release_args);
5d7bc7e8680c7 (Miklos Szeredi          2018-10-01 10:07:04 +0200   87) 	mutex_destroy(&ff->readdir.lock);
fd72faac95d7e (Miklos Szeredi          2005-11-07 00:59:51 -0800   88) 	kfree(ff);
fd72faac95d7e (Miklos Szeredi          2005-11-07 00:59:51 -0800   89) }
fd72faac95d7e (Miklos Szeredi          2005-11-07 00:59:51 -0800   90) 
267d84449f523 (Miklos Szeredi          2017-02-22 20:08:25 +0100   91) static struct fuse_file *fuse_file_get(struct fuse_file *ff)
c756e0a4d7920 (Miklos Szeredi          2007-10-16 23:31:00 -0700   92) {
4e8c2eb54327a (Elena Reshetova         2017-03-03 11:04:03 +0200   93) 	refcount_inc(&ff->count);
c756e0a4d7920 (Miklos Szeredi          2007-10-16 23:31:00 -0700   94) 	return ff;
c756e0a4d7920 (Miklos Szeredi          2007-10-16 23:31:00 -0700   95) }
c756e0a4d7920 (Miklos Szeredi          2007-10-16 23:31:00 -0700   96) 
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200   97) static void fuse_release_end(struct fuse_mount *fm, struct fuse_args *args,
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200   98) 			     int error)
819c4b3b40092 (Miklos Szeredi          2007-10-16 23:31:04 -0700   99) {
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200  100) 	struct fuse_release_args *ra = container_of(args, typeof(*ra), args);
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200  101) 
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200  102) 	iput(ra->inode);
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200  103) 	kfree(ra);
819c4b3b40092 (Miklos Szeredi          2007-10-16 23:31:04 -0700  104) }
819c4b3b40092 (Miklos Szeredi          2007-10-16 23:31:04 -0700  105) 
2e64ff154ce6c (Chad Austin             2018-12-10 10:54:52 -0800  106) static void fuse_file_put(struct fuse_file *ff, bool sync, bool isdir)
c756e0a4d7920 (Miklos Szeredi          2007-10-16 23:31:00 -0700  107) {
4e8c2eb54327a (Elena Reshetova         2017-03-03 11:04:03 +0200  108) 	if (refcount_dec_and_test(&ff->count)) {
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200  109) 		struct fuse_args *args = &ff->release_args->args;
8b0797a4984de (Miklos Szeredi          2009-04-28 16:56:39 +0200  110) 
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  111) 		if (isdir ? ff->fm->fc->no_opendir : ff->fm->fc->no_open) {
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200  112) 			/* Do nothing when client does not implement 'open' */
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  113) 			fuse_release_end(ff->fm, args, 0);
7678ac50615d9 (Andrew Gallagher        2013-11-05 16:05:52 +0100  114) 		} else if (sync) {
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  115) 			fuse_simple_request(ff->fm, args);
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  116) 			fuse_release_end(ff->fm, args, 0);
5a18ec176c934 (Miklos Szeredi          2011-02-25 14:44:58 +0100  117) 		} else {
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200  118) 			args->end = fuse_release_end;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  119) 			if (fuse_simple_background(ff->fm, args,
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200  120) 						   GFP_KERNEL | __GFP_NOFAIL))
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  121) 				fuse_release_end(ff->fm, args, -ENOTCONN);
5a18ec176c934 (Miklos Szeredi          2011-02-25 14:44:58 +0100  122) 		}
c756e0a4d7920 (Miklos Szeredi          2007-10-16 23:31:00 -0700  123) 		kfree(ff);
c756e0a4d7920 (Miklos Szeredi          2007-10-16 23:31:00 -0700  124) 	}
c756e0a4d7920 (Miklos Szeredi          2007-10-16 23:31:00 -0700  125) }
c756e0a4d7920 (Miklos Szeredi          2007-10-16 23:31:00 -0700  126) 
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  127) struct fuse_file *fuse_file_open(struct fuse_mount *fm, u64 nodeid,
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  128) 				 unsigned int open_flags, bool isdir)
91fe96b403f8a (Miklos Szeredi          2009-04-28 16:56:37 +0200  129) {
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  130) 	struct fuse_conn *fc = fm->fc;
91fe96b403f8a (Miklos Szeredi          2009-04-28 16:56:37 +0200  131) 	struct fuse_file *ff;
91fe96b403f8a (Miklos Szeredi          2009-04-28 16:56:37 +0200  132) 	int opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN;
91fe96b403f8a (Miklos Szeredi          2009-04-28 16:56:37 +0200  133) 
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  134) 	ff = fuse_file_alloc(fm);
91fe96b403f8a (Miklos Szeredi          2009-04-28 16:56:37 +0200  135) 	if (!ff)
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  136) 		return ERR_PTR(-ENOMEM);
91fe96b403f8a (Miklos Szeredi          2009-04-28 16:56:37 +0200  137) 
7678ac50615d9 (Andrew Gallagher        2013-11-05 16:05:52 +0100  138) 	ff->fh = 0;
fabf7e0262d0b (Chad Austin             2019-01-28 16:34:34 -0800  139) 	/* Default for no-open */
fabf7e0262d0b (Chad Austin             2019-01-28 16:34:34 -0800  140) 	ff->open_flags = FOPEN_KEEP_CACHE | (isdir ? FOPEN_CACHE_DIR : 0);
d9a9ea94f748f (Chad Austin             2019-01-07 16:53:17 -0800  141) 	if (isdir ? !fc->no_opendir : !fc->no_open) {
7678ac50615d9 (Andrew Gallagher        2013-11-05 16:05:52 +0100  142) 		struct fuse_open_out outarg;
7678ac50615d9 (Andrew Gallagher        2013-11-05 16:05:52 +0100  143) 		int err;
7678ac50615d9 (Andrew Gallagher        2013-11-05 16:05:52 +0100  144) 
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  145) 		err = fuse_send_open(fm, nodeid, open_flags, opcode, &outarg);
7678ac50615d9 (Andrew Gallagher        2013-11-05 16:05:52 +0100  146) 		if (!err) {
7678ac50615d9 (Andrew Gallagher        2013-11-05 16:05:52 +0100  147) 			ff->fh = outarg.fh;
7678ac50615d9 (Andrew Gallagher        2013-11-05 16:05:52 +0100  148) 			ff->open_flags = outarg.open_flags;
7678ac50615d9 (Andrew Gallagher        2013-11-05 16:05:52 +0100  149) 
d9a9ea94f748f (Chad Austin             2019-01-07 16:53:17 -0800  150) 		} else if (err != -ENOSYS) {
7678ac50615d9 (Andrew Gallagher        2013-11-05 16:05:52 +0100  151) 			fuse_file_free(ff);
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  152) 			return ERR_PTR(err);
7678ac50615d9 (Andrew Gallagher        2013-11-05 16:05:52 +0100  153) 		} else {
d9a9ea94f748f (Chad Austin             2019-01-07 16:53:17 -0800  154) 			if (isdir)
d9a9ea94f748f (Chad Austin             2019-01-07 16:53:17 -0800  155) 				fc->no_opendir = 1;
d9a9ea94f748f (Chad Austin             2019-01-07 16:53:17 -0800  156) 			else
d9a9ea94f748f (Chad Austin             2019-01-07 16:53:17 -0800  157) 				fc->no_open = 1;
7678ac50615d9 (Andrew Gallagher        2013-11-05 16:05:52 +0100  158) 		}
91fe96b403f8a (Miklos Szeredi          2009-04-28 16:56:37 +0200  159) 	}
91fe96b403f8a (Miklos Szeredi          2009-04-28 16:56:37 +0200  160) 
91fe96b403f8a (Miklos Szeredi          2009-04-28 16:56:37 +0200  161) 	if (isdir)
7678ac50615d9 (Andrew Gallagher        2013-11-05 16:05:52 +0100  162) 		ff->open_flags &= ~FOPEN_DIRECT_IO;
91fe96b403f8a (Miklos Szeredi          2009-04-28 16:56:37 +0200  163) 
91fe96b403f8a (Miklos Szeredi          2009-04-28 16:56:37 +0200  164) 	ff->nodeid = nodeid;
91fe96b403f8a (Miklos Szeredi          2009-04-28 16:56:37 +0200  165) 
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  166) 	return ff;
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  167) }
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  168) 
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  169) int fuse_do_open(struct fuse_mount *fm, u64 nodeid, struct file *file,
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  170) 		 bool isdir)
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  171) {
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  172) 	struct fuse_file *ff = fuse_file_open(fm, nodeid, file->f_flags, isdir);
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  173) 
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  174) 	if (!IS_ERR(ff))
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  175) 		file->private_data = ff;
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  176) 
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  177) 	return PTR_ERR_OR_ZERO(ff);
91fe96b403f8a (Miklos Szeredi          2009-04-28 16:56:37 +0200  178) }
08cbf542bf24f (Tejun Heo               2009-04-14 10:54:53 +0900  179) EXPORT_SYMBOL_GPL(fuse_do_open);
91fe96b403f8a (Miklos Szeredi          2009-04-28 16:56:37 +0200  180) 
650b22b941fa0 (Pavel Emelyanov         2013-10-10 17:10:04 +0400  181) static void fuse_link_write_file(struct file *file)
650b22b941fa0 (Pavel Emelyanov         2013-10-10 17:10:04 +0400  182) {
650b22b941fa0 (Pavel Emelyanov         2013-10-10 17:10:04 +0400  183) 	struct inode *inode = file_inode(file);
650b22b941fa0 (Pavel Emelyanov         2013-10-10 17:10:04 +0400  184) 	struct fuse_inode *fi = get_fuse_inode(inode);
650b22b941fa0 (Pavel Emelyanov         2013-10-10 17:10:04 +0400  185) 	struct fuse_file *ff = file->private_data;
650b22b941fa0 (Pavel Emelyanov         2013-10-10 17:10:04 +0400  186) 	/*
650b22b941fa0 (Pavel Emelyanov         2013-10-10 17:10:04 +0400  187) 	 * file may be written through mmap, so chain it onto the
650b22b941fa0 (Pavel Emelyanov         2013-10-10 17:10:04 +0400  188) 	 * inodes's write_file list
650b22b941fa0 (Pavel Emelyanov         2013-10-10 17:10:04 +0400  189) 	 */
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300  190) 	spin_lock(&fi->lock);
650b22b941fa0 (Pavel Emelyanov         2013-10-10 17:10:04 +0400  191) 	if (list_empty(&ff->write_entry))
650b22b941fa0 (Pavel Emelyanov         2013-10-10 17:10:04 +0400  192) 		list_add(&ff->write_entry, &fi->write_files);
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300  193) 	spin_unlock(&fi->lock);
650b22b941fa0 (Pavel Emelyanov         2013-10-10 17:10:04 +0400  194) }
650b22b941fa0 (Pavel Emelyanov         2013-10-10 17:10:04 +0400  195) 
c7b7143c6342b (Miklos Szeredi          2009-04-28 16:56:37 +0200  196) void fuse_finish_open(struct inode *inode, struct file *file)
fd72faac95d7e (Miklos Szeredi          2005-11-07 00:59:51 -0800  197) {
c7b7143c6342b (Miklos Szeredi          2009-04-28 16:56:37 +0200  198) 	struct fuse_file *ff = file->private_data;
a0822c55779d9 (Ken Sumrall             2010-11-24 12:57:00 -0800  199) 	struct fuse_conn *fc = get_fuse_conn(inode);
c7b7143c6342b (Miklos Szeredi          2009-04-28 16:56:37 +0200  200) 
c7b7143c6342b (Miklos Szeredi          2009-04-28 16:56:37 +0200  201) 	if (!(ff->open_flags & FOPEN_KEEP_CACHE))
b10099792b627 (Miklos Szeredi          2007-10-16 23:31:01 -0700  202) 		invalidate_inode_pages2(inode->i_mapping);
bbd84f33652f8 (Kirill Smelkov          2019-04-24 07:13:57 +0000  203) 	if (ff->open_flags & FOPEN_STREAM)
bbd84f33652f8 (Kirill Smelkov          2019-04-24 07:13:57 +0000  204) 		stream_open(inode, file);
bbd84f33652f8 (Kirill Smelkov          2019-04-24 07:13:57 +0000  205) 	else if (ff->open_flags & FOPEN_NONSEEKABLE)
a7c1b990f7157 (Tejun Heo               2008-10-16 16:08:57 +0200  206) 		nonseekable_open(inode, file);
a0822c55779d9 (Ken Sumrall             2010-11-24 12:57:00 -0800  207) 	if (fc->atomic_o_trunc && (file->f_flags & O_TRUNC)) {
a0822c55779d9 (Ken Sumrall             2010-11-24 12:57:00 -0800  208) 		struct fuse_inode *fi = get_fuse_inode(inode);
a0822c55779d9 (Ken Sumrall             2010-11-24 12:57:00 -0800  209) 
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300  210) 		spin_lock(&fi->lock);
4510d86fbbb36 (Kirill Tkhai            2018-11-09 13:33:17 +0300  211) 		fi->attr_version = atomic64_inc_return(&fc->attr_version);
a0822c55779d9 (Ken Sumrall             2010-11-24 12:57:00 -0800  212) 		i_size_write(inode, 0);
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300  213) 		spin_unlock(&fi->lock);
a0822c55779d9 (Ken Sumrall             2010-11-24 12:57:00 -0800  214) 		fuse_invalidate_attr(inode);
75caeecdf9c71 (Maxim Patlasov          2014-04-28 14:19:22 +0200  215) 		if (fc->writeback_cache)
75caeecdf9c71 (Maxim Patlasov          2014-04-28 14:19:22 +0200  216) 			file_update_time(file);
a0822c55779d9 (Ken Sumrall             2010-11-24 12:57:00 -0800  217) 	}
4d99ff8f12eb2 (Pavel Emelyanov         2013-10-10 17:12:18 +0400  218) 	if ((file->f_mode & FMODE_WRITE) && fc->writeback_cache)
4d99ff8f12eb2 (Pavel Emelyanov         2013-10-10 17:12:18 +0400  219) 		fuse_link_write_file(file);
fd72faac95d7e (Miklos Szeredi          2005-11-07 00:59:51 -0800  220) }
fd72faac95d7e (Miklos Szeredi          2005-11-07 00:59:51 -0800  221) 
91fe96b403f8a (Miklos Szeredi          2009-04-28 16:56:37 +0200  222) int fuse_open_common(struct inode *inode, struct file *file, bool isdir)
fd72faac95d7e (Miklos Szeredi          2005-11-07 00:59:51 -0800  223) {
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  224) 	struct fuse_mount *fm = get_fuse_mount(inode);
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  225) 	struct fuse_conn *fc = fm->fc;
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  226) 	int err;
e4648309b85a7 (Miklos Szeredi          2019-10-23 14:26:37 +0200  227) 	bool is_wb_truncate = (file->f_flags & O_TRUNC) &&
75caeecdf9c71 (Maxim Patlasov          2014-04-28 14:19:22 +0200  228) 			  fc->atomic_o_trunc &&
75caeecdf9c71 (Maxim Patlasov          2014-04-28 14:19:22 +0200  229) 			  fc->writeback_cache;
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400  230) 	bool dax_truncate = (file->f_flags & O_TRUNC) &&
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400  231) 			  fc->atomic_o_trunc && FUSE_IS_DAX(inode);
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  232) 
5d069dbe8aaf2 (Miklos Szeredi          2020-12-10 15:33:14 +0100  233) 	if (fuse_is_bad(inode))
5d069dbe8aaf2 (Miklos Szeredi          2020-12-10 15:33:14 +0100  234) 		return -EIO;
5d069dbe8aaf2 (Miklos Szeredi          2020-12-10 15:33:14 +0100  235) 
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  236) 	err = generic_file_open(inode, file);
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  237) 	if (err)
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  238) 		return err;
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  239) 
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400  240) 	if (is_wb_truncate || dax_truncate) {
5955102c9984f (Al Viro                 2016-01-22 15:40:57 -0500  241) 		inode_lock(inode);
e4648309b85a7 (Miklos Szeredi          2019-10-23 14:26:37 +0200  242) 		fuse_set_nowrite(inode);
e4648309b85a7 (Miklos Szeredi          2019-10-23 14:26:37 +0200  243) 	}
75caeecdf9c71 (Maxim Patlasov          2014-04-28 14:19:22 +0200  244) 
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400  245) 	if (dax_truncate) {
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400  246) 		down_write(&get_fuse_inode(inode)->i_mmap_sem);
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400  247) 		err = fuse_dax_break_layouts(inode, 0, 0);
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400  248) 		if (err)
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400  249) 			goto out;
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400  250) 	}
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  251) 
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  252) 	err = fuse_do_open(fm, get_node_id(inode), file, isdir);
75caeecdf9c71 (Maxim Patlasov          2014-04-28 14:19:22 +0200  253) 	if (!err)
75caeecdf9c71 (Maxim Patlasov          2014-04-28 14:19:22 +0200  254) 		fuse_finish_open(inode, file);
91fe96b403f8a (Miklos Szeredi          2009-04-28 16:56:37 +0200  255) 
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400  256) out:
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400  257) 	if (dax_truncate)
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400  258) 		up_write(&get_fuse_inode(inode)->i_mmap_sem);
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400  259) 
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400  260) 	if (is_wb_truncate | dax_truncate) {
e4648309b85a7 (Miklos Szeredi          2019-10-23 14:26:37 +0200  261) 		fuse_release_nowrite(inode);
5955102c9984f (Al Viro                 2016-01-22 15:40:57 -0500  262) 		inode_unlock(inode);
e4648309b85a7 (Miklos Szeredi          2019-10-23 14:26:37 +0200  263) 	}
75caeecdf9c71 (Maxim Patlasov          2014-04-28 14:19:22 +0200  264) 
75caeecdf9c71 (Maxim Patlasov          2014-04-28 14:19:22 +0200  265) 	return err;
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  266) }
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  267) 
ebf84d0c7220c (Kirill Tkhai            2018-11-09 13:33:11 +0300  268) static void fuse_prepare_release(struct fuse_inode *fi, struct fuse_file *ff,
54d601cb67572 (Miklos Szeredi          2021-04-07 14:36:45 +0200  269) 				 unsigned int flags, int opcode)
64c6d8ed4c55f (Miklos Szeredi          2006-01-16 22:14:42 -0800  270) {
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  271) 	struct fuse_conn *fc = ff->fm->fc;
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200  272) 	struct fuse_release_args *ra = ff->release_args;
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  273) 
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300  274) 	/* Inode is NULL on error path of fuse_create_open() */
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300  275) 	if (likely(fi)) {
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300  276) 		spin_lock(&fi->lock);
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300  277) 		list_del(&ff->write_entry);
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300  278) 		spin_unlock(&fi->lock);
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300  279) 	}
8b0797a4984de (Miklos Szeredi          2009-04-28 16:56:39 +0200  280) 	spin_lock(&fc->lock);
8b0797a4984de (Miklos Szeredi          2009-04-28 16:56:39 +0200  281) 	if (!RB_EMPTY_NODE(&ff->polled_node))
8b0797a4984de (Miklos Szeredi          2009-04-28 16:56:39 +0200  282) 		rb_erase(&ff->polled_node, &fc->polled_files);
8b0797a4984de (Miklos Szeredi          2009-04-28 16:56:39 +0200  283) 	spin_unlock(&fc->lock);
8b0797a4984de (Miklos Szeredi          2009-04-28 16:56:39 +0200  284) 
357ccf2b69bce (Bryan Green             2011-03-01 16:43:52 -0800  285) 	wake_up_interruptible_all(&ff->poll_wait);
8b0797a4984de (Miklos Szeredi          2009-04-28 16:56:39 +0200  286) 
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200  287) 	ra->inarg.fh = ff->fh;
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200  288) 	ra->inarg.flags = flags;
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200  289) 	ra->args.in_numargs = 1;
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200  290) 	ra->args.in_args[0].size = sizeof(struct fuse_release_in);
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200  291) 	ra->args.in_args[0].value = &ra->inarg;
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200  292) 	ra->args.opcode = opcode;
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200  293) 	ra->args.nodeid = ff->nodeid;
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200  294) 	ra->args.force = true;
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200  295) 	ra->args.nocreds = true;
fd72faac95d7e (Miklos Szeredi          2005-11-07 00:59:51 -0800  296) }
fd72faac95d7e (Miklos Szeredi          2005-11-07 00:59:51 -0800  297) 
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  298) void fuse_file_release(struct inode *inode, struct fuse_file *ff,
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  299) 		       unsigned int open_flags, fl_owner_t id, bool isdir)
fd72faac95d7e (Miklos Szeredi          2005-11-07 00:59:51 -0800  300) {
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  301) 	struct fuse_inode *fi = get_fuse_inode(inode);
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200  302) 	struct fuse_release_args *ra = ff->release_args;
2e64ff154ce6c (Chad Austin             2018-12-10 10:54:52 -0800  303) 	int opcode = isdir ? FUSE_RELEASEDIR : FUSE_RELEASE;
6b2db28a7a2da (Tejun Heo               2009-04-14 10:54:49 +0900  304) 
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  305) 	fuse_prepare_release(fi, ff, open_flags, opcode);
6b2db28a7a2da (Tejun Heo               2009-04-14 10:54:49 +0900  306) 
37fb3a30b4623 (Miklos Szeredi          2011-08-08 16:08:08 +0200  307) 	if (ff->flock) {
4cb548666e4c1 (Miklos Szeredi          2019-09-10 15:04:10 +0200  308) 		ra->inarg.release_flags |= FUSE_RELEASE_FLOCK_UNLOCK;
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  309) 		ra->inarg.lock_owner = fuse_lock_owner_id(ff->fm->fc, id);
37fb3a30b4623 (Miklos Szeredi          2011-08-08 16:08:08 +0200  310) 	}
baebccbe997d5 (Miklos Szeredi          2014-12-12 09:49:04 +0100  311) 	/* Hold inode until release is finished */
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  312) 	ra->inode = igrab(inode);
6b2db28a7a2da (Tejun Heo               2009-04-14 10:54:49 +0900  313) 
6b2db28a7a2da (Tejun Heo               2009-04-14 10:54:49 +0900  314) 	/*
6b2db28a7a2da (Tejun Heo               2009-04-14 10:54:49 +0900  315) 	 * Normally this will send the RELEASE request, however if
6b2db28a7a2da (Tejun Heo               2009-04-14 10:54:49 +0900  316) 	 * some asynchronous READ or WRITE requests are outstanding,
6b2db28a7a2da (Tejun Heo               2009-04-14 10:54:49 +0900  317) 	 * the sending will be delayed.
5a18ec176c934 (Miklos Szeredi          2011-02-25 14:44:58 +0100  318) 	 *
5a18ec176c934 (Miklos Szeredi          2011-02-25 14:44:58 +0100  319) 	 * Make the release synchronous if this is a fuseblk mount,
5a18ec176c934 (Miklos Szeredi          2011-02-25 14:44:58 +0100  320) 	 * synchronous RELEASE is allowed (and desirable) in this case
5a18ec176c934 (Miklos Szeredi          2011-02-25 14:44:58 +0100  321) 	 * because the server can be trusted not to screw up.
6b2db28a7a2da (Tejun Heo               2009-04-14 10:54:49 +0900  322) 	 */
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  323) 	fuse_file_put(ff, ff->fm->fc->destroy, isdir);
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  324) }
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  325) 
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  326) void fuse_release_common(struct file *file, bool isdir)
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  327) {
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  328) 	fuse_file_release(file_inode(file), file->private_data, file->f_flags,
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  329) 			  (fl_owner_t) file, isdir);
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  330) }
b9d54c6f29d9d (Miklos Szeredi          2021-04-07 14:36:45 +0200  331) 
04730fef1f9c7 (Miklos Szeredi          2005-09-09 13:10:36 -0700  332) static int fuse_open(struct inode *inode, struct file *file)
04730fef1f9c7 (Miklos Szeredi          2005-09-09 13:10:36 -0700  333) {
91fe96b403f8a (Miklos Szeredi          2009-04-28 16:56:37 +0200  334) 	return fuse_open_common(inode, file, false);
04730fef1f9c7 (Miklos Szeredi          2005-09-09 13:10:36 -0700  335) }
04730fef1f9c7 (Miklos Szeredi          2005-09-09 13:10:36 -0700  336) 
04730fef1f9c7 (Miklos Szeredi          2005-09-09 13:10:36 -0700  337) static int fuse_release(struct inode *inode, struct file *file)
04730fef1f9c7 (Miklos Szeredi          2005-09-09 13:10:36 -0700  338) {
e7cc133c370f5 (Pavel Emelyanov         2013-10-10 17:19:06 +0400  339) 	struct fuse_conn *fc = get_fuse_conn(inode);
e7cc133c370f5 (Pavel Emelyanov         2013-10-10 17:19:06 +0400  340) 
e7cc133c370f5 (Pavel Emelyanov         2013-10-10 17:19:06 +0400  341) 	/* see fuse_vma_close() for !writeback_cache case */
e7cc133c370f5 (Pavel Emelyanov         2013-10-10 17:19:06 +0400  342) 	if (fc->writeback_cache)
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200  343) 		write_inode_now(inode, 1);
b0aa760652179 (Maxim Patlasov          2013-12-26 19:51:11 +0400  344) 
2e64ff154ce6c (Chad Austin             2018-12-10 10:54:52 -0800  345) 	fuse_release_common(file, false);
8b0797a4984de (Miklos Szeredi          2009-04-28 16:56:39 +0200  346) 
8b0797a4984de (Miklos Szeredi          2009-04-28 16:56:39 +0200  347) 	/* return value is ignored by VFS */
8b0797a4984de (Miklos Szeredi          2009-04-28 16:56:39 +0200  348) 	return 0;
8b0797a4984de (Miklos Szeredi          2009-04-28 16:56:39 +0200  349) }
8b0797a4984de (Miklos Szeredi          2009-04-28 16:56:39 +0200  350) 
54d601cb67572 (Miklos Szeredi          2021-04-07 14:36:45 +0200  351) void fuse_sync_release(struct fuse_inode *fi, struct fuse_file *ff,
54d601cb67572 (Miklos Szeredi          2021-04-07 14:36:45 +0200  352) 		       unsigned int flags)
8b0797a4984de (Miklos Szeredi          2009-04-28 16:56:39 +0200  353) {
4e8c2eb54327a (Elena Reshetova         2017-03-03 11:04:03 +0200  354) 	WARN_ON(refcount_read(&ff->count) > 1);
ebf84d0c7220c (Kirill Tkhai            2018-11-09 13:33:11 +0300  355) 	fuse_prepare_release(fi, ff, flags, FUSE_RELEASE);
267d84449f523 (Miklos Szeredi          2017-02-22 20:08:25 +0100  356) 	/*
267d84449f523 (Miklos Szeredi          2017-02-22 20:08:25 +0100  357) 	 * iput(NULL) is a no-op and since the refcount is 1 and everything's
267d84449f523 (Miklos Szeredi          2017-02-22 20:08:25 +0100  358) 	 * synchronous, we are fine with not doing igrab() here"
267d84449f523 (Miklos Szeredi          2017-02-22 20:08:25 +0100  359) 	 */
2e64ff154ce6c (Chad Austin             2018-12-10 10:54:52 -0800  360) 	fuse_file_put(ff, true, false);
04730fef1f9c7 (Miklos Szeredi          2005-09-09 13:10:36 -0700  361) }
08cbf542bf24f (Tejun Heo               2009-04-14 10:54:53 +0900  362) EXPORT_SYMBOL_GPL(fuse_sync_release);
04730fef1f9c7 (Miklos Szeredi          2005-09-09 13:10:36 -0700  363) 
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700  364) /*
9c8ef5614da22 (Miklos Szeredi          2006-06-25 05:48:55 -0700  365)  * Scramble the ID space with XTEA, so that the value of the files_struct
9c8ef5614da22 (Miklos Szeredi          2006-06-25 05:48:55 -0700  366)  * pointer is not exposed to userspace.
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700  367)  */
f33321141b273 (Miklos Szeredi          2007-10-18 03:07:04 -0700  368) u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id)
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700  369) {
9c8ef5614da22 (Miklos Szeredi          2006-06-25 05:48:55 -0700  370) 	u32 *k = fc->scramble_key;
9c8ef5614da22 (Miklos Szeredi          2006-06-25 05:48:55 -0700  371) 	u64 v = (unsigned long) id;
9c8ef5614da22 (Miklos Szeredi          2006-06-25 05:48:55 -0700  372) 	u32 v0 = v;
9c8ef5614da22 (Miklos Szeredi          2006-06-25 05:48:55 -0700  373) 	u32 v1 = v >> 32;
9c8ef5614da22 (Miklos Szeredi          2006-06-25 05:48:55 -0700  374) 	u32 sum = 0;
9c8ef5614da22 (Miklos Szeredi          2006-06-25 05:48:55 -0700  375) 	int i;
9c8ef5614da22 (Miklos Szeredi          2006-06-25 05:48:55 -0700  376) 
9c8ef5614da22 (Miklos Szeredi          2006-06-25 05:48:55 -0700  377) 	for (i = 0; i < 32; i++) {
9c8ef5614da22 (Miklos Szeredi          2006-06-25 05:48:55 -0700  378) 		v0 += ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + k[sum & 3]);
9c8ef5614da22 (Miklos Szeredi          2006-06-25 05:48:55 -0700  379) 		sum += 0x9E3779B9;
9c8ef5614da22 (Miklos Szeredi          2006-06-25 05:48:55 -0700  380) 		v1 += ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + k[sum>>11 & 3]);
9c8ef5614da22 (Miklos Szeredi          2006-06-25 05:48:55 -0700  381) 	}
9c8ef5614da22 (Miklos Szeredi          2006-06-25 05:48:55 -0700  382) 
9c8ef5614da22 (Miklos Szeredi          2006-06-25 05:48:55 -0700  383) 	return (u64) v0 + ((u64) v1 << 32);
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700  384) }
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700  385) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200  386) struct fuse_writepage_args {
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200  387) 	struct fuse_io_args ia;
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300  388) 	struct rb_node writepages_entry;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200  389) 	struct list_head queue_entry;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200  390) 	struct fuse_writepage_args *next;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200  391) 	struct inode *inode;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200  392) };
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200  393) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200  394) static struct fuse_writepage_args *fuse_find_writeback(struct fuse_inode *fi,
2fe93bd432642 (Miklos Szeredi          2019-01-16 10:27:59 +0100  395) 					    pgoff_t idx_from, pgoff_t idx_to)
2fe93bd432642 (Miklos Szeredi          2019-01-16 10:27:59 +0100  396) {
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300  397) 	struct rb_node *n;
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300  398) 
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300  399) 	n = fi->writepages.rb_node;
2fe93bd432642 (Miklos Szeredi          2019-01-16 10:27:59 +0100  400) 
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300  401) 	while (n) {
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300  402) 		struct fuse_writepage_args *wpa;
2fe93bd432642 (Miklos Szeredi          2019-01-16 10:27:59 +0100  403) 		pgoff_t curr_index;
2fe93bd432642 (Miklos Szeredi          2019-01-16 10:27:59 +0100  404) 
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300  405) 		wpa = rb_entry(n, struct fuse_writepage_args, writepages_entry);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200  406) 		WARN_ON(get_fuse_inode(wpa->inode) != fi);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200  407) 		curr_index = wpa->ia.write.in.offset >> PAGE_SHIFT;
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300  408) 		if (idx_from >= curr_index + wpa->ia.ap.num_pages)
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300  409) 			n = n->rb_right;
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300  410) 		else if (idx_to < curr_index)
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300  411) 			n = n->rb_left;
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300  412) 		else
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200  413) 			return wpa;
2fe93bd432642 (Miklos Szeredi          2019-01-16 10:27:59 +0100  414) 	}
2fe93bd432642 (Miklos Szeredi          2019-01-16 10:27:59 +0100  415) 	return NULL;
2fe93bd432642 (Miklos Szeredi          2019-01-16 10:27:59 +0100  416) }
2fe93bd432642 (Miklos Szeredi          2019-01-16 10:27:59 +0100  417) 
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  418) /*
ea8cd33390faf (Pavel Emelyanov         2013-10-10 17:12:05 +0400  419)  * Check if any page in a range is under writeback
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  420)  *
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  421)  * This is currently done by walking the list of writepage requests
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  422)  * for the inode, which can be pretty inefficient.
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  423)  */
ea8cd33390faf (Pavel Emelyanov         2013-10-10 17:12:05 +0400  424) static bool fuse_range_is_writeback(struct inode *inode, pgoff_t idx_from,
ea8cd33390faf (Pavel Emelyanov         2013-10-10 17:12:05 +0400  425) 				   pgoff_t idx_to)
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  426) {
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  427) 	struct fuse_inode *fi = get_fuse_inode(inode);
2fe93bd432642 (Miklos Szeredi          2019-01-16 10:27:59 +0100  428) 	bool found;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  429) 
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300  430) 	spin_lock(&fi->lock);
2fe93bd432642 (Miklos Szeredi          2019-01-16 10:27:59 +0100  431) 	found = fuse_find_writeback(fi, idx_from, idx_to);
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300  432) 	spin_unlock(&fi->lock);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  433) 
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  434) 	return found;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  435) }
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  436) 
ea8cd33390faf (Pavel Emelyanov         2013-10-10 17:12:05 +0400  437) static inline bool fuse_page_is_writeback(struct inode *inode, pgoff_t index)
ea8cd33390faf (Pavel Emelyanov         2013-10-10 17:12:05 +0400  438) {
ea8cd33390faf (Pavel Emelyanov         2013-10-10 17:12:05 +0400  439) 	return fuse_range_is_writeback(inode, index, index);
ea8cd33390faf (Pavel Emelyanov         2013-10-10 17:12:05 +0400  440) }
ea8cd33390faf (Pavel Emelyanov         2013-10-10 17:12:05 +0400  441) 
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  442) /*
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  443)  * Wait for page writeback to be completed.
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  444)  *
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  445)  * Since fuse doesn't rely on the VM writeback tracking, this has to
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  446)  * use some other means.
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  447)  */
17b2cbe294922 (Maxim Patlasov          2019-07-22 10:17:17 +0300  448) static void fuse_wait_on_page_writeback(struct inode *inode, pgoff_t index)
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  449) {
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  450) 	struct fuse_inode *fi = get_fuse_inode(inode);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  451) 
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  452) 	wait_event(fi->page_waitq, !fuse_page_is_writeback(inode, index));
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  453) }
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  454) 
fe38d7df230b0 (Maxim Patlasov          2013-10-10 17:11:54 +0400  455) /*
fe38d7df230b0 (Maxim Patlasov          2013-10-10 17:11:54 +0400  456)  * Wait for all pending writepages on the inode to finish.
fe38d7df230b0 (Maxim Patlasov          2013-10-10 17:11:54 +0400  457)  *
fe38d7df230b0 (Maxim Patlasov          2013-10-10 17:11:54 +0400  458)  * This is currently done by blocking further writes with FUSE_NOWRITE
fe38d7df230b0 (Maxim Patlasov          2013-10-10 17:11:54 +0400  459)  * and waiting for all sent writes to complete.
fe38d7df230b0 (Maxim Patlasov          2013-10-10 17:11:54 +0400  460)  *
fe38d7df230b0 (Maxim Patlasov          2013-10-10 17:11:54 +0400  461)  * This must be called under i_mutex, otherwise the FUSE_NOWRITE usage
fe38d7df230b0 (Maxim Patlasov          2013-10-10 17:11:54 +0400  462)  * could conflict with truncation.
fe38d7df230b0 (Maxim Patlasov          2013-10-10 17:11:54 +0400  463)  */
fe38d7df230b0 (Maxim Patlasov          2013-10-10 17:11:54 +0400  464) static void fuse_sync_writes(struct inode *inode)
fe38d7df230b0 (Maxim Patlasov          2013-10-10 17:11:54 +0400  465) {
fe38d7df230b0 (Maxim Patlasov          2013-10-10 17:11:54 +0400  466) 	fuse_set_nowrite(inode);
fe38d7df230b0 (Maxim Patlasov          2013-10-10 17:11:54 +0400  467) 	fuse_release_nowrite(inode);
fe38d7df230b0 (Maxim Patlasov          2013-10-10 17:11:54 +0400  468) }
fe38d7df230b0 (Maxim Patlasov          2013-10-10 17:11:54 +0400  469) 
75e1fcc0b18df (Miklos Szeredi          2006-06-23 02:05:12 -0700  470) static int fuse_flush(struct file *file, fl_owner_t id)
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  471) {
6131ffaa1f091 (Al Viro                 2013-02-27 16:59:05 -0500  472) 	struct inode *inode = file_inode(file);
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  473) 	struct fuse_mount *fm = get_fuse_mount(inode);
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  474) 	struct fuse_file *ff = file->private_data;
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  475) 	struct fuse_flush_in inarg;
c500ebaa908db (Miklos Szeredi          2019-09-10 15:04:08 +0200  476) 	FUSE_ARGS(args);
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  477) 	int err;
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  478) 
5d069dbe8aaf2 (Miklos Szeredi          2020-12-10 15:33:14 +0100  479) 	if (fuse_is_bad(inode))
248d86e87d12d (Miklos Szeredi          2006-01-06 00:19:39 -0800  480) 		return -EIO;
248d86e87d12d (Miklos Szeredi          2006-01-06 00:19:39 -0800  481) 
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200  482) 	err = write_inode_now(inode, 1);
fe38d7df230b0 (Maxim Patlasov          2013-10-10 17:11:54 +0400  483) 	if (err)
fe38d7df230b0 (Maxim Patlasov          2013-10-10 17:11:54 +0400  484) 		return err;
fe38d7df230b0 (Maxim Patlasov          2013-10-10 17:11:54 +0400  485) 
5955102c9984f (Al Viro                 2016-01-22 15:40:57 -0500  486) 	inode_lock(inode);
fe38d7df230b0 (Maxim Patlasov          2013-10-10 17:11:54 +0400  487) 	fuse_sync_writes(inode);
5955102c9984f (Al Viro                 2016-01-22 15:40:57 -0500  488) 	inode_unlock(inode);
fe38d7df230b0 (Maxim Patlasov          2013-10-10 17:11:54 +0400  489) 
4a7f4e88fef17 (Miklos Szeredi          2016-07-29 14:10:57 +0200  490) 	err = filemap_check_errors(file->f_mapping);
9ebce595f63a4 (Maxim Patlasov          2016-07-19 18:12:26 -0700  491) 	if (err)
9ebce595f63a4 (Maxim Patlasov          2016-07-19 18:12:26 -0700  492) 		return err;
9ebce595f63a4 (Maxim Patlasov          2016-07-19 18:12:26 -0700  493) 
614c026e8a466 (Miklos Szeredi          2020-05-19 14:50:37 +0200  494) 	err = 0;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  495) 	if (fm->fc->no_flush)
614c026e8a466 (Miklos Szeredi          2020-05-19 14:50:37 +0200  496) 		goto inval_attr_out;
614c026e8a466 (Miklos Szeredi          2020-05-19 14:50:37 +0200  497) 
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  498) 	memset(&inarg, 0, sizeof(inarg));
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  499) 	inarg.fh = ff->fh;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  500) 	inarg.lock_owner = fuse_lock_owner_id(fm->fc, id);
c500ebaa908db (Miklos Szeredi          2019-09-10 15:04:08 +0200  501) 	args.opcode = FUSE_FLUSH;
c500ebaa908db (Miklos Szeredi          2019-09-10 15:04:08 +0200  502) 	args.nodeid = get_node_id(inode);
c500ebaa908db (Miklos Szeredi          2019-09-10 15:04:08 +0200  503) 	args.in_numargs = 1;
c500ebaa908db (Miklos Szeredi          2019-09-10 15:04:08 +0200  504) 	args.in_args[0].size = sizeof(inarg);
c500ebaa908db (Miklos Szeredi          2019-09-10 15:04:08 +0200  505) 	args.in_args[0].value = &inarg;
c500ebaa908db (Miklos Szeredi          2019-09-10 15:04:08 +0200  506) 	args.force = true;
c500ebaa908db (Miklos Szeredi          2019-09-10 15:04:08 +0200  507) 
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  508) 	err = fuse_simple_request(fm, &args);
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  509) 	if (err == -ENOSYS) {
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  510) 		fm->fc->no_flush = 1;
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  511) 		err = 0;
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  512) 	}
cf576c58b3a28 (Eryu Guan               2020-05-12 10:29:04 +0800  513) 
cf576c58b3a28 (Eryu Guan               2020-05-12 10:29:04 +0800  514) inval_attr_out:
cf576c58b3a28 (Eryu Guan               2020-05-12 10:29:04 +0800  515) 	/*
cf576c58b3a28 (Eryu Guan               2020-05-12 10:29:04 +0800  516) 	 * In memory i_blocks is not maintained by fuse, if writeback cache is
cf576c58b3a28 (Eryu Guan               2020-05-12 10:29:04 +0800  517) 	 * enabled, i_blocks from cached attr may not be accurate.
cf576c58b3a28 (Eryu Guan               2020-05-12 10:29:04 +0800  518) 	 */
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  519) 	if (!err && fm->fc->writeback_cache)
cf576c58b3a28 (Eryu Guan               2020-05-12 10:29:04 +0800  520) 		fuse_invalidate_attr(inode);
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  521) 	return err;
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  522) }
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  523) 
02c24a82187d5 (Josef Bacik             2011-07-16 20:44:56 -0400  524) int fuse_fsync_common(struct file *file, loff_t start, loff_t end,
a9c2d1e82fc29 (Miklos Szeredi          2018-12-03 10:14:43 +0100  525) 		      int datasync, int opcode)
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  526) {
7ea8085910ef3 (Christoph Hellwig       2010-05-26 17:53:25 +0200  527) 	struct inode *inode = file->f_mapping->host;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  528) 	struct fuse_mount *fm = get_fuse_mount(inode);
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  529) 	struct fuse_file *ff = file->private_data;
7078187a795f8 (Miklos Szeredi          2014-12-12 09:49:05 +0100  530) 	FUSE_ARGS(args);
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  531) 	struct fuse_fsync_in inarg;
a9c2d1e82fc29 (Miklos Szeredi          2018-12-03 10:14:43 +0100  532) 
a9c2d1e82fc29 (Miklos Szeredi          2018-12-03 10:14:43 +0100  533) 	memset(&inarg, 0, sizeof(inarg));
a9c2d1e82fc29 (Miklos Szeredi          2018-12-03 10:14:43 +0100  534) 	inarg.fh = ff->fh;
154603fe3ec46 (Alan Somers             2019-04-19 15:42:44 -0600  535) 	inarg.fsync_flags = datasync ? FUSE_FSYNC_FDATASYNC : 0;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200  536) 	args.opcode = opcode;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200  537) 	args.nodeid = get_node_id(inode);
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200  538) 	args.in_numargs = 1;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200  539) 	args.in_args[0].size = sizeof(inarg);
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200  540) 	args.in_args[0].value = &inarg;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  541) 	return fuse_simple_request(fm, &args);
a9c2d1e82fc29 (Miklos Szeredi          2018-12-03 10:14:43 +0100  542) }
a9c2d1e82fc29 (Miklos Szeredi          2018-12-03 10:14:43 +0100  543) 
a9c2d1e82fc29 (Miklos Szeredi          2018-12-03 10:14:43 +0100  544) static int fuse_fsync(struct file *file, loff_t start, loff_t end,
a9c2d1e82fc29 (Miklos Szeredi          2018-12-03 10:14:43 +0100  545) 		      int datasync)
a9c2d1e82fc29 (Miklos Szeredi          2018-12-03 10:14:43 +0100  546) {
a9c2d1e82fc29 (Miklos Szeredi          2018-12-03 10:14:43 +0100  547) 	struct inode *inode = file->f_mapping->host;
a9c2d1e82fc29 (Miklos Szeredi          2018-12-03 10:14:43 +0100  548) 	struct fuse_conn *fc = get_fuse_conn(inode);
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  549) 	int err;
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  550) 
5d069dbe8aaf2 (Miklos Szeredi          2020-12-10 15:33:14 +0100  551) 	if (fuse_is_bad(inode))
248d86e87d12d (Miklos Szeredi          2006-01-06 00:19:39 -0800  552) 		return -EIO;
248d86e87d12d (Miklos Szeredi          2006-01-06 00:19:39 -0800  553) 
5955102c9984f (Al Viro                 2016-01-22 15:40:57 -0500  554) 	inode_lock(inode);
02c24a82187d5 (Josef Bacik             2011-07-16 20:44:56 -0400  555) 
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  556) 	/*
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  557) 	 * Start writeback against all dirty pages of the inode, then
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  558) 	 * wait for all outstanding writes, before sending the FSYNC
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  559) 	 * request.
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  560) 	 */
7e51fe1dd180e (Jeff Layton             2017-07-22 09:27:43 -0400  561) 	err = file_write_and_wait_range(file, start, end);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  562) 	if (err)
02c24a82187d5 (Josef Bacik             2011-07-16 20:44:56 -0400  563) 		goto out;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  564) 
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  565) 	fuse_sync_writes(inode);
ac7f052b9e153 (Alexey Kuznetsov        2016-07-19 12:48:01 -0700  566) 
ac7f052b9e153 (Alexey Kuznetsov        2016-07-19 12:48:01 -0700  567) 	/*
ac7f052b9e153 (Alexey Kuznetsov        2016-07-19 12:48:01 -0700  568) 	 * Due to implementation of fuse writeback
7e51fe1dd180e (Jeff Layton             2017-07-22 09:27:43 -0400  569) 	 * file_write_and_wait_range() does not catch errors.
ac7f052b9e153 (Alexey Kuznetsov        2016-07-19 12:48:01 -0700  570) 	 * We have to do this directly after fuse_sync_writes()
ac7f052b9e153 (Alexey Kuznetsov        2016-07-19 12:48:01 -0700  571) 	 */
7e51fe1dd180e (Jeff Layton             2017-07-22 09:27:43 -0400  572) 	err = file_check_and_advance_wb_err(file);
ac7f052b9e153 (Alexey Kuznetsov        2016-07-19 12:48:01 -0700  573) 	if (err)
ac7f052b9e153 (Alexey Kuznetsov        2016-07-19 12:48:01 -0700  574) 		goto out;
ac7f052b9e153 (Alexey Kuznetsov        2016-07-19 12:48:01 -0700  575) 
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200  576) 	err = sync_inode_metadata(inode, 1);
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200  577) 	if (err)
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200  578) 		goto out;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  579) 
a9c2d1e82fc29 (Miklos Szeredi          2018-12-03 10:14:43 +0100  580) 	if (fc->no_fsync)
22401e7b7a686 (Miklos Szeredi          2014-04-28 14:19:23 +0200  581) 		goto out;
b0aa760652179 (Maxim Patlasov          2013-12-26 19:51:11 +0400  582) 
a9c2d1e82fc29 (Miklos Szeredi          2018-12-03 10:14:43 +0100  583) 	err = fuse_fsync_common(file, start, end, datasync, FUSE_FSYNC);
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  584) 	if (err == -ENOSYS) {
a9c2d1e82fc29 (Miklos Szeredi          2018-12-03 10:14:43 +0100  585) 		fc->no_fsync = 1;
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  586) 		err = 0;
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  587) 	}
02c24a82187d5 (Josef Bacik             2011-07-16 20:44:56 -0400  588) out:
5955102c9984f (Al Viro                 2016-01-22 15:40:57 -0500  589) 	inode_unlock(inode);
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  590) 
a9c2d1e82fc29 (Miklos Szeredi          2018-12-03 10:14:43 +0100  591) 	return err;
8254798199332 (Miklos Szeredi          2005-09-09 13:10:38 -0700  592) }
8254798199332 (Miklos Szeredi          2005-09-09 13:10:38 -0700  593) 
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  594) void fuse_read_args_fill(struct fuse_io_args *ia, struct file *file, loff_t pos,
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  595) 			 size_t count, int opcode)
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  596) {
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  597) 	struct fuse_file *ff = file->private_data;
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  598) 	struct fuse_args *args = &ia->ap.args;
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  599) 
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  600) 	ia->read.in.fh = ff->fh;
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  601) 	ia->read.in.offset = pos;
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  602) 	ia->read.in.size = count;
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  603) 	ia->read.in.flags = file->f_flags;
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  604) 	args->opcode = opcode;
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  605) 	args->nodeid = ff->nodeid;
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  606) 	args->in_numargs = 1;
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  607) 	args->in_args[0].size = sizeof(ia->read.in);
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  608) 	args->in_args[0].value = &ia->read.in;
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  609) 	args->out_argvar = true;
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  610) 	args->out_numargs = 1;
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  611) 	args->out_args[0].size = count;
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  612) }
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  613) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  614) static void fuse_release_user_pages(struct fuse_args_pages *ap,
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  615) 				    bool should_dirty)
187c5c36330bc (Maxim Patlasov          2012-12-14 19:20:25 +0400  616) {
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  617) 	unsigned int i;
187c5c36330bc (Maxim Patlasov          2012-12-14 19:20:25 +0400  618) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  619) 	for (i = 0; i < ap->num_pages; i++) {
8fba54aebbdf1 (Miklos Szeredi          2016-08-24 18:17:04 +0200  620) 		if (should_dirty)
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  621) 			set_page_dirty_lock(ap->pages[i]);
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  622) 		put_page(ap->pages[i]);
187c5c36330bc (Maxim Patlasov          2012-12-14 19:20:25 +0400  623) 	}
187c5c36330bc (Maxim Patlasov          2012-12-14 19:20:25 +0400  624) }
187c5c36330bc (Maxim Patlasov          2012-12-14 19:20:25 +0400  625) 
744742d692e37 (Seth Forshee            2016-03-11 10:35:34 -0600  626) static void fuse_io_release(struct kref *kref)
744742d692e37 (Seth Forshee            2016-03-11 10:35:34 -0600  627) {
744742d692e37 (Seth Forshee            2016-03-11 10:35:34 -0600  628) 	kfree(container_of(kref, struct fuse_io_priv, refcnt));
744742d692e37 (Seth Forshee            2016-03-11 10:35:34 -0600  629) }
744742d692e37 (Seth Forshee            2016-03-11 10:35:34 -0600  630) 
9d5722b7777e6 (Christoph Hellwig       2015-02-02 14:59:43 +0100  631) static ssize_t fuse_get_res_by_io(struct fuse_io_priv *io)
9d5722b7777e6 (Christoph Hellwig       2015-02-02 14:59:43 +0100  632) {
9d5722b7777e6 (Christoph Hellwig       2015-02-02 14:59:43 +0100  633) 	if (io->err)
9d5722b7777e6 (Christoph Hellwig       2015-02-02 14:59:43 +0100  634) 		return io->err;
9d5722b7777e6 (Christoph Hellwig       2015-02-02 14:59:43 +0100  635) 
9d5722b7777e6 (Christoph Hellwig       2015-02-02 14:59:43 +0100  636) 	if (io->bytes >= 0 && io->write)
9d5722b7777e6 (Christoph Hellwig       2015-02-02 14:59:43 +0100  637) 		return -EIO;
9d5722b7777e6 (Christoph Hellwig       2015-02-02 14:59:43 +0100  638) 
9d5722b7777e6 (Christoph Hellwig       2015-02-02 14:59:43 +0100  639) 	return io->bytes < 0 ? io->size : io->bytes;
9d5722b7777e6 (Christoph Hellwig       2015-02-02 14:59:43 +0100  640) }
9d5722b7777e6 (Christoph Hellwig       2015-02-02 14:59:43 +0100  641) 
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  642) /**
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  643)  * In case of short read, the caller sets 'pos' to the position of
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  644)  * actual end of fuse request in IO request. Otherwise, if bytes_requested
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  645)  * == bytes_transferred or rw == WRITE, the caller sets 'pos' to -1.
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  646)  *
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  647)  * An example:
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  648)  * User requested DIO read of 64K. It was splitted into two 32K fuse requests,
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  649)  * both submitted asynchronously. The first of them was ACKed by userspace as
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  650)  * fully completed (req->out.args[0].size == 32K) resulting in pos == -1. The
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  651)  * second request was ACKed as short, e.g. only 1K was read, resulting in
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  652)  * pos == 33K.
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  653)  *
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  654)  * Thus, when all fuse requests are completed, the minimal non-negative 'pos'
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  655)  * will be equal to the length of the longest contiguous fragment of
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  656)  * transferred data starting from the beginning of IO request.
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  657)  */
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  658) static void fuse_aio_complete(struct fuse_io_priv *io, int err, ssize_t pos)
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  659) {
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  660) 	int left;
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  661) 
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  662) 	spin_lock(&io->lock);
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  663) 	if (err)
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  664) 		io->err = io->err ? : err;
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  665) 	else if (pos >= 0 && (io->bytes < 0 || pos < io->bytes))
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  666) 		io->bytes = pos;
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  667) 
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  668) 	left = --io->reqs;
7879c4e58b7c8 (Ashish Sangwan          2016-04-07 17:18:11 +0530  669) 	if (!left && io->blocking)
9d5722b7777e6 (Christoph Hellwig       2015-02-02 14:59:43 +0100  670) 		complete(io->done);
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  671) 	spin_unlock(&io->lock);
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  672) 
7879c4e58b7c8 (Ashish Sangwan          2016-04-07 17:18:11 +0530  673) 	if (!left && !io->blocking) {
9d5722b7777e6 (Christoph Hellwig       2015-02-02 14:59:43 +0100  674) 		ssize_t res = fuse_get_res_by_io(io);
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  675) 
9d5722b7777e6 (Christoph Hellwig       2015-02-02 14:59:43 +0100  676) 		if (res >= 0) {
9d5722b7777e6 (Christoph Hellwig       2015-02-02 14:59:43 +0100  677) 			struct inode *inode = file_inode(io->iocb->ki_filp);
9d5722b7777e6 (Christoph Hellwig       2015-02-02 14:59:43 +0100  678) 			struct fuse_conn *fc = get_fuse_conn(inode);
9d5722b7777e6 (Christoph Hellwig       2015-02-02 14:59:43 +0100  679) 			struct fuse_inode *fi = get_fuse_inode(inode);
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  680) 
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300  681) 			spin_lock(&fi->lock);
4510d86fbbb36 (Kirill Tkhai            2018-11-09 13:33:17 +0300  682) 			fi->attr_version = atomic64_inc_return(&fc->attr_version);
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300  683) 			spin_unlock(&fi->lock);
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  684) 		}
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  685) 
04b2fa9f8f36e (Christoph Hellwig       2015-02-02 14:49:06 +0100  686) 		io->iocb->ki_complete(io->iocb, res, 0);
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  687) 	}
744742d692e37 (Seth Forshee            2016-03-11 10:35:34 -0600  688) 
744742d692e37 (Seth Forshee            2016-03-11 10:35:34 -0600  689) 	kref_put(&io->refcnt, fuse_io_release);
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  690) }
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  691) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  692) static struct fuse_io_args *fuse_io_alloc(struct fuse_io_priv *io,
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  693) 					  unsigned int npages)
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  694) {
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  695) 	struct fuse_io_args *ia;
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  696) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  697) 	ia = kzalloc(sizeof(*ia), GFP_KERNEL);
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  698) 	if (ia) {
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  699) 		ia->io = io;
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  700) 		ia->ap.pages = fuse_pages_alloc(npages, GFP_KERNEL,
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  701) 						&ia->ap.descs);
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  702) 		if (!ia->ap.pages) {
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  703) 			kfree(ia);
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  704) 			ia = NULL;
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  705) 		}
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  706) 	}
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  707) 	return ia;
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  708) }
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  709) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  710) static void fuse_io_free(struct fuse_io_args *ia)
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  711) {
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  712) 	kfree(ia->ap.pages);
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  713) 	kfree(ia);
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  714) }
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  715) 
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  716) static void fuse_aio_complete_req(struct fuse_mount *fm, struct fuse_args *args,
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  717) 				  int err)
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  718) {
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  719) 	struct fuse_io_args *ia = container_of(args, typeof(*ia), ap.args);
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  720) 	struct fuse_io_priv *io = ia->io;
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  721) 	ssize_t pos = -1;
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  722) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  723) 	fuse_release_user_pages(&ia->ap, io->should_dirty);
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  724) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  725) 	if (err) {
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  726) 		/* Nothing */
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  727) 	} else if (io->write) {
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  728) 		if (ia->write.out.size > ia->write.in.size) {
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  729) 			err = -EIO;
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  730) 		} else if (ia->write.in.size != ia->write.out.size) {
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  731) 			pos = ia->write.in.offset - io->offset +
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  732) 				ia->write.out.size;
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  733) 		}
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  734) 	} else {
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  735) 		u32 outsize = args->out_args[0].size;
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  736) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  737) 		if (ia->read.in.size != outsize)
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  738) 			pos = ia->read.in.offset - io->offset + outsize;
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  739) 	}
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  740) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  741) 	fuse_aio_complete(io, err, pos);
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  742) 	fuse_io_free(ia);
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  743) }
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  744) 
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  745) static ssize_t fuse_async_req_send(struct fuse_mount *fm,
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  746) 				   struct fuse_io_args *ia, size_t num_bytes)
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  747) {
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  748) 	ssize_t err;
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  749) 	struct fuse_io_priv *io = ia->io;
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  750) 
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  751) 	spin_lock(&io->lock);
744742d692e37 (Seth Forshee            2016-03-11 10:35:34 -0600  752) 	kref_get(&io->refcnt);
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  753) 	io->size += num_bytes;
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  754) 	io->reqs++;
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  755) 	spin_unlock(&io->lock);
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  756) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  757) 	ia->ap.args.end = fuse_aio_complete_req;
bb737bbe48bea (Vivek Goyal             2020-04-20 17:01:34 +0200  758) 	ia->ap.args.may_block = io->should_dirty;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  759) 	err = fuse_simple_background(fm, &ia->ap.args, GFP_KERNEL);
f1ebdeffc6f32 (Miklos Szeredi          2019-11-25 20:48:46 +0100  760) 	if (err)
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  761) 		fuse_aio_complete_req(fm, &ia->ap.args, err);
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  762) 
f1ebdeffc6f32 (Miklos Szeredi          2019-11-25 20:48:46 +0100  763) 	return num_bytes;
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  764) }
01e9d11a3e790 (Maxim Patlasov          2012-12-14 19:20:41 +0400  765) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  766) static ssize_t fuse_send_read(struct fuse_io_args *ia, loff_t pos, size_t count,
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  767) 			      fl_owner_t owner)
04730fef1f9c7 (Miklos Szeredi          2005-09-09 13:10:36 -0700  768) {
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  769) 	struct file *file = ia->io->iocb->ki_filp;
2106cb1893031 (Miklos Szeredi          2009-04-28 16:56:37 +0200  770) 	struct fuse_file *ff = file->private_data;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  771) 	struct fuse_mount *fm = ff->fm;
f33321141b273 (Miklos Szeredi          2007-10-18 03:07:04 -0700  772) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  773) 	fuse_read_args_fill(ia, file, pos, count, FUSE_READ);
f33321141b273 (Miklos Szeredi          2007-10-18 03:07:04 -0700  774) 	if (owner != NULL) {
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  775) 		ia->read.in.read_flags |= FUSE_READ_LOCKOWNER;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  776) 		ia->read.in.lock_owner = fuse_lock_owner_id(fm->fc, owner);
f33321141b273 (Miklos Szeredi          2007-10-18 03:07:04 -0700  777) 	}
36cf66ed9f871 (Maxim Patlasov          2012-12-14 19:20:51 +0400  778) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200  779) 	if (ia->io->async)
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  780) 		return fuse_async_req_send(fm, ia, count);
36cf66ed9f871 (Maxim Patlasov          2012-12-14 19:20:51 +0400  781) 
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  782) 	return fuse_simple_request(fm, &ia->ap.args);
04730fef1f9c7 (Miklos Szeredi          2005-09-09 13:10:36 -0700  783) }
04730fef1f9c7 (Miklos Szeredi          2005-09-09 13:10:36 -0700  784) 
5c5c5e51b2641 (Miklos Szeredi          2008-04-30 00:54:43 -0700  785) static void fuse_read_update_size(struct inode *inode, loff_t size,
5c5c5e51b2641 (Miklos Szeredi          2008-04-30 00:54:43 -0700  786) 				  u64 attr_ver)
5c5c5e51b2641 (Miklos Szeredi          2008-04-30 00:54:43 -0700  787) {
5c5c5e51b2641 (Miklos Szeredi          2008-04-30 00:54:43 -0700  788) 	struct fuse_conn *fc = get_fuse_conn(inode);
5c5c5e51b2641 (Miklos Szeredi          2008-04-30 00:54:43 -0700  789) 	struct fuse_inode *fi = get_fuse_inode(inode);
5c5c5e51b2641 (Miklos Szeredi          2008-04-30 00:54:43 -0700  790) 
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300  791) 	spin_lock(&fi->lock);
06a7c3c278140 (Maxim Patlasov          2013-08-30 17:06:04 +0400  792) 	if (attr_ver == fi->attr_version && size < inode->i_size &&
06a7c3c278140 (Maxim Patlasov          2013-08-30 17:06:04 +0400  793) 	    !test_bit(FUSE_I_SIZE_UNSTABLE, &fi->state)) {
4510d86fbbb36 (Kirill Tkhai            2018-11-09 13:33:17 +0300  794) 		fi->attr_version = atomic64_inc_return(&fc->attr_version);
5c5c5e51b2641 (Miklos Szeredi          2008-04-30 00:54:43 -0700  795) 		i_size_write(inode, size);
5c5c5e51b2641 (Miklos Szeredi          2008-04-30 00:54:43 -0700  796) 	}
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300  797) 	spin_unlock(&fi->lock);
5c5c5e51b2641 (Miklos Szeredi          2008-04-30 00:54:43 -0700  798) }
5c5c5e51b2641 (Miklos Szeredi          2008-04-30 00:54:43 -0700  799) 
a0d45d84f4c9d (Miklos Szeredi          2019-09-10 15:04:09 +0200  800) static void fuse_short_read(struct inode *inode, u64 attr_ver, size_t num_read,
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  801) 			    struct fuse_args_pages *ap)
a92adc824ed5f (Pavel Emelyanov         2013-10-10 17:10:16 +0400  802) {
8373200b124d0 (Pavel Emelyanov         2013-10-10 17:10:46 +0400  803) 	struct fuse_conn *fc = get_fuse_conn(inode);
8373200b124d0 (Pavel Emelyanov         2013-10-10 17:10:46 +0400  804) 
a73d47f57792d (Miklos Szeredi          2021-04-14 10:40:56 +0200  805) 	/*
a73d47f57792d (Miklos Szeredi          2021-04-14 10:40:56 +0200  806) 	 * If writeback_cache is enabled, a short read means there's a hole in
a73d47f57792d (Miklos Szeredi          2021-04-14 10:40:56 +0200  807) 	 * the file.  Some data after the hole is in page cache, but has not
a73d47f57792d (Miklos Szeredi          2021-04-14 10:40:56 +0200  808) 	 * reached the client fs yet.  So the hole is not present there.
a73d47f57792d (Miklos Szeredi          2021-04-14 10:40:56 +0200  809) 	 */
a73d47f57792d (Miklos Szeredi          2021-04-14 10:40:56 +0200  810) 	if (!fc->writeback_cache) {
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  811) 		loff_t pos = page_offset(ap->pages[0]) + num_read;
8373200b124d0 (Pavel Emelyanov         2013-10-10 17:10:46 +0400  812) 		fuse_read_update_size(inode, pos, attr_ver);
8373200b124d0 (Pavel Emelyanov         2013-10-10 17:10:46 +0400  813) 	}
a92adc824ed5f (Pavel Emelyanov         2013-10-10 17:10:16 +0400  814) }
a92adc824ed5f (Pavel Emelyanov         2013-10-10 17:10:16 +0400  815) 
482fce55d2809 (Maxim Patlasov          2013-10-10 17:11:25 +0400  816) static int fuse_do_readpage(struct file *file, struct page *page)
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  817) {
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  818) 	struct inode *inode = page->mapping->host;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  819) 	struct fuse_mount *fm = get_fuse_mount(inode);
5c5c5e51b2641 (Miklos Szeredi          2008-04-30 00:54:43 -0700  820) 	loff_t pos = page_offset(page);
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  821) 	struct fuse_page_desc desc = { .length = PAGE_SIZE };
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  822) 	struct fuse_io_args ia = {
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  823) 		.ap.args.page_zeroing = true,
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  824) 		.ap.args.out_pages = true,
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  825) 		.ap.num_pages = 1,
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  826) 		.ap.pages = &page,
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  827) 		.ap.descs = &desc,
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  828) 	};
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  829) 	ssize_t res;
5c5c5e51b2641 (Miklos Szeredi          2008-04-30 00:54:43 -0700  830) 	u64 attr_ver;
248d86e87d12d (Miklos Szeredi          2006-01-06 00:19:39 -0800  831) 
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  832) 	/*
25985edcedea6 (Lucas De Marchi         2011-03-30 22:57:33 -0300  833) 	 * Page writeback can extend beyond the lifetime of the
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  834) 	 * page-cache page, so make sure we read a properly synced
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  835) 	 * page.
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  836) 	 */
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  837) 	fuse_wait_on_page_writeback(inode, page->index);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700  838) 
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  839) 	attr_ver = fuse_get_attr_version(fm->fc);
5c5c5e51b2641 (Miklos Szeredi          2008-04-30 00:54:43 -0700  840) 
2f1398291bf35 (Miklos Szeredi          2020-02-06 16:39:28 +0100  841) 	/* Don't overflow end offset */
2f1398291bf35 (Miklos Szeredi          2020-02-06 16:39:28 +0100  842) 	if (pos + (desc.length - 1) == LLONG_MAX)
2f1398291bf35 (Miklos Szeredi          2020-02-06 16:39:28 +0100  843) 		desc.length--;
2f1398291bf35 (Miklos Szeredi          2020-02-06 16:39:28 +0100  844) 
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  845) 	fuse_read_args_fill(&ia, file, pos, desc.length, FUSE_READ);
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  846) 	res = fuse_simple_request(fm, &ia.ap.args);
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  847) 	if (res < 0)
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  848) 		return res;
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  849) 	/*
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  850) 	 * Short read means EOF.  If file size is larger, truncate it
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  851) 	 */
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  852) 	if (res < desc.length)
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  853) 		fuse_short_read(inode, attr_ver, res, &ia.ap);
5c5c5e51b2641 (Miklos Szeredi          2008-04-30 00:54:43 -0700  854) 
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  855) 	SetPageUptodate(page);
482fce55d2809 (Maxim Patlasov          2013-10-10 17:11:25 +0400  856) 
00793ca5d4439 (Miklos Szeredi          2019-09-10 15:04:09 +0200  857) 	return 0;
482fce55d2809 (Maxim Patlasov          2013-10-10 17:11:25 +0400  858) }
482fce55d2809 (Maxim Patlasov          2013-10-10 17:11:25 +0400  859) 
482fce55d2809 (Maxim Patlasov          2013-10-10 17:11:25 +0400  860) static int fuse_readpage(struct file *file, struct page *page)
482fce55d2809 (Maxim Patlasov          2013-10-10 17:11:25 +0400  861) {
482fce55d2809 (Maxim Patlasov          2013-10-10 17:11:25 +0400  862) 	struct inode *inode = page->mapping->host;
482fce55d2809 (Maxim Patlasov          2013-10-10 17:11:25 +0400  863) 	int err;
482fce55d2809 (Maxim Patlasov          2013-10-10 17:11:25 +0400  864) 
482fce55d2809 (Maxim Patlasov          2013-10-10 17:11:25 +0400  865) 	err = -EIO;
5d069dbe8aaf2 (Miklos Szeredi          2020-12-10 15:33:14 +0100  866) 	if (fuse_is_bad(inode))
482fce55d2809 (Maxim Patlasov          2013-10-10 17:11:25 +0400  867) 		goto out;
482fce55d2809 (Maxim Patlasov          2013-10-10 17:11:25 +0400  868) 
482fce55d2809 (Maxim Patlasov          2013-10-10 17:11:25 +0400  869) 	err = fuse_do_readpage(file, page);
451418fc928b5 (Andrew Gallagher        2013-11-05 03:55:43 -0800  870) 	fuse_invalidate_atime(inode);
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  871)  out:
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  872) 	unlock_page(page);
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  873) 	return err;
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  874) }
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700  875) 
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  876) static void fuse_readpages_end(struct fuse_mount *fm, struct fuse_args *args,
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  877) 			       int err)
db50b96c0f28a (Miklos Szeredi          2005-09-09 13:10:33 -0700  878) {
c1aa96a52e959 (Miklos Szeredi          2006-01-16 22:14:46 -0800  879) 	int i;
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  880) 	struct fuse_io_args *ia = container_of(args, typeof(*ia), ap.args);
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  881) 	struct fuse_args_pages *ap = &ia->ap;
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  882) 	size_t count = ia->read.in.size;
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  883) 	size_t num_read = args->out_args[0].size;
ce534fb052928 (Miklos Szeredi          2010-05-25 15:06:07 +0200  884) 	struct address_space *mapping = NULL;
c1aa96a52e959 (Miklos Szeredi          2006-01-16 22:14:46 -0800  885) 
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  886) 	for (i = 0; mapping == NULL && i < ap->num_pages; i++)
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  887) 		mapping = ap->pages[i]->mapping;
5c5c5e51b2641 (Miklos Szeredi          2008-04-30 00:54:43 -0700  888) 
ce534fb052928 (Miklos Szeredi          2010-05-25 15:06:07 +0200  889) 	if (mapping) {
ce534fb052928 (Miklos Szeredi          2010-05-25 15:06:07 +0200  890) 		struct inode *inode = mapping->host;
ce534fb052928 (Miklos Szeredi          2010-05-25 15:06:07 +0200  891) 
ce534fb052928 (Miklos Szeredi          2010-05-25 15:06:07 +0200  892) 		/*
ce534fb052928 (Miklos Szeredi          2010-05-25 15:06:07 +0200  893) 		 * Short read means EOF. If file size is larger, truncate it
ce534fb052928 (Miklos Szeredi          2010-05-25 15:06:07 +0200  894) 		 */
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  895) 		if (!err && num_read < count)
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  896) 			fuse_short_read(inode, ia->read.attr_ver, num_read, ap);
ce534fb052928 (Miklos Szeredi          2010-05-25 15:06:07 +0200  897) 
451418fc928b5 (Andrew Gallagher        2013-11-05 03:55:43 -0800  898) 		fuse_invalidate_atime(inode);
ce534fb052928 (Miklos Szeredi          2010-05-25 15:06:07 +0200  899) 	}
c1aa96a52e959 (Miklos Szeredi          2006-01-16 22:14:46 -0800  900) 
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  901) 	for (i = 0; i < ap->num_pages; i++) {
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  902) 		struct page *page = ap->pages[i];
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  903) 
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  904) 		if (!err)
db50b96c0f28a (Miklos Szeredi          2005-09-09 13:10:33 -0700  905) 			SetPageUptodate(page);
c1aa96a52e959 (Miklos Szeredi          2006-01-16 22:14:46 -0800  906) 		else
c1aa96a52e959 (Miklos Szeredi          2006-01-16 22:14:46 -0800  907) 			SetPageError(page);
db50b96c0f28a (Miklos Szeredi          2005-09-09 13:10:33 -0700  908) 		unlock_page(page);
09cbfeaf1a5a6 (Kirill A. Shutemov      2016-04-01 15:29:47 +0300  909) 		put_page(page);
db50b96c0f28a (Miklos Szeredi          2005-09-09 13:10:33 -0700  910) 	}
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  911) 	if (ia->ff)
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  912) 		fuse_file_put(ia->ff, false, false);
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  913) 
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  914) 	fuse_io_free(ia);
c1aa96a52e959 (Miklos Szeredi          2006-01-16 22:14:46 -0800  915) }
c1aa96a52e959 (Miklos Szeredi          2006-01-16 22:14:46 -0800  916) 
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  917) static void fuse_send_readpages(struct fuse_io_args *ia, struct file *file)
c1aa96a52e959 (Miklos Szeredi          2006-01-16 22:14:46 -0800  918) {
2106cb1893031 (Miklos Szeredi          2009-04-28 16:56:37 +0200  919) 	struct fuse_file *ff = file->private_data;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  920) 	struct fuse_mount *fm = ff->fm;
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  921) 	struct fuse_args_pages *ap = &ia->ap;
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  922) 	loff_t pos = page_offset(ap->pages[0]);
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  923) 	size_t count = ap->num_pages << PAGE_SHIFT;
7df1e988c723a (Miklos Szeredi          2020-01-16 11:09:36 +0100  924) 	ssize_t res;
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  925) 	int err;
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  926) 
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  927) 	ap->args.out_pages = true;
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  928) 	ap->args.page_zeroing = true;
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  929) 	ap->args.page_replace = true;
2f1398291bf35 (Miklos Szeredi          2020-02-06 16:39:28 +0100  930) 
2f1398291bf35 (Miklos Szeredi          2020-02-06 16:39:28 +0100  931) 	/* Don't overflow end offset */
2f1398291bf35 (Miklos Szeredi          2020-02-06 16:39:28 +0100  932) 	if (pos + (count - 1) == LLONG_MAX) {
2f1398291bf35 (Miklos Szeredi          2020-02-06 16:39:28 +0100  933) 		count--;
2f1398291bf35 (Miklos Szeredi          2020-02-06 16:39:28 +0100  934) 		ap->descs[ap->num_pages - 1].length--;
2f1398291bf35 (Miklos Szeredi          2020-02-06 16:39:28 +0100  935) 	}
2f1398291bf35 (Miklos Szeredi          2020-02-06 16:39:28 +0100  936) 	WARN_ON((loff_t) (pos + count) < 0);
2f1398291bf35 (Miklos Szeredi          2020-02-06 16:39:28 +0100  937) 
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  938) 	fuse_read_args_fill(ia, file, pos, count, FUSE_READ);
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  939) 	ia->read.attr_ver = fuse_get_attr_version(fm->fc);
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  940) 	if (fm->fc->async_read) {
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  941) 		ia->ff = fuse_file_get(ff);
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  942) 		ap->args.end = fuse_readpages_end;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  943) 		err = fuse_simple_background(fm, &ap->args, GFP_KERNEL);
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  944) 		if (!err)
134831e36bbdd (Miklos Szeredi          2019-09-10 15:04:10 +0200  945) 			return;
9cd684551124e (Miklos Szeredi          2006-02-01 03:04:40 -0800  946) 	} else {
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  947) 		res = fuse_simple_request(fm, &ap->args);
7df1e988c723a (Miklos Szeredi          2020-01-16 11:09:36 +0100  948) 		err = res < 0 ? res : 0;
9cd684551124e (Miklos Szeredi          2006-02-01 03:04:40 -0800  949) 	}
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200  950) 	fuse_readpages_end(fm, &ap->args, err);
db50b96c0f28a (Miklos Szeredi          2005-09-09 13:10:33 -0700  951) }
db50b96c0f28a (Miklos Szeredi          2005-09-09 13:10:33 -0700  952) 
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  953) static void fuse_readahead(struct readahead_control *rac)
db50b96c0f28a (Miklos Szeredi          2005-09-09 13:10:33 -0700  954) {
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  955) 	struct inode *inode = rac->mapping->host;
db50b96c0f28a (Miklos Szeredi          2005-09-09 13:10:33 -0700  956) 	struct fuse_conn *fc = get_fuse_conn(inode);
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  957) 	unsigned int i, max_pages, nr_pages = 0;
db50b96c0f28a (Miklos Szeredi          2005-09-09 13:10:33 -0700  958) 
5d069dbe8aaf2 (Miklos Szeredi          2020-12-10 15:33:14 +0100  959) 	if (fuse_is_bad(inode))
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  960) 		return;
248d86e87d12d (Miklos Szeredi          2006-01-06 00:19:39 -0800  961) 
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  962) 	max_pages = min_t(unsigned int, fc->max_pages,
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  963) 			fc->max_read / PAGE_SIZE);
db50b96c0f28a (Miklos Szeredi          2005-09-09 13:10:33 -0700  964) 
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  965) 	for (;;) {
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  966) 		struct fuse_io_args *ia;
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  967) 		struct fuse_args_pages *ap;
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  968) 
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  969) 		nr_pages = readahead_count(rac) - nr_pages;
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  970) 		if (nr_pages > max_pages)
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  971) 			nr_pages = max_pages;
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  972) 		if (nr_pages == 0)
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  973) 			break;
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  974) 		ia = fuse_io_alloc(NULL, nr_pages);
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  975) 		if (!ia)
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  976) 			return;
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  977) 		ap = &ia->ap;
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  978) 		nr_pages = __readahead_batch(rac, ap->pages, nr_pages);
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  979) 		for (i = 0; i < nr_pages; i++) {
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  980) 			fuse_wait_on_page_writeback(inode,
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  981) 						    readahead_index(rac) + i);
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  982) 			ap->descs[i].length = PAGE_SIZE;
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  983) 		}
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  984) 		ap->num_pages = nr_pages;
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700  985) 		fuse_send_readpages(ia, rac->file);
d3406ffa4af8a (Miklos Szeredi          2006-04-10 22:54:49 -0700  986) 	}
db50b96c0f28a (Miklos Szeredi          2005-09-09 13:10:33 -0700  987) }
db50b96c0f28a (Miklos Szeredi          2005-09-09 13:10:33 -0700  988) 
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100  989) static ssize_t fuse_cache_read_iter(struct kiocb *iocb, struct iov_iter *to)
bcb4be809d2a8 (Miklos Szeredi          2007-11-28 16:21:59 -0800  990) {
bcb4be809d2a8 (Miklos Szeredi          2007-11-28 16:21:59 -0800  991) 	struct inode *inode = iocb->ki_filp->f_mapping->host;
a8894274a3581 (Brian Foster            2012-07-16 15:23:50 -0400  992) 	struct fuse_conn *fc = get_fuse_conn(inode);
bcb4be809d2a8 (Miklos Szeredi          2007-11-28 16:21:59 -0800  993) 
a8894274a3581 (Brian Foster            2012-07-16 15:23:50 -0400  994) 	/*
a8894274a3581 (Brian Foster            2012-07-16 15:23:50 -0400  995) 	 * In auto invalidate mode, always update attributes on read.
a8894274a3581 (Brian Foster            2012-07-16 15:23:50 -0400  996) 	 * Otherwise, only update if we attempt to read past EOF (to ensure
a8894274a3581 (Brian Foster            2012-07-16 15:23:50 -0400  997) 	 * i_size is up to date).
a8894274a3581 (Brian Foster            2012-07-16 15:23:50 -0400  998) 	 */
a8894274a3581 (Brian Foster            2012-07-16 15:23:50 -0400  999) 	if (fc->auto_inval_data ||
37c20f16e7a73 (Al Viro                 2014-04-02 14:47:09 -0400 1000) 	    (iocb->ki_pos + iov_iter_count(to) > i_size_read(inode))) {
bcb4be809d2a8 (Miklos Szeredi          2007-11-28 16:21:59 -0800 1001) 		int err;
5b97eeacbd80a (Miklos Szeredi          2017-09-12 16:57:54 +0200 1002) 		err = fuse_update_attributes(inode, iocb->ki_filp);
bcb4be809d2a8 (Miklos Szeredi          2007-11-28 16:21:59 -0800 1003) 		if (err)
bcb4be809d2a8 (Miklos Szeredi          2007-11-28 16:21:59 -0800 1004) 			return err;
bcb4be809d2a8 (Miklos Szeredi          2007-11-28 16:21:59 -0800 1005) 	}
bcb4be809d2a8 (Miklos Szeredi          2007-11-28 16:21:59 -0800 1006) 
37c20f16e7a73 (Al Viro                 2014-04-02 14:47:09 -0400 1007) 	return generic_file_read_iter(iocb, to);
bcb4be809d2a8 (Miklos Szeredi          2007-11-28 16:21:59 -0800 1008) }
bcb4be809d2a8 (Miklos Szeredi          2007-11-28 16:21:59 -0800 1009) 
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1010) static void fuse_write_args_fill(struct fuse_io_args *ia, struct fuse_file *ff,
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1011) 				 loff_t pos, size_t count)
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1012) {
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1013) 	struct fuse_args *args = &ia->ap.args;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1014) 
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1015) 	ia->write.in.fh = ff->fh;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1016) 	ia->write.in.offset = pos;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1017) 	ia->write.in.size = count;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1018) 	args->opcode = FUSE_WRITE;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1019) 	args->nodeid = ff->nodeid;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1020) 	args->in_numargs = 2;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 1021) 	if (ff->fm->fc->minor < 9)
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1022) 		args->in_args[0].size = FUSE_COMPAT_WRITE_IN_SIZE;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1023) 	else
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1024) 		args->in_args[0].size = sizeof(ia->write.in);
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1025) 	args->in_args[0].value = &ia->write.in;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1026) 	args->in_args[1].size = count;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1027) 	args->out_numargs = 1;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1028) 	args->out_args[0].size = sizeof(ia->write.out);
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1029) 	args->out_args[0].value = &ia->write.out;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1030) }
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1031) 
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1032) static unsigned int fuse_write_flags(struct kiocb *iocb)
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1033) {
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1034) 	unsigned int flags = iocb->ki_filp->f_flags;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1035) 
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1036) 	if (iocb->ki_flags & IOCB_DSYNC)
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1037) 		flags |= O_DSYNC;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1038) 	if (iocb->ki_flags & IOCB_SYNC)
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1039) 		flags |= O_SYNC;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1040) 
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1041) 	return flags;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1042) }
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1043) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1044) static ssize_t fuse_send_write(struct fuse_io_args *ia, loff_t pos,
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1045) 			       size_t count, fl_owner_t owner)
b25e82e5673c7 (Miklos Szeredi          2007-10-18 03:07:03 -0700 1046) {
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1047) 	struct kiocb *iocb = ia->io->iocb;
e1c0eecba1a41 (Miklos Szeredi          2017-09-12 16:57:53 +0200 1048) 	struct file *file = iocb->ki_filp;
2106cb1893031 (Miklos Szeredi          2009-04-28 16:56:37 +0200 1049) 	struct fuse_file *ff = file->private_data;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 1050) 	struct fuse_mount *fm = ff->fm;
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1051) 	struct fuse_write_in *inarg = &ia->write.in;
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1052) 	ssize_t err;
2d698b0703824 (Miklos Szeredi          2009-04-28 16:56:36 +0200 1053) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1054) 	fuse_write_args_fill(ia, ff, pos, count);
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1055) 	inarg->flags = fuse_write_flags(iocb);
f33321141b273 (Miklos Szeredi          2007-10-18 03:07:04 -0700 1056) 	if (owner != NULL) {
f33321141b273 (Miklos Szeredi          2007-10-18 03:07:04 -0700 1057) 		inarg->write_flags |= FUSE_WRITE_LOCKOWNER;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 1058) 		inarg->lock_owner = fuse_lock_owner_id(fm->fc, owner);
f33321141b273 (Miklos Szeredi          2007-10-18 03:07:04 -0700 1059) 	}
36cf66ed9f871 (Maxim Patlasov          2012-12-14 19:20:51 +0400 1060) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1061) 	if (ia->io->async)
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 1062) 		return fuse_async_req_send(fm, ia, count);
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1063) 
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 1064) 	err = fuse_simple_request(fm, &ia->ap.args);
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1065) 	if (!err && ia->write.out.size > count)
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1066) 		err = -EIO;
36cf66ed9f871 (Maxim Patlasov          2012-12-14 19:20:51 +0400 1067) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1068) 	return err ?: ia->write.out.size;
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700 1069) }
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700 1070) 
b0aa760652179 (Maxim Patlasov          2013-12-26 19:51:11 +0400 1071) bool fuse_write_update_size(struct inode *inode, loff_t pos)
854512ec358f2 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1072) {
854512ec358f2 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1073) 	struct fuse_conn *fc = get_fuse_conn(inode);
854512ec358f2 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1074) 	struct fuse_inode *fi = get_fuse_inode(inode);
b0aa760652179 (Maxim Patlasov          2013-12-26 19:51:11 +0400 1075) 	bool ret = false;
854512ec358f2 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1076) 
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300 1077) 	spin_lock(&fi->lock);
4510d86fbbb36 (Kirill Tkhai            2018-11-09 13:33:17 +0300 1078) 	fi->attr_version = atomic64_inc_return(&fc->attr_version);
b0aa760652179 (Maxim Patlasov          2013-12-26 19:51:11 +0400 1079) 	if (pos > inode->i_size) {
854512ec358f2 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1080) 		i_size_write(inode, pos);
b0aa760652179 (Maxim Patlasov          2013-12-26 19:51:11 +0400 1081) 		ret = true;
b0aa760652179 (Maxim Patlasov          2013-12-26 19:51:11 +0400 1082) 	}
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300 1083) 	spin_unlock(&fi->lock);
b0aa760652179 (Maxim Patlasov          2013-12-26 19:51:11 +0400 1084) 
b0aa760652179 (Maxim Patlasov          2013-12-26 19:51:11 +0400 1085) 	return ret;
854512ec358f2 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1086) }
854512ec358f2 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1087) 
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1088) static ssize_t fuse_send_write_pages(struct fuse_io_args *ia,
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1089) 				     struct kiocb *iocb, struct inode *inode,
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1090) 				     loff_t pos, size_t count)
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1091) {
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1092) 	struct fuse_args_pages *ap = &ia->ap;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1093) 	struct file *file = iocb->ki_filp;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1094) 	struct fuse_file *ff = file->private_data;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 1095) 	struct fuse_mount *fm = ff->fm;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1096) 	unsigned int offset, i;
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1097) 	bool short_write;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1098) 	int err;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1099) 
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1100) 	for (i = 0; i < ap->num_pages; i++)
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1101) 		fuse_wait_on_page_writeback(inode, ap->pages[i]->index);
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1102) 
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1103) 	fuse_write_args_fill(ia, ff, pos, count);
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1104) 	ia->write.in.flags = fuse_write_flags(iocb);
b866739596ae3 (Vivek Goyal             2020-10-09 14:15:08 -0400 1105) 	if (fm->fc->handle_killpriv_v2 && !capable(CAP_FSETID))
b866739596ae3 (Vivek Goyal             2020-10-09 14:15:08 -0400 1106) 		ia->write.in.write_flags |= FUSE_WRITE_KILL_SUIDGID;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1107) 
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 1108) 	err = fuse_simple_request(fm, &ap->args);
8aab336b14c11 (Miklos Szeredi          2019-11-12 11:49:04 +0100 1109) 	if (!err && ia->write.out.size > count)
8aab336b14c11 (Miklos Szeredi          2019-11-12 11:49:04 +0100 1110) 		err = -EIO;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1111) 
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1112) 	short_write = ia->write.out.size < count;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1113) 	offset = ap->descs[0].offset;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1114) 	count = ia->write.out.size;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1115) 	for (i = 0; i < ap->num_pages; i++) {
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1116) 		struct page *page = ap->pages[i];
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1117) 
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1118) 		if (err) {
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1119) 			ClearPageUptodate(page);
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1120) 		} else {
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1121) 			if (count >= PAGE_SIZE - offset)
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1122) 				count -= PAGE_SIZE - offset;
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1123) 			else {
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1124) 				if (short_write)
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1125) 					ClearPageUptodate(page);
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1126) 				count = 0;
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1127) 			}
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1128) 			offset = 0;
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1129) 		}
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1130) 		if (ia->write.page_locked && (i == ap->num_pages - 1))
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1131) 			unlock_page(page);
09cbfeaf1a5a6 (Kirill A. Shutemov      2016-04-01 15:29:47 +0300 1132) 		put_page(page);
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1133) 	}
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1134) 
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1135) 	return err;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1136) }
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1137) 
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1138) static ssize_t fuse_fill_write_pages(struct fuse_io_args *ia,
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1139) 				     struct address_space *mapping,
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1140) 				     struct iov_iter *ii, loff_t pos,
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1141) 				     unsigned int max_pages)
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1142) {
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1143) 	struct fuse_args_pages *ap = &ia->ap;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1144) 	struct fuse_conn *fc = get_fuse_conn(mapping->host);
09cbfeaf1a5a6 (Kirill A. Shutemov      2016-04-01 15:29:47 +0300 1145) 	unsigned offset = pos & (PAGE_SIZE - 1);
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1146) 	size_t count = 0;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1147) 	int err;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1148) 
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1149) 	ap->args.in_pages = true;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1150) 	ap->descs[0].offset = offset;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1151) 
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1152) 	do {
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1153) 		size_t tmp;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1154) 		struct page *page;
09cbfeaf1a5a6 (Kirill A. Shutemov      2016-04-01 15:29:47 +0300 1155) 		pgoff_t index = pos >> PAGE_SHIFT;
09cbfeaf1a5a6 (Kirill A. Shutemov      2016-04-01 15:29:47 +0300 1156) 		size_t bytes = min_t(size_t, PAGE_SIZE - offset,
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1157) 				     iov_iter_count(ii));
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1158) 
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1159) 		bytes = min_t(size_t, bytes, fc->max_write - count);
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1160) 
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1161)  again:
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1162) 		err = -EFAULT;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1163) 		if (iov_iter_fault_in_readable(ii, bytes))
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1164) 			break;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1165) 
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1166) 		err = -ENOMEM;
54566b2c1594c (Nicholas Piggin         2009-01-04 12:00:53 -0800 1167) 		page = grab_cache_page_write_begin(mapping, index, 0);
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1168) 		if (!page)
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1169) 			break;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1170) 
931e80e4b3263 (anfei zhou              2010-02-02 13:44:02 -0800 1171) 		if (mapping_writably_mapped(mapping))
931e80e4b3263 (anfei zhou              2010-02-02 13:44:02 -0800 1172) 			flush_dcache_page(page);
931e80e4b3263 (anfei zhou              2010-02-02 13:44:02 -0800 1173) 
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1174) 		tmp = iov_iter_copy_from_user_atomic(page, ii, offset, bytes);
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1175) 		flush_dcache_page(page);
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1176) 
3ca8138f014a9 (Roman Gushchin          2015-10-12 16:33:44 +0300 1177) 		iov_iter_advance(ii, tmp);
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1178) 		if (!tmp) {
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1179) 			unlock_page(page);
09cbfeaf1a5a6 (Kirill A. Shutemov      2016-04-01 15:29:47 +0300 1180) 			put_page(page);
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1181) 			bytes = min(bytes, iov_iter_single_seg_count(ii));
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1182) 			goto again;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1183) 		}
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1184) 
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1185) 		err = 0;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1186) 		ap->pages[ap->num_pages] = page;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1187) 		ap->descs[ap->num_pages].length = tmp;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1188) 		ap->num_pages++;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1189) 
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1190) 		count += tmp;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1191) 		pos += tmp;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1192) 		offset += tmp;
09cbfeaf1a5a6 (Kirill A. Shutemov      2016-04-01 15:29:47 +0300 1193) 		if (offset == PAGE_SIZE)
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1194) 			offset = 0;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1195) 
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1196) 		/* If we copied full page, mark it uptodate */
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1197) 		if (tmp == PAGE_SIZE)
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1198) 			SetPageUptodate(page);
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1199) 
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1200) 		if (PageUptodate(page)) {
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1201) 			unlock_page(page);
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1202) 		} else {
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1203) 			ia->write.page_locked = true;
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1204) 			break;
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1205) 		}
78bb6cb9a890d (Miklos Szeredi          2008-05-12 14:02:32 -0700 1206) 		if (!fc->big_writes)
78bb6cb9a890d (Miklos Szeredi          2008-05-12 14:02:32 -0700 1207) 			break;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1208) 	} while (iov_iter_count(ii) && count < fc->max_write &&
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1209) 		 ap->num_pages < max_pages && offset == 0);
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1210) 
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1211) 	return count > 0 ? count : err;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1212) }
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1213) 
5da784cce4308 (Constantine Shulyupin   2018-09-06 15:37:06 +0300 1214) static inline unsigned int fuse_wr_pages(loff_t pos, size_t len,
5da784cce4308 (Constantine Shulyupin   2018-09-06 15:37:06 +0300 1215) 				     unsigned int max_pages)
d07f09f509fb2 (Maxim Patlasov          2012-10-26 19:49:00 +0400 1216) {
5da784cce4308 (Constantine Shulyupin   2018-09-06 15:37:06 +0300 1217) 	return min_t(unsigned int,
09cbfeaf1a5a6 (Kirill A. Shutemov      2016-04-01 15:29:47 +0300 1218) 		     ((pos + len - 1) >> PAGE_SHIFT) -
09cbfeaf1a5a6 (Kirill A. Shutemov      2016-04-01 15:29:47 +0300 1219) 		     (pos >> PAGE_SHIFT) + 1,
5da784cce4308 (Constantine Shulyupin   2018-09-06 15:37:06 +0300 1220) 		     max_pages);
d07f09f509fb2 (Maxim Patlasov          2012-10-26 19:49:00 +0400 1221) }
d07f09f509fb2 (Maxim Patlasov          2012-10-26 19:49:00 +0400 1222) 
e1c0eecba1a41 (Miklos Szeredi          2017-09-12 16:57:53 +0200 1223) static ssize_t fuse_perform_write(struct kiocb *iocb,
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1224) 				  struct address_space *mapping,
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1225) 				  struct iov_iter *ii, loff_t pos)
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1226) {
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1227) 	struct inode *inode = mapping->host;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1228) 	struct fuse_conn *fc = get_fuse_conn(inode);
06a7c3c278140 (Maxim Patlasov          2013-08-30 17:06:04 +0400 1229) 	struct fuse_inode *fi = get_fuse_inode(inode);
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1230) 	int err = 0;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1231) 	ssize_t res = 0;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1232) 
06a7c3c278140 (Maxim Patlasov          2013-08-30 17:06:04 +0400 1233) 	if (inode->i_size < pos + iov_iter_count(ii))
06a7c3c278140 (Maxim Patlasov          2013-08-30 17:06:04 +0400 1234) 		set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
06a7c3c278140 (Maxim Patlasov          2013-08-30 17:06:04 +0400 1235) 
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1236) 	do {
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1237) 		ssize_t count;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1238) 		struct fuse_io_args ia = {};
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1239) 		struct fuse_args_pages *ap = &ia.ap;
5da784cce4308 (Constantine Shulyupin   2018-09-06 15:37:06 +0300 1240) 		unsigned int nr_pages = fuse_wr_pages(pos, iov_iter_count(ii),
5da784cce4308 (Constantine Shulyupin   2018-09-06 15:37:06 +0300 1241) 						      fc->max_pages);
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1242) 
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1243) 		ap->pages = fuse_pages_alloc(nr_pages, GFP_KERNEL, &ap->descs);
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1244) 		if (!ap->pages) {
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1245) 			err = -ENOMEM;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1246) 			break;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1247) 		}
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1248) 
4f06dd92b5d0a (Vivek Goyal             2020-10-21 16:12:49 -0400 1249) 		count = fuse_fill_write_pages(&ia, mapping, ii, pos, nr_pages);
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1250) 		if (count <= 0) {
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1251) 			err = count;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1252) 		} else {
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1253) 			err = fuse_send_write_pages(&ia, iocb, inode,
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1254) 						    pos, count);
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1255) 			if (!err) {
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1256) 				size_t num_written = ia.write.out.size;
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1257) 
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1258) 				res += num_written;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1259) 				pos += num_written;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1260) 
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1261) 				/* break out of the loop on short write */
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1262) 				if (num_written != count)
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1263) 					err = -EIO;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1264) 			}
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1265) 		}
338f2e3f3341a (Miklos Szeredi          2019-09-10 15:04:09 +0200 1266) 		kfree(ap->pages);
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1267) 	} while (!err && iov_iter_count(ii));
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1268) 
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1269) 	if (res > 0)
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1270) 		fuse_write_update_size(inode, pos);
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1271) 
06a7c3c278140 (Maxim Patlasov          2013-08-30 17:06:04 +0400 1272) 	clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1273) 	fuse_invalidate_attr(inode);
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1274) 
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1275) 	return res > 0 ? res : err;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1276) }
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1277) 
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 1278) static ssize_t fuse_cache_write_iter(struct kiocb *iocb, struct iov_iter *from)
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1279) {
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1280) 	struct file *file = iocb->ki_filp;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1281) 	struct address_space *mapping = file->f_mapping;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1282) 	ssize_t written = 0;
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1283) 	ssize_t written_buffered = 0;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1284) 	struct inode *inode = mapping->host;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1285) 	ssize_t err;
8981bdfda7445 (Vivek Goyal             2020-10-09 14:15:10 -0400 1286) 	struct fuse_conn *fc = get_fuse_conn(inode);
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1287) 	loff_t endbyte = 0;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1288) 
8981bdfda7445 (Vivek Goyal             2020-10-09 14:15:10 -0400 1289) 	if (fc->writeback_cache) {
4d99ff8f12eb2 (Pavel Emelyanov         2013-10-10 17:12:18 +0400 1290) 		/* Update size (EOF optimization) and mode (SUID clearing) */
5b97eeacbd80a (Miklos Szeredi          2017-09-12 16:57:54 +0200 1291) 		err = fuse_update_attributes(mapping->host, file);
4d99ff8f12eb2 (Pavel Emelyanov         2013-10-10 17:12:18 +0400 1292) 		if (err)
4d99ff8f12eb2 (Pavel Emelyanov         2013-10-10 17:12:18 +0400 1293) 			return err;
4d99ff8f12eb2 (Pavel Emelyanov         2013-10-10 17:12:18 +0400 1294) 
8981bdfda7445 (Vivek Goyal             2020-10-09 14:15:10 -0400 1295) 		if (fc->handle_killpriv_v2 &&
8981bdfda7445 (Vivek Goyal             2020-10-09 14:15:10 -0400 1296) 		    should_remove_suid(file_dentry(file))) {
8981bdfda7445 (Vivek Goyal             2020-10-09 14:15:10 -0400 1297) 			goto writethrough;
8981bdfda7445 (Vivek Goyal             2020-10-09 14:15:10 -0400 1298) 		}
8981bdfda7445 (Vivek Goyal             2020-10-09 14:15:10 -0400 1299) 
84c3d55cc474f (Al Viro                 2014-04-03 14:33:23 -0400 1300) 		return generic_file_write_iter(iocb, from);
4d99ff8f12eb2 (Pavel Emelyanov         2013-10-10 17:12:18 +0400 1301) 	}
4d99ff8f12eb2 (Pavel Emelyanov         2013-10-10 17:12:18 +0400 1302) 
8981bdfda7445 (Vivek Goyal             2020-10-09 14:15:10 -0400 1303) writethrough:
5955102c9984f (Al Viro                 2016-01-22 15:40:57 -0500 1304) 	inode_lock(inode);
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1305) 
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1306) 	/* We can write back this queue in page reclaim */
de1414a654e66 (Christoph Hellwig       2015-01-14 10:42:36 +0100 1307) 	current->backing_dev_info = inode_to_bdi(inode);
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1308) 
3309dd04cbcd2 (Al Viro                 2015-04-09 12:55:47 -0400 1309) 	err = generic_write_checks(iocb, from);
3309dd04cbcd2 (Al Viro                 2015-04-09 12:55:47 -0400 1310) 	if (err <= 0)
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1311) 		goto out;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1312) 
5fa8e0a1c6a76 (Jan Kara                2015-05-21 16:05:53 +0200 1313) 	err = file_remove_privs(file);
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1314) 	if (err)
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1315) 		goto out;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1316) 
c3b2da3148344 (Josef Bacik             2012-03-26 09:59:21 -0400 1317) 	err = file_update_time(file);
c3b2da3148344 (Josef Bacik             2012-03-26 09:59:21 -0400 1318) 	if (err)
c3b2da3148344 (Josef Bacik             2012-03-26 09:59:21 -0400 1319) 		goto out;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1320) 
2ba48ce513c4e (Al Viro                 2015-04-09 13:52:01 -0400 1321) 	if (iocb->ki_flags & IOCB_DIRECT) {
3309dd04cbcd2 (Al Viro                 2015-04-09 12:55:47 -0400 1322) 		loff_t pos = iocb->ki_pos;
1af5bb491fbb4 (Christoph Hellwig       2016-04-07 08:51:56 -0700 1323) 		written = generic_file_direct_write(iocb, from);
84c3d55cc474f (Al Viro                 2014-04-03 14:33:23 -0400 1324) 		if (written < 0 || !iov_iter_count(from))
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1325) 			goto out;
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1326) 
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1327) 		pos += written;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1328) 
e1c0eecba1a41 (Miklos Szeredi          2017-09-12 16:57:53 +0200 1329) 		written_buffered = fuse_perform_write(iocb, mapping, from, pos);
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1330) 		if (written_buffered < 0) {
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1331) 			err = written_buffered;
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1332) 			goto out;
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1333) 		}
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1334) 		endbyte = pos + written_buffered - 1;
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1335) 
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1336) 		err = filemap_write_and_wait_range(file->f_mapping, pos,
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1337) 						   endbyte);
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1338) 		if (err)
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1339) 			goto out;
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1340) 
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1341) 		invalidate_mapping_pages(file->f_mapping,
09cbfeaf1a5a6 (Kirill A. Shutemov      2016-04-01 15:29:47 +0300 1342) 					 pos >> PAGE_SHIFT,
09cbfeaf1a5a6 (Kirill A. Shutemov      2016-04-01 15:29:47 +0300 1343) 					 endbyte >> PAGE_SHIFT);
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1344) 
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1345) 		written += written_buffered;
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1346) 		iocb->ki_pos = pos + written_buffered;
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1347) 	} else {
e1c0eecba1a41 (Miklos Szeredi          2017-09-12 16:57:53 +0200 1348) 		written = fuse_perform_write(iocb, mapping, from, iocb->ki_pos);
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1349) 		if (written >= 0)
3309dd04cbcd2 (Al Viro                 2015-04-09 12:55:47 -0400 1350) 			iocb->ki_pos += written;
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1351) 	}
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1352) out:
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1353) 	current->backing_dev_info = NULL;
5955102c9984f (Al Viro                 2016-01-22 15:40:57 -0500 1354) 	inode_unlock(inode);
e1c0eecba1a41 (Miklos Szeredi          2017-09-12 16:57:53 +0200 1355) 	if (written > 0)
e1c0eecba1a41 (Miklos Szeredi          2017-09-12 16:57:53 +0200 1356) 		written = generic_write_sync(iocb, written);
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1357) 
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1358) 	return written ? written : err;
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1359) }
ea9b9907b82a0 (Nicholas Piggin         2008-04-30 00:54:42 -0700 1360) 
7c190c8b9c0dd (Maxim Patlasov          2012-10-26 19:50:29 +0400 1361) static inline unsigned long fuse_get_user_addr(const struct iov_iter *ii)
7c190c8b9c0dd (Maxim Patlasov          2012-10-26 19:50:29 +0400 1362) {
7c190c8b9c0dd (Maxim Patlasov          2012-10-26 19:50:29 +0400 1363) 	return (unsigned long)ii->iov->iov_base + ii->iov_offset;
7c190c8b9c0dd (Maxim Patlasov          2012-10-26 19:50:29 +0400 1364) }
7c190c8b9c0dd (Maxim Patlasov          2012-10-26 19:50:29 +0400 1365) 
7c190c8b9c0dd (Maxim Patlasov          2012-10-26 19:50:29 +0400 1366) static inline size_t fuse_get_frag_size(const struct iov_iter *ii,
7c190c8b9c0dd (Maxim Patlasov          2012-10-26 19:50:29 +0400 1367) 					size_t max_size)
7c190c8b9c0dd (Maxim Patlasov          2012-10-26 19:50:29 +0400 1368) {
7c190c8b9c0dd (Maxim Patlasov          2012-10-26 19:50:29 +0400 1369) 	return min(iov_iter_single_seg_count(ii), max_size);
7c190c8b9c0dd (Maxim Patlasov          2012-10-26 19:50:29 +0400 1370) }
7c190c8b9c0dd (Maxim Patlasov          2012-10-26 19:50:29 +0400 1371) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1372) static int fuse_get_user_pages(struct fuse_args_pages *ap, struct iov_iter *ii,
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1373) 			       size_t *nbytesp, int write,
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1374) 			       unsigned int max_pages)
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 1375) {
7c190c8b9c0dd (Maxim Patlasov          2012-10-26 19:50:29 +0400 1376) 	size_t nbytes = 0;  /* # bytes already packed in req */
742f992708dff (Ashish Samant           2016-03-14 21:57:35 -0700 1377) 	ssize_t ret = 0;
b98d023a24496 (Maxim Patlasov          2012-10-26 19:50:15 +0400 1378) 
f4975c67dd9ad (Miklos Szeredi          2009-04-02 14:25:34 +0200 1379) 	/* Special case for kernel I/O: can copy directly into the buffer */
00e23707442a7 (David Howells           2018-10-22 13:07:28 +0100 1380) 	if (iov_iter_is_kvec(ii)) {
7c190c8b9c0dd (Maxim Patlasov          2012-10-26 19:50:29 +0400 1381) 		unsigned long user_addr = fuse_get_user_addr(ii);
7c190c8b9c0dd (Maxim Patlasov          2012-10-26 19:50:29 +0400 1382) 		size_t frag_size = fuse_get_frag_size(ii, *nbytesp);
7c190c8b9c0dd (Maxim Patlasov          2012-10-26 19:50:29 +0400 1383) 
f4975c67dd9ad (Miklos Szeredi          2009-04-02 14:25:34 +0200 1384) 		if (write)
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1385) 			ap->args.in_args[1].value = (void *) user_addr;
f4975c67dd9ad (Miklos Szeredi          2009-04-02 14:25:34 +0200 1386) 		else
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1387) 			ap->args.out_args[0].value = (void *) user_addr;
f4975c67dd9ad (Miklos Szeredi          2009-04-02 14:25:34 +0200 1388) 
b98d023a24496 (Maxim Patlasov          2012-10-26 19:50:15 +0400 1389) 		iov_iter_advance(ii, frag_size);
b98d023a24496 (Maxim Patlasov          2012-10-26 19:50:15 +0400 1390) 		*nbytesp = frag_size;
f4975c67dd9ad (Miklos Szeredi          2009-04-02 14:25:34 +0200 1391) 		return 0;
f4975c67dd9ad (Miklos Szeredi          2009-04-02 14:25:34 +0200 1392) 	}
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 1393) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1394) 	while (nbytes < *nbytesp && ap->num_pages < max_pages) {
7c190c8b9c0dd (Maxim Patlasov          2012-10-26 19:50:29 +0400 1395) 		unsigned npages;
f67da30c1d5fc (Al Viro                 2014-03-19 01:16:16 -0400 1396) 		size_t start;
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1397) 		ret = iov_iter_get_pages(ii, &ap->pages[ap->num_pages],
2c80929c4c4d5 (Miklos Szeredi          2014-09-24 17:09:11 +0200 1398) 					*nbytesp - nbytes,
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1399) 					max_pages - ap->num_pages,
c7f3888ad7f09 (Al Viro                 2014-06-18 20:34:33 -0400 1400) 					&start);
7c190c8b9c0dd (Maxim Patlasov          2012-10-26 19:50:29 +0400 1401) 		if (ret < 0)
742f992708dff (Ashish Samant           2016-03-14 21:57:35 -0700 1402) 			break;
7c190c8b9c0dd (Maxim Patlasov          2012-10-26 19:50:29 +0400 1403) 
c9c37e2e63786 (Al Viro                 2014-03-16 16:08:30 -0400 1404) 		iov_iter_advance(ii, ret);
c9c37e2e63786 (Al Viro                 2014-03-16 16:08:30 -0400 1405) 		nbytes += ret;
7c190c8b9c0dd (Maxim Patlasov          2012-10-26 19:50:29 +0400 1406) 
c9c37e2e63786 (Al Viro                 2014-03-16 16:08:30 -0400 1407) 		ret += start;
c9c37e2e63786 (Al Viro                 2014-03-16 16:08:30 -0400 1408) 		npages = (ret + PAGE_SIZE - 1) / PAGE_SIZE;
7c190c8b9c0dd (Maxim Patlasov          2012-10-26 19:50:29 +0400 1409) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1410) 		ap->descs[ap->num_pages].offset = start;
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1411) 		fuse_page_descs_length_init(ap->descs, ap->num_pages, npages);
7c190c8b9c0dd (Maxim Patlasov          2012-10-26 19:50:29 +0400 1412) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1413) 		ap->num_pages += npages;
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1414) 		ap->descs[ap->num_pages - 1].length -=
c9c37e2e63786 (Al Viro                 2014-03-16 16:08:30 -0400 1415) 			(PAGE_SIZE - ret) & (PAGE_SIZE - 1);
7c190c8b9c0dd (Maxim Patlasov          2012-10-26 19:50:29 +0400 1416) 	}
f4975c67dd9ad (Miklos Szeredi          2009-04-02 14:25:34 +0200 1417) 
f4975c67dd9ad (Miklos Szeredi          2009-04-02 14:25:34 +0200 1418) 	if (write)
cabdb4fa2f666 (zhengbin                2020-01-14 20:39:45 +0800 1419) 		ap->args.in_pages = true;
f4975c67dd9ad (Miklos Szeredi          2009-04-02 14:25:34 +0200 1420) 	else
cabdb4fa2f666 (zhengbin                2020-01-14 20:39:45 +0800 1421) 		ap->args.out_pages = true;
f4975c67dd9ad (Miklos Szeredi          2009-04-02 14:25:34 +0200 1422) 
7c190c8b9c0dd (Maxim Patlasov          2012-10-26 19:50:29 +0400 1423) 	*nbytesp = nbytes;
f4975c67dd9ad (Miklos Szeredi          2009-04-02 14:25:34 +0200 1424) 
2c932d4c9165d (Ashish Samant           2016-03-25 10:53:41 -0700 1425) 	return ret < 0 ? ret : 0;
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 1426) }
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 1427) 
d22a943f44c79 (Al Viro                 2014-03-16 15:50:47 -0400 1428) ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
d22a943f44c79 (Al Viro                 2014-03-16 15:50:47 -0400 1429) 		       loff_t *ppos, int flags)
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 1430) {
ea8cd33390faf (Pavel Emelyanov         2013-10-10 17:12:05 +0400 1431) 	int write = flags & FUSE_DIO_WRITE;
ea8cd33390faf (Pavel Emelyanov         2013-10-10 17:12:05 +0400 1432) 	int cuse = flags & FUSE_DIO_CUSE;
e1c0eecba1a41 (Miklos Szeredi          2017-09-12 16:57:53 +0200 1433) 	struct file *file = io->iocb->ki_filp;
ea8cd33390faf (Pavel Emelyanov         2013-10-10 17:12:05 +0400 1434) 	struct inode *inode = file->f_mapping->host;
2106cb1893031 (Miklos Szeredi          2009-04-28 16:56:37 +0200 1435) 	struct fuse_file *ff = file->private_data;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 1436) 	struct fuse_conn *fc = ff->fm->fc;
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 1437) 	size_t nmax = write ? fc->max_write : fc->max_read;
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 1438) 	loff_t pos = *ppos;
d22a943f44c79 (Al Viro                 2014-03-16 15:50:47 -0400 1439) 	size_t count = iov_iter_count(iter);
09cbfeaf1a5a6 (Kirill A. Shutemov      2016-04-01 15:29:47 +0300 1440) 	pgoff_t idx_from = pos >> PAGE_SHIFT;
09cbfeaf1a5a6 (Kirill A. Shutemov      2016-04-01 15:29:47 +0300 1441) 	pgoff_t idx_to = (pos + count - 1) >> PAGE_SHIFT;
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 1442) 	ssize_t res = 0;
742f992708dff (Ashish Samant           2016-03-14 21:57:35 -0700 1443) 	int err = 0;
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1444) 	struct fuse_io_args *ia;
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1445) 	unsigned int max_pages;
248d86e87d12d (Miklos Szeredi          2006-01-06 00:19:39 -0800 1446) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1447) 	max_pages = iov_iter_npages(iter, fc->max_pages);
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1448) 	ia = fuse_io_alloc(io, max_pages);
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1449) 	if (!ia)
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1450) 		return -ENOMEM;
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 1451) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1452) 	ia->io = io;
ea8cd33390faf (Pavel Emelyanov         2013-10-10 17:12:05 +0400 1453) 	if (!cuse && fuse_range_is_writeback(inode, idx_from, idx_to)) {
ea8cd33390faf (Pavel Emelyanov         2013-10-10 17:12:05 +0400 1454) 		if (!write)
5955102c9984f (Al Viro                 2016-01-22 15:40:57 -0500 1455) 			inode_lock(inode);
ea8cd33390faf (Pavel Emelyanov         2013-10-10 17:12:05 +0400 1456) 		fuse_sync_writes(inode);
ea8cd33390faf (Pavel Emelyanov         2013-10-10 17:12:05 +0400 1457) 		if (!write)
5955102c9984f (Al Viro                 2016-01-22 15:40:57 -0500 1458) 			inode_unlock(inode);
ea8cd33390faf (Pavel Emelyanov         2013-10-10 17:12:05 +0400 1459) 	}
ea8cd33390faf (Pavel Emelyanov         2013-10-10 17:12:05 +0400 1460) 
61c12b49e1c9c (Ashish Samant           2017-07-12 19:26:58 -0700 1461) 	io->should_dirty = !write && iter_is_iovec(iter);
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 1462) 	while (count) {
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1463) 		ssize_t nres;
2106cb1893031 (Miklos Szeredi          2009-04-28 16:56:37 +0200 1464) 		fl_owner_t owner = current->files;
f4975c67dd9ad (Miklos Szeredi          2009-04-02 14:25:34 +0200 1465) 		size_t nbytes = min(count, nmax);
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1466) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1467) 		err = fuse_get_user_pages(&ia->ap, iter, &nbytes, write,
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1468) 					  max_pages);
742f992708dff (Ashish Samant           2016-03-14 21:57:35 -0700 1469) 		if (err && !nbytes)
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 1470) 			break;
f4975c67dd9ad (Miklos Szeredi          2009-04-02 14:25:34 +0200 1471) 
4a2abf99f9c28 (Miklos Szeredi          2019-05-27 09:08:12 +0200 1472) 		if (write) {
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1473) 			if (!capable(CAP_FSETID))
10c52c84e3f48 (Miklos Szeredi          2020-11-11 17:22:32 +0100 1474) 				ia->write.in.write_flags |= FUSE_WRITE_KILL_SUIDGID;
4a2abf99f9c28 (Miklos Szeredi          2019-05-27 09:08:12 +0200 1475) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1476) 			nres = fuse_send_write(ia, pos, nbytes, owner);
4a2abf99f9c28 (Miklos Szeredi          2019-05-27 09:08:12 +0200 1477) 		} else {
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1478) 			nres = fuse_send_read(ia, pos, nbytes, owner);
4a2abf99f9c28 (Miklos Szeredi          2019-05-27 09:08:12 +0200 1479) 		}
2106cb1893031 (Miklos Szeredi          2009-04-28 16:56:37 +0200 1480) 
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1481) 		if (!io->async || nres < 0) {
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1482) 			fuse_release_user_pages(&ia->ap, io->should_dirty);
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1483) 			fuse_io_free(ia);
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1484) 		}
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1485) 		ia = NULL;
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1486) 		if (nres < 0) {
f658adeea45e4 (Miklos Szeredi          2020-02-06 16:39:28 +0100 1487) 			iov_iter_revert(iter, nbytes);
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1488) 			err = nres;
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 1489) 			break;
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 1490) 		}
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1491) 		WARN_ON(nres > nbytes);
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1492) 
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 1493) 		count -= nres;
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 1494) 		res += nres;
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 1495) 		pos += nres;
f658adeea45e4 (Miklos Szeredi          2020-02-06 16:39:28 +0100 1496) 		if (nres != nbytes) {
f658adeea45e4 (Miklos Szeredi          2020-02-06 16:39:28 +0100 1497) 			iov_iter_revert(iter, nbytes - nres);
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 1498) 			break;
f658adeea45e4 (Miklos Szeredi          2020-02-06 16:39:28 +0100 1499) 		}
56cf34ff07956 (Miklos Szeredi          2006-04-11 21:16:51 +0200 1500) 		if (count) {
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1501) 			max_pages = iov_iter_npages(iter, fc->max_pages);
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1502) 			ia = fuse_io_alloc(io, max_pages);
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1503) 			if (!ia)
56cf34ff07956 (Miklos Szeredi          2006-04-11 21:16:51 +0200 1504) 				break;
56cf34ff07956 (Miklos Szeredi          2006-04-11 21:16:51 +0200 1505) 		}
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 1506) 	}
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1507) 	if (ia)
45ac96ed7c369 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1508) 		fuse_io_free(ia);
d09cb9d7f6e4c (Miklos Szeredi          2009-04-28 16:56:36 +0200 1509) 	if (res > 0)
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 1510) 		*ppos = pos;
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 1511) 
742f992708dff (Ashish Samant           2016-03-14 21:57:35 -0700 1512) 	return res > 0 ? res : err;
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 1513) }
08cbf542bf24f (Tejun Heo               2009-04-14 10:54:53 +0900 1514) EXPORT_SYMBOL_GPL(fuse_direct_io);
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 1515) 
36cf66ed9f871 (Maxim Patlasov          2012-12-14 19:20:51 +0400 1516) static ssize_t __fuse_direct_read(struct fuse_io_priv *io,
d22a943f44c79 (Al Viro                 2014-03-16 15:50:47 -0400 1517) 				  struct iov_iter *iter,
d22a943f44c79 (Al Viro                 2014-03-16 15:50:47 -0400 1518) 				  loff_t *ppos)
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 1519) {
d09cb9d7f6e4c (Miklos Szeredi          2009-04-28 16:56:36 +0200 1520) 	ssize_t res;
e1c0eecba1a41 (Miklos Szeredi          2017-09-12 16:57:53 +0200 1521) 	struct inode *inode = file_inode(io->iocb->ki_filp);
d09cb9d7f6e4c (Miklos Szeredi          2009-04-28 16:56:36 +0200 1522) 
d22a943f44c79 (Al Viro                 2014-03-16 15:50:47 -0400 1523) 	res = fuse_direct_io(io, iter, ppos, 0);
d09cb9d7f6e4c (Miklos Szeredi          2009-04-28 16:56:36 +0200 1524) 
9a2eb24d1a349 (Miklos Szeredi          2018-10-15 15:43:06 +0200 1525) 	fuse_invalidate_atime(inode);
d09cb9d7f6e4c (Miklos Szeredi          2009-04-28 16:56:36 +0200 1526) 
d09cb9d7f6e4c (Miklos Szeredi          2009-04-28 16:56:36 +0200 1527) 	return res;
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 1528) }
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 1529) 
23c94e1cdcbf5 (Martin Raiber           2018-10-27 16:48:48 +0000 1530) static ssize_t fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter);
23c94e1cdcbf5 (Martin Raiber           2018-10-27 16:48:48 +0000 1531) 
15316263649d9 (Al Viro                 2015-03-30 22:08:36 -0400 1532) static ssize_t fuse_direct_read_iter(struct kiocb *iocb, struct iov_iter *to)
b98d023a24496 (Maxim Patlasov          2012-10-26 19:50:15 +0400 1533) {
23c94e1cdcbf5 (Martin Raiber           2018-10-27 16:48:48 +0000 1534) 	ssize_t res;
23c94e1cdcbf5 (Martin Raiber           2018-10-27 16:48:48 +0000 1535) 
23c94e1cdcbf5 (Martin Raiber           2018-10-27 16:48:48 +0000 1536) 	if (!is_sync_kiocb(iocb) && iocb->ki_flags & IOCB_DIRECT) {
23c94e1cdcbf5 (Martin Raiber           2018-10-27 16:48:48 +0000 1537) 		res = fuse_direct_IO(iocb, to);
23c94e1cdcbf5 (Martin Raiber           2018-10-27 16:48:48 +0000 1538) 	} else {
23c94e1cdcbf5 (Martin Raiber           2018-10-27 16:48:48 +0000 1539) 		struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(iocb);
23c94e1cdcbf5 (Martin Raiber           2018-10-27 16:48:48 +0000 1540) 
23c94e1cdcbf5 (Martin Raiber           2018-10-27 16:48:48 +0000 1541) 		res = __fuse_direct_read(&io, to, &iocb->ki_pos);
23c94e1cdcbf5 (Martin Raiber           2018-10-27 16:48:48 +0000 1542) 	}
23c94e1cdcbf5 (Martin Raiber           2018-10-27 16:48:48 +0000 1543) 
23c94e1cdcbf5 (Martin Raiber           2018-10-27 16:48:48 +0000 1544) 	return res;
b98d023a24496 (Maxim Patlasov          2012-10-26 19:50:15 +0400 1545) }
b98d023a24496 (Maxim Patlasov          2012-10-26 19:50:15 +0400 1546) 
15316263649d9 (Al Viro                 2015-03-30 22:08:36 -0400 1547) static ssize_t fuse_direct_write_iter(struct kiocb *iocb, struct iov_iter *from)
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1548) {
e1c0eecba1a41 (Miklos Szeredi          2017-09-12 16:57:53 +0200 1549) 	struct inode *inode = file_inode(iocb->ki_filp);
e1c0eecba1a41 (Miklos Szeredi          2017-09-12 16:57:53 +0200 1550) 	struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(iocb);
15316263649d9 (Al Viro                 2015-03-30 22:08:36 -0400 1551) 	ssize_t res;
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1552) 
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1553) 	/* Don't allow parallel writes to the same file */
5955102c9984f (Al Viro                 2016-01-22 15:40:57 -0500 1554) 	inode_lock(inode);
3309dd04cbcd2 (Al Viro                 2015-04-09 12:55:47 -0400 1555) 	res = generic_write_checks(iocb, from);
23c94e1cdcbf5 (Martin Raiber           2018-10-27 16:48:48 +0000 1556) 	if (res > 0) {
23c94e1cdcbf5 (Martin Raiber           2018-10-27 16:48:48 +0000 1557) 		if (!is_sync_kiocb(iocb) && iocb->ki_flags & IOCB_DIRECT) {
23c94e1cdcbf5 (Martin Raiber           2018-10-27 16:48:48 +0000 1558) 			res = fuse_direct_IO(iocb, from);
23c94e1cdcbf5 (Martin Raiber           2018-10-27 16:48:48 +0000 1559) 		} else {
23c94e1cdcbf5 (Martin Raiber           2018-10-27 16:48:48 +0000 1560) 			res = fuse_direct_io(&io, from, &iocb->ki_pos,
23c94e1cdcbf5 (Martin Raiber           2018-10-27 16:48:48 +0000 1561) 					     FUSE_DIO_WRITE);
23c94e1cdcbf5 (Martin Raiber           2018-10-27 16:48:48 +0000 1562) 		}
23c94e1cdcbf5 (Martin Raiber           2018-10-27 16:48:48 +0000 1563) 	}
812408fb51ef5 (Al Viro                 2015-03-30 22:15:58 -0400 1564) 	fuse_invalidate_attr(inode);
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 1565) 	if (res > 0)
15316263649d9 (Al Viro                 2015-03-30 22:08:36 -0400 1566) 		fuse_write_update_size(inode, iocb->ki_pos);
5955102c9984f (Al Viro                 2016-01-22 15:40:57 -0500 1567) 	inode_unlock(inode);
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1568) 
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1569) 	return res;
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1570) }
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 1571) 
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 1572) static ssize_t fuse_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 1573) {
2f7b6f5bed01a (Miklos Szeredi          2019-01-24 10:40:17 +0100 1574) 	struct file *file = iocb->ki_filp;
2f7b6f5bed01a (Miklos Szeredi          2019-01-24 10:40:17 +0100 1575) 	struct fuse_file *ff = file->private_data;
c2d0ad00d948d (Vivek Goyal             2020-08-19 18:19:51 -0400 1576) 	struct inode *inode = file_inode(file);
2f7b6f5bed01a (Miklos Szeredi          2019-01-24 10:40:17 +0100 1577) 
5d069dbe8aaf2 (Miklos Szeredi          2020-12-10 15:33:14 +0100 1578) 	if (fuse_is_bad(inode))
2f7b6f5bed01a (Miklos Szeredi          2019-01-24 10:40:17 +0100 1579) 		return -EIO;
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 1580) 
c2d0ad00d948d (Vivek Goyal             2020-08-19 18:19:51 -0400 1581) 	if (FUSE_IS_DAX(inode))
c2d0ad00d948d (Vivek Goyal             2020-08-19 18:19:51 -0400 1582) 		return fuse_dax_read_iter(iocb, to);
c2d0ad00d948d (Vivek Goyal             2020-08-19 18:19:51 -0400 1583) 
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 1584) 	if (!(ff->open_flags & FOPEN_DIRECT_IO))
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 1585) 		return fuse_cache_read_iter(iocb, to);
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 1586) 	else
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 1587) 		return fuse_direct_read_iter(iocb, to);
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 1588) }
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 1589) 
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 1590) static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 1591) {
2f7b6f5bed01a (Miklos Szeredi          2019-01-24 10:40:17 +0100 1592) 	struct file *file = iocb->ki_filp;
2f7b6f5bed01a (Miklos Szeredi          2019-01-24 10:40:17 +0100 1593) 	struct fuse_file *ff = file->private_data;
c2d0ad00d948d (Vivek Goyal             2020-08-19 18:19:51 -0400 1594) 	struct inode *inode = file_inode(file);
2f7b6f5bed01a (Miklos Szeredi          2019-01-24 10:40:17 +0100 1595) 
5d069dbe8aaf2 (Miklos Szeredi          2020-12-10 15:33:14 +0100 1596) 	if (fuse_is_bad(inode))
2f7b6f5bed01a (Miklos Szeredi          2019-01-24 10:40:17 +0100 1597) 		return -EIO;
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 1598) 
c2d0ad00d948d (Vivek Goyal             2020-08-19 18:19:51 -0400 1599) 	if (FUSE_IS_DAX(inode))
c2d0ad00d948d (Vivek Goyal             2020-08-19 18:19:51 -0400 1600) 		return fuse_dax_write_iter(iocb, from);
c2d0ad00d948d (Vivek Goyal             2020-08-19 18:19:51 -0400 1601) 
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 1602) 	if (!(ff->open_flags & FOPEN_DIRECT_IO))
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 1603) 		return fuse_cache_write_iter(iocb, from);
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 1604) 	else
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 1605) 		return fuse_direct_write_iter(iocb, from);
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 1606) }
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 1607) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1608) static void fuse_writepage_free(struct fuse_writepage_args *wpa)
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700 1609) {
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1610) 	struct fuse_args_pages *ap = &wpa->ia.ap;
385b126815d92 (Pavel Emelyanov         2013-06-29 21:42:48 +0400 1611) 	int i;
385b126815d92 (Pavel Emelyanov         2013-06-29 21:42:48 +0400 1612) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1613) 	for (i = 0; i < ap->num_pages; i++)
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1614) 		__free_page(ap->pages[i]);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1615) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1616) 	if (wpa->ia.ff)
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1617) 		fuse_file_put(wpa->ia.ff, false, false);
8b284dc47291d (Miklos Szeredi          2013-10-01 16:44:53 +0200 1618) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1619) 	kfree(ap->pages);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1620) 	kfree(wpa);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1621) }
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1622) 
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 1623) static void fuse_writepage_finish(struct fuse_mount *fm,
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1624) 				  struct fuse_writepage_args *wpa)
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1625) {
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1626) 	struct fuse_args_pages *ap = &wpa->ia.ap;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1627) 	struct inode *inode = wpa->inode;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1628) 	struct fuse_inode *fi = get_fuse_inode(inode);
de1414a654e66 (Christoph Hellwig       2015-01-14 10:42:36 +0100 1629) 	struct backing_dev_info *bdi = inode_to_bdi(inode);
385b126815d92 (Pavel Emelyanov         2013-06-29 21:42:48 +0400 1630) 	int i;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1631) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1632) 	for (i = 0; i < ap->num_pages; i++) {
93f78d882865c (Tejun Heo               2015-05-22 17:13:27 -0400 1633) 		dec_wb_stat(&bdi->wb, WB_WRITEBACK);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1634) 		dec_node_page_state(ap->pages[i], NR_WRITEBACK_TEMP);
93f78d882865c (Tejun Heo               2015-05-22 17:13:27 -0400 1635) 		wb_writeout_inc(&bdi->wb);
385b126815d92 (Pavel Emelyanov         2013-06-29 21:42:48 +0400 1636) 	}
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1637) 	wake_up(&fi->page_waitq);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1638) }
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1639) 
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300 1640) /* Called under fi->lock, may release and reacquire it */
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 1641) static void fuse_send_writepage(struct fuse_mount *fm,
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1642) 				struct fuse_writepage_args *wpa, loff_t size)
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300 1643) __releases(fi->lock)
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300 1644) __acquires(fi->lock)
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1645) {
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1646) 	struct fuse_writepage_args *aux, *next;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1647) 	struct fuse_inode *fi = get_fuse_inode(wpa->inode);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1648) 	struct fuse_write_in *inarg = &wpa->ia.write.in;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1649) 	struct fuse_args *args = &wpa->ia.ap.args;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1650) 	__u64 data_size = wpa->ia.ap.num_pages * PAGE_SIZE;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1651) 	int err;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1652) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1653) 	fi->writectr++;
385b126815d92 (Pavel Emelyanov         2013-06-29 21:42:48 +0400 1654) 	if (inarg->offset + data_size <= size) {
385b126815d92 (Pavel Emelyanov         2013-06-29 21:42:48 +0400 1655) 		inarg->size = data_size;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1656) 	} else if (inarg->offset < size) {
385b126815d92 (Pavel Emelyanov         2013-06-29 21:42:48 +0400 1657) 		inarg->size = size - inarg->offset;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1658) 	} else {
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1659) 		/* Got truncated off completely */
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1660) 		goto out_free;
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700 1661) 	}
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1662) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1663) 	args->in_args[1].size = inarg->size;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1664) 	args->force = true;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1665) 	args->nocreds = true;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1666) 
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 1667) 	err = fuse_simple_background(fm, args, GFP_ATOMIC);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1668) 	if (err == -ENOMEM) {
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1669) 		spin_unlock(&fi->lock);
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 1670) 		err = fuse_simple_background(fm, args, GFP_NOFS | __GFP_NOFAIL);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1671) 		spin_lock(&fi->lock);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1672) 	}
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1673) 
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300 1674) 	/* Fails on broken connection only */
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1675) 	if (unlikely(err))
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300 1676) 		goto out_free;
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300 1677) 
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1678) 	return;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1679) 
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1680)  out_free:
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1681) 	fi->writectr--;
69a6487ac0ea1 (Miklos Szeredi          2020-07-14 14:45:41 +0200 1682) 	rb_erase(&wpa->writepages_entry, &fi->writepages);
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 1683) 	fuse_writepage_finish(fm, wpa);
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300 1684) 	spin_unlock(&fi->lock);
e2653bd53a984 (Miklos Szeredi          2019-01-24 10:40:15 +0100 1685) 
e2653bd53a984 (Miklos Szeredi          2019-01-24 10:40:15 +0100 1686) 	/* After fuse_writepage_finish() aux request list is private */
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1687) 	for (aux = wpa->next; aux; aux = next) {
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1688) 		next = aux->next;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1689) 		aux->next = NULL;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1690) 		fuse_writepage_free(aux);
e2653bd53a984 (Miklos Szeredi          2019-01-24 10:40:15 +0100 1691) 	}
e2653bd53a984 (Miklos Szeredi          2019-01-24 10:40:15 +0100 1692) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1693) 	fuse_writepage_free(wpa);
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300 1694) 	spin_lock(&fi->lock);
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700 1695) }
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700 1696) 
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1697) /*
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1698)  * If fi->writectr is positive (no truncate or fsync going on) send
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1699)  * all queued writepage requests.
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1700)  *
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300 1701)  * Called with fi->lock
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1702)  */
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1703) void fuse_flush_writepages(struct inode *inode)
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300 1704) __releases(fi->lock)
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300 1705) __acquires(fi->lock)
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700 1706) {
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 1707) 	struct fuse_mount *fm = get_fuse_mount(inode);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1708) 	struct fuse_inode *fi = get_fuse_inode(inode);
9de5be06d0a89 (Miklos Szeredi          2019-04-24 17:05:06 +0200 1709) 	loff_t crop = i_size_read(inode);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1710) 	struct fuse_writepage_args *wpa;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1711) 
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1712) 	while (fi->writectr >= 0 && !list_empty(&fi->queued_writes)) {
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1713) 		wpa = list_entry(fi->queued_writes.next,
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1714) 				 struct fuse_writepage_args, queue_entry);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1715) 		list_del_init(&wpa->queue_entry);
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 1716) 		fuse_send_writepage(fm, wpa, crop);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1717) 	}
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1718) }
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1719) 
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 1720) static struct fuse_writepage_args *fuse_insert_writeback(struct rb_root *root,
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 1721) 						struct fuse_writepage_args *wpa)
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1722) {
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1723) 	pgoff_t idx_from = wpa->ia.write.in.offset >> PAGE_SHIFT;
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1724) 	pgoff_t idx_to = idx_from + wpa->ia.ap.num_pages - 1;
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1725) 	struct rb_node **p = &root->rb_node;
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1726) 	struct rb_node  *parent = NULL;
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1727) 
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1728) 	WARN_ON(!wpa->ia.ap.num_pages);
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1729) 	while (*p) {
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1730) 		struct fuse_writepage_args *curr;
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1731) 		pgoff_t curr_index;
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1732) 
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1733) 		parent = *p;
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1734) 		curr = rb_entry(parent, struct fuse_writepage_args,
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1735) 				writepages_entry);
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1736) 		WARN_ON(curr->inode != wpa->inode);
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1737) 		curr_index = curr->ia.write.in.offset >> PAGE_SHIFT;
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1738) 
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1739) 		if (idx_from >= curr_index + curr->ia.ap.num_pages)
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1740) 			p = &(*p)->rb_right;
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1741) 		else if (idx_to < curr_index)
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1742) 			p = &(*p)->rb_left;
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1743) 		else
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 1744) 			return curr;
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1745) 	}
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1746) 
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1747) 	rb_link_node(&wpa->writepages_entry, parent, p);
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1748) 	rb_insert_color(&wpa->writepages_entry, root);
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 1749) 	return NULL;
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 1750) }
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 1751) 
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 1752) static void tree_insert(struct rb_root *root, struct fuse_writepage_args *wpa)
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 1753) {
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 1754) 	WARN_ON(fuse_insert_writeback(root, wpa));
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1755) }
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1756) 
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 1757) static void fuse_writepage_end(struct fuse_mount *fm, struct fuse_args *args,
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1758) 			       int error)
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1759) {
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1760) 	struct fuse_writepage_args *wpa =
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1761) 		container_of(args, typeof(*wpa), ia.ap.args);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1762) 	struct inode *inode = wpa->inode;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1763) 	struct fuse_inode *fi = get_fuse_inode(inode);
3466958beb31a (Vivek Goyal             2021-04-06 10:07:06 -0400 1764) 	struct fuse_conn *fc = get_fuse_conn(inode);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1765) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1766) 	mapping_set_error(inode->i_mapping, error);
3466958beb31a (Vivek Goyal             2021-04-06 10:07:06 -0400 1767) 	/*
3466958beb31a (Vivek Goyal             2021-04-06 10:07:06 -0400 1768) 	 * A writeback finished and this might have updated mtime/ctime on
3466958beb31a (Vivek Goyal             2021-04-06 10:07:06 -0400 1769) 	 * server making local mtime/ctime stale.  Hence invalidate attrs.
3466958beb31a (Vivek Goyal             2021-04-06 10:07:06 -0400 1770) 	 * Do this only if writeback_cache is not enabled.  If writeback_cache
3466958beb31a (Vivek Goyal             2021-04-06 10:07:06 -0400 1771) 	 * is enabled, we trust local ctime/mtime.
3466958beb31a (Vivek Goyal             2021-04-06 10:07:06 -0400 1772) 	 */
3466958beb31a (Vivek Goyal             2021-04-06 10:07:06 -0400 1773) 	if (!fc->writeback_cache)
3466958beb31a (Vivek Goyal             2021-04-06 10:07:06 -0400 1774) 		fuse_invalidate_attr(inode);
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300 1775) 	spin_lock(&fi->lock);
69a6487ac0ea1 (Miklos Szeredi          2020-07-14 14:45:41 +0200 1776) 	rb_erase(&wpa->writepages_entry, &fi->writepages);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1777) 	while (wpa->next) {
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 1778) 		struct fuse_mount *fm = get_fuse_mount(inode);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1779) 		struct fuse_write_in *inarg = &wpa->ia.write.in;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1780) 		struct fuse_writepage_args *next = wpa->next;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1781) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1782) 		wpa->next = next->next;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1783) 		next->next = NULL;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1784) 		next->ia.ff = fuse_file_get(wpa->ia.ff);
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1785) 		tree_insert(&fi->writepages, next);
6eaf4782eb09e (Maxim Patlasov          2013-10-02 21:38:32 +0400 1786) 
6eaf4782eb09e (Maxim Patlasov          2013-10-02 21:38:32 +0400 1787) 		/*
6eaf4782eb09e (Maxim Patlasov          2013-10-02 21:38:32 +0400 1788) 		 * Skip fuse_flush_writepages() to make it easy to crop requests
6eaf4782eb09e (Maxim Patlasov          2013-10-02 21:38:32 +0400 1789) 		 * based on primary request size.
6eaf4782eb09e (Maxim Patlasov          2013-10-02 21:38:32 +0400 1790) 		 *
6eaf4782eb09e (Maxim Patlasov          2013-10-02 21:38:32 +0400 1791) 		 * 1st case (trivial): there are no concurrent activities using
6eaf4782eb09e (Maxim Patlasov          2013-10-02 21:38:32 +0400 1792) 		 * fuse_set/release_nowrite.  Then we're on safe side because
6eaf4782eb09e (Maxim Patlasov          2013-10-02 21:38:32 +0400 1793) 		 * fuse_flush_writepages() would call fuse_send_writepage()
6eaf4782eb09e (Maxim Patlasov          2013-10-02 21:38:32 +0400 1794) 		 * anyway.
6eaf4782eb09e (Maxim Patlasov          2013-10-02 21:38:32 +0400 1795) 		 *
6eaf4782eb09e (Maxim Patlasov          2013-10-02 21:38:32 +0400 1796) 		 * 2nd case: someone called fuse_set_nowrite and it is waiting
6eaf4782eb09e (Maxim Patlasov          2013-10-02 21:38:32 +0400 1797) 		 * now for completion of all in-flight requests.  This happens
6eaf4782eb09e (Maxim Patlasov          2013-10-02 21:38:32 +0400 1798) 		 * rarely and no more than once per page, so this should be
6eaf4782eb09e (Maxim Patlasov          2013-10-02 21:38:32 +0400 1799) 		 * okay.
6eaf4782eb09e (Maxim Patlasov          2013-10-02 21:38:32 +0400 1800) 		 *
6eaf4782eb09e (Maxim Patlasov          2013-10-02 21:38:32 +0400 1801) 		 * 3rd case: someone (e.g. fuse_do_setattr()) is in the middle
6eaf4782eb09e (Maxim Patlasov          2013-10-02 21:38:32 +0400 1802) 		 * of fuse_set_nowrite..fuse_release_nowrite section.  The fact
6eaf4782eb09e (Maxim Patlasov          2013-10-02 21:38:32 +0400 1803) 		 * that fuse_set_nowrite returned implies that all in-flight
6eaf4782eb09e (Maxim Patlasov          2013-10-02 21:38:32 +0400 1804) 		 * requests were completed along with all of their secondary
6eaf4782eb09e (Maxim Patlasov          2013-10-02 21:38:32 +0400 1805) 		 * requests.  Further primary requests are blocked by negative
6eaf4782eb09e (Maxim Patlasov          2013-10-02 21:38:32 +0400 1806) 		 * writectr.  Hence there cannot be any in-flight requests and
6eaf4782eb09e (Maxim Patlasov          2013-10-02 21:38:32 +0400 1807) 		 * no invocations of fuse_writepage_end() while we're in
6eaf4782eb09e (Maxim Patlasov          2013-10-02 21:38:32 +0400 1808) 		 * fuse_set_nowrite..fuse_release_nowrite section.
6eaf4782eb09e (Maxim Patlasov          2013-10-02 21:38:32 +0400 1809) 		 */
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 1810) 		fuse_send_writepage(fm, next, inarg->offset + inarg->size);
8b284dc47291d (Miklos Szeredi          2013-10-01 16:44:53 +0200 1811) 	}
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1812) 	fi->writectr--;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 1813) 	fuse_writepage_finish(fm, wpa);
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300 1814) 	spin_unlock(&fi->lock);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1815) 	fuse_writepage_free(wpa);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1816) }
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1817) 
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200 1818) static struct fuse_file *__fuse_write_file_get(struct fuse_conn *fc,
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200 1819) 					       struct fuse_inode *fi)
adcadfa8f373f (Pavel Emelyanov         2013-06-29 21:42:20 +0400 1820) {
72523425fb434 (Miklos Szeredi          2013-10-01 16:44:52 +0200 1821) 	struct fuse_file *ff = NULL;
adcadfa8f373f (Pavel Emelyanov         2013-06-29 21:42:20 +0400 1822) 
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300 1823) 	spin_lock(&fi->lock);
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200 1824) 	if (!list_empty(&fi->write_files)) {
72523425fb434 (Miklos Szeredi          2013-10-01 16:44:52 +0200 1825) 		ff = list_entry(fi->write_files.next, struct fuse_file,
72523425fb434 (Miklos Szeredi          2013-10-01 16:44:52 +0200 1826) 				write_entry);
72523425fb434 (Miklos Szeredi          2013-10-01 16:44:52 +0200 1827) 		fuse_file_get(ff);
72523425fb434 (Miklos Szeredi          2013-10-01 16:44:52 +0200 1828) 	}
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300 1829) 	spin_unlock(&fi->lock);
adcadfa8f373f (Pavel Emelyanov         2013-06-29 21:42:20 +0400 1830) 
adcadfa8f373f (Pavel Emelyanov         2013-06-29 21:42:20 +0400 1831) 	return ff;
adcadfa8f373f (Pavel Emelyanov         2013-06-29 21:42:20 +0400 1832) }
adcadfa8f373f (Pavel Emelyanov         2013-06-29 21:42:20 +0400 1833) 
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200 1834) static struct fuse_file *fuse_write_file_get(struct fuse_conn *fc,
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200 1835) 					     struct fuse_inode *fi)
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200 1836) {
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200 1837) 	struct fuse_file *ff = __fuse_write_file_get(fc, fi);
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200 1838) 	WARN_ON(!ff);
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200 1839) 	return ff;
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200 1840) }
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200 1841) 
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200 1842) int fuse_write_inode(struct inode *inode, struct writeback_control *wbc)
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200 1843) {
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200 1844) 	struct fuse_conn *fc = get_fuse_conn(inode);
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200 1845) 	struct fuse_inode *fi = get_fuse_inode(inode);
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200 1846) 	struct fuse_file *ff;
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200 1847) 	int err;
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200 1848) 
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200 1849) 	ff = __fuse_write_file_get(fc, fi);
ab9e13f7c771b (Maxim Patlasov          2014-04-28 14:19:24 +0200 1850) 	err = fuse_flush_times(inode, ff);
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200 1851) 	if (ff)
2e64ff154ce6c (Chad Austin             2018-12-10 10:54:52 -0800 1852) 		fuse_file_put(ff, false, false);
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200 1853) 
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200 1854) 	return err;
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200 1855) }
1e18bda86e2dc (Miklos Szeredi          2014-04-28 14:19:23 +0200 1856) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1857) static struct fuse_writepage_args *fuse_writepage_args_alloc(void)
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1858) {
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1859) 	struct fuse_writepage_args *wpa;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1860) 	struct fuse_args_pages *ap;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1861) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1862) 	wpa = kzalloc(sizeof(*wpa), GFP_NOFS);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1863) 	if (wpa) {
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1864) 		ap = &wpa->ia.ap;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1865) 		ap->num_pages = 0;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1866) 		ap->pages = fuse_pages_alloc(1, GFP_NOFS, &ap->descs);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1867) 		if (!ap->pages) {
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1868) 			kfree(wpa);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1869) 			wpa = NULL;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1870) 		}
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1871) 	}
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1872) 	return wpa;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1873) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1874) }
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1875) 
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1876) static int fuse_writepage_locked(struct page *page)
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1877) {
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1878) 	struct address_space *mapping = page->mapping;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1879) 	struct inode *inode = mapping->host;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1880) 	struct fuse_conn *fc = get_fuse_conn(inode);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1881) 	struct fuse_inode *fi = get_fuse_inode(inode);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1882) 	struct fuse_writepage_args *wpa;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1883) 	struct fuse_args_pages *ap;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1884) 	struct page *tmp_page;
72523425fb434 (Miklos Szeredi          2013-10-01 16:44:52 +0200 1885) 	int error = -ENOMEM;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1886) 
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1887) 	set_page_writeback(page);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1888) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1889) 	wpa = fuse_writepage_args_alloc();
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1890) 	if (!wpa)
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1891) 		goto err;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1892) 	ap = &wpa->ia.ap;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1893) 
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1894) 	tmp_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1895) 	if (!tmp_page)
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1896) 		goto err_free;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1897) 
72523425fb434 (Miklos Szeredi          2013-10-01 16:44:52 +0200 1898) 	error = -EIO;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1899) 	wpa->ia.ff = fuse_write_file_get(fc, fi);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1900) 	if (!wpa->ia.ff)
27f1b36326bc8 (Maxim Patlasov          2014-07-10 15:32:43 +0400 1901) 		goto err_nofile;
72523425fb434 (Miklos Szeredi          2013-10-01 16:44:52 +0200 1902) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1903) 	fuse_write_args_fill(&wpa->ia, wpa->ia.ff, page_offset(page), 0);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1904) 
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1905) 	copy_highpage(tmp_page, page);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1906) 	wpa->ia.write.in.write_flags |= FUSE_WRITE_CACHE;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1907) 	wpa->next = NULL;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1908) 	ap->args.in_pages = true;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1909) 	ap->num_pages = 1;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1910) 	ap->pages[0] = tmp_page;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1911) 	ap->descs[0].offset = 0;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1912) 	ap->descs[0].length = PAGE_SIZE;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1913) 	ap->args.end = fuse_writepage_end;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1914) 	wpa->inode = inode;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1915) 
93f78d882865c (Tejun Heo               2015-05-22 17:13:27 -0400 1916) 	inc_wb_stat(&inode_to_bdi(inode)->wb, WB_WRITEBACK);
11fb998986a72 (Mel Gorman              2016-07-28 15:46:20 -0700 1917) 	inc_node_page_state(tmp_page, NR_WRITEBACK_TEMP);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1918) 
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300 1919) 	spin_lock(&fi->lock);
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 1920) 	tree_insert(&fi->writepages, wpa);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1921) 	list_add_tail(&wpa->queue_entry, &fi->queued_writes);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1922) 	fuse_flush_writepages(inode);
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300 1923) 	spin_unlock(&fi->lock);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1924) 
4a4ac4eba1010 (Maxim Patlasov          2013-08-12 20:39:30 +0400 1925) 	end_page_writeback(page);
4a4ac4eba1010 (Maxim Patlasov          2013-08-12 20:39:30 +0400 1926) 
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1927) 	return 0;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1928) 
27f1b36326bc8 (Maxim Patlasov          2014-07-10 15:32:43 +0400 1929) err_nofile:
27f1b36326bc8 (Maxim Patlasov          2014-07-10 15:32:43 +0400 1930) 	__free_page(tmp_page);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1931) err_free:
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1932) 	kfree(wpa);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1933) err:
9183976ef1c85 (Jeff Layton             2017-05-25 06:57:50 -0400 1934) 	mapping_set_error(page->mapping, error);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1935) 	end_page_writeback(page);
72523425fb434 (Miklos Szeredi          2013-10-01 16:44:52 +0200 1936) 	return error;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1937) }
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1938) 
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1939) static int fuse_writepage(struct page *page, struct writeback_control *wbc)
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1940) {
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1941) 	int err;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1942) 
ff17be0864777 (Miklos Szeredi          2013-10-01 16:44:53 +0200 1943) 	if (fuse_page_is_writeback(page->mapping->host, page->index)) {
ff17be0864777 (Miklos Szeredi          2013-10-01 16:44:53 +0200 1944) 		/*
ff17be0864777 (Miklos Szeredi          2013-10-01 16:44:53 +0200 1945) 		 * ->writepages() should be called for sync() and friends.  We
ff17be0864777 (Miklos Szeredi          2013-10-01 16:44:53 +0200 1946) 		 * should only get here on direct reclaim and then we are
ff17be0864777 (Miklos Szeredi          2013-10-01 16:44:53 +0200 1947) 		 * allowed to skip a page which is already in flight
ff17be0864777 (Miklos Szeredi          2013-10-01 16:44:53 +0200 1948) 		 */
ff17be0864777 (Miklos Szeredi          2013-10-01 16:44:53 +0200 1949) 		WARN_ON(wbc->sync_mode == WB_SYNC_ALL);
ff17be0864777 (Miklos Szeredi          2013-10-01 16:44:53 +0200 1950) 
ff17be0864777 (Miklos Szeredi          2013-10-01 16:44:53 +0200 1951) 		redirty_page_for_writepage(wbc, page);
d5880c7a86202 (Vasily Averin           2019-09-13 18:17:11 +0300 1952) 		unlock_page(page);
ff17be0864777 (Miklos Szeredi          2013-10-01 16:44:53 +0200 1953) 		return 0;
ff17be0864777 (Miklos Szeredi          2013-10-01 16:44:53 +0200 1954) 	}
ff17be0864777 (Miklos Szeredi          2013-10-01 16:44:53 +0200 1955) 
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1956) 	err = fuse_writepage_locked(page);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1957) 	unlock_page(page);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1958) 
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1959) 	return err;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1960) }
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 1961) 
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 1962) struct fuse_fill_wb_data {
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1963) 	struct fuse_writepage_args *wpa;
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 1964) 	struct fuse_file *ff;
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 1965) 	struct inode *inode;
2d033eaa0073d (Maxim Patlasov          2013-08-16 15:51:41 +0400 1966) 	struct page **orig_pages;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1967) 	unsigned int max_pages;
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 1968) };
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 1969) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1970) static bool fuse_pages_realloc(struct fuse_fill_wb_data *data)
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1971) {
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1972) 	struct fuse_args_pages *ap = &data->wpa->ia.ap;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1973) 	struct fuse_conn *fc = get_fuse_conn(data->inode);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1974) 	struct page **pages;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1975) 	struct fuse_page_desc *descs;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1976) 	unsigned int npages = min_t(unsigned int,
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1977) 				    max_t(unsigned int, data->max_pages * 2,
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1978) 					  FUSE_DEFAULT_MAX_PAGES_PER_REQ),
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1979) 				    fc->max_pages);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1980) 	WARN_ON(npages <= data->max_pages);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1981) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1982) 	pages = fuse_pages_alloc(npages, GFP_NOFS, &descs);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1983) 	if (!pages)
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1984) 		return false;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1985) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1986) 	memcpy(pages, ap->pages, sizeof(struct page *) * ap->num_pages);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1987) 	memcpy(descs, ap->descs, sizeof(struct fuse_page_desc) * ap->num_pages);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1988) 	kfree(ap->pages);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1989) 	ap->pages = pages;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1990) 	ap->descs = descs;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1991) 	data->max_pages = npages;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1992) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1993) 	return true;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1994) }
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1995) 
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 1996) static void fuse_writepages_send(struct fuse_fill_wb_data *data)
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 1997) {
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 1998) 	struct fuse_writepage_args *wpa = data->wpa;
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 1999) 	struct inode *inode = data->inode;
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2000) 	struct fuse_inode *fi = get_fuse_inode(inode);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2001) 	int num_pages = wpa->ia.ap.num_pages;
2d033eaa0073d (Maxim Patlasov          2013-08-16 15:51:41 +0400 2002) 	int i;
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2003) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2004) 	wpa->ia.ff = fuse_file_get(data->ff);
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300 2005) 	spin_lock(&fi->lock);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2006) 	list_add_tail(&wpa->queue_entry, &fi->queued_writes);
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2007) 	fuse_flush_writepages(inode);
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300 2008) 	spin_unlock(&fi->lock);
2d033eaa0073d (Maxim Patlasov          2013-08-16 15:51:41 +0400 2009) 
2d033eaa0073d (Maxim Patlasov          2013-08-16 15:51:41 +0400 2010) 	for (i = 0; i < num_pages; i++)
2d033eaa0073d (Maxim Patlasov          2013-08-16 15:51:41 +0400 2011) 		end_page_writeback(data->orig_pages[i]);
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2012) }
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2013) 
7f305ca1928d8 (Miklos Szeredi          2019-01-16 10:27:59 +0100 2014) /*
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 2015)  * Check under fi->lock if the page is under writeback, and insert it onto the
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 2016)  * rb_tree if not. Otherwise iterate auxiliary write requests, to see if there's
419234d5958b8 (Miklos Szeredi          2019-01-16 10:27:59 +0100 2017)  * one already added for a page at this offset.  If there's none, then insert
419234d5958b8 (Miklos Szeredi          2019-01-16 10:27:59 +0100 2018)  * this new request onto the auxiliary list, otherwise reuse the existing one by
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 2019)  * swapping the new temp page with the old one.
7f305ca1928d8 (Miklos Szeredi          2019-01-16 10:27:59 +0100 2020)  */
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 2021) static bool fuse_writepage_add(struct fuse_writepage_args *new_wpa,
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 2022) 			       struct page *page)
8b284dc47291d (Miklos Szeredi          2013-10-01 16:44:53 +0200 2023) {
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2024) 	struct fuse_inode *fi = get_fuse_inode(new_wpa->inode);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2025) 	struct fuse_writepage_args *tmp;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2026) 	struct fuse_writepage_args *old_wpa;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2027) 	struct fuse_args_pages *new_ap = &new_wpa->ia.ap;
8b284dc47291d (Miklos Szeredi          2013-10-01 16:44:53 +0200 2028) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2029) 	WARN_ON(new_ap->num_pages != 0);
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 2030) 	new_ap->num_pages = 1;
8b284dc47291d (Miklos Szeredi          2013-10-01 16:44:53 +0200 2031) 
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300 2032) 	spin_lock(&fi->lock);
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 2033) 	old_wpa = fuse_insert_writeback(&fi->writepages, new_wpa);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2034) 	if (!old_wpa) {
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300 2035) 		spin_unlock(&fi->lock);
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 2036) 		return true;
f6011081f5e29 (Maxim Patlasov          2013-10-02 15:01:07 +0400 2037) 	}
8b284dc47291d (Miklos Szeredi          2013-10-01 16:44:53 +0200 2038) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2039) 	for (tmp = old_wpa->next; tmp; tmp = tmp->next) {
7f305ca1928d8 (Miklos Szeredi          2019-01-16 10:27:59 +0100 2040) 		pgoff_t curr_index;
7f305ca1928d8 (Miklos Szeredi          2019-01-16 10:27:59 +0100 2041) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2042) 		WARN_ON(tmp->inode != new_wpa->inode);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2043) 		curr_index = tmp->ia.write.in.offset >> PAGE_SHIFT;
419234d5958b8 (Miklos Szeredi          2019-01-16 10:27:59 +0100 2044) 		if (curr_index == page->index) {
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2045) 			WARN_ON(tmp->ia.ap.num_pages != 1);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2046) 			swap(tmp->ia.ap.pages[0], new_ap->pages[0]);
7f305ca1928d8 (Miklos Szeredi          2019-01-16 10:27:59 +0100 2047) 			break;
8b284dc47291d (Miklos Szeredi          2013-10-01 16:44:53 +0200 2048) 		}
8b284dc47291d (Miklos Szeredi          2013-10-01 16:44:53 +0200 2049) 	}
8b284dc47291d (Miklos Szeredi          2013-10-01 16:44:53 +0200 2050) 
7f305ca1928d8 (Miklos Szeredi          2019-01-16 10:27:59 +0100 2051) 	if (!tmp) {
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2052) 		new_wpa->next = old_wpa->next;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2053) 		old_wpa->next = new_wpa;
7f305ca1928d8 (Miklos Szeredi          2019-01-16 10:27:59 +0100 2054) 	}
41b6e41fc6097 (Maxim Patlasov          2013-10-02 21:38:43 +0400 2055) 
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300 2056) 	spin_unlock(&fi->lock);
7f305ca1928d8 (Miklos Szeredi          2019-01-16 10:27:59 +0100 2057) 
7f305ca1928d8 (Miklos Szeredi          2019-01-16 10:27:59 +0100 2058) 	if (tmp) {
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2059) 		struct backing_dev_info *bdi = inode_to_bdi(new_wpa->inode);
8b284dc47291d (Miklos Szeredi          2013-10-01 16:44:53 +0200 2060) 
93f78d882865c (Tejun Heo               2015-05-22 17:13:27 -0400 2061) 		dec_wb_stat(&bdi->wb, WB_WRITEBACK);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2062) 		dec_node_page_state(new_ap->pages[0], NR_WRITEBACK_TEMP);
93f78d882865c (Tejun Heo               2015-05-22 17:13:27 -0400 2063) 		wb_writeout_inc(&bdi->wb);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2064) 		fuse_writepage_free(new_wpa);
8b284dc47291d (Miklos Szeredi          2013-10-01 16:44:53 +0200 2065) 	}
7f305ca1928d8 (Miklos Szeredi          2019-01-16 10:27:59 +0100 2066) 
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 2067) 	return false;
8b284dc47291d (Miklos Szeredi          2013-10-01 16:44:53 +0200 2068) }
8b284dc47291d (Miklos Szeredi          2013-10-01 16:44:53 +0200 2069) 
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2070) static bool fuse_writepage_need_send(struct fuse_conn *fc, struct page *page,
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2071) 				     struct fuse_args_pages *ap,
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2072) 				     struct fuse_fill_wb_data *data)
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2073) {
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2074) 	WARN_ON(!ap->num_pages);
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2075) 
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2076) 	/*
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2077) 	 * Being under writeback is unlikely but possible.  For example direct
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2078) 	 * read to an mmaped fuse file will set the page dirty twice; once when
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2079) 	 * the pages are faulted with get_user_pages(), and then after the read
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2080) 	 * completed.
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2081) 	 */
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2082) 	if (fuse_page_is_writeback(data->inode, page->index))
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2083) 		return true;
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2084) 
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2085) 	/* Reached max pages */
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2086) 	if (ap->num_pages == fc->max_pages)
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2087) 		return true;
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2088) 
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2089) 	/* Reached max write bytes */
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2090) 	if ((ap->num_pages + 1) * PAGE_SIZE > fc->max_write)
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2091) 		return true;
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2092) 
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2093) 	/* Discontinuity */
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2094) 	if (data->orig_pages[ap->num_pages - 1]->index + 1 != page->index)
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2095) 		return true;
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2096) 
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2097) 	/* Need to grow the pages array?  If so, did the expansion fail? */
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2098) 	if (ap->num_pages == data->max_pages && !fuse_pages_realloc(data))
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2099) 		return true;
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2100) 
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2101) 	return false;
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2102) }
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2103) 
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2104) static int fuse_writepages_fill(struct page *page,
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2105) 		struct writeback_control *wbc, void *_data)
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2106) {
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2107) 	struct fuse_fill_wb_data *data = _data;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2108) 	struct fuse_writepage_args *wpa = data->wpa;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2109) 	struct fuse_args_pages *ap = &wpa->ia.ap;
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2110) 	struct inode *inode = data->inode;
f15ecfef058d9 (Kirill Tkhai            2018-11-09 13:33:22 +0300 2111) 	struct fuse_inode *fi = get_fuse_inode(inode);
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2112) 	struct fuse_conn *fc = get_fuse_conn(inode);
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2113) 	struct page *tmp_page;
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2114) 	int err;
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2115) 
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2116) 	if (!data->ff) {
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2117) 		err = -EIO;
091d1a7267726 (Vasily Averin           2019-08-19 08:48:26 +0300 2118) 		data->ff = fuse_write_file_get(fc, fi);
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2119) 		if (!data->ff)
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2120) 			goto out_unlock;
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2121) 	}
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2122) 
6ddf3af93e32b (Miklos Szeredi          2020-07-14 14:45:41 +0200 2123) 	if (wpa && fuse_writepage_need_send(fc, page, ap, data)) {
8b284dc47291d (Miklos Szeredi          2013-10-01 16:44:53 +0200 2124) 		fuse_writepages_send(data);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2125) 		data->wpa = NULL;
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2126) 	}
e52a8250480ac (Miklos Szeredi          2018-10-01 10:07:06 +0200 2127) 
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2128) 	err = -ENOMEM;
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2129) 	tmp_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM);
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2130) 	if (!tmp_page)
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2131) 		goto out_unlock;
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2132) 
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2133) 	/*
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2134) 	 * The page must not be redirtied until the writeout is completed
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2135) 	 * (i.e. userspace has sent a reply to the write request).  Otherwise
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2136) 	 * there could be more than one temporary page instance for each real
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2137) 	 * page.
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2138) 	 *
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2139) 	 * This is ensured by holding the page lock in page_mkwrite() while
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2140) 	 * checking fuse_page_is_writeback().  We already hold the page lock
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2141) 	 * since clear_page_dirty_for_io() and keep it held until we add the
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2142) 	 * request to the fi->writepages list and increment ap->num_pages.
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2143) 	 * After this fuse_page_is_writeback() will indicate that the page is
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2144) 	 * under writeback, so we can release the page lock.
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2145) 	 */
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2146) 	if (data->wpa == NULL) {
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2147) 		err = -ENOMEM;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2148) 		wpa = fuse_writepage_args_alloc();
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2149) 		if (!wpa) {
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2150) 			__free_page(tmp_page);
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2151) 			goto out_unlock;
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2152) 		}
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2153) 		data->max_pages = 1;
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2154) 
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2155) 		ap = &wpa->ia.ap;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2156) 		fuse_write_args_fill(&wpa->ia, data->ff, page_offset(page), 0);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2157) 		wpa->ia.write.in.write_flags |= FUSE_WRITE_CACHE;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2158) 		wpa->next = NULL;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2159) 		ap->args.in_pages = true;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2160) 		ap->args.end = fuse_writepage_end;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2161) 		ap->num_pages = 0;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2162) 		wpa->inode = inode;
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2163) 	}
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2164) 	set_page_writeback(page);
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2165) 
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2166) 	copy_highpage(tmp_page, page);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2167) 	ap->pages[ap->num_pages] = tmp_page;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2168) 	ap->descs[ap->num_pages].offset = 0;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2169) 	ap->descs[ap->num_pages].length = PAGE_SIZE;
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 2170) 	data->orig_pages[ap->num_pages] = page;
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2171) 
93f78d882865c (Tejun Heo               2015-05-22 17:13:27 -0400 2172) 	inc_wb_stat(&inode_to_bdi(inode)->wb, WB_WRITEBACK);
11fb998986a72 (Mel Gorman              2016-07-28 15:46:20 -0700 2173) 	inc_node_page_state(tmp_page, NR_WRITEBACK_TEMP);
8b284dc47291d (Miklos Szeredi          2013-10-01 16:44:53 +0200 2174) 
8b284dc47291d (Miklos Szeredi          2013-10-01 16:44:53 +0200 2175) 	err = 0;
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 2176) 	if (data->wpa) {
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 2177) 		/*
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 2178) 		 * Protected by fi->lock against concurrent access by
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 2179) 		 * fuse_page_is_writeback().
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 2180) 		 */
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 2181) 		spin_lock(&fi->lock);
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 2182) 		ap->num_pages++;
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 2183) 		spin_unlock(&fi->lock);
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 2184) 	} else if (fuse_writepage_add(wpa, page)) {
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 2185) 		data->wpa = wpa;
c146024ec44c2 (Miklos Szeredi          2020-07-14 14:45:41 +0200 2186) 	} else {
8b284dc47291d (Miklos Szeredi          2013-10-01 16:44:53 +0200 2187) 		end_page_writeback(page);
8b284dc47291d (Miklos Szeredi          2013-10-01 16:44:53 +0200 2188) 	}
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2189) out_unlock:
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2190) 	unlock_page(page);
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2191) 
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2192) 	return err;
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2193) }
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2194) 
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2195) static int fuse_writepages(struct address_space *mapping,
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2196) 			   struct writeback_control *wbc)
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2197) {
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2198) 	struct inode *inode = mapping->host;
5da784cce4308 (Constantine Shulyupin   2018-09-06 15:37:06 +0300 2199) 	struct fuse_conn *fc = get_fuse_conn(inode);
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2200) 	struct fuse_fill_wb_data data;
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2201) 	int err;
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2202) 
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2203) 	err = -EIO;
5d069dbe8aaf2 (Miklos Szeredi          2020-12-10 15:33:14 +0100 2204) 	if (fuse_is_bad(inode))
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2205) 		goto out;
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2206) 
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2207) 	data.inode = inode;
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2208) 	data.wpa = NULL;
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2209) 	data.ff = NULL;
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2210) 
2d033eaa0073d (Maxim Patlasov          2013-08-16 15:51:41 +0400 2211) 	err = -ENOMEM;
5da784cce4308 (Constantine Shulyupin   2018-09-06 15:37:06 +0300 2212) 	data.orig_pages = kcalloc(fc->max_pages,
f2b3455e47c72 (Fabian Frederick        2014-06-23 18:35:15 +0200 2213) 				  sizeof(struct page *),
2d033eaa0073d (Maxim Patlasov          2013-08-16 15:51:41 +0400 2214) 				  GFP_NOFS);
2d033eaa0073d (Maxim Patlasov          2013-08-16 15:51:41 +0400 2215) 	if (!data.orig_pages)
2d033eaa0073d (Maxim Patlasov          2013-08-16 15:51:41 +0400 2216) 		goto out;
2d033eaa0073d (Maxim Patlasov          2013-08-16 15:51:41 +0400 2217) 
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2218) 	err = write_cache_pages(mapping, wbc, fuse_writepages_fill, &data);
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2219) 	if (data.wpa) {
33826ebbbe4b4 (Miklos Szeredi          2019-09-10 15:04:10 +0200 2220) 		WARN_ON(!data.wpa->ia.ap.num_pages);
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2221) 		fuse_writepages_send(&data);
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2222) 	}
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2223) 	if (data.ff)
2e64ff154ce6c (Chad Austin             2018-12-10 10:54:52 -0800 2224) 		fuse_file_put(data.ff, false, false);
2d033eaa0073d (Maxim Patlasov          2013-08-16 15:51:41 +0400 2225) 
2d033eaa0073d (Maxim Patlasov          2013-08-16 15:51:41 +0400 2226) 	kfree(data.orig_pages);
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2227) out:
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2228) 	return err;
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2229) }
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 2230) 
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2231) /*
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2232)  * It's worthy to make sure that space is reserved on disk for the write,
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2233)  * but how to implement it without killing performance need more thinking.
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2234)  */
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2235) static int fuse_write_begin(struct file *file, struct address_space *mapping,
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2236) 		loff_t pos, unsigned len, unsigned flags,
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2237) 		struct page **pagep, void **fsdata)
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2238) {
09cbfeaf1a5a6 (Kirill A. Shutemov      2016-04-01 15:29:47 +0300 2239) 	pgoff_t index = pos >> PAGE_SHIFT;
a455589f181e6 (Al Viro                 2014-10-21 20:11:25 -0400 2240) 	struct fuse_conn *fc = get_fuse_conn(file_inode(file));
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2241) 	struct page *page;
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2242) 	loff_t fsize;
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2243) 	int err = -ENOMEM;
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2244) 
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2245) 	WARN_ON(!fc->writeback_cache);
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2246) 
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2247) 	page = grab_cache_page_write_begin(mapping, index, flags);
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2248) 	if (!page)
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2249) 		goto error;
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2250) 
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2251) 	fuse_wait_on_page_writeback(mapping->host, page->index);
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2252) 
09cbfeaf1a5a6 (Kirill A. Shutemov      2016-04-01 15:29:47 +0300 2253) 	if (PageUptodate(page) || len == PAGE_SIZE)
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2254) 		goto success;
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2255) 	/*
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2256) 	 * Check if the start this page comes after the end of file, in which
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2257) 	 * case the readpage can be optimized away.
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2258) 	 */
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2259) 	fsize = i_size_read(mapping->host);
09cbfeaf1a5a6 (Kirill A. Shutemov      2016-04-01 15:29:47 +0300 2260) 	if (fsize <= (pos & PAGE_MASK)) {
09cbfeaf1a5a6 (Kirill A. Shutemov      2016-04-01 15:29:47 +0300 2261) 		size_t off = pos & ~PAGE_MASK;
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2262) 		if (off)
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2263) 			zero_user_segment(page, 0, off);
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2264) 		goto success;
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2265) 	}
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2266) 	err = fuse_do_readpage(file, page);
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2267) 	if (err)
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2268) 		goto cleanup;
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2269) success:
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2270) 	*pagep = page;
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2271) 	return 0;
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2272) 
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2273) cleanup:
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2274) 	unlock_page(page);
09cbfeaf1a5a6 (Kirill A. Shutemov      2016-04-01 15:29:47 +0300 2275) 	put_page(page);
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2276) error:
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2277) 	return err;
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2278) }
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2279) 
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2280) static int fuse_write_end(struct file *file, struct address_space *mapping,
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2281) 		loff_t pos, unsigned len, unsigned copied,
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2282) 		struct page *page, void *fsdata)
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2283) {
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2284) 	struct inode *inode = page->mapping->host;
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2285) 
59c3b76cc61d1 (Miklos Szeredi          2016-08-18 09:10:44 +0200 2286) 	/* Haven't copied anything?  Skip zeroing, size extending, dirtying. */
59c3b76cc61d1 (Miklos Szeredi          2016-08-18 09:10:44 +0200 2287) 	if (!copied)
59c3b76cc61d1 (Miklos Szeredi          2016-08-18 09:10:44 +0200 2288) 		goto unlock;
59c3b76cc61d1 (Miklos Szeredi          2016-08-18 09:10:44 +0200 2289) 
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2290) 	if (!PageUptodate(page)) {
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2291) 		/* Zero any unwritten bytes at the end of the page */
09cbfeaf1a5a6 (Kirill A. Shutemov      2016-04-01 15:29:47 +0300 2292) 		size_t endoff = (pos + copied) & ~PAGE_MASK;
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2293) 		if (endoff)
09cbfeaf1a5a6 (Kirill A. Shutemov      2016-04-01 15:29:47 +0300 2294) 			zero_user_segment(page, endoff, PAGE_SIZE);
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2295) 		SetPageUptodate(page);
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2296) 	}
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2297) 
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2298) 	fuse_write_update_size(inode, pos + copied);
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2299) 	set_page_dirty(page);
59c3b76cc61d1 (Miklos Szeredi          2016-08-18 09:10:44 +0200 2300) 
59c3b76cc61d1 (Miklos Szeredi          2016-08-18 09:10:44 +0200 2301) unlock:
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2302) 	unlock_page(page);
09cbfeaf1a5a6 (Kirill A. Shutemov      2016-04-01 15:29:47 +0300 2303) 	put_page(page);
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2304) 
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2305) 	return copied;
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2306) }
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 2307) 
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2308) static int fuse_launder_page(struct page *page)
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2309) {
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2310) 	int err = 0;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2311) 	if (clear_page_dirty_for_io(page)) {
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2312) 		struct inode *inode = page->mapping->host;
3993382bb3198 (Miklos Szeredi          2020-11-11 17:22:31 +0100 2313) 
3993382bb3198 (Miklos Szeredi          2020-11-11 17:22:31 +0100 2314) 		/* Serialize with pending writeback for the same page */
3993382bb3198 (Miklos Szeredi          2020-11-11 17:22:31 +0100 2315) 		fuse_wait_on_page_writeback(inode, page->index);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2316) 		err = fuse_writepage_locked(page);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2317) 		if (!err)
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2318) 			fuse_wait_on_page_writeback(inode, page->index);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2319) 	}
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2320) 	return err;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2321) }
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2322) 
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2323) /*
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2324)  * Write back dirty pages now, because there may not be any suitable
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2325)  * open files later
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2326)  */
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2327) static void fuse_vma_close(struct vm_area_struct *vma)
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2328) {
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2329) 	filemap_write_and_wait(vma->vm_file->f_mapping);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2330) }
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2331) 
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2332) /*
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2333)  * Wait for writeback against this page to complete before allowing it
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2334)  * to be marked dirty again, and hence written back again, possibly
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2335)  * before the previous writepage completed.
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2336)  *
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2337)  * Block here, instead of in ->writepage(), so that the userspace fs
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2338)  * can only block processes actually operating on the filesystem.
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2339)  *
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2340)  * Otherwise unprivileged userspace fs would be able to block
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2341)  * unrelated:
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2342)  *
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2343)  * - page migration
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2344)  * - sync(2)
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2345)  * - try_to_free_pages() with order > PAGE_ALLOC_COSTLY_ORDER
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2346)  */
46fb504a7145a (Souptick Joarder        2018-05-12 10:25:37 +0530 2347) static vm_fault_t fuse_page_mkwrite(struct vm_fault *vmf)
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2348) {
c2ec175c39f62 (Nicholas Piggin         2009-03-31 15:23:21 -0700 2349) 	struct page *page = vmf->page;
11bac80004499 (Dave Jiang              2017-02-24 14:56:41 -0800 2350) 	struct inode *inode = file_inode(vmf->vma->vm_file);
cca2437045dda (Miklos Szeredi          2013-10-01 16:44:51 +0200 2351) 
11bac80004499 (Dave Jiang              2017-02-24 14:56:41 -0800 2352) 	file_update_time(vmf->vma->vm_file);
cca2437045dda (Miklos Szeredi          2013-10-01 16:44:51 +0200 2353) 	lock_page(page);
cca2437045dda (Miklos Szeredi          2013-10-01 16:44:51 +0200 2354) 	if (page->mapping != inode->i_mapping) {
cca2437045dda (Miklos Szeredi          2013-10-01 16:44:51 +0200 2355) 		unlock_page(page);
cca2437045dda (Miklos Szeredi          2013-10-01 16:44:51 +0200 2356) 		return VM_FAULT_NOPAGE;
cca2437045dda (Miklos Szeredi          2013-10-01 16:44:51 +0200 2357) 	}
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2358) 
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2359) 	fuse_wait_on_page_writeback(inode, page->index);
cca2437045dda (Miklos Szeredi          2013-10-01 16:44:51 +0200 2360) 	return VM_FAULT_LOCKED;
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2361) }
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2362) 
f0f37e2f77731 (Alexey Dobriyan         2009-09-27 22:29:37 +0400 2363) static const struct vm_operations_struct fuse_file_vm_ops = {
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2364) 	.close		= fuse_vma_close,
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2365) 	.fault		= filemap_fault,
f1820361f83d5 (Kirill A. Shutemov      2014-04-07 15:37:19 -0700 2366) 	.map_pages	= filemap_map_pages,
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2367) 	.page_mkwrite	= fuse_page_mkwrite,
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2368) };
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2369) 
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2370) static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma)
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2371) {
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 2372) 	struct fuse_file *ff = file->private_data;
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 2373) 
2a9a609a0c4a3 (Stefan Hajnoczi         2020-08-19 18:19:52 -0400 2374) 	/* DAX mmap is superior to direct_io mmap */
2a9a609a0c4a3 (Stefan Hajnoczi         2020-08-19 18:19:52 -0400 2375) 	if (FUSE_IS_DAX(file_inode(file)))
2a9a609a0c4a3 (Stefan Hajnoczi         2020-08-19 18:19:52 -0400 2376) 		return fuse_dax_mmap(file, vma);
2a9a609a0c4a3 (Stefan Hajnoczi         2020-08-19 18:19:52 -0400 2377) 
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 2378) 	if (ff->open_flags & FOPEN_DIRECT_IO) {
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 2379) 		/* Can't provide the coherency needed for MAP_SHARED */
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 2380) 		if (vma->vm_flags & VM_MAYSHARE)
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 2381) 			return -ENODEV;
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 2382) 
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 2383) 		invalidate_inode_pages2(file->f_mapping);
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 2384) 
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 2385) 		return generic_file_mmap(file, vma);
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 2386) 	}
55752a3aba138 (Miklos Szeredi          2019-01-24 10:40:17 +0100 2387) 
650b22b941fa0 (Pavel Emelyanov         2013-10-10 17:10:04 +0400 2388) 	if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE))
650b22b941fa0 (Pavel Emelyanov         2013-10-10 17:10:04 +0400 2389) 		fuse_link_write_file(file);
650b22b941fa0 (Pavel Emelyanov         2013-10-10 17:10:04 +0400 2390) 
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2391) 	file_accessed(file);
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 2392) 	vma->vm_ops = &fuse_file_vm_ops;
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700 2393) 	return 0;
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700 2394) }
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700 2395) 
0b6e9ea041e6c (Seth Forshee            2014-07-02 16:29:19 -0500 2396) static int convert_fuse_file_lock(struct fuse_conn *fc,
0b6e9ea041e6c (Seth Forshee            2014-07-02 16:29:19 -0500 2397) 				  const struct fuse_file_lock *ffl,
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2398) 				  struct file_lock *fl)
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2399) {
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2400) 	switch (ffl->type) {
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2401) 	case F_UNLCK:
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2402) 		break;
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2403) 
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2404) 	case F_RDLCK:
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2405) 	case F_WRLCK:
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2406) 		if (ffl->start > OFFSET_MAX || ffl->end > OFFSET_MAX ||
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2407) 		    ffl->end < ffl->start)
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2408) 			return -EIO;
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2409) 
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2410) 		fl->fl_start = ffl->start;
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2411) 		fl->fl_end = ffl->end;
0b6e9ea041e6c (Seth Forshee            2014-07-02 16:29:19 -0500 2412) 
0b6e9ea041e6c (Seth Forshee            2014-07-02 16:29:19 -0500 2413) 		/*
9d5b86ac13c57 (Benjamin Coddington     2017-07-16 10:28:22 -0400 2414) 		 * Convert pid into init's pid namespace.  The locks API will
9d5b86ac13c57 (Benjamin Coddington     2017-07-16 10:28:22 -0400 2415) 		 * translate it into the caller's pid namespace.
0b6e9ea041e6c (Seth Forshee            2014-07-02 16:29:19 -0500 2416) 		 */
0b6e9ea041e6c (Seth Forshee            2014-07-02 16:29:19 -0500 2417) 		rcu_read_lock();
9d5b86ac13c57 (Benjamin Coddington     2017-07-16 10:28:22 -0400 2418) 		fl->fl_pid = pid_nr_ns(find_pid_ns(ffl->pid, fc->pid_ns), &init_pid_ns);
0b6e9ea041e6c (Seth Forshee            2014-07-02 16:29:19 -0500 2419) 		rcu_read_unlock();
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2420) 		break;
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2421) 
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2422) 	default:
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2423) 		return -EIO;
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2424) 	}
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2425) 	fl->fl_type = ffl->type;
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2426) 	return 0;
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2427) }
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2428) 
7078187a795f8 (Miklos Szeredi          2014-12-12 09:49:05 +0100 2429) static void fuse_lk_fill(struct fuse_args *args, struct file *file,
a9ff4f87056cd (Miklos Szeredi          2007-10-18 03:07:02 -0700 2430) 			 const struct file_lock *fl, int opcode, pid_t pid,
7078187a795f8 (Miklos Szeredi          2014-12-12 09:49:05 +0100 2431) 			 int flock, struct fuse_lk_in *inarg)
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2432) {
6131ffaa1f091 (Al Viro                 2013-02-27 16:59:05 -0500 2433) 	struct inode *inode = file_inode(file);
9c8ef5614da22 (Miklos Szeredi          2006-06-25 05:48:55 -0700 2434) 	struct fuse_conn *fc = get_fuse_conn(inode);
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2435) 	struct fuse_file *ff = file->private_data;
7078187a795f8 (Miklos Szeredi          2014-12-12 09:49:05 +0100 2436) 
7078187a795f8 (Miklos Szeredi          2014-12-12 09:49:05 +0100 2437) 	memset(inarg, 0, sizeof(*inarg));
7078187a795f8 (Miklos Szeredi          2014-12-12 09:49:05 +0100 2438) 	inarg->fh = ff->fh;
7078187a795f8 (Miklos Szeredi          2014-12-12 09:49:05 +0100 2439) 	inarg->owner = fuse_lock_owner_id(fc, fl->fl_owner);
7078187a795f8 (Miklos Szeredi          2014-12-12 09:49:05 +0100 2440) 	inarg->lk.start = fl->fl_start;
7078187a795f8 (Miklos Szeredi          2014-12-12 09:49:05 +0100 2441) 	inarg->lk.end = fl->fl_end;
7078187a795f8 (Miklos Szeredi          2014-12-12 09:49:05 +0100 2442) 	inarg->lk.type = fl->fl_type;
7078187a795f8 (Miklos Szeredi          2014-12-12 09:49:05 +0100 2443) 	inarg->lk.pid = pid;
a9ff4f87056cd (Miklos Szeredi          2007-10-18 03:07:02 -0700 2444) 	if (flock)
7078187a795f8 (Miklos Szeredi          2014-12-12 09:49:05 +0100 2445) 		inarg->lk_flags |= FUSE_LK_FLOCK;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2446) 	args->opcode = opcode;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2447) 	args->nodeid = get_node_id(inode);
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2448) 	args->in_numargs = 1;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2449) 	args->in_args[0].size = sizeof(*inarg);
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2450) 	args->in_args[0].value = inarg;
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2451) }
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2452) 
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2453) static int fuse_getlk(struct file *file, struct file_lock *fl)
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2454) {
6131ffaa1f091 (Al Viro                 2013-02-27 16:59:05 -0500 2455) 	struct inode *inode = file_inode(file);
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2456) 	struct fuse_mount *fm = get_fuse_mount(inode);
7078187a795f8 (Miklos Szeredi          2014-12-12 09:49:05 +0100 2457) 	FUSE_ARGS(args);
7078187a795f8 (Miklos Szeredi          2014-12-12 09:49:05 +0100 2458) 	struct fuse_lk_in inarg;
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2459) 	struct fuse_lk_out outarg;
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2460) 	int err;
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2461) 
7078187a795f8 (Miklos Szeredi          2014-12-12 09:49:05 +0100 2462) 	fuse_lk_fill(&args, file, fl, FUSE_GETLK, 0, 0, &inarg);
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2463) 	args.out_numargs = 1;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2464) 	args.out_args[0].size = sizeof(outarg);
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2465) 	args.out_args[0].value = &outarg;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2466) 	err = fuse_simple_request(fm, &args);
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2467) 	if (!err)
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2468) 		err = convert_fuse_file_lock(fm->fc, &outarg.lk, fl);
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2469) 
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2470) 	return err;
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2471) }
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2472) 
a9ff4f87056cd (Miklos Szeredi          2007-10-18 03:07:02 -0700 2473) static int fuse_setlk(struct file *file, struct file_lock *fl, int flock)
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2474) {
6131ffaa1f091 (Al Viro                 2013-02-27 16:59:05 -0500 2475) 	struct inode *inode = file_inode(file);
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2476) 	struct fuse_mount *fm = get_fuse_mount(inode);
7078187a795f8 (Miklos Szeredi          2014-12-12 09:49:05 +0100 2477) 	FUSE_ARGS(args);
7078187a795f8 (Miklos Szeredi          2014-12-12 09:49:05 +0100 2478) 	struct fuse_lk_in inarg;
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2479) 	int opcode = (fl->fl_flags & FL_SLEEP) ? FUSE_SETLKW : FUSE_SETLK;
0b6e9ea041e6c (Seth Forshee            2014-07-02 16:29:19 -0500 2480) 	struct pid *pid = fl->fl_type != F_UNLCK ? task_tgid(current) : NULL;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2481) 	pid_t pid_nr = pid_nr_ns(pid, fm->fc->pid_ns);
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2482) 	int err;
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2483) 
8fb47a4fbf858 (J. Bruce Fields         2011-07-20 20:21:59 -0400 2484) 	if (fl->fl_lmops && fl->fl_lmops->lm_grant) {
48e90761b570f (Miklos Szeredi          2008-07-25 01:49:02 -0700 2485) 		/* NLM needs asynchronous locks, which we don't support yet */
48e90761b570f (Miklos Szeredi          2008-07-25 01:49:02 -0700 2486) 		return -ENOLCK;
48e90761b570f (Miklos Szeredi          2008-07-25 01:49:02 -0700 2487) 	}
48e90761b570f (Miklos Szeredi          2008-07-25 01:49:02 -0700 2488) 
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2489) 	/* Unlock on close is handled by the flush method */
50f2112cf7a3e (Benjamin Coddington     2017-04-11 12:50:09 -0400 2490) 	if ((fl->fl_flags & FL_CLOSE_POSIX) == FL_CLOSE_POSIX)
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2491) 		return 0;
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2492) 
0b6e9ea041e6c (Seth Forshee            2014-07-02 16:29:19 -0500 2493) 	fuse_lk_fill(&args, file, fl, opcode, pid_nr, flock, &inarg);
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2494) 	err = fuse_simple_request(fm, &args);
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2495) 
a4d27e75ffb7b (Miklos Szeredi          2006-06-25 05:48:54 -0700 2496) 	/* locking is restartable */
a4d27e75ffb7b (Miklos Szeredi          2006-06-25 05:48:54 -0700 2497) 	if (err == -EINTR)
a4d27e75ffb7b (Miklos Szeredi          2006-06-25 05:48:54 -0700 2498) 		err = -ERESTARTSYS;
7078187a795f8 (Miklos Szeredi          2014-12-12 09:49:05 +0100 2499) 
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2500) 	return err;
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2501) }
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2502) 
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2503) static int fuse_file_lock(struct file *file, int cmd, struct file_lock *fl)
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2504) {
6131ffaa1f091 (Al Viro                 2013-02-27 16:59:05 -0500 2505) 	struct inode *inode = file_inode(file);
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2506) 	struct fuse_conn *fc = get_fuse_conn(inode);
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2507) 	int err;
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2508) 
48e90761b570f (Miklos Szeredi          2008-07-25 01:49:02 -0700 2509) 	if (cmd == F_CANCELLK) {
48e90761b570f (Miklos Szeredi          2008-07-25 01:49:02 -0700 2510) 		err = 0;
48e90761b570f (Miklos Szeredi          2008-07-25 01:49:02 -0700 2511) 	} else if (cmd == F_GETLK) {
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2512) 		if (fc->no_lock) {
9d6a8c5c213e3 (Marc Eshel              2007-02-21 00:55:18 -0500 2513) 			posix_test_lock(file, fl);
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2514) 			err = 0;
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2515) 		} else
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2516) 			err = fuse_getlk(file, fl);
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2517) 	} else {
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2518) 		if (fc->no_lock)
48e90761b570f (Miklos Szeredi          2008-07-25 01:49:02 -0700 2519) 			err = posix_lock_file(file, fl, NULL);
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2520) 		else
a9ff4f87056cd (Miklos Szeredi          2007-10-18 03:07:02 -0700 2521) 			err = fuse_setlk(file, fl, 0);
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2522) 	}
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2523) 	return err;
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2524) }
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 2525) 
a9ff4f87056cd (Miklos Szeredi          2007-10-18 03:07:02 -0700 2526) static int fuse_file_flock(struct file *file, int cmd, struct file_lock *fl)
a9ff4f87056cd (Miklos Szeredi          2007-10-18 03:07:02 -0700 2527) {
6131ffaa1f091 (Al Viro                 2013-02-27 16:59:05 -0500 2528) 	struct inode *inode = file_inode(file);
a9ff4f87056cd (Miklos Szeredi          2007-10-18 03:07:02 -0700 2529) 	struct fuse_conn *fc = get_fuse_conn(inode);
a9ff4f87056cd (Miklos Szeredi          2007-10-18 03:07:02 -0700 2530) 	int err;
a9ff4f87056cd (Miklos Szeredi          2007-10-18 03:07:02 -0700 2531) 
37fb3a30b4623 (Miklos Szeredi          2011-08-08 16:08:08 +0200 2532) 	if (fc->no_flock) {
4f6563677ae83 (Benjamin Coddington     2015-10-22 13:38:14 -0400 2533) 		err = locks_lock_file_wait(file, fl);
a9ff4f87056cd (Miklos Szeredi          2007-10-18 03:07:02 -0700 2534) 	} else {
37fb3a30b4623 (Miklos Szeredi          2011-08-08 16:08:08 +0200 2535) 		struct fuse_file *ff = file->private_data;
37fb3a30b4623 (Miklos Szeredi          2011-08-08 16:08:08 +0200 2536) 
a9ff4f87056cd (Miklos Szeredi          2007-10-18 03:07:02 -0700 2537) 		/* emulate flock with POSIX locks */
37fb3a30b4623 (Miklos Szeredi          2011-08-08 16:08:08 +0200 2538) 		ff->flock = true;
a9ff4f87056cd (Miklos Szeredi          2007-10-18 03:07:02 -0700 2539) 		err = fuse_setlk(file, fl, 1);
a9ff4f87056cd (Miklos Szeredi          2007-10-18 03:07:02 -0700 2540) 	}
a9ff4f87056cd (Miklos Szeredi          2007-10-18 03:07:02 -0700 2541) 
a9ff4f87056cd (Miklos Szeredi          2007-10-18 03:07:02 -0700 2542) 	return err;
a9ff4f87056cd (Miklos Szeredi          2007-10-18 03:07:02 -0700 2543) }
a9ff4f87056cd (Miklos Szeredi          2007-10-18 03:07:02 -0700 2544) 
b2d2272fae1e1 (Miklos Szeredi          2006-12-06 20:35:51 -0800 2545) static sector_t fuse_bmap(struct address_space *mapping, sector_t block)
b2d2272fae1e1 (Miklos Szeredi          2006-12-06 20:35:51 -0800 2546) {
b2d2272fae1e1 (Miklos Szeredi          2006-12-06 20:35:51 -0800 2547) 	struct inode *inode = mapping->host;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2548) 	struct fuse_mount *fm = get_fuse_mount(inode);
7078187a795f8 (Miklos Szeredi          2014-12-12 09:49:05 +0100 2549) 	FUSE_ARGS(args);
b2d2272fae1e1 (Miklos Szeredi          2006-12-06 20:35:51 -0800 2550) 	struct fuse_bmap_in inarg;
b2d2272fae1e1 (Miklos Szeredi          2006-12-06 20:35:51 -0800 2551) 	struct fuse_bmap_out outarg;
b2d2272fae1e1 (Miklos Szeredi          2006-12-06 20:35:51 -0800 2552) 	int err;
b2d2272fae1e1 (Miklos Szeredi          2006-12-06 20:35:51 -0800 2553) 
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2554) 	if (!inode->i_sb->s_bdev || fm->fc->no_bmap)
b2d2272fae1e1 (Miklos Szeredi          2006-12-06 20:35:51 -0800 2555) 		return 0;
b2d2272fae1e1 (Miklos Szeredi          2006-12-06 20:35:51 -0800 2556) 
b2d2272fae1e1 (Miklos Szeredi          2006-12-06 20:35:51 -0800 2557) 	memset(&inarg, 0, sizeof(inarg));
b2d2272fae1e1 (Miklos Szeredi          2006-12-06 20:35:51 -0800 2558) 	inarg.block = block;
b2d2272fae1e1 (Miklos Szeredi          2006-12-06 20:35:51 -0800 2559) 	inarg.blocksize = inode->i_sb->s_blocksize;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2560) 	args.opcode = FUSE_BMAP;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2561) 	args.nodeid = get_node_id(inode);
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2562) 	args.in_numargs = 1;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2563) 	args.in_args[0].size = sizeof(inarg);
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2564) 	args.in_args[0].value = &inarg;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2565) 	args.out_numargs = 1;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2566) 	args.out_args[0].size = sizeof(outarg);
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2567) 	args.out_args[0].value = &outarg;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2568) 	err = fuse_simple_request(fm, &args);
b2d2272fae1e1 (Miklos Szeredi          2006-12-06 20:35:51 -0800 2569) 	if (err == -ENOSYS)
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2570) 		fm->fc->no_bmap = 1;
b2d2272fae1e1 (Miklos Szeredi          2006-12-06 20:35:51 -0800 2571) 
b2d2272fae1e1 (Miklos Szeredi          2006-12-06 20:35:51 -0800 2572) 	return err ? 0 : outarg.block;
b2d2272fae1e1 (Miklos Szeredi          2006-12-06 20:35:51 -0800 2573) }
b2d2272fae1e1 (Miklos Szeredi          2006-12-06 20:35:51 -0800 2574) 
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2575) static loff_t fuse_lseek(struct file *file, loff_t offset, int whence)
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2576) {
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2577) 	struct inode *inode = file->f_mapping->host;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2578) 	struct fuse_mount *fm = get_fuse_mount(inode);
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2579) 	struct fuse_file *ff = file->private_data;
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2580) 	FUSE_ARGS(args);
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2581) 	struct fuse_lseek_in inarg = {
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2582) 		.fh = ff->fh,
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2583) 		.offset = offset,
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2584) 		.whence = whence
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2585) 	};
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2586) 	struct fuse_lseek_out outarg;
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2587) 	int err;
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2588) 
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2589) 	if (fm->fc->no_lseek)
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2590) 		goto fallback;
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2591) 
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2592) 	args.opcode = FUSE_LSEEK;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2593) 	args.nodeid = ff->nodeid;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2594) 	args.in_numargs = 1;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2595) 	args.in_args[0].size = sizeof(inarg);
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2596) 	args.in_args[0].value = &inarg;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2597) 	args.out_numargs = 1;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2598) 	args.out_args[0].size = sizeof(outarg);
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2599) 	args.out_args[0].value = &outarg;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2600) 	err = fuse_simple_request(fm, &args);
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2601) 	if (err) {
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2602) 		if (err == -ENOSYS) {
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2603) 			fm->fc->no_lseek = 1;
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2604) 			goto fallback;
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2605) 		}
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2606) 		return err;
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2607) 	}
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2608) 
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2609) 	return vfs_setpos(file, outarg.offset, inode->i_sb->s_maxbytes);
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2610) 
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2611) fallback:
5b97eeacbd80a (Miklos Szeredi          2017-09-12 16:57:54 +0200 2612) 	err = fuse_update_attributes(inode, file);
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2613) 	if (!err)
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2614) 		return generic_file_llseek(file, offset, whence);
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2615) 	else
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2616) 		return err;
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2617) }
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2618) 
965c8e59cfcf8 (Andrew Morton           2012-12-17 15:59:39 -0800 2619) static loff_t fuse_file_llseek(struct file *file, loff_t offset, int whence)
5559b8f4d1f63 (Miklos Szeredi          2008-04-30 00:54:45 -0700 2620) {
5559b8f4d1f63 (Miklos Szeredi          2008-04-30 00:54:45 -0700 2621) 	loff_t retval;
6131ffaa1f091 (Al Viro                 2013-02-27 16:59:05 -0500 2622) 	struct inode *inode = file_inode(file);
5559b8f4d1f63 (Miklos Szeredi          2008-04-30 00:54:45 -0700 2623) 
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2624) 	switch (whence) {
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2625) 	case SEEK_SET:
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2626) 	case SEEK_CUR:
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2627) 		 /* No i_mutex protection necessary for SEEK_CUR and SEEK_SET */
965c8e59cfcf8 (Andrew Morton           2012-12-17 15:59:39 -0800 2628) 		retval = generic_file_llseek(file, offset, whence);
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2629) 		break;
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2630) 	case SEEK_END:
5955102c9984f (Al Viro                 2016-01-22 15:40:57 -0500 2631) 		inode_lock(inode);
5b97eeacbd80a (Miklos Szeredi          2017-09-12 16:57:54 +0200 2632) 		retval = fuse_update_attributes(inode, file);
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2633) 		if (!retval)
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2634) 			retval = generic_file_llseek(file, offset, whence);
5955102c9984f (Al Viro                 2016-01-22 15:40:57 -0500 2635) 		inode_unlock(inode);
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2636) 		break;
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2637) 	case SEEK_HOLE:
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2638) 	case SEEK_DATA:
5955102c9984f (Al Viro                 2016-01-22 15:40:57 -0500 2639) 		inode_lock(inode);
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2640) 		retval = fuse_lseek(file, offset, whence);
5955102c9984f (Al Viro                 2016-01-22 15:40:57 -0500 2641) 		inode_unlock(inode);
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2642) 		break;
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2643) 	default:
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2644) 		retval = -EINVAL;
0b5da8db145bf (Ravishankar N           2015-06-30 23:40:22 +0530 2645) 	}
c07c3d193412b (Miklos Szeredi          2011-12-13 11:58:48 +0100 2646) 
5559b8f4d1f63 (Miklos Szeredi          2008-04-30 00:54:45 -0700 2647) 	return retval;
5559b8f4d1f63 (Miklos Szeredi          2008-04-30 00:54:45 -0700 2648) }
5559b8f4d1f63 (Miklos Szeredi          2008-04-30 00:54:45 -0700 2649) 
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2650) /*
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2651)  * All files which have been polled are linked to RB tree
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2652)  * fuse_conn->polled_files which is indexed by kh.  Walk the tree and
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2653)  * find the matching one.
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2654)  */
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2655) static struct rb_node **fuse_find_polled_node(struct fuse_conn *fc, u64 kh,
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2656) 					      struct rb_node **parent_out)
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2657) {
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2658) 	struct rb_node **link = &fc->polled_files.rb_node;
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2659) 	struct rb_node *last = NULL;
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2660) 
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2661) 	while (*link) {
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2662) 		struct fuse_file *ff;
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2663) 
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2664) 		last = *link;
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2665) 		ff = rb_entry(last, struct fuse_file, polled_node);
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2666) 
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2667) 		if (kh < ff->kh)
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2668) 			link = &last->rb_left;
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2669) 		else if (kh > ff->kh)
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2670) 			link = &last->rb_right;
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2671) 		else
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2672) 			return link;
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2673) 	}
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2674) 
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2675) 	if (parent_out)
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2676) 		*parent_out = last;
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2677) 	return link;
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2678) }
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2679) 
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2680) /*
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2681)  * The file is about to be polled.  Make sure it's on the polled_files
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2682)  * RB tree.  Note that files once added to the polled_files tree are
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2683)  * not removed before the file is released.  This is because a file
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2684)  * polled once is likely to be polled again.
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2685)  */
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2686) static void fuse_register_polled_file(struct fuse_conn *fc,
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2687) 				      struct fuse_file *ff)
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2688) {
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2689) 	spin_lock(&fc->lock);
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2690) 	if (RB_EMPTY_NODE(&ff->polled_node)) {
3f649ab728cda (Kees Cook               2020-06-03 13:09:38 -0700 2691) 		struct rb_node **link, *parent;
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2692) 
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2693) 		link = fuse_find_polled_node(fc, ff->kh, &parent);
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2694) 		BUG_ON(*link);
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2695) 		rb_link_node(&ff->polled_node, parent, link);
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2696) 		rb_insert_color(&ff->polled_node, &fc->polled_files);
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2697) 	}
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2698) 	spin_unlock(&fc->lock);
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2699) }
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2700) 
076ccb76e1a6c (Al Viro                 2017-07-03 01:02:18 -0400 2701) __poll_t fuse_file_poll(struct file *file, poll_table *wait)
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2702) {
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2703) 	struct fuse_file *ff = file->private_data;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2704) 	struct fuse_mount *fm = ff->fm;
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2705) 	struct fuse_poll_in inarg = { .fh = ff->fh, .kh = ff->kh };
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2706) 	struct fuse_poll_out outarg;
7078187a795f8 (Miklos Szeredi          2014-12-12 09:49:05 +0100 2707) 	FUSE_ARGS(args);
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2708) 	int err;
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2709) 
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2710) 	if (fm->fc->no_poll)
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2711) 		return DEFAULT_POLLMASK;
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2712) 
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2713) 	poll_wait(file, &ff->poll_wait, wait);
c71d227fc4133 (Al Viro                 2017-11-29 19:00:41 -0500 2714) 	inarg.events = mangle_poll(poll_requested_events(wait));
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2715) 
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2716) 	/*
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2717) 	 * Ask for notification iff there's someone waiting for it.
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2718) 	 * The client may ignore the flag and always notify.
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2719) 	 */
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2720) 	if (waitqueue_active(&ff->poll_wait)) {
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2721) 		inarg.flags |= FUSE_POLL_SCHEDULE_NOTIFY;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2722) 		fuse_register_polled_file(fm->fc, ff);
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2723) 	}
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2724) 
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2725) 	args.opcode = FUSE_POLL;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2726) 	args.nodeid = ff->nodeid;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2727) 	args.in_numargs = 1;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2728) 	args.in_args[0].size = sizeof(inarg);
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2729) 	args.in_args[0].value = &inarg;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2730) 	args.out_numargs = 1;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2731) 	args.out_args[0].size = sizeof(outarg);
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2732) 	args.out_args[0].value = &outarg;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2733) 	err = fuse_simple_request(fm, &args);
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2734) 
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2735) 	if (!err)
c71d227fc4133 (Al Viro                 2017-11-29 19:00:41 -0500 2736) 		return demangle_poll(outarg.revents);
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2737) 	if (err == -ENOSYS) {
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2738) 		fm->fc->no_poll = 1;
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2739) 		return DEFAULT_POLLMASK;
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2740) 	}
a9a08845e9acb (Linus Torvalds          2018-02-11 14:34:03 -0800 2741) 	return EPOLLERR;
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2742) }
08cbf542bf24f (Tejun Heo               2009-04-14 10:54:53 +0900 2743) EXPORT_SYMBOL_GPL(fuse_file_poll);
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2744) 
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2745) /*
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2746)  * This is called from fuse_handle_notify() on FUSE_NOTIFY_POLL and
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2747)  * wakes up the poll waiters.
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2748)  */
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2749) int fuse_notify_poll_wakeup(struct fuse_conn *fc,
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2750) 			    struct fuse_notify_poll_wakeup_out *outarg)
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2751) {
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2752) 	u64 kh = outarg->kh;
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2753) 	struct rb_node **link;
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2754) 
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2755) 	spin_lock(&fc->lock);
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2756) 
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2757) 	link = fuse_find_polled_node(fc, kh, NULL);
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2758) 	if (*link) {
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2759) 		struct fuse_file *ff;
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2760) 
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2761) 		ff = rb_entry(*link, struct fuse_file, polled_node);
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2762) 		wake_up_interruptible_sync(&ff->poll_wait);
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2763) 	}
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2764) 
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2765) 	spin_unlock(&fc->lock);
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2766) 	return 0;
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2767) }
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 2768) 
efb9fa9e911b2 (Maxim Patlasov          2012-12-18 14:05:08 +0400 2769) static void fuse_do_truncate(struct file *file)
efb9fa9e911b2 (Maxim Patlasov          2012-12-18 14:05:08 +0400 2770) {
efb9fa9e911b2 (Maxim Patlasov          2012-12-18 14:05:08 +0400 2771) 	struct inode *inode = file->f_mapping->host;
efb9fa9e911b2 (Maxim Patlasov          2012-12-18 14:05:08 +0400 2772) 	struct iattr attr;
efb9fa9e911b2 (Maxim Patlasov          2012-12-18 14:05:08 +0400 2773) 
efb9fa9e911b2 (Maxim Patlasov          2012-12-18 14:05:08 +0400 2774) 	attr.ia_valid = ATTR_SIZE;
efb9fa9e911b2 (Maxim Patlasov          2012-12-18 14:05:08 +0400 2775) 	attr.ia_size = i_size_read(inode);
efb9fa9e911b2 (Maxim Patlasov          2012-12-18 14:05:08 +0400 2776) 
efb9fa9e911b2 (Maxim Patlasov          2012-12-18 14:05:08 +0400 2777) 	attr.ia_file = file;
efb9fa9e911b2 (Maxim Patlasov          2012-12-18 14:05:08 +0400 2778) 	attr.ia_valid |= ATTR_FILE;
efb9fa9e911b2 (Maxim Patlasov          2012-12-18 14:05:08 +0400 2779) 
62490330769c1 (Jan Kara                2016-05-26 17:12:41 +0200 2780) 	fuse_do_setattr(file_dentry(file), &attr, file);
efb9fa9e911b2 (Maxim Patlasov          2012-12-18 14:05:08 +0400 2781) }
efb9fa9e911b2 (Maxim Patlasov          2012-12-18 14:05:08 +0400 2782) 
5da784cce4308 (Constantine Shulyupin   2018-09-06 15:37:06 +0300 2783) static inline loff_t fuse_round_up(struct fuse_conn *fc, loff_t off)
e5c5f05dca0cf (Maxim Patlasov          2013-05-30 16:41:34 +0400 2784) {
5da784cce4308 (Constantine Shulyupin   2018-09-06 15:37:06 +0300 2785) 	return round_up(off, fc->max_pages << PAGE_SHIFT);
e5c5f05dca0cf (Maxim Patlasov          2013-05-30 16:41:34 +0400 2786) }
e5c5f05dca0cf (Maxim Patlasov          2013-05-30 16:41:34 +0400 2787) 
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 2788) static ssize_t
c8b8e32d700fe (Christoph Hellwig       2016-04-07 08:51:58 -0700 2789) fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 2790) {
9d5722b7777e6 (Christoph Hellwig       2015-02-02 14:59:43 +0100 2791) 	DECLARE_COMPLETION_ONSTACK(wait);
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 2792) 	ssize_t ret = 0;
60b9df7a54804 (Miklos Szeredi          2013-05-01 14:37:21 +0200 2793) 	struct file *file = iocb->ki_filp;
60b9df7a54804 (Miklos Szeredi          2013-05-01 14:37:21 +0200 2794) 	struct fuse_file *ff = file->private_data;
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 2795) 	loff_t pos = 0;
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2796) 	struct inode *inode;
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2797) 	loff_t i_size;
933a3752babcf (Al Viro                 2020-09-17 17:26:56 -0400 2798) 	size_t count = iov_iter_count(iter), shortened = 0;
c8b8e32d700fe (Christoph Hellwig       2016-04-07 08:51:58 -0700 2799) 	loff_t offset = iocb->ki_pos;
36cf66ed9f871 (Maxim Patlasov          2012-12-14 19:20:51 +0400 2800) 	struct fuse_io_priv *io;
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 2801) 
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 2802) 	pos = offset;
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2803) 	inode = file->f_mapping->host;
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2804) 	i_size = i_size_read(inode);
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 2805) 
933a3752babcf (Al Viro                 2020-09-17 17:26:56 -0400 2806) 	if ((iov_iter_rw(iter) == READ) && (offset >= i_size))
9fe55eea7e4b4 (Steven Whitehouse       2014-01-24 14:42:22 +0000 2807) 		return 0;
9fe55eea7e4b4 (Steven Whitehouse       2014-01-24 14:42:22 +0000 2808) 
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2809) 	io = kmalloc(sizeof(struct fuse_io_priv), GFP_KERNEL);
36cf66ed9f871 (Maxim Patlasov          2012-12-14 19:20:51 +0400 2810) 	if (!io)
36cf66ed9f871 (Maxim Patlasov          2012-12-14 19:20:51 +0400 2811) 		return -ENOMEM;
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2812) 	spin_lock_init(&io->lock);
744742d692e37 (Seth Forshee            2016-03-11 10:35:34 -0600 2813) 	kref_init(&io->refcnt);
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2814) 	io->reqs = 1;
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2815) 	io->bytes = -1;
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2816) 	io->size = 0;
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2817) 	io->offset = offset;
6f67376318abe (Omar Sandoval           2015-03-16 04:33:52 -0700 2818) 	io->write = (iov_iter_rw(iter) == WRITE);
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2819) 	io->err = 0;
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2820) 	/*
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2821) 	 * By default, we want to optimize all I/Os with async request
60b9df7a54804 (Miklos Szeredi          2013-05-01 14:37:21 +0200 2822) 	 * submission to the client filesystem if supported.
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2823) 	 */
694565356c2e0 (Linus Torvalds          2020-10-19 14:28:30 -0700 2824) 	io->async = ff->fm->fc->async_dio;
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2825) 	io->iocb = iocb;
7879c4e58b7c8 (Ashish Sangwan          2016-04-07 17:18:11 +0530 2826) 	io->blocking = is_sync_kiocb(iocb);
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2827) 
933a3752babcf (Al Viro                 2020-09-17 17:26:56 -0400 2828) 	/* optimization for short read */
933a3752babcf (Al Viro                 2020-09-17 17:26:56 -0400 2829) 	if (io->async && !io->write && offset + count > i_size) {
694565356c2e0 (Linus Torvalds          2020-10-19 14:28:30 -0700 2830) 		iov_iter_truncate(iter, fuse_round_up(ff->fm->fc, i_size - offset));
933a3752babcf (Al Viro                 2020-09-17 17:26:56 -0400 2831) 		shortened = count - iov_iter_count(iter);
933a3752babcf (Al Viro                 2020-09-17 17:26:56 -0400 2832) 		count -= shortened;
933a3752babcf (Al Viro                 2020-09-17 17:26:56 -0400 2833) 	}
933a3752babcf (Al Viro                 2020-09-17 17:26:56 -0400 2834) 
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2835) 	/*
7879c4e58b7c8 (Ashish Sangwan          2016-04-07 17:18:11 +0530 2836) 	 * We cannot asynchronously extend the size of a file.
7879c4e58b7c8 (Ashish Sangwan          2016-04-07 17:18:11 +0530 2837) 	 * In such case the aio will behave exactly like sync io.
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2838) 	 */
933a3752babcf (Al Viro                 2020-09-17 17:26:56 -0400 2839) 	if ((offset + count > i_size) && io->write)
7879c4e58b7c8 (Ashish Sangwan          2016-04-07 17:18:11 +0530 2840) 		io->blocking = true;
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 2841) 
7879c4e58b7c8 (Ashish Sangwan          2016-04-07 17:18:11 +0530 2842) 	if (io->async && io->blocking) {
744742d692e37 (Seth Forshee            2016-03-11 10:35:34 -0600 2843) 		/*
744742d692e37 (Seth Forshee            2016-03-11 10:35:34 -0600 2844) 		 * Additional reference to keep io around after
744742d692e37 (Seth Forshee            2016-03-11 10:35:34 -0600 2845) 		 * calling fuse_aio_complete()
744742d692e37 (Seth Forshee            2016-03-11 10:35:34 -0600 2846) 		 */
744742d692e37 (Seth Forshee            2016-03-11 10:35:34 -0600 2847) 		kref_get(&io->refcnt);
9d5722b7777e6 (Christoph Hellwig       2015-02-02 14:59:43 +0100 2848) 		io->done = &wait;
744742d692e37 (Seth Forshee            2016-03-11 10:35:34 -0600 2849) 	}
9d5722b7777e6 (Christoph Hellwig       2015-02-02 14:59:43 +0100 2850) 
6f67376318abe (Omar Sandoval           2015-03-16 04:33:52 -0700 2851) 	if (iov_iter_rw(iter) == WRITE) {
6b775b18eecf6 (Al Viro                 2015-04-07 15:06:19 -0400 2852) 		ret = fuse_direct_io(io, iter, &pos, FUSE_DIO_WRITE);
812408fb51ef5 (Al Viro                 2015-03-30 22:15:58 -0400 2853) 		fuse_invalidate_attr(inode);
812408fb51ef5 (Al Viro                 2015-03-30 22:15:58 -0400 2854) 	} else {
d22a943f44c79 (Al Viro                 2014-03-16 15:50:47 -0400 2855) 		ret = __fuse_direct_read(io, iter, &pos);
812408fb51ef5 (Al Viro                 2015-03-30 22:15:58 -0400 2856) 	}
933a3752babcf (Al Viro                 2020-09-17 17:26:56 -0400 2857) 	iov_iter_reexpand(iter, iov_iter_count(iter) + shortened);
36cf66ed9f871 (Maxim Patlasov          2012-12-14 19:20:51 +0400 2858) 
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2859) 	if (io->async) {
ebacb81273599 (Lukas Czerner           2018-11-09 14:51:46 +0100 2860) 		bool blocking = io->blocking;
ebacb81273599 (Lukas Czerner           2018-11-09 14:51:46 +0100 2861) 
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2862) 		fuse_aio_complete(io, ret < 0 ? ret : 0, -1);
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2863) 
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2864) 		/* we have a non-extending, async request, so return */
ebacb81273599 (Lukas Czerner           2018-11-09 14:51:46 +0100 2865) 		if (!blocking)
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2866) 			return -EIOCBQUEUED;
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2867) 
9d5722b7777e6 (Christoph Hellwig       2015-02-02 14:59:43 +0100 2868) 		wait_for_completion(&wait);
9d5722b7777e6 (Christoph Hellwig       2015-02-02 14:59:43 +0100 2869) 		ret = fuse_get_res_by_io(io);
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2870) 	}
bcba24ccdc82f (Maxim Patlasov          2012-12-14 19:21:08 +0400 2871) 
744742d692e37 (Seth Forshee            2016-03-11 10:35:34 -0600 2872) 	kref_put(&io->refcnt, fuse_io_release);
9d5722b7777e6 (Christoph Hellwig       2015-02-02 14:59:43 +0100 2873) 
6f67376318abe (Omar Sandoval           2015-03-16 04:33:52 -0700 2874) 	if (iov_iter_rw(iter) == WRITE) {
efb9fa9e911b2 (Maxim Patlasov          2012-12-18 14:05:08 +0400 2875) 		if (ret > 0)
efb9fa9e911b2 (Maxim Patlasov          2012-12-18 14:05:08 +0400 2876) 			fuse_write_update_size(inode, pos);
efb9fa9e911b2 (Maxim Patlasov          2012-12-18 14:05:08 +0400 2877) 		else if (ret < 0 && offset + count > i_size)
efb9fa9e911b2 (Maxim Patlasov          2012-12-18 14:05:08 +0400 2878) 			fuse_do_truncate(file);
efb9fa9e911b2 (Maxim Patlasov          2012-12-18 14:05:08 +0400 2879) 	}
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 2880) 
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 2881) 	return ret;
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 2882) }
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 2883) 
26eb3bae50035 (Miklos Szeredi          2019-05-28 13:22:50 +0200 2884) static int fuse_writeback_range(struct inode *inode, loff_t start, loff_t end)
26eb3bae50035 (Miklos Szeredi          2019-05-28 13:22:50 +0200 2885) {
26eb3bae50035 (Miklos Szeredi          2019-05-28 13:22:50 +0200 2886) 	int err = filemap_write_and_wait_range(inode->i_mapping, start, end);
26eb3bae50035 (Miklos Szeredi          2019-05-28 13:22:50 +0200 2887) 
26eb3bae50035 (Miklos Szeredi          2019-05-28 13:22:50 +0200 2888) 	if (!err)
26eb3bae50035 (Miklos Szeredi          2019-05-28 13:22:50 +0200 2889) 		fuse_sync_writes(inode);
26eb3bae50035 (Miklos Szeredi          2019-05-28 13:22:50 +0200 2890) 
26eb3bae50035 (Miklos Szeredi          2019-05-28 13:22:50 +0200 2891) 	return err;
26eb3bae50035 (Miklos Szeredi          2019-05-28 13:22:50 +0200 2892) }
26eb3bae50035 (Miklos Szeredi          2019-05-28 13:22:50 +0200 2893) 
cdadb11cef180 (Miklos Szeredi          2012-11-10 16:55:56 +0100 2894) static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
cdadb11cef180 (Miklos Szeredi          2012-11-10 16:55:56 +0100 2895) 				loff_t length)
05ba1f0823004 (Anatol Pomozov          2012-04-22 18:45:24 -0700 2896) {
05ba1f0823004 (Anatol Pomozov          2012-04-22 18:45:24 -0700 2897) 	struct fuse_file *ff = file->private_data;
1c68271cf1bfe (Miklos Szeredi          2014-12-12 10:04:51 +0100 2898) 	struct inode *inode = file_inode(file);
0ab08f576b9e6 (Maxim Patlasov          2013-09-13 19:20:16 +0400 2899) 	struct fuse_inode *fi = get_fuse_inode(inode);
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2900) 	struct fuse_mount *fm = ff->fm;
7078187a795f8 (Miklos Szeredi          2014-12-12 09:49:05 +0100 2901) 	FUSE_ARGS(args);
05ba1f0823004 (Anatol Pomozov          2012-04-22 18:45:24 -0700 2902) 	struct fuse_fallocate_in inarg = {
05ba1f0823004 (Anatol Pomozov          2012-04-22 18:45:24 -0700 2903) 		.fh = ff->fh,
05ba1f0823004 (Anatol Pomozov          2012-04-22 18:45:24 -0700 2904) 		.offset = offset,
05ba1f0823004 (Anatol Pomozov          2012-04-22 18:45:24 -0700 2905) 		.length = length,
05ba1f0823004 (Anatol Pomozov          2012-04-22 18:45:24 -0700 2906) 		.mode = mode
05ba1f0823004 (Anatol Pomozov          2012-04-22 18:45:24 -0700 2907) 	};
05ba1f0823004 (Anatol Pomozov          2012-04-22 18:45:24 -0700 2908) 	int err;
14c14414d157e (Maxim Patlasov          2013-06-13 12:16:39 +0400 2909) 	bool lock_inode = !(mode & FALLOC_FL_KEEP_SIZE) ||
14c14414d157e (Maxim Patlasov          2013-06-13 12:16:39 +0400 2910) 			   (mode & FALLOC_FL_PUNCH_HOLE);
05ba1f0823004 (Anatol Pomozov          2012-04-22 18:45:24 -0700 2911) 
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400 2912) 	bool block_faults = FUSE_IS_DAX(inode) && lock_inode;
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400 2913) 
4adb83029de8e (Miklos Szeredi          2014-04-28 14:19:21 +0200 2914) 	if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
4adb83029de8e (Miklos Szeredi          2014-04-28 14:19:21 +0200 2915) 		return -EOPNOTSUPP;
4adb83029de8e (Miklos Szeredi          2014-04-28 14:19:21 +0200 2916) 
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2917) 	if (fm->fc->no_fallocate)
519c6040ce044 (Miklos Szeredi          2012-04-26 10:56:36 +0200 2918) 		return -EOPNOTSUPP;
519c6040ce044 (Miklos Szeredi          2012-04-26 10:56:36 +0200 2919) 
14c14414d157e (Maxim Patlasov          2013-06-13 12:16:39 +0400 2920) 	if (lock_inode) {
5955102c9984f (Al Viro                 2016-01-22 15:40:57 -0500 2921) 		inode_lock(inode);
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400 2922) 		if (block_faults) {
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400 2923) 			down_write(&fi->i_mmap_sem);
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400 2924) 			err = fuse_dax_break_layouts(inode, 0, 0);
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400 2925) 			if (err)
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400 2926) 				goto out;
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400 2927) 		}
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400 2928) 
bde52788bdb75 (Maxim Patlasov          2013-09-13 19:19:54 +0400 2929) 		if (mode & FALLOC_FL_PUNCH_HOLE) {
bde52788bdb75 (Maxim Patlasov          2013-09-13 19:19:54 +0400 2930) 			loff_t endbyte = offset + length - 1;
26eb3bae50035 (Miklos Szeredi          2019-05-28 13:22:50 +0200 2931) 
26eb3bae50035 (Miklos Szeredi          2019-05-28 13:22:50 +0200 2932) 			err = fuse_writeback_range(inode, offset, endbyte);
bde52788bdb75 (Maxim Patlasov          2013-09-13 19:19:54 +0400 2933) 			if (err)
bde52788bdb75 (Maxim Patlasov          2013-09-13 19:19:54 +0400 2934) 				goto out;
bde52788bdb75 (Maxim Patlasov          2013-09-13 19:19:54 +0400 2935) 		}
3634a6327815d (Brian Foster            2013-05-17 09:30:32 -0400 2936) 	}
3634a6327815d (Brian Foster            2013-05-17 09:30:32 -0400 2937) 
0cbade024ba50 (Liu Bo                  2019-04-18 04:04:41 +0800 2938) 	if (!(mode & FALLOC_FL_KEEP_SIZE) &&
0cbade024ba50 (Liu Bo                  2019-04-18 04:04:41 +0800 2939) 	    offset + length > i_size_read(inode)) {
0cbade024ba50 (Liu Bo                  2019-04-18 04:04:41 +0800 2940) 		err = inode_newsize_ok(inode, offset + length);
0cbade024ba50 (Liu Bo                  2019-04-18 04:04:41 +0800 2941) 		if (err)
35d6fcbb7c3e2 (Miklos Szeredi          2019-05-27 11:42:07 +0200 2942) 			goto out;
0cbade024ba50 (Liu Bo                  2019-04-18 04:04:41 +0800 2943) 	}
0cbade024ba50 (Liu Bo                  2019-04-18 04:04:41 +0800 2944) 
0ab08f576b9e6 (Maxim Patlasov          2013-09-13 19:20:16 +0400 2945) 	if (!(mode & FALLOC_FL_KEEP_SIZE))
0ab08f576b9e6 (Maxim Patlasov          2013-09-13 19:20:16 +0400 2946) 		set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
0ab08f576b9e6 (Maxim Patlasov          2013-09-13 19:20:16 +0400 2947) 
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2948) 	args.opcode = FUSE_FALLOCATE;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2949) 	args.nodeid = ff->nodeid;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2950) 	args.in_numargs = 1;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2951) 	args.in_args[0].size = sizeof(inarg);
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 2952) 	args.in_args[0].value = &inarg;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2953) 	err = fuse_simple_request(fm, &args);
519c6040ce044 (Miklos Szeredi          2012-04-26 10:56:36 +0200 2954) 	if (err == -ENOSYS) {
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2955) 		fm->fc->no_fallocate = 1;
519c6040ce044 (Miklos Szeredi          2012-04-26 10:56:36 +0200 2956) 		err = -EOPNOTSUPP;
519c6040ce044 (Miklos Szeredi          2012-04-26 10:56:36 +0200 2957) 	}
bee6c307800bb (Brian Foster            2013-05-17 15:27:34 -0400 2958) 	if (err)
bee6c307800bb (Brian Foster            2013-05-17 15:27:34 -0400 2959) 		goto out;
bee6c307800bb (Brian Foster            2013-05-17 15:27:34 -0400 2960) 
bee6c307800bb (Brian Foster            2013-05-17 15:27:34 -0400 2961) 	/* we could have extended the file */
b0aa760652179 (Maxim Patlasov          2013-12-26 19:51:11 +0400 2962) 	if (!(mode & FALLOC_FL_KEEP_SIZE)) {
b0aa760652179 (Maxim Patlasov          2013-12-26 19:51:11 +0400 2963) 		bool changed = fuse_write_update_size(inode, offset + length);
b0aa760652179 (Maxim Patlasov          2013-12-26 19:51:11 +0400 2964) 
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2965) 		if (changed && fm->fc->writeback_cache)
93d2269d2ffb8 (Miklos Szeredi          2014-04-28 14:19:22 +0200 2966) 			file_update_time(file);
b0aa760652179 (Maxim Patlasov          2013-12-26 19:51:11 +0400 2967) 	}
bee6c307800bb (Brian Foster            2013-05-17 15:27:34 -0400 2968) 
bee6c307800bb (Brian Foster            2013-05-17 15:27:34 -0400 2969) 	if (mode & FALLOC_FL_PUNCH_HOLE)
bee6c307800bb (Brian Foster            2013-05-17 15:27:34 -0400 2970) 		truncate_pagecache_range(inode, offset, offset + length - 1);
bee6c307800bb (Brian Foster            2013-05-17 15:27:34 -0400 2971) 
bee6c307800bb (Brian Foster            2013-05-17 15:27:34 -0400 2972) 	fuse_invalidate_attr(inode);
bee6c307800bb (Brian Foster            2013-05-17 15:27:34 -0400 2973) 
3634a6327815d (Brian Foster            2013-05-17 09:30:32 -0400 2974) out:
0ab08f576b9e6 (Maxim Patlasov          2013-09-13 19:20:16 +0400 2975) 	if (!(mode & FALLOC_FL_KEEP_SIZE))
0ab08f576b9e6 (Maxim Patlasov          2013-09-13 19:20:16 +0400 2976) 		clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
0ab08f576b9e6 (Maxim Patlasov          2013-09-13 19:20:16 +0400 2977) 
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400 2978) 	if (block_faults)
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400 2979) 		up_write(&fi->i_mmap_sem);
6ae330cad6ef2 (Vivek Goyal             2020-08-19 18:19:54 -0400 2980) 
bde52788bdb75 (Maxim Patlasov          2013-09-13 19:19:54 +0400 2981) 	if (lock_inode)
5955102c9984f (Al Viro                 2016-01-22 15:40:57 -0500 2982) 		inode_unlock(inode);
3634a6327815d (Brian Foster            2013-05-17 09:30:32 -0400 2983) 
05ba1f0823004 (Anatol Pomozov          2012-04-22 18:45:24 -0700 2984) 	return err;
05ba1f0823004 (Anatol Pomozov          2012-04-22 18:45:24 -0700 2985) }
05ba1f0823004 (Anatol Pomozov          2012-04-22 18:45:24 -0700 2986) 
64bf5ff58dff7 (Dave Chinner            2019-06-05 08:04:47 -0700 2987) static ssize_t __fuse_copy_file_range(struct file *file_in, loff_t pos_in,
64bf5ff58dff7 (Dave Chinner            2019-06-05 08:04:47 -0700 2988) 				      struct file *file_out, loff_t pos_out,
64bf5ff58dff7 (Dave Chinner            2019-06-05 08:04:47 -0700 2989) 				      size_t len, unsigned int flags)
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 2990) {
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 2991) 	struct fuse_file *ff_in = file_in->private_data;
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 2992) 	struct fuse_file *ff_out = file_out->private_data;
a2bc923629410 (Miklos Szeredi          2019-05-28 13:22:50 +0200 2993) 	struct inode *inode_in = file_inode(file_in);
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 2994) 	struct inode *inode_out = file_inode(file_out);
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 2995) 	struct fuse_inode *fi_out = get_fuse_inode(inode_out);
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2996) 	struct fuse_mount *fm = ff_in->fm;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 2997) 	struct fuse_conn *fc = fm->fc;
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 2998) 	FUSE_ARGS(args);
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 2999) 	struct fuse_copy_file_range_in inarg = {
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3000) 		.fh_in = ff_in->fh,
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3001) 		.off_in = pos_in,
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3002) 		.nodeid_out = ff_out->nodeid,
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3003) 		.fh_out = ff_out->fh,
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3004) 		.off_out = pos_out,
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3005) 		.len = len,
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3006) 		.flags = flags
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3007) 	};
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3008) 	struct fuse_write_out outarg;
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3009) 	ssize_t err;
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3010) 	/* mark unstable when write-back is not used, and file_out gets
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3011) 	 * extended */
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3012) 	bool is_unstable = (!fc->writeback_cache) &&
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3013) 			   ((pos_out + len) > inode_out->i_size);
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3014) 
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3015) 	if (fc->no_copy_file_range)
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3016) 		return -EOPNOTSUPP;
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3017) 
5dae222a5ff0c (Amir Goldstein          2019-06-05 08:04:50 -0700 3018) 	if (file_inode(file_in)->i_sb != file_inode(file_out)->i_sb)
5dae222a5ff0c (Amir Goldstein          2019-06-05 08:04:50 -0700 3019) 		return -EXDEV;
5dae222a5ff0c (Amir Goldstein          2019-06-05 08:04:50 -0700 3020) 
2c4656dfd9945 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3021) 	inode_lock(inode_in);
2c4656dfd9945 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3022) 	err = fuse_writeback_range(inode_in, pos_in, pos_in + len - 1);
2c4656dfd9945 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3023) 	inode_unlock(inode_in);
2c4656dfd9945 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3024) 	if (err)
2c4656dfd9945 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3025) 		return err;
a2bc923629410 (Miklos Szeredi          2019-05-28 13:22:50 +0200 3026) 
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3027) 	inode_lock(inode_out);
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3028) 
fe0da9c09b2dc (Amir Goldstein          2019-06-05 08:04:51 -0700 3029) 	err = file_modified(file_out);
fe0da9c09b2dc (Amir Goldstein          2019-06-05 08:04:51 -0700 3030) 	if (err)
fe0da9c09b2dc (Amir Goldstein          2019-06-05 08:04:51 -0700 3031) 		goto out;
fe0da9c09b2dc (Amir Goldstein          2019-06-05 08:04:51 -0700 3032) 
9b46418c40fe9 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3033) 	/*
9b46418c40fe9 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3034) 	 * Write out dirty pages in the destination file before sending the COPY
9b46418c40fe9 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3035) 	 * request to userspace.  After the request is completed, truncate off
9b46418c40fe9 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3036) 	 * pages (including partial ones) from the cache that have been copied,
9b46418c40fe9 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3037) 	 * since these contain stale data at that point.
9b46418c40fe9 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3038) 	 *
9b46418c40fe9 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3039) 	 * This should be mostly correct, but if the COPY writes to partial
9b46418c40fe9 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3040) 	 * pages (at the start or end) and the parts not covered by the COPY are
9b46418c40fe9 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3041) 	 * written through a memory map after calling fuse_writeback_range(),
9b46418c40fe9 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3042) 	 * then these partial page modifications will be lost on truncation.
9b46418c40fe9 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3043) 	 *
9b46418c40fe9 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3044) 	 * It is unlikely that someone would rely on such mixed style
9b46418c40fe9 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3045) 	 * modifications.  Yet this does give less guarantees than if the
9b46418c40fe9 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3046) 	 * copying was performed with write(2).
9b46418c40fe9 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3047) 	 *
9b46418c40fe9 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3048) 	 * To fix this a i_mmap_sem style lock could be used to prevent new
9b46418c40fe9 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3049) 	 * faults while the copy is ongoing.
9b46418c40fe9 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3050) 	 */
2c4656dfd9945 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3051) 	err = fuse_writeback_range(inode_out, pos_out, pos_out + len - 1);
2c4656dfd9945 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3052) 	if (err)
2c4656dfd9945 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3053) 		goto out;
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3054) 
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3055) 	if (is_unstable)
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3056) 		set_bit(FUSE_I_SIZE_UNSTABLE, &fi_out->state);
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3057) 
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 3058) 	args.opcode = FUSE_COPY_FILE_RANGE;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 3059) 	args.nodeid = ff_in->nodeid;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 3060) 	args.in_numargs = 1;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 3061) 	args.in_args[0].size = sizeof(inarg);
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 3062) 	args.in_args[0].value = &inarg;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 3063) 	args.out_numargs = 1;
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 3064) 	args.out_args[0].size = sizeof(outarg);
d5b4854357f47 (Miklos Szeredi          2019-09-10 15:04:08 +0200 3065) 	args.out_args[0].value = &outarg;
fcee216beb9c1 (Max Reitz               2020-05-06 17:44:12 +0200 3066) 	err = fuse_simple_request(fm, &args);
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3067) 	if (err == -ENOSYS) {
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3068) 		fc->no_copy_file_range = 1;
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3069) 		err = -EOPNOTSUPP;
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3070) 	}
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3071) 	if (err)
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3072) 		goto out;
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3073) 
9b46418c40fe9 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3074) 	truncate_inode_pages_range(inode_out->i_mapping,
9b46418c40fe9 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3075) 				   ALIGN_DOWN(pos_out, PAGE_SIZE),
9b46418c40fe9 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3076) 				   ALIGN(pos_out + outarg.size, PAGE_SIZE) - 1);
9b46418c40fe9 (Miklos Szeredi          2020-05-20 11:39:35 +0200 3077) 
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3078) 	if (fc->writeback_cache) {
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3079) 		fuse_write_update_size(inode_out, pos_out + outarg.size);
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3080) 		file_update_time(file_out);
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3081) 	}
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3082) 
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3083) 	fuse_invalidate_attr(inode_out);
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3084) 
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3085) 	err = outarg.size;
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3086) out:
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3087) 	if (is_unstable)
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3088) 		clear_bit(FUSE_I_SIZE_UNSTABLE, &fi_out->state);
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3089) 
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3090) 	inode_unlock(inode_out);
fe0da9c09b2dc (Amir Goldstein          2019-06-05 08:04:51 -0700 3091) 	file_accessed(file_in);
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3092) 
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3093) 	return err;
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3094) }
88bc7d5097a11 (Niels de Vos            2018-08-21 14:36:31 +0200 3095) 
64bf5ff58dff7 (Dave Chinner            2019-06-05 08:04:47 -0700 3096) static ssize_t fuse_copy_file_range(struct file *src_file, loff_t src_off,
64bf5ff58dff7 (Dave Chinner            2019-06-05 08:04:47 -0700 3097) 				    struct file *dst_file, loff_t dst_off,
64bf5ff58dff7 (Dave Chinner            2019-06-05 08:04:47 -0700 3098) 				    size_t len, unsigned int flags)
64bf5ff58dff7 (Dave Chinner            2019-06-05 08:04:47 -0700 3099) {
64bf5ff58dff7 (Dave Chinner            2019-06-05 08:04:47 -0700 3100) 	ssize_t ret;
64bf5ff58dff7 (Dave Chinner            2019-06-05 08:04:47 -0700 3101) 
64bf5ff58dff7 (Dave Chinner            2019-06-05 08:04:47 -0700 3102) 	ret = __fuse_copy_file_range(src_file, src_off, dst_file, dst_off,
64bf5ff58dff7 (Dave Chinner            2019-06-05 08:04:47 -0700 3103) 				     len, flags);
64bf5ff58dff7 (Dave Chinner            2019-06-05 08:04:47 -0700 3104) 
5dae222a5ff0c (Amir Goldstein          2019-06-05 08:04:50 -0700 3105) 	if (ret == -EOPNOTSUPP || ret == -EXDEV)
64bf5ff58dff7 (Dave Chinner            2019-06-05 08:04:47 -0700 3106) 		ret = generic_copy_file_range(src_file, src_off, dst_file,
64bf5ff58dff7 (Dave Chinner            2019-06-05 08:04:47 -0700 3107) 					      dst_off, len, flags);
64bf5ff58dff7 (Dave Chinner            2019-06-05 08:04:47 -0700 3108) 	return ret;
64bf5ff58dff7 (Dave Chinner            2019-06-05 08:04:47 -0700 3109) }
64bf5ff58dff7 (Dave Chinner            2019-06-05 08:04:47 -0700 3110) 
4b6f5d20b04dc (Arjan van de Ven        2006-03-28 01:56:42 -0800 3111) static const struct file_operations fuse_file_operations = {
5559b8f4d1f63 (Miklos Szeredi          2008-04-30 00:54:45 -0700 3112) 	.llseek		= fuse_file_llseek,
37c20f16e7a73 (Al Viro                 2014-04-02 14:47:09 -0400 3113) 	.read_iter	= fuse_file_read_iter,
84c3d55cc474f (Al Viro                 2014-04-03 14:33:23 -0400 3114) 	.write_iter	= fuse_file_write_iter,
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700 3115) 	.mmap		= fuse_file_mmap,
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700 3116) 	.open		= fuse_open,
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700 3117) 	.flush		= fuse_flush,
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700 3118) 	.release	= fuse_release,
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700 3119) 	.fsync		= fuse_fsync,
7142125937e14 (Miklos Szeredi          2006-06-25 05:48:52 -0700 3120) 	.lock		= fuse_file_lock,
2a9a609a0c4a3 (Stefan Hajnoczi         2020-08-19 18:19:52 -0400 3121) 	.get_unmapped_area = thp_get_unmapped_area,
a9ff4f87056cd (Miklos Szeredi          2007-10-18 03:07:02 -0700 3122) 	.flock		= fuse_file_flock,
3c3db095b68c5 (Miklos Szeredi          2019-01-24 10:40:17 +0100 3123) 	.splice_read	= generic_file_splice_read,
3c3db095b68c5 (Miklos Szeredi          2019-01-24 10:40:17 +0100 3124) 	.splice_write	= iter_file_splice_write,
59efec7b90398 (Tejun Heo               2008-11-26 12:03:55 +0100 3125) 	.unlocked_ioctl	= fuse_file_ioctl,
59efec7b90398 (Tejun Heo               2008-11-26 12:03:55 +0100 3126) 	.compat_ioctl	= fuse_file_compat_ioctl,
95668a69a4bb8 (Tejun Heo               2008-11-26 12:03:55 +0100 3127) 	.poll		= fuse_file_poll,
05ba1f0823004 (Anatol Pomozov          2012-04-22 18:45:24 -0700 3128) 	.fallocate	= fuse_file_fallocate,
d4136d60751a5 (Miklos Szeredi          2019-01-24 10:40:17 +0100 3129) 	.copy_file_range = fuse_copy_file_range,
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 3130) };
413ef8cb30251 (Miklos Szeredi          2005-09-09 13:10:35 -0700 3131) 
f5e54d6e53a20 (Christoph Hellwig       2006-06-28 04:26:44 -0700 3132) static const struct address_space_operations fuse_file_aops  = {
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700 3133) 	.readpage	= fuse_readpage,
76a0294eb19b5 (Matthew Wilcox (Oracle) 2020-06-01 21:47:31 -0700 3134) 	.readahead	= fuse_readahead,
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 3135) 	.writepage	= fuse_writepage,
26d614df1da9d (Pavel Emelyanov         2013-06-29 21:45:29 +0400 3136) 	.writepages	= fuse_writepages,
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 3137) 	.launder_page	= fuse_launder_page,
3be5a52b30aa5 (Miklos Szeredi          2008-04-30 00:54:41 -0700 3138) 	.set_page_dirty	= __set_page_dirty_nobuffers,
b2d2272fae1e1 (Miklos Szeredi          2006-12-06 20:35:51 -0800 3139) 	.bmap		= fuse_bmap,
4273b793ec687 (Anand Avati             2012-02-17 12:46:25 -0500 3140) 	.direct_IO	= fuse_direct_IO,
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 3141) 	.write_begin	= fuse_write_begin,
6b12c1b37e555 (Pavel Emelyanov         2013-10-10 17:11:43 +0400 3142) 	.write_end	= fuse_write_end,
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700 3143) };
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700 3144) 
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700 3145) void fuse_init_file_inode(struct inode *inode)
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700 3146) {
ab2257e9941b9 (Miklos Szeredi          2018-10-01 10:07:05 +0200 3147) 	struct fuse_inode *fi = get_fuse_inode(inode);
ab2257e9941b9 (Miklos Szeredi          2018-10-01 10:07:05 +0200 3148) 
45323fb76465a (Miklos Szeredi          2005-09-09 13:10:37 -0700 3149) 	inode->i_fop = &fuse_file_operations;
45323fb76465a (Miklos Szeredi          2005-09-09 13:10:37 -0700 3150) 	inode->i_data.a_ops = &fuse_file_aops;
ab2257e9941b9 (Miklos Szeredi          2018-10-01 10:07:05 +0200 3151) 
ab2257e9941b9 (Miklos Szeredi          2018-10-01 10:07:05 +0200 3152) 	INIT_LIST_HEAD(&fi->write_files);
ab2257e9941b9 (Miklos Szeredi          2018-10-01 10:07:05 +0200 3153) 	INIT_LIST_HEAD(&fi->queued_writes);
ab2257e9941b9 (Miklos Szeredi          2018-10-01 10:07:05 +0200 3154) 	fi->writectr = 0;
ab2257e9941b9 (Miklos Szeredi          2018-10-01 10:07:05 +0200 3155) 	init_waitqueue_head(&fi->page_waitq);
6b2fb79963fbe (Maxim Patlasov          2019-09-19 17:11:20 +0300 3156) 	fi->writepages = RB_ROOT;
c2d0ad00d948d (Vivek Goyal             2020-08-19 18:19:51 -0400 3157) 
c2d0ad00d948d (Vivek Goyal             2020-08-19 18:19:51 -0400 3158) 	if (IS_ENABLED(CONFIG_FUSE_DAX))
c2d0ad00d948d (Vivek Goyal             2020-08-19 18:19:51 -0400 3159) 		fuse_dax_inode_init(inode);
b6aeadeda22a9 (Miklos Szeredi          2005-09-09 13:10:30 -0700 3160) }