VisionFive2 Linux kernel

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

More than 9999 Commits   32 Branches   54 Tags
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700    1) /*
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -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>
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700    4) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700    5)   This program can be distributed under the terms of the GNU GPL.
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700    6)   See the file COPYING.
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700    7) */
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700    8) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700    9) #include "fuse_i.h"
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   10) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   11) #include <linux/init.h>
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   12) #include <linux/module.h>
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   13) #include <linux/poll.h>
174cd4b1e5fbd (Ingo Molnar           2017-02-02 19:15:33 +0100   14) #include <linux/sched/signal.h>
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   15) #include <linux/uio.h>
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   16) #include <linux/miscdevice.h>
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   17) #include <linux/pagemap.h>
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   18) #include <linux/file.h>
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   19) #include <linux/slab.h>
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200   20) #include <linux/pipe_fs_i.h>
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200   21) #include <linux/swap.h>
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200   22) #include <linux/splice.h>
0b6e9ea041e6c (Seth Forshee          2014-07-02 16:29:19 -0500   23) #include <linux/sched.h>
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   24) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   25) MODULE_ALIAS_MISCDEV(FUSE_MINOR);
578454ff7eab6 (Kay Sievers           2010-05-20 18:07:20 +0200   26) MODULE_ALIAS("devname:fuse");
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   27) 
c59fd85e4fd07 (Kirill Tkhai          2018-09-11 13:11:56 +0300   28) /* Ordinary requests have even IDs, while interrupts IDs are odd */
c59fd85e4fd07 (Kirill Tkhai          2018-09-11 13:11:56 +0300   29) #define FUSE_INT_REQ_BIT (1ULL << 0)
c59fd85e4fd07 (Kirill Tkhai          2018-09-11 13:11:56 +0300   30) #define FUSE_REQ_ID_STEP (1ULL << 1)
c59fd85e4fd07 (Kirill Tkhai          2018-09-11 13:11:56 +0300   31) 
e18b890bb0881 (Christoph Lameter     2006-12-06 20:33:20 -0800   32) static struct kmem_cache *fuse_req_cachep;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   33) 
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200   34) static struct fuse_dev *fuse_get_dev(struct file *file)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   35) {
0720b31597644 (Miklos Szeredi        2006-04-10 22:54:55 -0700   36) 	/*
0720b31597644 (Miklos Szeredi        2006-04-10 22:54:55 -0700   37) 	 * Lockless access is OK, because file->private data is set
0720b31597644 (Miklos Szeredi        2006-04-10 22:54:55 -0700   38) 	 * once during mount and is valid until the file is released.
0720b31597644 (Miklos Szeredi        2006-04-10 22:54:55 -0700   39) 	 */
6aa7de059173a (Mark Rutland          2017-10-23 14:07:29 -0700   40) 	return READ_ONCE(file->private_data);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   41) }
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   42) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200   43) static void fuse_request_init(struct fuse_mount *fm, struct fuse_req *req)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   44) {
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   45) 	INIT_LIST_HEAD(&req->list);
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700   46) 	INIT_LIST_HEAD(&req->intr_entry);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   47) 	init_waitqueue_head(&req->waitq);
ec99f6d31f259 (Elena Reshetova       2017-03-03 11:04:04 +0200   48) 	refcount_set(&req->count, 1);
33e14b4dfdc47 (Miklos Szeredi        2015-07-01 16:26:01 +0200   49) 	__set_bit(FR_PENDING, &req->flags);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200   50) 	req->fm = fm;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   51) }
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   52) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200   53) static struct fuse_req *fuse_request_alloc(struct fuse_mount *fm, gfp_t flags)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   54) {
8a7aa286ab67d (Miklos Szeredi        2018-10-01 10:07:05 +0200   55) 	struct fuse_req *req = kmem_cache_zalloc(fuse_req_cachep, flags);
7213394c4e184 (Miklos Szeredi        2019-09-10 15:04:11 +0200   56) 	if (req)
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200   57) 		fuse_request_init(fm, req);
4250c0668ea10 (Maxim Patlasov        2012-10-26 19:48:07 +0400   58) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   59) 	return req;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   60) }
4250c0668ea10 (Maxim Patlasov        2012-10-26 19:48:07 +0400   61) 
66abc3599c3c8 (Miklos Szeredi        2019-09-10 15:04:11 +0200   62) static void fuse_request_free(struct fuse_req *req)
e52a8250480ac (Miklos Szeredi        2018-10-01 10:07:06 +0200   63) {
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   64) 	kmem_cache_free(fuse_req_cachep, req);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   65) }
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   66) 
66abc3599c3c8 (Miklos Szeredi        2019-09-10 15:04:11 +0200   67) static void __fuse_get_request(struct fuse_req *req)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   68) {
ec99f6d31f259 (Elena Reshetova       2017-03-03 11:04:04 +0200   69) 	refcount_inc(&req->count);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   70) }
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   71) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   72) /* Must be called with > 1 refcount */
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   73) static void __fuse_put_request(struct fuse_req *req)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   74) {
ec99f6d31f259 (Elena Reshetova       2017-03-03 11:04:04 +0200   75) 	refcount_dec(&req->count);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   76) }
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700   77) 
9759bd5189945 (Miklos Szeredi        2015-01-06 10:45:35 +0100   78) void fuse_set_initialized(struct fuse_conn *fc)
9759bd5189945 (Miklos Szeredi        2015-01-06 10:45:35 +0100   79) {
9759bd5189945 (Miklos Szeredi        2015-01-06 10:45:35 +0100   80) 	/* Make sure stores before this are seen on another CPU */
9759bd5189945 (Miklos Szeredi        2015-01-06 10:45:35 +0100   81) 	smp_wmb();
9759bd5189945 (Miklos Szeredi        2015-01-06 10:45:35 +0100   82) 	fc->initialized = 1;
9759bd5189945 (Miklos Szeredi        2015-01-06 10:45:35 +0100   83) }
9759bd5189945 (Miklos Szeredi        2015-01-06 10:45:35 +0100   84) 
0aada88476a33 (Maxim Patlasov        2013-03-21 18:02:28 +0400   85) static bool fuse_block_alloc(struct fuse_conn *fc, bool for_background)
0aada88476a33 (Maxim Patlasov        2013-03-21 18:02:28 +0400   86) {
0aada88476a33 (Maxim Patlasov        2013-03-21 18:02:28 +0400   87) 	return !fc->initialized || (for_background && fc->blocked);
0aada88476a33 (Maxim Patlasov        2013-03-21 18:02:28 +0400   88) }
0aada88476a33 (Maxim Patlasov        2013-03-21 18:02:28 +0400   89) 
b8f95e5d13f5f (Miklos Szeredi        2018-07-26 16:13:11 +0200   90) static void fuse_drop_waiting(struct fuse_conn *fc)
b8f95e5d13f5f (Miklos Szeredi        2018-07-26 16:13:11 +0200   91) {
2d84a2d19b615 (Miklos Szeredi        2018-11-09 15:52:16 +0100   92) 	/*
2d84a2d19b615 (Miklos Szeredi        2018-11-09 15:52:16 +0100   93) 	 * lockess check of fc->connected is okay, because atomic_dec_and_test()
2d84a2d19b615 (Miklos Szeredi        2018-11-09 15:52:16 +0100   94) 	 * provides a memory barrier mached with the one in fuse_wait_aborted()
2d84a2d19b615 (Miklos Szeredi        2018-11-09 15:52:16 +0100   95) 	 * to ensure no wake-up is missed.
2d84a2d19b615 (Miklos Szeredi        2018-11-09 15:52:16 +0100   96) 	 */
2d84a2d19b615 (Miklos Szeredi        2018-11-09 15:52:16 +0100   97) 	if (atomic_dec_and_test(&fc->num_waiting) &&
2d84a2d19b615 (Miklos Szeredi        2018-11-09 15:52:16 +0100   98) 	    !READ_ONCE(fc->connected)) {
b8f95e5d13f5f (Miklos Szeredi        2018-07-26 16:13:11 +0200   99) 		/* wake up aborters */
b8f95e5d13f5f (Miklos Szeredi        2018-07-26 16:13:11 +0200  100) 		wake_up_all(&fc->blocked_waitq);
b8f95e5d13f5f (Miklos Szeredi        2018-07-26 16:13:11 +0200  101) 	}
b8f95e5d13f5f (Miklos Szeredi        2018-07-26 16:13:11 +0200  102) }
b8f95e5d13f5f (Miklos Szeredi        2018-07-26 16:13:11 +0200  103) 
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200  104) static void fuse_put_request(struct fuse_req *req);
66abc3599c3c8 (Miklos Szeredi        2019-09-10 15:04:11 +0200  105) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  106) static struct fuse_req *fuse_get_req(struct fuse_mount *fm, bool for_background)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  107) {
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  108) 	struct fuse_conn *fc = fm->fc;
08a53cdce62d3 (Miklos Szeredi        2006-04-10 22:54:59 -0700  109) 	struct fuse_req *req;
08a53cdce62d3 (Miklos Szeredi        2006-04-10 22:54:59 -0700  110) 	int err;
9bc5dddad1294 (Miklos Szeredi        2006-04-11 21:16:09 +0200  111) 	atomic_inc(&fc->num_waiting);
0aada88476a33 (Maxim Patlasov        2013-03-21 18:02:28 +0400  112) 
0aada88476a33 (Maxim Patlasov        2013-03-21 18:02:28 +0400  113) 	if (fuse_block_alloc(fc, for_background)) {
0aada88476a33 (Maxim Patlasov        2013-03-21 18:02:28 +0400  114) 		err = -EINTR;
7d3a07fcb8a0d (Al Viro               2016-07-19 03:08:27 -0400  115) 		if (wait_event_killable_exclusive(fc->blocked_waitq,
7d3a07fcb8a0d (Al Viro               2016-07-19 03:08:27 -0400  116) 				!fuse_block_alloc(fc, for_background)))
0aada88476a33 (Maxim Patlasov        2013-03-21 18:02:28 +0400  117) 			goto out;
0aada88476a33 (Maxim Patlasov        2013-03-21 18:02:28 +0400  118) 	}
9759bd5189945 (Miklos Szeredi        2015-01-06 10:45:35 +0100  119) 	/* Matches smp_wmb() in fuse_set_initialized() */
9759bd5189945 (Miklos Szeredi        2015-01-06 10:45:35 +0100  120) 	smp_rmb();
08a53cdce62d3 (Miklos Szeredi        2006-04-10 22:54:59 -0700  121) 
51eb01e73599e (Miklos Szeredi        2006-06-25 05:48:50 -0700  122) 	err = -ENOTCONN;
51eb01e73599e (Miklos Szeredi        2006-06-25 05:48:50 -0700  123) 	if (!fc->connected)
51eb01e73599e (Miklos Szeredi        2006-06-25 05:48:50 -0700  124) 		goto out;
51eb01e73599e (Miklos Szeredi        2006-06-25 05:48:50 -0700  125) 
de15522646b98 (Miklos Szeredi        2015-07-01 16:25:57 +0200  126) 	err = -ECONNREFUSED;
de15522646b98 (Miklos Szeredi        2015-07-01 16:25:57 +0200  127) 	if (fc->conn_error)
de15522646b98 (Miklos Szeredi        2015-07-01 16:25:57 +0200  128) 		goto out;
de15522646b98 (Miklos Szeredi        2015-07-01 16:25:57 +0200  129) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  130) 	req = fuse_request_alloc(fm, GFP_KERNEL);
9bc5dddad1294 (Miklos Szeredi        2006-04-11 21:16:09 +0200  131) 	err = -ENOMEM;
722d2bea8c601 (Maxim Patlasov        2013-03-21 18:02:36 +0400  132) 	if (!req) {
722d2bea8c601 (Maxim Patlasov        2013-03-21 18:02:36 +0400  133) 		if (for_background)
722d2bea8c601 (Maxim Patlasov        2013-03-21 18:02:36 +0400  134) 			wake_up(&fc->blocked_waitq);
9bc5dddad1294 (Miklos Szeredi        2006-04-11 21:16:09 +0200  135) 		goto out;
722d2bea8c601 (Maxim Patlasov        2013-03-21 18:02:36 +0400  136) 	}
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  137) 
8cb08329b0809 (Eric W. Biederman     2018-02-21 11:18:07 -0600  138) 	req->in.h.uid = from_kuid(fc->user_ns, current_fsuid());
8cb08329b0809 (Eric W. Biederman     2018-02-21 11:18:07 -0600  139) 	req->in.h.gid = from_kgid(fc->user_ns, current_fsgid());
c9582eb0ff7d2 (Eric W. Biederman     2018-02-21 10:52:06 -0600  140) 	req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns);
c9582eb0ff7d2 (Eric W. Biederman     2018-02-21 10:52:06 -0600  141) 
825d6d3395e88 (Miklos Szeredi        2015-07-01 16:25:58 +0200  142) 	__set_bit(FR_WAITING, &req->flags);
825d6d3395e88 (Miklos Szeredi        2015-07-01 16:25:58 +0200  143) 	if (for_background)
825d6d3395e88 (Miklos Szeredi        2015-07-01 16:25:58 +0200  144) 		__set_bit(FR_BACKGROUND, &req->flags);
825d6d3395e88 (Miklos Szeredi        2015-07-01 16:25:58 +0200  145) 
c9582eb0ff7d2 (Eric W. Biederman     2018-02-21 10:52:06 -0600  146) 	if (unlikely(req->in.h.uid == ((uid_t)-1) ||
c9582eb0ff7d2 (Eric W. Biederman     2018-02-21 10:52:06 -0600  147) 		     req->in.h.gid == ((gid_t)-1))) {
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200  148) 		fuse_put_request(req);
c9582eb0ff7d2 (Eric W. Biederman     2018-02-21 10:52:06 -0600  149) 		return ERR_PTR(-EOVERFLOW);
c9582eb0ff7d2 (Eric W. Biederman     2018-02-21 10:52:06 -0600  150) 	}
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  151) 	return req;
9bc5dddad1294 (Miklos Szeredi        2006-04-11 21:16:09 +0200  152) 
9bc5dddad1294 (Miklos Szeredi        2006-04-11 21:16:09 +0200  153)  out:
b8f95e5d13f5f (Miklos Szeredi        2018-07-26 16:13:11 +0200  154) 	fuse_drop_waiting(fc);
9bc5dddad1294 (Miklos Szeredi        2006-04-11 21:16:09 +0200  155) 	return ERR_PTR(err);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  156) }
8b41e6715ed55 (Maxim Patlasov        2013-03-21 18:02:04 +0400  157) 
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200  158) static void fuse_put_request(struct fuse_req *req)
7128ec2a747d7 (Miklos Szeredi        2006-02-04 23:27:40 -0800  159) {
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  160) 	struct fuse_conn *fc = req->fm->fc;
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200  161) 
ec99f6d31f259 (Elena Reshetova       2017-03-03 11:04:04 +0200  162) 	if (refcount_dec_and_test(&req->count)) {
825d6d3395e88 (Miklos Szeredi        2015-07-01 16:25:58 +0200  163) 		if (test_bit(FR_BACKGROUND, &req->flags)) {
722d2bea8c601 (Maxim Patlasov        2013-03-21 18:02:36 +0400  164) 			/*
722d2bea8c601 (Maxim Patlasov        2013-03-21 18:02:36 +0400  165) 			 * We get here in the unlikely case that a background
722d2bea8c601 (Maxim Patlasov        2013-03-21 18:02:36 +0400  166) 			 * request was allocated but not sent
722d2bea8c601 (Maxim Patlasov        2013-03-21 18:02:36 +0400  167) 			 */
ae2dffa39485c (Kirill Tkhai          2018-08-27 18:29:46 +0300  168) 			spin_lock(&fc->bg_lock);
722d2bea8c601 (Maxim Patlasov        2013-03-21 18:02:36 +0400  169) 			if (!fc->blocked)
722d2bea8c601 (Maxim Patlasov        2013-03-21 18:02:36 +0400  170) 				wake_up(&fc->blocked_waitq);
ae2dffa39485c (Kirill Tkhai          2018-08-27 18:29:46 +0300  171) 			spin_unlock(&fc->bg_lock);
722d2bea8c601 (Maxim Patlasov        2013-03-21 18:02:36 +0400  172) 		}
722d2bea8c601 (Maxim Patlasov        2013-03-21 18:02:36 +0400  173) 
825d6d3395e88 (Miklos Szeredi        2015-07-01 16:25:58 +0200  174) 		if (test_bit(FR_WAITING, &req->flags)) {
825d6d3395e88 (Miklos Szeredi        2015-07-01 16:25:58 +0200  175) 			__clear_bit(FR_WAITING, &req->flags);
b8f95e5d13f5f (Miklos Szeredi        2018-07-26 16:13:11 +0200  176) 			fuse_drop_waiting(fc);
73e0e738441b2 (Miklos Szeredi        2015-07-01 16:25:56 +0200  177) 		}
33649c91a3df5 (Miklos Szeredi        2006-06-25 05:48:52 -0700  178) 
40ac7ab2d0217 (Miklos Szeredi        2019-09-10 15:04:08 +0200  179) 		fuse_request_free(req);
7128ec2a747d7 (Miklos Szeredi        2006-02-04 23:27:40 -0800  180) 	}
7128ec2a747d7 (Miklos Szeredi        2006-02-04 23:27:40 -0800  181) }
7128ec2a747d7 (Miklos Szeredi        2006-02-04 23:27:40 -0800  182) 
14d46d7abc397 (Stefan Hajnoczi       2018-06-21 09:34:25 +0100  183) unsigned int fuse_len_args(unsigned int numargs, struct fuse_arg *args)
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  184) {
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  185) 	unsigned nbytes = 0;
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  186) 	unsigned i;
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  187) 
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  188) 	for (i = 0; i < numargs; i++)
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  189) 		nbytes += args[i].size;
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  190) 
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  191) 	return nbytes;
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  192) }
14d46d7abc397 (Stefan Hajnoczi       2018-06-21 09:34:25 +0100  193) EXPORT_SYMBOL_GPL(fuse_len_args);
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  194) 
79d96efffda75 (Stefan Hajnoczi       2018-06-22 13:48:30 +0100  195) u64 fuse_get_unique(struct fuse_iqueue *fiq)
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  196) {
c59fd85e4fd07 (Kirill Tkhai          2018-09-11 13:11:56 +0300  197) 	fiq->reqctr += FUSE_REQ_ID_STEP;
c59fd85e4fd07 (Kirill Tkhai          2018-09-11 13:11:56 +0300  198) 	return fiq->reqctr;
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  199) }
79d96efffda75 (Stefan Hajnoczi       2018-06-22 13:48:30 +0100  200) EXPORT_SYMBOL_GPL(fuse_get_unique);
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  201) 
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300  202) static unsigned int fuse_req_hash(u64 unique)
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300  203) {
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300  204) 	return hash_long(unique & ~FUSE_INT_REQ_BIT, FUSE_PQ_HASH_BITS);
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300  205) }
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300  206) 
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  207) /**
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  208)  * A new request is available, wake fiq->waitq
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  209)  */
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  210) static void fuse_dev_wake_and_unlock(struct fuse_iqueue *fiq)
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  211) __releases(fiq->lock)
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  212) {
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  213) 	wake_up(&fiq->waitq);
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  214) 	kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  215) 	spin_unlock(&fiq->lock);
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  216) }
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  217) 
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  218) const struct fuse_iqueue_ops fuse_dev_fiq_ops = {
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  219) 	.wake_forget_and_unlock		= fuse_dev_wake_and_unlock,
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  220) 	.wake_interrupt_and_unlock	= fuse_dev_wake_and_unlock,
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  221) 	.wake_pending_and_unlock	= fuse_dev_wake_and_unlock,
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  222) };
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  223) EXPORT_SYMBOL_GPL(fuse_dev_fiq_ops);
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  224) 
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  225) static void queue_request_and_unlock(struct fuse_iqueue *fiq,
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  226) 				     struct fuse_req *req)
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  227) __releases(fiq->lock)
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  228) {
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  229) 	req->in.h.len = sizeof(struct fuse_in_header) +
14d46d7abc397 (Stefan Hajnoczi       2018-06-21 09:34:25 +0100  230) 		fuse_len_args(req->args->in_numargs,
14d46d7abc397 (Stefan Hajnoczi       2018-06-21 09:34:25 +0100  231) 			      (struct fuse_arg *) req->args->in_args);
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200  232) 	list_add_tail(&req->list, &fiq->pending);
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  233) 	fiq->ops->wake_pending_and_unlock(fiq);
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  234) }
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  235) 
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100  236) void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget,
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100  237) 		       u64 nodeid, u64 nlookup)
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100  238) {
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200  239) 	struct fuse_iqueue *fiq = &fc->iq;
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200  240) 
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100  241) 	forget->forget_one.nodeid = nodeid;
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100  242) 	forget->forget_one.nlookup = nlookup;
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100  243) 
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700  244) 	spin_lock(&fiq->lock);
e16714d8756dc (Miklos Szeredi        2015-07-01 16:26:01 +0200  245) 	if (fiq->connected) {
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200  246) 		fiq->forget_list_tail->next = forget;
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200  247) 		fiq->forget_list_tail = forget;
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  248) 		fiq->ops->wake_forget_and_unlock(fiq);
5dfcc87fd79df (Miklos Szeredi        2011-09-12 09:38:03 +0200  249) 	} else {
5dfcc87fd79df (Miklos Szeredi        2011-09-12 09:38:03 +0200  250) 		kfree(forget);
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  251) 		spin_unlock(&fiq->lock);
5dfcc87fd79df (Miklos Szeredi        2011-09-12 09:38:03 +0200  252) 	}
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100  253) }
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100  254) 
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  255) static void flush_bg_queue(struct fuse_conn *fc)
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  256) {
e287179afe219 (Kirill Tkhai          2018-07-31 13:25:25 +0300  257) 	struct fuse_iqueue *fiq = &fc->iq;
e287179afe219 (Kirill Tkhai          2018-07-31 13:25:25 +0300  258) 
7a6d3c8b3049d (Csaba Henk            2009-07-01 17:28:41 -0700  259) 	while (fc->active_background < fc->max_background &&
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  260) 	       !list_empty(&fc->bg_queue)) {
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  261) 		struct fuse_req *req;
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  262) 
e287179afe219 (Kirill Tkhai          2018-07-31 13:25:25 +0300  263) 		req = list_first_entry(&fc->bg_queue, struct fuse_req, list);
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  264) 		list_del(&req->list);
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  265) 		fc->active_background++;
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700  266) 		spin_lock(&fiq->lock);
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200  267) 		req->in.h.unique = fuse_get_unique(fiq);
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  268) 		queue_request_and_unlock(fiq, req);
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  269) 	}
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  270) }
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  271) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  272) /*
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  273)  * This function is called when a request is finished.  Either a reply
f9a2842e5612b (Miklos Szeredi        2006-06-25 05:48:53 -0700  274)  * has arrived or it was aborted (and not yet sent) or some error
f43b155a5a8a9 (Miklos Szeredi        2006-01-16 22:14:26 -0800  275)  * occurred during communication with userspace, or the device file
51eb01e73599e (Miklos Szeredi        2006-06-25 05:48:50 -0700  276)  * was closed.  The requester thread is woken up (if still waiting),
51eb01e73599e (Miklos Szeredi        2006-06-25 05:48:50 -0700  277)  * the 'end' callback is called if given, else the reference to the
51eb01e73599e (Miklos Szeredi        2006-06-25 05:48:50 -0700  278)  * request is released
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  279)  */
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200  280) void fuse_request_end(struct fuse_req *req)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  281) {
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  282) 	struct fuse_mount *fm = req->fm;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  283) 	struct fuse_conn *fc = fm->fc;
4ce6081260ea4 (Miklos Szeredi        2015-07-01 16:26:02 +0200  284) 	struct fuse_iqueue *fiq = &fc->iq;
365ae710df91e (Miklos Szeredi        2015-07-01 16:26:06 +0200  285) 
efe2800facb45 (Miklos Szeredi        2015-07-01 16:26:07 +0200  286) 	if (test_and_set_bit(FR_FINISHED, &req->flags))
b8f95e5d13f5f (Miklos Szeredi        2018-07-26 16:13:11 +0200  287) 		goto put_request;
2b319d1f6f92a (Miklos Szeredi        2019-10-21 09:11:40 +0200  288) 
217316a601016 (Kirill Tkhai          2018-11-08 12:05:25 +0300  289) 	/*
217316a601016 (Kirill Tkhai          2018-11-08 12:05:25 +0300  290) 	 * test_and_set_bit() implies smp_mb() between bit
217316a601016 (Kirill Tkhai          2018-11-08 12:05:25 +0300  291) 	 * changing and below intr_entry check. Pairs with
217316a601016 (Kirill Tkhai          2018-11-08 12:05:25 +0300  292) 	 * smp_mb() from queue_interrupt().
217316a601016 (Kirill Tkhai          2018-11-08 12:05:25 +0300  293) 	 */
217316a601016 (Kirill Tkhai          2018-11-08 12:05:25 +0300  294) 	if (!list_empty(&req->intr_entry)) {
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700  295) 		spin_lock(&fiq->lock);
217316a601016 (Kirill Tkhai          2018-11-08 12:05:25 +0300  296) 		list_del_init(&req->intr_entry);
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700  297) 		spin_unlock(&fiq->lock);
217316a601016 (Kirill Tkhai          2018-11-08 12:05:25 +0300  298) 	}
33e14b4dfdc47 (Miklos Szeredi        2015-07-01 16:26:01 +0200  299) 	WARN_ON(test_bit(FR_PENDING, &req->flags));
33e14b4dfdc47 (Miklos Szeredi        2015-07-01 16:26:01 +0200  300) 	WARN_ON(test_bit(FR_SENT, &req->flags));
825d6d3395e88 (Miklos Szeredi        2015-07-01 16:25:58 +0200  301) 	if (test_bit(FR_BACKGROUND, &req->flags)) {
ae2dffa39485c (Kirill Tkhai          2018-08-27 18:29:46 +0300  302) 		spin_lock(&fc->bg_lock);
825d6d3395e88 (Miklos Szeredi        2015-07-01 16:25:58 +0200  303) 		clear_bit(FR_BACKGROUND, &req->flags);
908a572b80f6e (Miklos Szeredi        2018-09-28 16:43:22 +0200  304) 		if (fc->num_background == fc->max_background) {
51eb01e73599e (Miklos Szeredi        2006-06-25 05:48:50 -0700  305) 			fc->blocked = 0;
722d2bea8c601 (Maxim Patlasov        2013-03-21 18:02:36 +0400  306) 			wake_up(&fc->blocked_waitq);
908a572b80f6e (Miklos Szeredi        2018-09-28 16:43:22 +0200  307) 		} else if (!fc->blocked) {
908a572b80f6e (Miklos Szeredi        2018-09-28 16:43:22 +0200  308) 			/*
908a572b80f6e (Miklos Szeredi        2018-09-28 16:43:22 +0200  309) 			 * Wake up next waiter, if any.  It's okay to use
908a572b80f6e (Miklos Szeredi        2018-09-28 16:43:22 +0200  310) 			 * waitqueue_active(), as we've already synced up
908a572b80f6e (Miklos Szeredi        2018-09-28 16:43:22 +0200  311) 			 * fc->blocked with waiters with the wake_up() call
908a572b80f6e (Miklos Szeredi        2018-09-28 16:43:22 +0200  312) 			 * above.
908a572b80f6e (Miklos Szeredi        2018-09-28 16:43:22 +0200  313) 			 */
908a572b80f6e (Miklos Szeredi        2018-09-28 16:43:22 +0200  314) 			if (waitqueue_active(&fc->blocked_waitq))
908a572b80f6e (Miklos Szeredi        2018-09-28 16:43:22 +0200  315) 				wake_up(&fc->blocked_waitq);
908a572b80f6e (Miklos Szeredi        2018-09-28 16:43:22 +0200  316) 		}
722d2bea8c601 (Maxim Patlasov        2013-03-21 18:02:36 +0400  317) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  318) 		if (fc->num_background == fc->congestion_threshold && fm->sb) {
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  319) 			clear_bdi_congested(fm->sb->s_bdi, BLK_RW_SYNC);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  320) 			clear_bdi_congested(fm->sb->s_bdi, BLK_RW_ASYNC);
f92b99b9dccb6 (Miklos Szeredi        2007-10-16 23:30:59 -0700  321) 		}
51eb01e73599e (Miklos Szeredi        2006-06-25 05:48:50 -0700  322) 		fc->num_background--;
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  323) 		fc->active_background--;
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  324) 		flush_bg_queue(fc);
ae2dffa39485c (Kirill Tkhai          2018-08-27 18:29:46 +0300  325) 		spin_unlock(&fc->bg_lock);
5e0fed717a383 (Kirill Tkhai          2018-11-08 12:05:31 +0300  326) 	} else {
5e0fed717a383 (Kirill Tkhai          2018-11-08 12:05:31 +0300  327) 		/* Wake up waiter sleeping in request_wait_answer() */
5e0fed717a383 (Kirill Tkhai          2018-11-08 12:05:31 +0300  328) 		wake_up(&req->waitq);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  329) 	}
5e0fed717a383 (Kirill Tkhai          2018-11-08 12:05:31 +0300  330) 
3e8cb8b2eaeb2 (Miklos Szeredi        2020-02-13 09:16:07 +0100  331) 	if (test_bit(FR_ASYNC, &req->flags))
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  332) 		req->args->end(fm, req->args, req->out.h.error);
b8f95e5d13f5f (Miklos Szeredi        2018-07-26 16:13:11 +0200  333) put_request:
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200  334) 	fuse_put_request(req);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  335) }
04ec5af0776e9 (Stefan Hajnoczi       2018-06-21 09:33:40 +0100  336) EXPORT_SYMBOL_GPL(fuse_request_end);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  337) 
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200  338) static int queue_interrupt(struct fuse_req *req)
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700  339) {
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  340) 	struct fuse_iqueue *fiq = &req->fm->fc->iq;
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200  341) 
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700  342) 	spin_lock(&fiq->lock);
b782911b5297c (Kirill Tkhai          2018-11-08 12:05:42 +0300  343) 	/* Check for we've sent request to interrupt this req */
b782911b5297c (Kirill Tkhai          2018-11-08 12:05:42 +0300  344) 	if (unlikely(!test_bit(FR_INTERRUPTED, &req->flags))) {
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700  345) 		spin_unlock(&fiq->lock);
b782911b5297c (Kirill Tkhai          2018-11-08 12:05:42 +0300  346) 		return -EINVAL;
b782911b5297c (Kirill Tkhai          2018-11-08 12:05:42 +0300  347) 	}
b782911b5297c (Kirill Tkhai          2018-11-08 12:05:42 +0300  348) 
8f7bb368dbdda (Miklos Szeredi        2015-07-01 16:26:03 +0200  349) 	if (list_empty(&req->intr_entry)) {
8f7bb368dbdda (Miklos Szeredi        2015-07-01 16:26:03 +0200  350) 		list_add_tail(&req->intr_entry, &fiq->interrupts);
217316a601016 (Kirill Tkhai          2018-11-08 12:05:25 +0300  351) 		/*
217316a601016 (Kirill Tkhai          2018-11-08 12:05:25 +0300  352) 		 * Pairs with smp_mb() implied by test_and_set_bit()
75d892588e959 (Kirill Tkhai          2020-02-28 15:15:24 +0300  353) 		 * from fuse_request_end().
217316a601016 (Kirill Tkhai          2018-11-08 12:05:25 +0300  354) 		 */
217316a601016 (Kirill Tkhai          2018-11-08 12:05:25 +0300  355) 		smp_mb();
217316a601016 (Kirill Tkhai          2018-11-08 12:05:25 +0300  356) 		if (test_bit(FR_FINISHED, &req->flags)) {
217316a601016 (Kirill Tkhai          2018-11-08 12:05:25 +0300  357) 			list_del_init(&req->intr_entry);
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700  358) 			spin_unlock(&fiq->lock);
b782911b5297c (Kirill Tkhai          2018-11-08 12:05:42 +0300  359) 			return 0;
217316a601016 (Kirill Tkhai          2018-11-08 12:05:25 +0300  360) 		}
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  361) 		fiq->ops->wake_interrupt_and_unlock(fiq);
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  362) 	} else {
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  363) 		spin_unlock(&fiq->lock);
8f7bb368dbdda (Miklos Szeredi        2015-07-01 16:26:03 +0200  364) 	}
b782911b5297c (Kirill Tkhai          2018-11-08 12:05:42 +0300  365) 	return 0;
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700  366) }
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700  367) 
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200  368) static void request_wait_answer(struct fuse_req *req)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  369) {
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  370) 	struct fuse_conn *fc = req->fm->fc;
4ce6081260ea4 (Miklos Szeredi        2015-07-01 16:26:02 +0200  371) 	struct fuse_iqueue *fiq = &fc->iq;
c47752673acb1 (Miklos Szeredi        2015-07-01 16:26:00 +0200  372) 	int err;
c47752673acb1 (Miklos Szeredi        2015-07-01 16:26:00 +0200  373) 
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700  374) 	if (!fc->no_interrupt) {
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700  375) 		/* Any signal may interrupt this */
c47752673acb1 (Miklos Szeredi        2015-07-01 16:26:00 +0200  376) 		err = wait_event_interruptible(req->waitq,
33e14b4dfdc47 (Miklos Szeredi        2015-07-01 16:26:01 +0200  377) 					test_bit(FR_FINISHED, &req->flags));
c47752673acb1 (Miklos Szeredi        2015-07-01 16:26:00 +0200  378) 		if (!err)
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700  379) 			return;
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700  380) 
825d6d3395e88 (Miklos Szeredi        2015-07-01 16:25:58 +0200  381) 		set_bit(FR_INTERRUPTED, &req->flags);
8f7bb368dbdda (Miklos Szeredi        2015-07-01 16:26:03 +0200  382) 		/* matches barrier in fuse_dev_do_read() */
8f7bb368dbdda (Miklos Szeredi        2015-07-01 16:26:03 +0200  383) 		smp_mb__after_atomic();
33e14b4dfdc47 (Miklos Szeredi        2015-07-01 16:26:01 +0200  384) 		if (test_bit(FR_SENT, &req->flags))
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200  385) 			queue_interrupt(req);
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700  386) 	}
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700  387) 
825d6d3395e88 (Miklos Szeredi        2015-07-01 16:25:58 +0200  388) 	if (!test_bit(FR_FORCE, &req->flags)) {
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700  389) 		/* Only fatal signals may interrupt this */
7d3a07fcb8a0d (Al Viro               2016-07-19 03:08:27 -0400  390) 		err = wait_event_killable(req->waitq,
33e14b4dfdc47 (Miklos Szeredi        2015-07-01 16:26:01 +0200  391) 					test_bit(FR_FINISHED, &req->flags));
c47752673acb1 (Miklos Szeredi        2015-07-01 16:26:00 +0200  392) 		if (!err)
a131de0a482ac (Miklos Szeredi        2007-10-16 23:31:04 -0700  393) 			return;
a131de0a482ac (Miklos Szeredi        2007-10-16 23:31:04 -0700  394) 
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700  395) 		spin_lock(&fiq->lock);
a131de0a482ac (Miklos Szeredi        2007-10-16 23:31:04 -0700  396) 		/* Request is not yet in userspace, bail out */
33e14b4dfdc47 (Miklos Szeredi        2015-07-01 16:26:01 +0200  397) 		if (test_bit(FR_PENDING, &req->flags)) {
a131de0a482ac (Miklos Szeredi        2007-10-16 23:31:04 -0700  398) 			list_del(&req->list);
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700  399) 			spin_unlock(&fiq->lock);
a131de0a482ac (Miklos Szeredi        2007-10-16 23:31:04 -0700  400) 			__fuse_put_request(req);
a131de0a482ac (Miklos Szeredi        2007-10-16 23:31:04 -0700  401) 			req->out.h.error = -EINTR;
a131de0a482ac (Miklos Szeredi        2007-10-16 23:31:04 -0700  402) 			return;
a131de0a482ac (Miklos Szeredi        2007-10-16 23:31:04 -0700  403) 		}
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700  404) 		spin_unlock(&fiq->lock);
51eb01e73599e (Miklos Szeredi        2006-06-25 05:48:50 -0700  405) 	}
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  406) 
a131de0a482ac (Miklos Szeredi        2007-10-16 23:31:04 -0700  407) 	/*
a131de0a482ac (Miklos Szeredi        2007-10-16 23:31:04 -0700  408) 	 * Either request is already in userspace, or it was forced.
a131de0a482ac (Miklos Szeredi        2007-10-16 23:31:04 -0700  409) 	 * Wait it out.
a131de0a482ac (Miklos Szeredi        2007-10-16 23:31:04 -0700  410) 	 */
33e14b4dfdc47 (Miklos Szeredi        2015-07-01 16:26:01 +0200  411) 	wait_event(req->waitq, test_bit(FR_FINISHED, &req->flags));
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  412) }
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  413) 
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200  414) static void __fuse_request_send(struct fuse_req *req)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  415) {
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  416) 	struct fuse_iqueue *fiq = &req->fm->fc->iq;
e16714d8756dc (Miklos Szeredi        2015-07-01 16:26:01 +0200  417) 
825d6d3395e88 (Miklos Szeredi        2015-07-01 16:25:58 +0200  418) 	BUG_ON(test_bit(FR_BACKGROUND, &req->flags));
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700  419) 	spin_lock(&fiq->lock);
e16714d8756dc (Miklos Szeredi        2015-07-01 16:26:01 +0200  420) 	if (!fiq->connected) {
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700  421) 		spin_unlock(&fiq->lock);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  422) 		req->out.h.error = -ENOTCONN;
c47752673acb1 (Miklos Szeredi        2015-07-01 16:26:00 +0200  423) 	} else {
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200  424) 		req->in.h.unique = fuse_get_unique(fiq);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  425) 		/* acquire extra reference, since request is still needed
04ec5af0776e9 (Stefan Hajnoczi       2018-06-21 09:33:40 +0100  426) 		   after fuse_request_end() */
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  427) 		__fuse_get_request(req);
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  428) 		queue_request_and_unlock(fiq, req);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  429) 
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200  430) 		request_wait_answer(req);
04ec5af0776e9 (Stefan Hajnoczi       2018-06-21 09:33:40 +0100  431) 		/* Pairs with smp_wmb() in fuse_request_end() */
c47752673acb1 (Miklos Szeredi        2015-07-01 16:26:00 +0200  432) 		smp_rmb();
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  433) 	}
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  434) }
6a4e922c3db06 (Eric Wong             2013-02-04 13:04:44 +0000  435) 
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  436) static void fuse_adjust_compat(struct fuse_conn *fc, struct fuse_args *args)
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  437) {
d5b4854357f47 (Miklos Szeredi        2019-09-10 15:04:08 +0200  438) 	if (fc->minor < 4 && args->opcode == FUSE_STATFS)
d5b4854357f47 (Miklos Szeredi        2019-09-10 15:04:08 +0200  439) 		args->out_args[0].size = FUSE_COMPAT_STATFS_SIZE;
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  440) 
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  441) 	if (fc->minor < 9) {
d5b4854357f47 (Miklos Szeredi        2019-09-10 15:04:08 +0200  442) 		switch (args->opcode) {
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  443) 		case FUSE_LOOKUP:
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  444) 		case FUSE_CREATE:
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  445) 		case FUSE_MKNOD:
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  446) 		case FUSE_MKDIR:
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  447) 		case FUSE_SYMLINK:
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  448) 		case FUSE_LINK:
d5b4854357f47 (Miklos Szeredi        2019-09-10 15:04:08 +0200  449) 			args->out_args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  450) 			break;
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  451) 		case FUSE_GETATTR:
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  452) 		case FUSE_SETATTR:
d5b4854357f47 (Miklos Szeredi        2019-09-10 15:04:08 +0200  453) 			args->out_args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  454) 			break;
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  455) 		}
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  456) 	}
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  457) 	if (fc->minor < 12) {
d5b4854357f47 (Miklos Szeredi        2019-09-10 15:04:08 +0200  458) 		switch (args->opcode) {
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  459) 		case FUSE_CREATE:
d5b4854357f47 (Miklos Szeredi        2019-09-10 15:04:08 +0200  460) 			args->in_args[0].size = sizeof(struct fuse_open_in);
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  461) 			break;
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  462) 		case FUSE_MKNOD:
d5b4854357f47 (Miklos Szeredi        2019-09-10 15:04:08 +0200  463) 			args->in_args[0].size = FUSE_COMPAT_MKNOD_IN_SIZE;
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  464) 			break;
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  465) 		}
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  466) 	}
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  467) }
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  468) 
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200  469) static void fuse_force_creds(struct fuse_req *req)
e413754b267e0 (Miklos Szeredi        2019-09-10 15:04:08 +0200  470) {
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  471) 	struct fuse_conn *fc = req->fm->fc;
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200  472) 
e413754b267e0 (Miklos Szeredi        2019-09-10 15:04:08 +0200  473) 	req->in.h.uid = from_kuid_munged(fc->user_ns, current_fsuid());
e413754b267e0 (Miklos Szeredi        2019-09-10 15:04:08 +0200  474) 	req->in.h.gid = from_kgid_munged(fc->user_ns, current_fsgid());
e413754b267e0 (Miklos Szeredi        2019-09-10 15:04:08 +0200  475) 	req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns);
e413754b267e0 (Miklos Szeredi        2019-09-10 15:04:08 +0200  476) }
e413754b267e0 (Miklos Szeredi        2019-09-10 15:04:08 +0200  477) 
5addcd5dbd8c2 (YueHaibing            2019-09-23 13:52:31 +0800  478) static void fuse_args_to_req(struct fuse_req *req, struct fuse_args *args)
68583165f9627 (Miklos Szeredi        2019-09-10 15:04:09 +0200  479) {
68583165f9627 (Miklos Szeredi        2019-09-10 15:04:09 +0200  480) 	req->in.h.opcode = args->opcode;
68583165f9627 (Miklos Szeredi        2019-09-10 15:04:09 +0200  481) 	req->in.h.nodeid = args->nodeid;
d49937749fef2 (Miklos Szeredi        2019-09-10 15:04:11 +0200  482) 	req->args = args;
3e8cb8b2eaeb2 (Miklos Szeredi        2020-02-13 09:16:07 +0100  483) 	if (args->end)
3e8cb8b2eaeb2 (Miklos Szeredi        2020-02-13 09:16:07 +0100  484) 		__set_bit(FR_ASYNC, &req->flags);
68583165f9627 (Miklos Szeredi        2019-09-10 15:04:09 +0200  485) }
68583165f9627 (Miklos Szeredi        2019-09-10 15:04:09 +0200  486) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  487) ssize_t fuse_simple_request(struct fuse_mount *fm, struct fuse_args *args)
7078187a795f8 (Miklos Szeredi        2014-12-12 09:49:05 +0100  488) {
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  489) 	struct fuse_conn *fc = fm->fc;
7078187a795f8 (Miklos Szeredi        2014-12-12 09:49:05 +0100  490) 	struct fuse_req *req;
7078187a795f8 (Miklos Szeredi        2014-12-12 09:49:05 +0100  491) 	ssize_t ret;
7078187a795f8 (Miklos Szeredi        2014-12-12 09:49:05 +0100  492) 
c500ebaa908db (Miklos Szeredi        2019-09-10 15:04:08 +0200  493) 	if (args->force) {
e413754b267e0 (Miklos Szeredi        2019-09-10 15:04:08 +0200  494) 		atomic_inc(&fc->num_waiting);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  495) 		req = fuse_request_alloc(fm, GFP_KERNEL | __GFP_NOFAIL);
e413754b267e0 (Miklos Szeredi        2019-09-10 15:04:08 +0200  496) 
e413754b267e0 (Miklos Szeredi        2019-09-10 15:04:08 +0200  497) 		if (!args->nocreds)
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200  498) 			fuse_force_creds(req);
e413754b267e0 (Miklos Szeredi        2019-09-10 15:04:08 +0200  499) 
e413754b267e0 (Miklos Szeredi        2019-09-10 15:04:08 +0200  500) 		__set_bit(FR_WAITING, &req->flags);
c500ebaa908db (Miklos Szeredi        2019-09-10 15:04:08 +0200  501) 		__set_bit(FR_FORCE, &req->flags);
c500ebaa908db (Miklos Szeredi        2019-09-10 15:04:08 +0200  502) 	} else {
e413754b267e0 (Miklos Szeredi        2019-09-10 15:04:08 +0200  503) 		WARN_ON(args->nocreds);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  504) 		req = fuse_get_req(fm, false);
c500ebaa908db (Miklos Szeredi        2019-09-10 15:04:08 +0200  505) 		if (IS_ERR(req))
c500ebaa908db (Miklos Szeredi        2019-09-10 15:04:08 +0200  506) 			return PTR_ERR(req);
c500ebaa908db (Miklos Szeredi        2019-09-10 15:04:08 +0200  507) 	}
7078187a795f8 (Miklos Szeredi        2014-12-12 09:49:05 +0100  508) 
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  509) 	/* Needs to be done after fuse_get_req() so that fc->minor is valid */
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  510) 	fuse_adjust_compat(fc, args);
68583165f9627 (Miklos Szeredi        2019-09-10 15:04:09 +0200  511) 	fuse_args_to_req(req, args);
21f621741a770 (Miklos Szeredi        2015-01-06 10:45:35 +0100  512) 
454a7613f54e6 (Miklos Szeredi        2019-09-10 15:04:08 +0200  513) 	if (!args->noreply)
454a7613f54e6 (Miklos Szeredi        2019-09-10 15:04:08 +0200  514) 		__set_bit(FR_ISREPLY, &req->flags);
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200  515) 	__fuse_request_send(req);
7078187a795f8 (Miklos Szeredi        2014-12-12 09:49:05 +0100  516) 	ret = req->out.h.error;
d5b4854357f47 (Miklos Szeredi        2019-09-10 15:04:08 +0200  517) 	if (!ret && args->out_argvar) {
093f38a2c1a81 (Miklos Szeredi        2019-09-10 15:04:09 +0200  518) 		BUG_ON(args->out_numargs == 0);
d49937749fef2 (Miklos Szeredi        2019-09-10 15:04:11 +0200  519) 		ret = args->out_args[args->out_numargs - 1].size;
7078187a795f8 (Miklos Szeredi        2014-12-12 09:49:05 +0100  520) 	}
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200  521) 	fuse_put_request(req);
7078187a795f8 (Miklos Szeredi        2014-12-12 09:49:05 +0100  522) 
7078187a795f8 (Miklos Szeredi        2014-12-12 09:49:05 +0100  523) 	return ret;
7078187a795f8 (Miklos Szeredi        2014-12-12 09:49:05 +0100  524) }
7078187a795f8 (Miklos Szeredi        2014-12-12 09:49:05 +0100  525) 
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200  526) static bool fuse_request_queue_background(struct fuse_req *req)
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  527) {
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  528) 	struct fuse_mount *fm = req->fm;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  529) 	struct fuse_conn *fc = fm->fc;
63825b4e1da5a (Kirill Tkhai          2018-08-27 18:29:56 +0300  530) 	bool queued = false;
63825b4e1da5a (Kirill Tkhai          2018-08-27 18:29:56 +0300  531) 
63825b4e1da5a (Kirill Tkhai          2018-08-27 18:29:56 +0300  532) 	WARN_ON(!test_bit(FR_BACKGROUND, &req->flags));
825d6d3395e88 (Miklos Szeredi        2015-07-01 16:25:58 +0200  533) 	if (!test_bit(FR_WAITING, &req->flags)) {
825d6d3395e88 (Miklos Szeredi        2015-07-01 16:25:58 +0200  534) 		__set_bit(FR_WAITING, &req->flags);
5437f2417225d (Miklos Szeredi        2015-07-01 16:25:56 +0200  535) 		atomic_inc(&fc->num_waiting);
5437f2417225d (Miklos Szeredi        2015-07-01 16:25:56 +0200  536) 	}
825d6d3395e88 (Miklos Szeredi        2015-07-01 16:25:58 +0200  537) 	__set_bit(FR_ISREPLY, &req->flags);
ae2dffa39485c (Kirill Tkhai          2018-08-27 18:29:46 +0300  538) 	spin_lock(&fc->bg_lock);
63825b4e1da5a (Kirill Tkhai          2018-08-27 18:29:56 +0300  539) 	if (likely(fc->connected)) {
63825b4e1da5a (Kirill Tkhai          2018-08-27 18:29:56 +0300  540) 		fc->num_background++;
63825b4e1da5a (Kirill Tkhai          2018-08-27 18:29:56 +0300  541) 		if (fc->num_background == fc->max_background)
63825b4e1da5a (Kirill Tkhai          2018-08-27 18:29:56 +0300  542) 			fc->blocked = 1;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  543) 		if (fc->num_background == fc->congestion_threshold && fm->sb) {
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  544) 			set_bdi_congested(fm->sb->s_bdi, BLK_RW_SYNC);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  545) 			set_bdi_congested(fm->sb->s_bdi, BLK_RW_ASYNC);
63825b4e1da5a (Kirill Tkhai          2018-08-27 18:29:56 +0300  546) 		}
63825b4e1da5a (Kirill Tkhai          2018-08-27 18:29:56 +0300  547) 		list_add_tail(&req->list, &fc->bg_queue);
63825b4e1da5a (Kirill Tkhai          2018-08-27 18:29:56 +0300  548) 		flush_bg_queue(fc);
63825b4e1da5a (Kirill Tkhai          2018-08-27 18:29:56 +0300  549) 		queued = true;
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  550) 	}
ae2dffa39485c (Kirill Tkhai          2018-08-27 18:29:46 +0300  551) 	spin_unlock(&fc->bg_lock);
63825b4e1da5a (Kirill Tkhai          2018-08-27 18:29:56 +0300  552) 
63825b4e1da5a (Kirill Tkhai          2018-08-27 18:29:56 +0300  553) 	return queued;
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  554) }
d12def1bcb809 (Miklos Szeredi        2008-02-06 01:38:39 -0800  555) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  556) int fuse_simple_background(struct fuse_mount *fm, struct fuse_args *args,
1259728731a79 (Miklos Szeredi        2019-09-10 15:04:10 +0200  557) 			    gfp_t gfp_flags)
1259728731a79 (Miklos Szeredi        2019-09-10 15:04:10 +0200  558) {
1259728731a79 (Miklos Szeredi        2019-09-10 15:04:10 +0200  559) 	struct fuse_req *req;
1259728731a79 (Miklos Szeredi        2019-09-10 15:04:10 +0200  560) 
1259728731a79 (Miklos Szeredi        2019-09-10 15:04:10 +0200  561) 	if (args->force) {
1259728731a79 (Miklos Szeredi        2019-09-10 15:04:10 +0200  562) 		WARN_ON(!args->nocreds);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  563) 		req = fuse_request_alloc(fm, gfp_flags);
1259728731a79 (Miklos Szeredi        2019-09-10 15:04:10 +0200  564) 		if (!req)
1259728731a79 (Miklos Szeredi        2019-09-10 15:04:10 +0200  565) 			return -ENOMEM;
1259728731a79 (Miklos Szeredi        2019-09-10 15:04:10 +0200  566) 		__set_bit(FR_BACKGROUND, &req->flags);
1259728731a79 (Miklos Szeredi        2019-09-10 15:04:10 +0200  567) 	} else {
1259728731a79 (Miklos Szeredi        2019-09-10 15:04:10 +0200  568) 		WARN_ON(args->nocreds);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  569) 		req = fuse_get_req(fm, true);
1259728731a79 (Miklos Szeredi        2019-09-10 15:04:10 +0200  570) 		if (IS_ERR(req))
1259728731a79 (Miklos Szeredi        2019-09-10 15:04:10 +0200  571) 			return PTR_ERR(req);
1259728731a79 (Miklos Szeredi        2019-09-10 15:04:10 +0200  572) 	}
1259728731a79 (Miklos Szeredi        2019-09-10 15:04:10 +0200  573) 
1259728731a79 (Miklos Szeredi        2019-09-10 15:04:10 +0200  574) 	fuse_args_to_req(req, args);
1259728731a79 (Miklos Szeredi        2019-09-10 15:04:10 +0200  575) 
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200  576) 	if (!fuse_request_queue_background(req)) {
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200  577) 		fuse_put_request(req);
1259728731a79 (Miklos Szeredi        2019-09-10 15:04:10 +0200  578) 		return -ENOTCONN;
1259728731a79 (Miklos Szeredi        2019-09-10 15:04:10 +0200  579) 	}
1259728731a79 (Miklos Szeredi        2019-09-10 15:04:10 +0200  580) 
1259728731a79 (Miklos Szeredi        2019-09-10 15:04:10 +0200  581) 	return 0;
1259728731a79 (Miklos Szeredi        2019-09-10 15:04:10 +0200  582) }
1259728731a79 (Miklos Szeredi        2019-09-10 15:04:10 +0200  583) EXPORT_SYMBOL_GPL(fuse_simple_background);
1259728731a79 (Miklos Szeredi        2019-09-10 15:04:10 +0200  584) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  585) static int fuse_simple_notify_reply(struct fuse_mount *fm,
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200  586) 				    struct fuse_args *args, u64 unique)
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200  587) {
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200  588) 	struct fuse_req *req;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  589) 	struct fuse_iqueue *fiq = &fm->fc->iq;
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200  590) 	int err = 0;
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200  591) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  592) 	req = fuse_get_req(fm, false);
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200  593) 	if (IS_ERR(req))
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200  594) 		return PTR_ERR(req);
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200  595) 
825d6d3395e88 (Miklos Szeredi        2015-07-01 16:25:58 +0200  596) 	__clear_bit(FR_ISREPLY, &req->flags);
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200  597) 	req->in.h.unique = unique;
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200  598) 
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200  599) 	fuse_args_to_req(req, args);
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200  600) 
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700  601) 	spin_lock(&fiq->lock);
e16714d8756dc (Miklos Szeredi        2015-07-01 16:26:01 +0200  602) 	if (fiq->connected) {
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  603) 		queue_request_and_unlock(fiq, req);
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200  604) 	} else {
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200  605) 		err = -ENODEV;
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200  606) 		spin_unlock(&fiq->lock);
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200  607) 		fuse_put_request(req);
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200  608) 	}
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200  609) 
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200  610) 	return err;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200  611) }
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200  612) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  613) /*
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  614)  * Lock the request.  Up to the next unlock_request() there mustn't be
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  615)  * anything that could cause a page-fault.  If the request was already
f9a2842e5612b (Miklos Szeredi        2006-06-25 05:48:53 -0700  616)  * aborted bail out.
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  617)  */
dc00809a53edd (Miklos Szeredi        2015-07-01 16:25:58 +0200  618) static int lock_request(struct fuse_req *req)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  619) {
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  620) 	int err = 0;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  621) 	if (req) {
dc00809a53edd (Miklos Szeredi        2015-07-01 16:25:58 +0200  622) 		spin_lock(&req->waitq.lock);
825d6d3395e88 (Miklos Szeredi        2015-07-01 16:25:58 +0200  623) 		if (test_bit(FR_ABORTED, &req->flags))
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  624) 			err = -ENOENT;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  625) 		else
825d6d3395e88 (Miklos Szeredi        2015-07-01 16:25:58 +0200  626) 			set_bit(FR_LOCKED, &req->flags);
dc00809a53edd (Miklos Szeredi        2015-07-01 16:25:58 +0200  627) 		spin_unlock(&req->waitq.lock);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  628) 	}
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  629) 	return err;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  630) }
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  631) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  632) /*
0d8e84b0432be (Miklos Szeredi        2015-07-01 16:25:58 +0200  633)  * Unlock request.  If it was aborted while locked, caller is responsible
0d8e84b0432be (Miklos Szeredi        2015-07-01 16:25:58 +0200  634)  * for unlocking and ending the request.
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  635)  */
dc00809a53edd (Miklos Szeredi        2015-07-01 16:25:58 +0200  636) static int unlock_request(struct fuse_req *req)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  637) {
0d8e84b0432be (Miklos Szeredi        2015-07-01 16:25:58 +0200  638) 	int err = 0;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  639) 	if (req) {
dc00809a53edd (Miklos Szeredi        2015-07-01 16:25:58 +0200  640) 		spin_lock(&req->waitq.lock);
825d6d3395e88 (Miklos Szeredi        2015-07-01 16:25:58 +0200  641) 		if (test_bit(FR_ABORTED, &req->flags))
0d8e84b0432be (Miklos Szeredi        2015-07-01 16:25:58 +0200  642) 			err = -ENOENT;
0d8e84b0432be (Miklos Szeredi        2015-07-01 16:25:58 +0200  643) 		else
825d6d3395e88 (Miklos Szeredi        2015-07-01 16:25:58 +0200  644) 			clear_bit(FR_LOCKED, &req->flags);
dc00809a53edd (Miklos Szeredi        2015-07-01 16:25:58 +0200  645) 		spin_unlock(&req->waitq.lock);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  646) 	}
0d8e84b0432be (Miklos Szeredi        2015-07-01 16:25:58 +0200  647) 	return err;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  648) }
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  649) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  650) struct fuse_copy_state {
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  651) 	int write;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  652) 	struct fuse_req *req;
6c09e94a32e10 (Al Viro               2015-04-03 22:06:08 -0400  653) 	struct iov_iter *iter;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200  654) 	struct pipe_buffer *pipebufs;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200  655) 	struct pipe_buffer *currbuf;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200  656) 	struct pipe_inode_info *pipe;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  657) 	unsigned long nr_segs;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  658) 	struct page *pg;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  659) 	unsigned len;
c55a01d360afa (Miklos Szeredi        2014-07-07 15:28:51 +0200  660) 	unsigned offset;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  661) 	unsigned move_pages:1;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  662) };
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  663) 
dc00809a53edd (Miklos Szeredi        2015-07-01 16:25:58 +0200  664) static void fuse_copy_init(struct fuse_copy_state *cs, int write,
6c09e94a32e10 (Al Viro               2015-04-03 22:06:08 -0400  665) 			   struct iov_iter *iter)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  666) {
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  667) 	memset(cs, 0, sizeof(*cs));
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  668) 	cs->write = write;
6c09e94a32e10 (Al Viro               2015-04-03 22:06:08 -0400  669) 	cs->iter = iter;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  670) }
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  671) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  672) /* Unmap and put previous page of userspace buffer */
8bfc016d2e2ff (Miklos Szeredi        2006-01-16 22:14:28 -0800  673) static void fuse_copy_finish(struct fuse_copy_state *cs)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  674) {
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200  675) 	if (cs->currbuf) {
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200  676) 		struct pipe_buffer *buf = cs->currbuf;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200  677) 
c55a01d360afa (Miklos Szeredi        2014-07-07 15:28:51 +0200  678) 		if (cs->write)
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  679) 			buf->len = PAGE_SIZE - cs->len;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200  680) 		cs->currbuf = NULL;
c55a01d360afa (Miklos Szeredi        2014-07-07 15:28:51 +0200  681) 	} else if (cs->pg) {
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  682) 		if (cs->write) {
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  683) 			flush_dcache_page(cs->pg);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  684) 			set_page_dirty_lock(cs->pg);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  685) 		}
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  686) 		put_page(cs->pg);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  687) 	}
c55a01d360afa (Miklos Szeredi        2014-07-07 15:28:51 +0200  688) 	cs->pg = NULL;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  689) }
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  690) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  691) /*
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  692)  * Get another pagefull of userspace buffer, and map it to kernel
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  693)  * address space, and lock request
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  694)  */
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  695) static int fuse_copy_fill(struct fuse_copy_state *cs)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  696) {
c55a01d360afa (Miklos Szeredi        2014-07-07 15:28:51 +0200  697) 	struct page *page;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  698) 	int err;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  699) 
dc00809a53edd (Miklos Szeredi        2015-07-01 16:25:58 +0200  700) 	err = unlock_request(cs->req);
0d8e84b0432be (Miklos Szeredi        2015-07-01 16:25:58 +0200  701) 	if (err)
0d8e84b0432be (Miklos Szeredi        2015-07-01 16:25:58 +0200  702) 		return err;
0d8e84b0432be (Miklos Szeredi        2015-07-01 16:25:58 +0200  703) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  704) 	fuse_copy_finish(cs);
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200  705) 	if (cs->pipebufs) {
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200  706) 		struct pipe_buffer *buf = cs->pipebufs;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200  707) 
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  708) 		if (!cs->write) {
fba597db4218a (Miklos Szeredi        2016-09-27 10:45:12 +0200  709) 			err = pipe_buf_confirm(cs->pipe, buf);
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  710) 			if (err)
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  711) 				return err;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  712) 
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  713) 			BUG_ON(!cs->nr_segs);
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  714) 			cs->currbuf = buf;
c55a01d360afa (Miklos Szeredi        2014-07-07 15:28:51 +0200  715) 			cs->pg = buf->page;
c55a01d360afa (Miklos Szeredi        2014-07-07 15:28:51 +0200  716) 			cs->offset = buf->offset;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  717) 			cs->len = buf->len;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  718) 			cs->pipebufs++;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  719) 			cs->nr_segs--;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  720) 		} else {
6718b6f855a0b (David Howells         2019-10-16 16:47:32 +0100  721) 			if (cs->nr_segs >= cs->pipe->max_usage)
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  722) 				return -EIO;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  723) 
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  724) 			page = alloc_page(GFP_HIGHUSER);
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  725) 			if (!page)
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  726) 				return -ENOMEM;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  727) 
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  728) 			buf->page = page;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  729) 			buf->offset = 0;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  730) 			buf->len = 0;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  731) 
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  732) 			cs->currbuf = buf;
c55a01d360afa (Miklos Szeredi        2014-07-07 15:28:51 +0200  733) 			cs->pg = page;
c55a01d360afa (Miklos Szeredi        2014-07-07 15:28:51 +0200  734) 			cs->offset = 0;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  735) 			cs->len = PAGE_SIZE;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  736) 			cs->pipebufs++;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  737) 			cs->nr_segs++;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  738) 		}
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200  739) 	} else {
6c09e94a32e10 (Al Viro               2015-04-03 22:06:08 -0400  740) 		size_t off;
6c09e94a32e10 (Al Viro               2015-04-03 22:06:08 -0400  741) 		err = iov_iter_get_pages(cs->iter, &page, PAGE_SIZE, 1, &off);
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200  742) 		if (err < 0)
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200  743) 			return err;
6c09e94a32e10 (Al Viro               2015-04-03 22:06:08 -0400  744) 		BUG_ON(!err);
6c09e94a32e10 (Al Viro               2015-04-03 22:06:08 -0400  745) 		cs->len = err;
6c09e94a32e10 (Al Viro               2015-04-03 22:06:08 -0400  746) 		cs->offset = off;
c55a01d360afa (Miklos Szeredi        2014-07-07 15:28:51 +0200  747) 		cs->pg = page;
6c09e94a32e10 (Al Viro               2015-04-03 22:06:08 -0400  748) 		iov_iter_advance(cs->iter, err);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  749) 	}
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  750) 
dc00809a53edd (Miklos Szeredi        2015-07-01 16:25:58 +0200  751) 	return lock_request(cs->req);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  752) }
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  753) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  754) /* Do as much copy to/from userspace buffer as we can */
8bfc016d2e2ff (Miklos Szeredi        2006-01-16 22:14:28 -0800  755) static int fuse_copy_do(struct fuse_copy_state *cs, void **val, unsigned *size)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  756) {
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  757) 	unsigned ncpy = min(*size, cs->len);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  758) 	if (val) {
c55a01d360afa (Miklos Szeredi        2014-07-07 15:28:51 +0200  759) 		void *pgaddr = kmap_atomic(cs->pg);
c55a01d360afa (Miklos Szeredi        2014-07-07 15:28:51 +0200  760) 		void *buf = pgaddr + cs->offset;
c55a01d360afa (Miklos Szeredi        2014-07-07 15:28:51 +0200  761) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  762) 		if (cs->write)
c55a01d360afa (Miklos Szeredi        2014-07-07 15:28:51 +0200  763) 			memcpy(buf, *val, ncpy);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  764) 		else
c55a01d360afa (Miklos Szeredi        2014-07-07 15:28:51 +0200  765) 			memcpy(*val, buf, ncpy);
c55a01d360afa (Miklos Szeredi        2014-07-07 15:28:51 +0200  766) 
c55a01d360afa (Miklos Szeredi        2014-07-07 15:28:51 +0200  767) 		kunmap_atomic(pgaddr);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  768) 		*val += ncpy;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  769) 	}
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  770) 	*size -= ncpy;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  771) 	cs->len -= ncpy;
c55a01d360afa (Miklos Szeredi        2014-07-07 15:28:51 +0200  772) 	cs->offset += ncpy;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  773) 	return ncpy;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  774) }
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  775) 
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  776) static int fuse_check_page(struct page *page)
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  777) {
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  778) 	if (page_mapcount(page) ||
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  779) 	    page->mapping != NULL ||
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  780) 	    (page->flags & PAGE_FLAGS_CHECK_AT_PREP &
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  781) 	     ~(1 << PG_locked |
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  782) 	       1 << PG_referenced |
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  783) 	       1 << PG_uptodate |
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  784) 	       1 << PG_lru |
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  785) 	       1 << PG_active |
76d97f2f3b028 (Miklos Szeredi        2021-06-18 21:16:42 +0200  786) 	       1 << PG_workingset |
a5005c3cda6ee (Miklos Szeredi        2020-05-19 14:50:37 +0200  787) 	       1 << PG_reclaim |
a5005c3cda6ee (Miklos Szeredi        2020-05-19 14:50:37 +0200  788) 	       1 << PG_waiters))) {
00589386172ac (Miklos Szeredi        2020-05-19 14:50:37 +0200  789) 		dump_page(page, "fuse: trying to steal weird page");
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  790) 		return 1;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  791) 	}
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  792) 	return 0;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  793) }
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  794) 
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  795) static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  796) {
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  797) 	int err;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  798) 	struct page *oldpage = *pagep;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  799) 	struct page *newpage;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  800) 	struct pipe_buffer *buf = cs->pipebufs;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  801) 
d78092e4937de (Miklos Szeredi        2020-09-18 10:36:50 +0200  802) 	get_page(oldpage);
dc00809a53edd (Miklos Szeredi        2015-07-01 16:25:58 +0200  803) 	err = unlock_request(cs->req);
0d8e84b0432be (Miklos Szeredi        2015-07-01 16:25:58 +0200  804) 	if (err)
d78092e4937de (Miklos Szeredi        2020-09-18 10:36:50 +0200  805) 		goto out_put_old;
0d8e84b0432be (Miklos Szeredi        2015-07-01 16:25:58 +0200  806) 
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  807) 	fuse_copy_finish(cs);
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  808) 
fba597db4218a (Miklos Szeredi        2016-09-27 10:45:12 +0200  809) 	err = pipe_buf_confirm(cs->pipe, buf);
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  810) 	if (err)
d78092e4937de (Miklos Szeredi        2020-09-18 10:36:50 +0200  811) 		goto out_put_old;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  812) 
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  813) 	BUG_ON(!cs->nr_segs);
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  814) 	cs->currbuf = buf;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  815) 	cs->len = buf->len;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  816) 	cs->pipebufs++;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  817) 	cs->nr_segs--;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  818) 
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  819) 	if (cs->len != PAGE_SIZE)
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  820) 		goto out_fallback;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  821) 
c928f642c29a5 (Christoph Hellwig     2020-05-20 17:58:16 +0200  822) 	if (!pipe_buf_try_steal(cs->pipe, buf))
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  823) 		goto out_fallback;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  824) 
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  825) 	newpage = buf->page;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  826) 
aa991b3b267e2 (Miklos Szeredi        2015-02-26 11:45:47 +0100  827) 	if (!PageUptodate(newpage))
aa991b3b267e2 (Miklos Szeredi        2015-02-26 11:45:47 +0100  828) 		SetPageUptodate(newpage);
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  829) 
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  830) 	ClearPageMappedToDisk(newpage);
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  831) 
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  832) 	if (fuse_check_page(newpage) != 0)
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  833) 		goto out_fallback_unlock;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  834) 
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  835) 	/*
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  836) 	 * This is a new and locked page, it shouldn't be mapped or
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  837) 	 * have any special flags on it
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  838) 	 */
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  839) 	if (WARN_ON(page_mapped(oldpage)))
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  840) 		goto out_fallback_unlock;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  841) 	if (WARN_ON(page_has_private(oldpage)))
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  842) 		goto out_fallback_unlock;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  843) 	if (WARN_ON(PageDirty(oldpage) || PageWriteback(oldpage)))
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  844) 		goto out_fallback_unlock;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  845) 	if (WARN_ON(PageMlocked(oldpage)))
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  846) 		goto out_fallback_unlock;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  847) 
1f7ef65774034 (Baolin Wang           2021-02-24 12:01:42 -0800  848) 	replace_page_cache_page(oldpage, newpage);
ef6a3c63112e8 (Miklos Szeredi        2011-03-22 16:30:52 -0700  849) 
09cbfeaf1a5a6 (Kirill A. Shutemov    2016-04-01 15:29:47 +0300  850) 	get_page(newpage);
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  851) 
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  852) 	if (!(buf->flags & PIPE_BUF_FLAG_LRU))
6058eaec816f2 (Johannes Weiner       2020-06-03 16:02:40 -0700  853) 		lru_cache_add(newpage);
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  854) 
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  855) 	err = 0;
dc00809a53edd (Miklos Szeredi        2015-07-01 16:25:58 +0200  856) 	spin_lock(&cs->req->waitq.lock);
825d6d3395e88 (Miklos Szeredi        2015-07-01 16:25:58 +0200  857) 	if (test_bit(FR_ABORTED, &cs->req->flags))
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  858) 		err = -ENOENT;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  859) 	else
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  860) 		*pagep = newpage;
dc00809a53edd (Miklos Szeredi        2015-07-01 16:25:58 +0200  861) 	spin_unlock(&cs->req->waitq.lock);
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  862) 
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  863) 	if (err) {
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  864) 		unlock_page(newpage);
09cbfeaf1a5a6 (Kirill A. Shutemov    2016-04-01 15:29:47 +0300  865) 		put_page(newpage);
d78092e4937de (Miklos Szeredi        2020-09-18 10:36:50 +0200  866) 		goto out_put_old;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  867) 	}
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  868) 
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  869) 	unlock_page(oldpage);
d78092e4937de (Miklos Szeredi        2020-09-18 10:36:50 +0200  870) 	/* Drop ref for ap->pages[] array */
09cbfeaf1a5a6 (Kirill A. Shutemov    2016-04-01 15:29:47 +0300  871) 	put_page(oldpage);
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  872) 	cs->len = 0;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  873) 
d78092e4937de (Miklos Szeredi        2020-09-18 10:36:50 +0200  874) 	err = 0;
d78092e4937de (Miklos Szeredi        2020-09-18 10:36:50 +0200  875) out_put_old:
d78092e4937de (Miklos Szeredi        2020-09-18 10:36:50 +0200  876) 	/* Drop ref obtained in this function */
d78092e4937de (Miklos Szeredi        2020-09-18 10:36:50 +0200  877) 	put_page(oldpage);
d78092e4937de (Miklos Szeredi        2020-09-18 10:36:50 +0200  878) 	return err;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  879) 
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  880) out_fallback_unlock:
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  881) 	unlock_page(newpage);
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  882) out_fallback:
c55a01d360afa (Miklos Szeredi        2014-07-07 15:28:51 +0200  883) 	cs->pg = buf->page;
c55a01d360afa (Miklos Szeredi        2014-07-07 15:28:51 +0200  884) 	cs->offset = buf->offset;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  885) 
dc00809a53edd (Miklos Szeredi        2015-07-01 16:25:58 +0200  886) 	err = lock_request(cs->req);
d78092e4937de (Miklos Szeredi        2020-09-18 10:36:50 +0200  887) 	if (!err)
d78092e4937de (Miklos Szeredi        2020-09-18 10:36:50 +0200  888) 		err = 1;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  889) 
d78092e4937de (Miklos Szeredi        2020-09-18 10:36:50 +0200  890) 	goto out_put_old;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  891) }
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  892) 
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  893) static int fuse_ref_page(struct fuse_copy_state *cs, struct page *page,
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  894) 			 unsigned offset, unsigned count)
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  895) {
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  896) 	struct pipe_buffer *buf;
0d8e84b0432be (Miklos Szeredi        2015-07-01 16:25:58 +0200  897) 	int err;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  898) 
6718b6f855a0b (David Howells         2019-10-16 16:47:32 +0100  899) 	if (cs->nr_segs >= cs->pipe->max_usage)
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  900) 		return -EIO;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  901) 
d78092e4937de (Miklos Szeredi        2020-09-18 10:36:50 +0200  902) 	get_page(page);
dc00809a53edd (Miklos Szeredi        2015-07-01 16:25:58 +0200  903) 	err = unlock_request(cs->req);
d78092e4937de (Miklos Szeredi        2020-09-18 10:36:50 +0200  904) 	if (err) {
d78092e4937de (Miklos Szeredi        2020-09-18 10:36:50 +0200  905) 		put_page(page);
0d8e84b0432be (Miklos Szeredi        2015-07-01 16:25:58 +0200  906) 		return err;
d78092e4937de (Miklos Szeredi        2020-09-18 10:36:50 +0200  907) 	}
0d8e84b0432be (Miklos Szeredi        2015-07-01 16:25:58 +0200  908) 
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  909) 	fuse_copy_finish(cs);
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  910) 
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  911) 	buf = cs->pipebufs;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  912) 	buf->page = page;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  913) 	buf->offset = offset;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  914) 	buf->len = count;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  915) 
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  916) 	cs->pipebufs++;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  917) 	cs->nr_segs++;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  918) 	cs->len = 0;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  919) 
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  920) 	return 0;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  921) }
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  922) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  923) /*
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  924)  * Copy a page in the request to/from the userspace buffer.  Must be
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  925)  * done atomically
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  926)  */
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  927) static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep,
8bfc016d2e2ff (Miklos Szeredi        2006-01-16 22:14:28 -0800  928) 			  unsigned offset, unsigned count, int zeroing)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  929) {
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  930) 	int err;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  931) 	struct page *page = *pagep;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  932) 
b6777c40c7916 (Miklos Szeredi        2010-10-26 14:22:27 -0700  933) 	if (page && zeroing && count < PAGE_SIZE)
b6777c40c7916 (Miklos Szeredi        2010-10-26 14:22:27 -0700  934) 		clear_highpage(page);
b6777c40c7916 (Miklos Szeredi        2010-10-26 14:22:27 -0700  935) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  936) 	while (count) {
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  937) 		if (cs->write && cs->pipebufs && page) {
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  938) 			return fuse_ref_page(cs, page, offset, count);
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200  939) 		} else if (!cs->len) {
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  940) 			if (cs->move_pages && page &&
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  941) 			    offset == 0 && count == PAGE_SIZE) {
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  942) 				err = fuse_try_move_page(cs, pagep);
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  943) 				if (err <= 0)
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  944) 					return err;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  945) 			} else {
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  946) 				err = fuse_copy_fill(cs);
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  947) 				if (err)
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  948) 					return err;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  949) 			}
1729a16c2c92b (Miklos Szeredi        2008-11-26 12:03:54 +0100  950) 		}
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  951) 		if (page) {
2408f6ef6bf58 (Cong Wang             2011-11-25 23:14:30 +0800  952) 			void *mapaddr = kmap_atomic(page);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  953) 			void *buf = mapaddr + offset;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  954) 			offset += fuse_copy_do(cs, &buf, &count);
2408f6ef6bf58 (Cong Wang             2011-11-25 23:14:30 +0800  955) 			kunmap_atomic(mapaddr);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  956) 		} else
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  957) 			offset += fuse_copy_do(cs, NULL, &count);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  958) 	}
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  959) 	if (page && !cs->write)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  960) 		flush_dcache_page(page);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  961) 	return 0;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  962) }
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  963) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  964) /* Copy pages in the request to/from userspace buffer */
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  965) static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes,
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  966) 			   int zeroing)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  967) {
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  968) 	unsigned i;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  969) 	struct fuse_req *req = cs->req;
05ea48cc2b098 (Miklos Szeredi        2019-09-10 15:04:11 +0200  970) 	struct fuse_args_pages *ap = container_of(req->args, typeof(*ap), args);
05ea48cc2b098 (Miklos Szeredi        2019-09-10 15:04:11 +0200  971) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  972) 
05ea48cc2b098 (Miklos Szeredi        2019-09-10 15:04:11 +0200  973) 	for (i = 0; i < ap->num_pages && (nbytes || zeroing); i++) {
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  974) 		int err;
05ea48cc2b098 (Miklos Szeredi        2019-09-10 15:04:11 +0200  975) 		unsigned int offset = ap->descs[i].offset;
05ea48cc2b098 (Miklos Szeredi        2019-09-10 15:04:11 +0200  976) 		unsigned int count = min(nbytes, ap->descs[i].length);
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200  977) 
05ea48cc2b098 (Miklos Szeredi        2019-09-10 15:04:11 +0200  978) 		err = fuse_copy_page(cs, &ap->pages[i], offset, count, zeroing);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  979) 		if (err)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  980) 			return err;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  981) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  982) 		nbytes -= count;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  983) 	}
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  984) 	return 0;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  985) }
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  986) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  987) /* Copy a single argument in the request to/from userspace buffer */
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  988) static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  989) {
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  990) 	while (size) {
1729a16c2c92b (Miklos Szeredi        2008-11-26 12:03:54 +0100  991) 		if (!cs->len) {
1729a16c2c92b (Miklos Szeredi        2008-11-26 12:03:54 +0100  992) 			int err = fuse_copy_fill(cs);
1729a16c2c92b (Miklos Szeredi        2008-11-26 12:03:54 +0100  993) 			if (err)
1729a16c2c92b (Miklos Szeredi        2008-11-26 12:03:54 +0100  994) 				return err;
1729a16c2c92b (Miklos Szeredi        2008-11-26 12:03:54 +0100  995) 		}
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  996) 		fuse_copy_do(cs, &val, &size);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  997) 	}
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  998) 	return 0;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700  999) }
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1000) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1001) /* Copy request arguments to/from userspace buffer */
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1002) static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs,
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1003) 			  unsigned argpages, struct fuse_arg *args,
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1004) 			  int zeroing)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1005) {
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1006) 	int err = 0;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1007) 	unsigned i;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1008) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1009) 	for (i = 0; !err && i < numargs; i++)  {
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1010) 		struct fuse_arg *arg = &args[i];
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1011) 		if (i == numargs - 1 && argpages)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1012) 			err = fuse_copy_pages(cs, arg->size, zeroing);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1013) 		else
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1014) 			err = fuse_copy_one(cs, arg->value, arg->size);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1015) 	}
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1016) 	return err;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1017) }
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1018) 
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200 1019) static int forget_pending(struct fuse_iqueue *fiq)
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1020) {
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200 1021) 	return fiq->forget_list_head.next != NULL;
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1022) }
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1023) 
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200 1024) static int request_pending(struct fuse_iqueue *fiq)
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1025) {
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200 1026) 	return !list_empty(&fiq->pending) || !list_empty(&fiq->interrupts) ||
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200 1027) 		forget_pending(fiq);
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1028) }
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1029) 
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1030) /*
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1031)  * Transfer an interrupt request to userspace
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1032)  *
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1033)  * Unlike other requests this is assembled on demand, without a need
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1034)  * to allocate a separate fuse_req structure.
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1035)  *
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 1036)  * Called with fiq->lock held, releases it
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1037)  */
fd22d62ed0c36 (Miklos Szeredi        2015-07-01 16:26:03 +0200 1038) static int fuse_read_interrupt(struct fuse_iqueue *fiq,
fd22d62ed0c36 (Miklos Szeredi        2015-07-01 16:26:03 +0200 1039) 			       struct fuse_copy_state *cs,
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1040) 			       size_t nbytes, struct fuse_req *req)
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 1041) __releases(fiq->lock)
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1042) {
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1043) 	struct fuse_in_header ih;
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1044) 	struct fuse_interrupt_in arg;
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1045) 	unsigned reqsize = sizeof(ih) + sizeof(arg);
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1046) 	int err;
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1047) 
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1048) 	list_del_init(&req->intr_entry);
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1049) 	memset(&ih, 0, sizeof(ih));
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1050) 	memset(&arg, 0, sizeof(arg));
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1051) 	ih.len = reqsize;
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1052) 	ih.opcode = FUSE_INTERRUPT;
3a5358d1a1b70 (Kirill Tkhai          2018-09-11 13:12:05 +0300 1053) 	ih.unique = (req->in.h.unique | FUSE_INT_REQ_BIT);
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1054) 	arg.unique = req->in.h.unique;
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1055) 
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 1056) 	spin_unlock(&fiq->lock);
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1057) 	if (nbytes < reqsize)
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1058) 		return -EINVAL;
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1059) 
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1060) 	err = fuse_copy_one(cs, &ih, sizeof(ih));
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1061) 	if (!err)
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1062) 		err = fuse_copy_one(cs, &arg, sizeof(arg));
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1063) 	fuse_copy_finish(cs);
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1064) 
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1065) 	return err ? err : reqsize;
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1066) }
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1067) 
4388c5aac4bae (Vivek Goyal           2019-06-05 15:50:43 -0400 1068) struct fuse_forget_link *fuse_dequeue_forget(struct fuse_iqueue *fiq,
4388c5aac4bae (Vivek Goyal           2019-06-05 15:50:43 -0400 1069) 					     unsigned int max,
4388c5aac4bae (Vivek Goyal           2019-06-05 15:50:43 -0400 1070) 					     unsigned int *countp)
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1071) {
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200 1072) 	struct fuse_forget_link *head = fiq->forget_list_head.next;
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1073) 	struct fuse_forget_link **newhead = &head;
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1074) 	unsigned count;
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1075) 
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1076) 	for (count = 0; *newhead != NULL && count < max; count++)
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1077) 		newhead = &(*newhead)->next;
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1078) 
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200 1079) 	fiq->forget_list_head.next = *newhead;
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1080) 	*newhead = NULL;
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200 1081) 	if (fiq->forget_list_head.next == NULL)
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200 1082) 		fiq->forget_list_tail = &fiq->forget_list_head;
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1083) 
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1084) 	if (countp != NULL)
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1085) 		*countp = count;
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1086) 
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1087) 	return head;
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1088) }
4388c5aac4bae (Vivek Goyal           2019-06-05 15:50:43 -0400 1089) EXPORT_SYMBOL(fuse_dequeue_forget);
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1090) 
fd22d62ed0c36 (Miklos Szeredi        2015-07-01 16:26:03 +0200 1091) static int fuse_read_single_forget(struct fuse_iqueue *fiq,
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1092) 				   struct fuse_copy_state *cs,
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1093) 				   size_t nbytes)
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 1094) __releases(fiq->lock)
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1095) {
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1096) 	int err;
4388c5aac4bae (Vivek Goyal           2019-06-05 15:50:43 -0400 1097) 	struct fuse_forget_link *forget = fuse_dequeue_forget(fiq, 1, NULL);
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1098) 	struct fuse_forget_in arg = {
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1099) 		.nlookup = forget->forget_one.nlookup,
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1100) 	};
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1101) 	struct fuse_in_header ih = {
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1102) 		.opcode = FUSE_FORGET,
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1103) 		.nodeid = forget->forget_one.nodeid,
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200 1104) 		.unique = fuse_get_unique(fiq),
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1105) 		.len = sizeof(ih) + sizeof(arg),
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1106) 	};
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1107) 
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 1108) 	spin_unlock(&fiq->lock);
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1109) 	kfree(forget);
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1110) 	if (nbytes < ih.len)
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1111) 		return -EINVAL;
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1112) 
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1113) 	err = fuse_copy_one(cs, &ih, sizeof(ih));
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1114) 	if (!err)
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1115) 		err = fuse_copy_one(cs, &arg, sizeof(arg));
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1116) 	fuse_copy_finish(cs);
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1117) 
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1118) 	if (err)
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1119) 		return err;
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1120) 
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1121) 	return ih.len;
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1122) }
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1123) 
fd22d62ed0c36 (Miklos Szeredi        2015-07-01 16:26:03 +0200 1124) static int fuse_read_batch_forget(struct fuse_iqueue *fiq,
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1125) 				   struct fuse_copy_state *cs, size_t nbytes)
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 1126) __releases(fiq->lock)
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1127) {
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1128) 	int err;
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1129) 	unsigned max_forgets;
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1130) 	unsigned count;
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1131) 	struct fuse_forget_link *head;
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1132) 	struct fuse_batch_forget_in arg = { .count = 0 };
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1133) 	struct fuse_in_header ih = {
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1134) 		.opcode = FUSE_BATCH_FORGET,
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200 1135) 		.unique = fuse_get_unique(fiq),
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1136) 		.len = sizeof(ih) + sizeof(arg),
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1137) 	};
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1138) 
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1139) 	if (nbytes < ih.len) {
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 1140) 		spin_unlock(&fiq->lock);
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1141) 		return -EINVAL;
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1142) 	}
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1143) 
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1144) 	max_forgets = (nbytes - ih.len) / sizeof(struct fuse_forget_one);
4388c5aac4bae (Vivek Goyal           2019-06-05 15:50:43 -0400 1145) 	head = fuse_dequeue_forget(fiq, max_forgets, &count);
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 1146) 	spin_unlock(&fiq->lock);
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1147) 
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1148) 	arg.count = count;
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1149) 	ih.len += count * sizeof(struct fuse_forget_one);
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1150) 	err = fuse_copy_one(cs, &ih, sizeof(ih));
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1151) 	if (!err)
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1152) 		err = fuse_copy_one(cs, &arg, sizeof(arg));
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1153) 
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1154) 	while (head) {
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1155) 		struct fuse_forget_link *forget = head;
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1156) 
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1157) 		if (!err) {
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1158) 			err = fuse_copy_one(cs, &forget->forget_one,
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1159) 					    sizeof(forget->forget_one));
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1160) 		}
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1161) 		head = forget->next;
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1162) 		kfree(forget);
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1163) 	}
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1164) 
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1165) 	fuse_copy_finish(cs);
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1166) 
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1167) 	if (err)
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1168) 		return err;
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1169) 
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1170) 	return ih.len;
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1171) }
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1172) 
fd22d62ed0c36 (Miklos Szeredi        2015-07-01 16:26:03 +0200 1173) static int fuse_read_forget(struct fuse_conn *fc, struct fuse_iqueue *fiq,
fd22d62ed0c36 (Miklos Szeredi        2015-07-01 16:26:03 +0200 1174) 			    struct fuse_copy_state *cs,
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1175) 			    size_t nbytes)
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 1176) __releases(fiq->lock)
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1177) {
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200 1178) 	if (fc->minor < 16 || fiq->forget_list_head.next->next == NULL)
fd22d62ed0c36 (Miklos Szeredi        2015-07-01 16:26:03 +0200 1179) 		return fuse_read_single_forget(fiq, cs, nbytes);
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1180) 	else
fd22d62ed0c36 (Miklos Szeredi        2015-07-01 16:26:03 +0200 1181) 		return fuse_read_batch_forget(fiq, cs, nbytes);
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1182) }
02c048b919455 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1183) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1184) /*
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1185)  * Read a single request into the userspace filesystem's buffer.  This
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1186)  * function waits until a request is available, then removes it from
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1187)  * the pending list and copies request data to userspace buffer.  If
f9a2842e5612b (Miklos Szeredi        2006-06-25 05:48:53 -0700 1188)  * no reply is needed (FORGET) or request has been aborted or there
f9a2842e5612b (Miklos Szeredi        2006-06-25 05:48:53 -0700 1189)  * was an error during the copying then it's finished by calling
04ec5af0776e9 (Stefan Hajnoczi       2018-06-21 09:33:40 +0100 1190)  * fuse_request_end().  Otherwise add it to the processing list, and set
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1191)  * the 'sent' flag.
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1192)  */
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 1193) static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1194) 				struct fuse_copy_state *cs, size_t nbytes)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1195) {
82cbdcd320852 (Miklos Szeredi        2015-07-01 16:26:05 +0200 1196) 	ssize_t err;
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 1197) 	struct fuse_conn *fc = fud->fc;
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200 1198) 	struct fuse_iqueue *fiq = &fc->iq;
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 1199) 	struct fuse_pqueue *fpq = &fud->pq;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1200) 	struct fuse_req *req;
d49937749fef2 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1201) 	struct fuse_args *args;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1202) 	unsigned reqsize;
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 1203) 	unsigned int hash;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1204) 
1fb027d759646 (Kirill Smelkov        2019-07-08 17:03:31 +0000 1205) 	/*
1fb027d759646 (Kirill Smelkov        2019-07-08 17:03:31 +0000 1206) 	 * Require sane minimum read buffer - that has capacity for fixed part
1fb027d759646 (Kirill Smelkov        2019-07-08 17:03:31 +0000 1207) 	 * of any request header + negotiated max_write room for data.
1fb027d759646 (Kirill Smelkov        2019-07-08 17:03:31 +0000 1208) 	 *
1fb027d759646 (Kirill Smelkov        2019-07-08 17:03:31 +0000 1209) 	 * Historically libfuse reserves 4K for fixed header room, but e.g.
1fb027d759646 (Kirill Smelkov        2019-07-08 17:03:31 +0000 1210) 	 * GlusterFS reserves only 80 bytes
1fb027d759646 (Kirill Smelkov        2019-07-08 17:03:31 +0000 1211) 	 *
1fb027d759646 (Kirill Smelkov        2019-07-08 17:03:31 +0000 1212) 	 *	= `sizeof(fuse_in_header) + sizeof(fuse_write_in)`
1fb027d759646 (Kirill Smelkov        2019-07-08 17:03:31 +0000 1213) 	 *
1fb027d759646 (Kirill Smelkov        2019-07-08 17:03:31 +0000 1214) 	 * which is the absolute minimum any sane filesystem should be using
1fb027d759646 (Kirill Smelkov        2019-07-08 17:03:31 +0000 1215) 	 * for header room.
1fb027d759646 (Kirill Smelkov        2019-07-08 17:03:31 +0000 1216) 	 */
1fb027d759646 (Kirill Smelkov        2019-07-08 17:03:31 +0000 1217) 	if (nbytes < max_t(size_t, FUSE_MIN_READ_BUFFER,
1fb027d759646 (Kirill Smelkov        2019-07-08 17:03:31 +0000 1218) 			   sizeof(struct fuse_in_header) +
1fb027d759646 (Kirill Smelkov        2019-07-08 17:03:31 +0000 1219) 			   sizeof(struct fuse_write_in) +
1fb027d759646 (Kirill Smelkov        2019-07-08 17:03:31 +0000 1220) 			   fc->max_write))
1fb027d759646 (Kirill Smelkov        2019-07-08 17:03:31 +0000 1221) 		return -EINVAL;
1fb027d759646 (Kirill Smelkov        2019-07-08 17:03:31 +0000 1222) 
1d3d752b471d2 (Miklos Szeredi        2006-01-06 00:19:40 -0800 1223)  restart:
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 1224) 	for (;;) {
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 1225) 		spin_lock(&fiq->lock);
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 1226) 		if (!fiq->connected || request_pending(fiq))
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 1227) 			break;
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 1228) 		spin_unlock(&fiq->lock);
e5ac1d1e70a8c (Jeff Dike             2006-04-10 22:54:53 -0700 1229) 
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 1230) 		if (file->f_flags & O_NONBLOCK)
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 1231) 			return -EAGAIN;
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 1232) 		err = wait_event_interruptible_exclusive(fiq->waitq,
5250921bb0b25 (Miklos Szeredi        2015-07-01 16:26:03 +0200 1233) 				!fiq->connected || request_pending(fiq));
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 1234) 		if (err)
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 1235) 			return err;
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 1236) 	}
5250921bb0b25 (Miklos Szeredi        2015-07-01 16:26:03 +0200 1237) 
3b7008b226f3d (Szymon Lukasz         2017-11-09 21:23:35 +0100 1238) 	if (!fiq->connected) {
eb98e3bdf3aa7 (Miklos Szeredi        2019-01-24 10:40:16 +0100 1239) 		err = fc->aborted ? -ECONNABORTED : -ENODEV;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1240) 		goto err_unlock;
3b7008b226f3d (Szymon Lukasz         2017-11-09 21:23:35 +0100 1241) 	}
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1242) 
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200 1243) 	if (!list_empty(&fiq->interrupts)) {
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200 1244) 		req = list_entry(fiq->interrupts.next, struct fuse_req,
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1245) 				 intr_entry);
fd22d62ed0c36 (Miklos Szeredi        2015-07-01 16:26:03 +0200 1246) 		return fuse_read_interrupt(fiq, cs, nbytes, req);
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1247) 	}
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1248) 
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200 1249) 	if (forget_pending(fiq)) {
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200 1250) 		if (list_empty(&fiq->pending) || fiq->forget_batch-- > 0)
fd22d62ed0c36 (Miklos Szeredi        2015-07-01 16:26:03 +0200 1251) 			return fuse_read_forget(fc, fiq, cs, nbytes);
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1252) 
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200 1253) 		if (fiq->forget_batch <= -8)
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200 1254) 			fiq->forget_batch = 16;
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1255) 	}
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100 1256) 
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200 1257) 	req = list_entry(fiq->pending.next, struct fuse_req, list);
33e14b4dfdc47 (Miklos Szeredi        2015-07-01 16:26:01 +0200 1258) 	clear_bit(FR_PENDING, &req->flags);
ef759258869c6 (Miklos Szeredi        2015-07-01 16:26:02 +0200 1259) 	list_del_init(&req->list);
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 1260) 	spin_unlock(&fiq->lock);
4ce6081260ea4 (Miklos Szeredi        2015-07-01 16:26:02 +0200 1261) 
d49937749fef2 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1262) 	args = req->args;
d49937749fef2 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1263) 	reqsize = req->in.h.len;
5d6d3a301c4e7 (Miklos Szeredi        2017-09-12 16:57:53 +0200 1264) 
1d3d752b471d2 (Miklos Szeredi        2006-01-06 00:19:40 -0800 1265) 	/* If request is too large, reply with an error and restart the read */
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1266) 	if (nbytes < reqsize) {
1d3d752b471d2 (Miklos Szeredi        2006-01-06 00:19:40 -0800 1267) 		req->out.h.error = -EIO;
1d3d752b471d2 (Miklos Szeredi        2006-01-06 00:19:40 -0800 1268) 		/* SETXATTR is special, since it may contain too large data */
d49937749fef2 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1269) 		if (args->opcode == FUSE_SETXATTR)
1d3d752b471d2 (Miklos Szeredi        2006-01-06 00:19:40 -0800 1270) 			req->out.h.error = -E2BIG;
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200 1271) 		fuse_request_end(req);
1d3d752b471d2 (Miklos Szeredi        2006-01-06 00:19:40 -0800 1272) 		goto restart;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1273) 	}
45a91cb1a4fd9 (Miklos Szeredi        2015-07-01 16:26:06 +0200 1274) 	spin_lock(&fpq->lock);
2644fd6588e59 (Miklos Szeredi        2021-06-22 09:15:35 +0200 1275) 	/*
2644fd6588e59 (Miklos Szeredi        2021-06-22 09:15:35 +0200 1276) 	 *  Must not put request on fpq->io queue after having been shut down by
2644fd6588e59 (Miklos Szeredi        2021-06-22 09:15:35 +0200 1277) 	 *  fuse_abort_conn()
2644fd6588e59 (Miklos Szeredi        2021-06-22 09:15:35 +0200 1278) 	 */
2644fd6588e59 (Miklos Szeredi        2021-06-22 09:15:35 +0200 1279) 	if (!fpq->connected) {
2644fd6588e59 (Miklos Szeredi        2021-06-22 09:15:35 +0200 1280) 		req->out.h.error = err = -ECONNABORTED;
2644fd6588e59 (Miklos Szeredi        2021-06-22 09:15:35 +0200 1281) 		goto out_end;
2644fd6588e59 (Miklos Szeredi        2021-06-22 09:15:35 +0200 1282) 
2644fd6588e59 (Miklos Szeredi        2021-06-22 09:15:35 +0200 1283) 	}
82cbdcd320852 (Miklos Szeredi        2015-07-01 16:26:05 +0200 1284) 	list_add(&req->list, &fpq->io);
45a91cb1a4fd9 (Miklos Szeredi        2015-07-01 16:26:06 +0200 1285) 	spin_unlock(&fpq->lock);
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1286) 	cs->req = req;
d49937749fef2 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1287) 	err = fuse_copy_one(cs, &req->in.h, sizeof(req->in.h));
1d3d752b471d2 (Miklos Szeredi        2006-01-06 00:19:40 -0800 1288) 	if (!err)
d49937749fef2 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1289) 		err = fuse_copy_args(cs, args->in_numargs, args->in_pages,
d49937749fef2 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1290) 				     (struct fuse_arg *) args->in_args, 0);
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1291) 	fuse_copy_finish(cs);
45a91cb1a4fd9 (Miklos Szeredi        2015-07-01 16:26:06 +0200 1292) 	spin_lock(&fpq->lock);
825d6d3395e88 (Miklos Szeredi        2015-07-01 16:25:58 +0200 1293) 	clear_bit(FR_LOCKED, &req->flags);
e96edd94d0887 (Miklos Szeredi        2015-07-01 16:26:04 +0200 1294) 	if (!fpq->connected) {
eb98e3bdf3aa7 (Miklos Szeredi        2019-01-24 10:40:16 +0100 1295) 		err = fc->aborted ? -ECONNABORTED : -ENODEV;
82cbdcd320852 (Miklos Szeredi        2015-07-01 16:26:05 +0200 1296) 		goto out_end;
c9c9d7df5f8ae (Miklos Szeredi        2007-10-16 23:31:05 -0700 1297) 	}
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1298) 	if (err) {
c9c9d7df5f8ae (Miklos Szeredi        2007-10-16 23:31:05 -0700 1299) 		req->out.h.error = -EIO;
82cbdcd320852 (Miklos Szeredi        2015-07-01 16:26:05 +0200 1300) 		goto out_end;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1301) 	}
825d6d3395e88 (Miklos Szeredi        2015-07-01 16:25:58 +0200 1302) 	if (!test_bit(FR_ISREPLY, &req->flags)) {
82cbdcd320852 (Miklos Szeredi        2015-07-01 16:26:05 +0200 1303) 		err = reqsize;
82cbdcd320852 (Miklos Szeredi        2015-07-01 16:26:05 +0200 1304) 		goto out_end;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1305) 	}
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 1306) 	hash = fuse_req_hash(req->in.h.unique);
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 1307) 	list_move_tail(&req->list, &fpq->processing[hash]);
bc78abbd55dd2 (Kirill Tkhai          2018-09-25 12:28:55 +0300 1308) 	__fuse_get_request(req);
82cbdcd320852 (Miklos Szeredi        2015-07-01 16:26:05 +0200 1309) 	set_bit(FR_SENT, &req->flags);
4c316f2f3ff31 (Miklos Szeredi        2018-09-28 16:43:22 +0200 1310) 	spin_unlock(&fpq->lock);
82cbdcd320852 (Miklos Szeredi        2015-07-01 16:26:05 +0200 1311) 	/* matches barrier in request_wait_answer() */
82cbdcd320852 (Miklos Szeredi        2015-07-01 16:26:05 +0200 1312) 	smp_mb__after_atomic();
82cbdcd320852 (Miklos Szeredi        2015-07-01 16:26:05 +0200 1313) 	if (test_bit(FR_INTERRUPTED, &req->flags))
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200 1314) 		queue_interrupt(req);
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200 1315) 	fuse_put_request(req);
82cbdcd320852 (Miklos Szeredi        2015-07-01 16:26:05 +0200 1316) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1317) 	return reqsize;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1318) 
82cbdcd320852 (Miklos Szeredi        2015-07-01 16:26:05 +0200 1319) out_end:
77cd9d488b32d (Miklos Szeredi        2015-07-01 16:26:06 +0200 1320) 	if (!test_bit(FR_PRIVATE, &req->flags))
77cd9d488b32d (Miklos Szeredi        2015-07-01 16:26:06 +0200 1321) 		list_del_init(&req->list);
45a91cb1a4fd9 (Miklos Szeredi        2015-07-01 16:26:06 +0200 1322) 	spin_unlock(&fpq->lock);
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200 1323) 	fuse_request_end(req);
82cbdcd320852 (Miklos Szeredi        2015-07-01 16:26:05 +0200 1324) 	return err;
82cbdcd320852 (Miklos Szeredi        2015-07-01 16:26:05 +0200 1325) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1326)  err_unlock:
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 1327) 	spin_unlock(&fiq->lock);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1328) 	return err;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1329) }
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1330) 
94e4fe2cab3d4 (Tom Van Braeckel      2015-01-12 05:22:16 +0100 1331) static int fuse_dev_open(struct inode *inode, struct file *file)
94e4fe2cab3d4 (Tom Van Braeckel      2015-01-12 05:22:16 +0100 1332) {
94e4fe2cab3d4 (Tom Van Braeckel      2015-01-12 05:22:16 +0100 1333) 	/*
94e4fe2cab3d4 (Tom Van Braeckel      2015-01-12 05:22:16 +0100 1334) 	 * The fuse device's file's private_data is used to hold
94e4fe2cab3d4 (Tom Van Braeckel      2015-01-12 05:22:16 +0100 1335) 	 * the fuse_conn(ection) when it is mounted, and is used to
94e4fe2cab3d4 (Tom Van Braeckel      2015-01-12 05:22:16 +0100 1336) 	 * keep track of whether the file has been mounted already.
94e4fe2cab3d4 (Tom Van Braeckel      2015-01-12 05:22:16 +0100 1337) 	 */
94e4fe2cab3d4 (Tom Van Braeckel      2015-01-12 05:22:16 +0100 1338) 	file->private_data = NULL;
94e4fe2cab3d4 (Tom Van Braeckel      2015-01-12 05:22:16 +0100 1339) 	return 0;
94e4fe2cab3d4 (Tom Van Braeckel      2015-01-12 05:22:16 +0100 1340) }
94e4fe2cab3d4 (Tom Van Braeckel      2015-01-12 05:22:16 +0100 1341) 
fbdbacca61531 (Al Viro               2015-04-03 21:53:39 -0400 1342) static ssize_t fuse_dev_read(struct kiocb *iocb, struct iov_iter *to)
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1343) {
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1344) 	struct fuse_copy_state cs;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1345) 	struct file *file = iocb->ki_filp;
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1346) 	struct fuse_dev *fud = fuse_get_dev(file);
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1347) 
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1348) 	if (!fud)
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1349) 		return -EPERM;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1350) 
fbdbacca61531 (Al Viro               2015-04-03 21:53:39 -0400 1351) 	if (!iter_is_iovec(to))
fbdbacca61531 (Al Viro               2015-04-03 21:53:39 -0400 1352) 		return -EINVAL;
fbdbacca61531 (Al Viro               2015-04-03 21:53:39 -0400 1353) 
dc00809a53edd (Miklos Szeredi        2015-07-01 16:25:58 +0200 1354) 	fuse_copy_init(&cs, 1, to);
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1355) 
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 1356) 	return fuse_dev_do_read(fud, file, &cs, iov_iter_count(to));
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1357) }
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1358) 
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1359) static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1360) 				    struct pipe_inode_info *pipe,
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1361) 				    size_t len, unsigned int flags)
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1362) {
d82718e348fee (Al Viro               2016-09-17 22:56:25 -0400 1363) 	int total, ret;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1364) 	int page_nr = 0;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1365) 	struct pipe_buffer *bufs;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1366) 	struct fuse_copy_state cs;
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1367) 	struct fuse_dev *fud = fuse_get_dev(in);
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1368) 
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1369) 	if (!fud)
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1370) 		return -EPERM;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1371) 
6718b6f855a0b (David Howells         2019-10-16 16:47:32 +0100 1372) 	bufs = kvmalloc_array(pipe->max_usage, sizeof(struct pipe_buffer),
d6d931adce119 (Andrey Ryabinin       2018-07-17 19:00:34 +0300 1373) 			      GFP_KERNEL);
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1374) 	if (!bufs)
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1375) 		return -ENOMEM;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1376) 
dc00809a53edd (Miklos Szeredi        2015-07-01 16:25:58 +0200 1377) 	fuse_copy_init(&cs, 1, NULL);
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1378) 	cs.pipebufs = bufs;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1379) 	cs.pipe = pipe;
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 1380) 	ret = fuse_dev_do_read(fud, in, &cs, len);
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1381) 	if (ret < 0)
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1382) 		goto out;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1383) 
6718b6f855a0b (David Howells         2019-10-16 16:47:32 +0100 1384) 	if (pipe_occupancy(pipe->head, pipe->tail) + cs.nr_segs > pipe->max_usage) {
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1385) 		ret = -EIO;
d82718e348fee (Al Viro               2016-09-17 22:56:25 -0400 1386) 		goto out;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1387) 	}
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1388) 
d82718e348fee (Al Viro               2016-09-17 22:56:25 -0400 1389) 	for (ret = total = 0; page_nr < cs.nr_segs; total += ret) {
28a625cbc2a14 (Miklos Szeredi        2014-01-22 19:36:57 +0100 1390) 		/*
28a625cbc2a14 (Miklos Szeredi        2014-01-22 19:36:57 +0100 1391) 		 * Need to be careful about this.  Having buf->ops in module
28a625cbc2a14 (Miklos Szeredi        2014-01-22 19:36:57 +0100 1392) 		 * code can Oops if the buffer persists after module unload.
28a625cbc2a14 (Miklos Szeredi        2014-01-22 19:36:57 +0100 1393) 		 */
d82718e348fee (Al Viro               2016-09-17 22:56:25 -0400 1394) 		bufs[page_nr].ops = &nosteal_pipe_buf_ops;
84588a93d097b (Miklos Szeredi        2017-02-16 15:08:20 +0100 1395) 		bufs[page_nr].flags = 0;
d82718e348fee (Al Viro               2016-09-17 22:56:25 -0400 1396) 		ret = add_to_pipe(pipe, &bufs[page_nr++]);
d82718e348fee (Al Viro               2016-09-17 22:56:25 -0400 1397) 		if (unlikely(ret < 0))
d82718e348fee (Al Viro               2016-09-17 22:56:25 -0400 1398) 			break;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1399) 	}
d82718e348fee (Al Viro               2016-09-17 22:56:25 -0400 1400) 	if (total)
d82718e348fee (Al Viro               2016-09-17 22:56:25 -0400 1401) 		ret = total;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1402) out:
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1403) 	for (; page_nr < cs.nr_segs; page_nr++)
09cbfeaf1a5a6 (Kirill A. Shutemov    2016-04-01 15:29:47 +0300 1404) 		put_page(bufs[page_nr].page);
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1405) 
d6d931adce119 (Andrey Ryabinin       2018-07-17 19:00:34 +0300 1406) 	kvfree(bufs);
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1407) 	return ret;
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1408) }
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1409) 
95668a69a4bb8 (Tejun Heo             2008-11-26 12:03:55 +0100 1410) static int fuse_notify_poll(struct fuse_conn *fc, unsigned int size,
95668a69a4bb8 (Tejun Heo             2008-11-26 12:03:55 +0100 1411) 			    struct fuse_copy_state *cs)
95668a69a4bb8 (Tejun Heo             2008-11-26 12:03:55 +0100 1412) {
95668a69a4bb8 (Tejun Heo             2008-11-26 12:03:55 +0100 1413) 	struct fuse_notify_poll_wakeup_out outarg;
f6d47a1761896 (Miklos Szeredi        2009-01-26 15:00:59 +0100 1414) 	int err = -EINVAL;
95668a69a4bb8 (Tejun Heo             2008-11-26 12:03:55 +0100 1415) 
95668a69a4bb8 (Tejun Heo             2008-11-26 12:03:55 +0100 1416) 	if (size != sizeof(outarg))
f6d47a1761896 (Miklos Szeredi        2009-01-26 15:00:59 +0100 1417) 		goto err;
95668a69a4bb8 (Tejun Heo             2008-11-26 12:03:55 +0100 1418) 
95668a69a4bb8 (Tejun Heo             2008-11-26 12:03:55 +0100 1419) 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
95668a69a4bb8 (Tejun Heo             2008-11-26 12:03:55 +0100 1420) 	if (err)
f6d47a1761896 (Miklos Szeredi        2009-01-26 15:00:59 +0100 1421) 		goto err;
95668a69a4bb8 (Tejun Heo             2008-11-26 12:03:55 +0100 1422) 
f6d47a1761896 (Miklos Szeredi        2009-01-26 15:00:59 +0100 1423) 	fuse_copy_finish(cs);
95668a69a4bb8 (Tejun Heo             2008-11-26 12:03:55 +0100 1424) 	return fuse_notify_poll_wakeup(fc, &outarg);
f6d47a1761896 (Miklos Szeredi        2009-01-26 15:00:59 +0100 1425) 
f6d47a1761896 (Miklos Szeredi        2009-01-26 15:00:59 +0100 1426) err:
f6d47a1761896 (Miklos Szeredi        2009-01-26 15:00:59 +0100 1427) 	fuse_copy_finish(cs);
f6d47a1761896 (Miklos Szeredi        2009-01-26 15:00:59 +0100 1428) 	return err;
95668a69a4bb8 (Tejun Heo             2008-11-26 12:03:55 +0100 1429) }
95668a69a4bb8 (Tejun Heo             2008-11-26 12:03:55 +0100 1430) 
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1431) static int fuse_notify_inval_inode(struct fuse_conn *fc, unsigned int size,
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1432) 				   struct fuse_copy_state *cs)
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1433) {
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1434) 	struct fuse_notify_inval_inode_out outarg;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1435) 	int err = -EINVAL;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1436) 
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1437) 	if (size != sizeof(outarg))
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1438) 		goto err;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1439) 
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1440) 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1441) 	if (err)
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1442) 		goto err;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1443) 	fuse_copy_finish(cs);
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1444) 
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1445) 	down_read(&fc->killsb);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1446) 	err = fuse_reverse_inval_inode(fc, outarg.ino,
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1447) 				       outarg.off, outarg.len);
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1448) 	up_read(&fc->killsb);
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1449) 	return err;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1450) 
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1451) err:
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1452) 	fuse_copy_finish(cs);
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1453) 	return err;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1454) }
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1455) 
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1456) static int fuse_notify_inval_entry(struct fuse_conn *fc, unsigned int size,
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1457) 				   struct fuse_copy_state *cs)
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1458) {
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1459) 	struct fuse_notify_inval_entry_out outarg;
b2d82ee3c8b21 (Fang Wenqi            2009-12-30 18:37:13 +0800 1460) 	int err = -ENOMEM;
b2d82ee3c8b21 (Fang Wenqi            2009-12-30 18:37:13 +0800 1461) 	char *buf;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1462) 	struct qstr name;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1463) 
b2d82ee3c8b21 (Fang Wenqi            2009-12-30 18:37:13 +0800 1464) 	buf = kzalloc(FUSE_NAME_MAX + 1, GFP_KERNEL);
b2d82ee3c8b21 (Fang Wenqi            2009-12-30 18:37:13 +0800 1465) 	if (!buf)
b2d82ee3c8b21 (Fang Wenqi            2009-12-30 18:37:13 +0800 1466) 		goto err;
b2d82ee3c8b21 (Fang Wenqi            2009-12-30 18:37:13 +0800 1467) 
b2d82ee3c8b21 (Fang Wenqi            2009-12-30 18:37:13 +0800 1468) 	err = -EINVAL;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1469) 	if (size < sizeof(outarg))
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1470) 		goto err;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1471) 
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1472) 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1473) 	if (err)
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1474) 		goto err;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1475) 
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1476) 	err = -ENAMETOOLONG;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1477) 	if (outarg.namelen > FUSE_NAME_MAX)
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1478) 		goto err;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1479) 
c2183d1e9b3f3 (Miklos Szeredi        2011-08-24 10:20:17 +0200 1480) 	err = -EINVAL;
c2183d1e9b3f3 (Miklos Szeredi        2011-08-24 10:20:17 +0200 1481) 	if (size != sizeof(outarg) + outarg.namelen + 1)
c2183d1e9b3f3 (Miklos Szeredi        2011-08-24 10:20:17 +0200 1482) 		goto err;
c2183d1e9b3f3 (Miklos Szeredi        2011-08-24 10:20:17 +0200 1483) 
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1484) 	name.name = buf;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1485) 	name.len = outarg.namelen;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1486) 	err = fuse_copy_one(cs, buf, outarg.namelen + 1);
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1487) 	if (err)
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1488) 		goto err;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1489) 	fuse_copy_finish(cs);
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1490) 	buf[outarg.namelen] = 0;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1491) 
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1492) 	down_read(&fc->killsb);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1493) 	err = fuse_reverse_inval_entry(fc, outarg.parent, 0, &name);
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1494) 	up_read(&fc->killsb);
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1495) 	kfree(buf);
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1496) 	return err;
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1497) 
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1498) err:
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1499) 	kfree(buf);
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1500) 	fuse_copy_finish(cs);
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1501) 	return err;
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1502) }
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1503) 
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1504) static int fuse_notify_delete(struct fuse_conn *fc, unsigned int size,
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1505) 			      struct fuse_copy_state *cs)
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1506) {
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1507) 	struct fuse_notify_delete_out outarg;
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1508) 	int err = -ENOMEM;
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1509) 	char *buf;
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1510) 	struct qstr name;
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1511) 
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1512) 	buf = kzalloc(FUSE_NAME_MAX + 1, GFP_KERNEL);
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1513) 	if (!buf)
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1514) 		goto err;
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1515) 
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1516) 	err = -EINVAL;
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1517) 	if (size < sizeof(outarg))
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1518) 		goto err;
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1519) 
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1520) 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1521) 	if (err)
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1522) 		goto err;
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1523) 
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1524) 	err = -ENAMETOOLONG;
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1525) 	if (outarg.namelen > FUSE_NAME_MAX)
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1526) 		goto err;
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1527) 
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1528) 	err = -EINVAL;
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1529) 	if (size != sizeof(outarg) + outarg.namelen + 1)
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1530) 		goto err;
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1531) 
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1532) 	name.name = buf;
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1533) 	name.len = outarg.namelen;
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1534) 	err = fuse_copy_one(cs, buf, outarg.namelen + 1);
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1535) 	if (err)
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1536) 		goto err;
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1537) 	fuse_copy_finish(cs);
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1538) 	buf[outarg.namelen] = 0;
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1539) 
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1540) 	down_read(&fc->killsb);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1541) 	err = fuse_reverse_inval_entry(fc, outarg.parent, outarg.child, &name);
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1542) 	up_read(&fc->killsb);
b2d82ee3c8b21 (Fang Wenqi            2009-12-30 18:37:13 +0800 1543) 	kfree(buf);
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1544) 	return err;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1545) 
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1546) err:
b2d82ee3c8b21 (Fang Wenqi            2009-12-30 18:37:13 +0800 1547) 	kfree(buf);
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1548) 	fuse_copy_finish(cs);
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1549) 	return err;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1550) }
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1551) 
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1552) static int fuse_notify_store(struct fuse_conn *fc, unsigned int size,
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1553) 			     struct fuse_copy_state *cs)
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1554) {
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1555) 	struct fuse_notify_store_out outarg;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1556) 	struct inode *inode;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1557) 	struct address_space *mapping;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1558) 	u64 nodeid;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1559) 	int err;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1560) 	pgoff_t index;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1561) 	unsigned int offset;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1562) 	unsigned int num;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1563) 	loff_t file_size;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1564) 	loff_t end;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1565) 
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1566) 	err = -EINVAL;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1567) 	if (size < sizeof(outarg))
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1568) 		goto out_finish;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1569) 
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1570) 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1571) 	if (err)
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1572) 		goto out_finish;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1573) 
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1574) 	err = -EINVAL;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1575) 	if (size - sizeof(outarg) != outarg.size)
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1576) 		goto out_finish;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1577) 
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1578) 	nodeid = outarg.nodeid;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1579) 
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1580) 	down_read(&fc->killsb);
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1581) 
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1582) 	err = -ENOENT;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1583) 	inode = fuse_ilookup(fc, nodeid,  NULL);
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1584) 	if (!inode)
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1585) 		goto out_up_killsb;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1586) 
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1587) 	mapping = inode->i_mapping;
09cbfeaf1a5a6 (Kirill A. Shutemov    2016-04-01 15:29:47 +0300 1588) 	index = outarg.offset >> PAGE_SHIFT;
09cbfeaf1a5a6 (Kirill A. Shutemov    2016-04-01 15:29:47 +0300 1589) 	offset = outarg.offset & ~PAGE_MASK;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1590) 	file_size = i_size_read(inode);
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1591) 	end = outarg.offset + outarg.size;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1592) 	if (end > file_size) {
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1593) 		file_size = end;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1594) 		fuse_write_update_size(inode, file_size);
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1595) 	}
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1596) 
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1597) 	num = outarg.size;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1598) 	while (num) {
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1599) 		struct page *page;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1600) 		unsigned int this_num;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1601) 
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1602) 		err = -ENOMEM;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1603) 		page = find_or_create_page(mapping, index,
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1604) 					   mapping_gfp_mask(mapping));
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1605) 		if (!page)
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1606) 			goto out_iput;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1607) 
09cbfeaf1a5a6 (Kirill A. Shutemov    2016-04-01 15:29:47 +0300 1608) 		this_num = min_t(unsigned, num, PAGE_SIZE - offset);
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1609) 		err = fuse_copy_page(cs, &page, offset, this_num, 0);
063ec1e595f8a (Miklos Szeredi        2014-01-22 19:36:58 +0100 1610) 		if (!err && offset == 0 &&
09cbfeaf1a5a6 (Kirill A. Shutemov    2016-04-01 15:29:47 +0300 1611) 		    (this_num == PAGE_SIZE || file_size == end))
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1612) 			SetPageUptodate(page);
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1613) 		unlock_page(page);
09cbfeaf1a5a6 (Kirill A. Shutemov    2016-04-01 15:29:47 +0300 1614) 		put_page(page);
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1615) 
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1616) 		if (err)
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1617) 			goto out_iput;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1618) 
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1619) 		num -= this_num;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1620) 		offset = 0;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1621) 		index++;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1622) 	}
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1623) 
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1624) 	err = 0;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1625) 
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1626) out_iput:
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1627) 	iput(inode);
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1628) out_up_killsb:
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1629) 	up_read(&fc->killsb);
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1630) out_finish:
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1631) 	fuse_copy_finish(cs);
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1632) 	return err;
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1633) }
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1634) 
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1635) struct fuse_retrieve_args {
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1636) 	struct fuse_args_pages ap;
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1637) 	struct fuse_notify_retrieve_in inarg;
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1638) };
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1639) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1640) static void fuse_retrieve_end(struct fuse_mount *fm, struct fuse_args *args,
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1641) 			      int error)
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1642) {
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1643) 	struct fuse_retrieve_args *ra =
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1644) 		container_of(args, typeof(*ra), ap.args);
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1645) 
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1646) 	release_pages(ra->ap.pages, ra->ap.num_pages);
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1647) 	kfree(ra);
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1648) }
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1649) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1650) static int fuse_retrieve(struct fuse_mount *fm, struct inode *inode,
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1651) 			 struct fuse_notify_retrieve_out *outarg)
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1652) {
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1653) 	int err;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1654) 	struct address_space *mapping = inode->i_mapping;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1655) 	pgoff_t index;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1656) 	loff_t file_size;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1657) 	unsigned int num;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1658) 	unsigned int offset;
0157443c56bcc (Geert Uytterhoeven    2010-09-30 22:06:21 +0200 1659) 	size_t total_len = 0;
5da784cce4308 (Constantine Shulyupin 2018-09-06 15:37:06 +0300 1660) 	unsigned int num_pages;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1661) 	struct fuse_conn *fc = fm->fc;
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1662) 	struct fuse_retrieve_args *ra;
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1663) 	size_t args_size = sizeof(*ra);
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1664) 	struct fuse_args_pages *ap;
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1665) 	struct fuse_args *args;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1666) 
09cbfeaf1a5a6 (Kirill A. Shutemov    2016-04-01 15:29:47 +0300 1667) 	offset = outarg->offset & ~PAGE_MASK;
4d53dc99baf13 (Maxim Patlasov        2012-10-26 19:48:42 +0400 1668) 	file_size = i_size_read(inode);
4d53dc99baf13 (Maxim Patlasov        2012-10-26 19:48:42 +0400 1669) 
7640682e67b33 (Kirill Smelkov        2019-03-27 10:15:19 +0000 1670) 	num = min(outarg->size, fc->max_write);
4d53dc99baf13 (Maxim Patlasov        2012-10-26 19:48:42 +0400 1671) 	if (outarg->offset > file_size)
4d53dc99baf13 (Maxim Patlasov        2012-10-26 19:48:42 +0400 1672) 		num = 0;
4d53dc99baf13 (Maxim Patlasov        2012-10-26 19:48:42 +0400 1673) 	else if (outarg->offset + num > file_size)
4d53dc99baf13 (Maxim Patlasov        2012-10-26 19:48:42 +0400 1674) 		num = file_size - outarg->offset;
4d53dc99baf13 (Maxim Patlasov        2012-10-26 19:48:42 +0400 1675) 
4d53dc99baf13 (Maxim Patlasov        2012-10-26 19:48:42 +0400 1676) 	num_pages = (num + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
5da784cce4308 (Constantine Shulyupin 2018-09-06 15:37:06 +0300 1677) 	num_pages = min(num_pages, fc->max_pages);
4d53dc99baf13 (Maxim Patlasov        2012-10-26 19:48:42 +0400 1678) 
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1679) 	args_size += num_pages * (sizeof(ap->pages[0]) + sizeof(ap->descs[0]));
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1680) 
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1681) 	ra = kzalloc(args_size, GFP_KERNEL);
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1682) 	if (!ra)
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1683) 		return -ENOMEM;
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1684) 
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1685) 	ap = &ra->ap;
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1686) 	ap->pages = (void *) (ra + 1);
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1687) 	ap->descs = (void *) (ap->pages + num_pages);
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1688) 
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1689) 	args = &ap->args;
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1690) 	args->nodeid = outarg->nodeid;
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1691) 	args->opcode = FUSE_NOTIFY_REPLY;
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1692) 	args->in_numargs = 2;
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1693) 	args->in_pages = true;
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1694) 	args->end = fuse_retrieve_end;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1695) 
09cbfeaf1a5a6 (Kirill A. Shutemov    2016-04-01 15:29:47 +0300 1696) 	index = outarg->offset >> PAGE_SHIFT;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1697) 
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1698) 	while (num && ap->num_pages < num_pages) {
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1699) 		struct page *page;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1700) 		unsigned int this_num;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1701) 
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1702) 		page = find_get_page(mapping, index);
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1703) 		if (!page)
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1704) 			break;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1705) 
09cbfeaf1a5a6 (Kirill A. Shutemov    2016-04-01 15:29:47 +0300 1706) 		this_num = min_t(unsigned, num, PAGE_SIZE - offset);
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1707) 		ap->pages[ap->num_pages] = page;
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1708) 		ap->descs[ap->num_pages].offset = offset;
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1709) 		ap->descs[ap->num_pages].length = this_num;
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1710) 		ap->num_pages++;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1711) 
c9e67d483776d (Miklos Szeredi        2012-09-04 18:45:54 +0200 1712) 		offset = 0;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1713) 		num -= this_num;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1714) 		total_len += this_num;
48706d0a91583 (Miklos Szeredi        2011-12-13 10:36:59 +0100 1715) 		index++;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1716) 	}
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1717) 	ra->inarg.offset = outarg->offset;
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1718) 	ra->inarg.size = total_len;
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1719) 	args->in_args[0].size = sizeof(ra->inarg);
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1720) 	args->in_args[0].value = &ra->inarg;
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1721) 	args->in_args[1].size = total_len;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1722) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1723) 	err = fuse_simple_notify_reply(fm, args, outarg->notify_unique);
75b399dda5be1 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1724) 	if (err)
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1725) 		fuse_retrieve_end(fm, args, err);
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1726) 
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1727) 	return err;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1728) }
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1729) 
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1730) static int fuse_notify_retrieve(struct fuse_conn *fc, unsigned int size,
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1731) 				struct fuse_copy_state *cs)
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1732) {
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1733) 	struct fuse_notify_retrieve_out outarg;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1734) 	struct fuse_mount *fm;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1735) 	struct inode *inode;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1736) 	u64 nodeid;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1737) 	int err;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1738) 
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1739) 	err = -EINVAL;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1740) 	if (size != sizeof(outarg))
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1741) 		goto copy_finish;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1742) 
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1743) 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1744) 	if (err)
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1745) 		goto copy_finish;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1746) 
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1747) 	fuse_copy_finish(cs);
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1748) 
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1749) 	down_read(&fc->killsb);
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1750) 	err = -ENOENT;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1751) 	nodeid = outarg.nodeid;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1752) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1753) 	inode = fuse_ilookup(fc, nodeid, &fm);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1754) 	if (inode) {
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1755) 		err = fuse_retrieve(fm, inode, &outarg);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1756) 		iput(inode);
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1757) 	}
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1758) 	up_read(&fc->killsb);
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1759) 
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1760) 	return err;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1761) 
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1762) copy_finish:
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1763) 	fuse_copy_finish(cs);
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1764) 	return err;
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1765) }
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1766) 
8599396b5062b (Tejun Heo             2008-11-26 12:03:55 +0100 1767) static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code,
8599396b5062b (Tejun Heo             2008-11-26 12:03:55 +0100 1768) 		       unsigned int size, struct fuse_copy_state *cs)
8599396b5062b (Tejun Heo             2008-11-26 12:03:55 +0100 1769) {
0d2783626a53d (Miklos Szeredi        2015-02-26 11:45:47 +0100 1770) 	/* Don't try to move pages (yet) */
0d2783626a53d (Miklos Szeredi        2015-02-26 11:45:47 +0100 1771) 	cs->move_pages = 0;
0d2783626a53d (Miklos Szeredi        2015-02-26 11:45:47 +0100 1772) 
8599396b5062b (Tejun Heo             2008-11-26 12:03:55 +0100 1773) 	switch (code) {
95668a69a4bb8 (Tejun Heo             2008-11-26 12:03:55 +0100 1774) 	case FUSE_NOTIFY_POLL:
95668a69a4bb8 (Tejun Heo             2008-11-26 12:03:55 +0100 1775) 		return fuse_notify_poll(fc, size, cs);
95668a69a4bb8 (Tejun Heo             2008-11-26 12:03:55 +0100 1776) 
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1777) 	case FUSE_NOTIFY_INVAL_INODE:
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1778) 		return fuse_notify_inval_inode(fc, size, cs);
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1779) 
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1780) 	case FUSE_NOTIFY_INVAL_ENTRY:
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1781) 		return fuse_notify_inval_entry(fc, size, cs);
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1782) 
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1783) 	case FUSE_NOTIFY_STORE:
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1784) 		return fuse_notify_store(fc, size, cs);
a1d75f258230b (Miklos Szeredi        2010-07-12 14:41:40 +0200 1785) 
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1786) 	case FUSE_NOTIFY_RETRIEVE:
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1787) 		return fuse_notify_retrieve(fc, size, cs);
2d45ba381a74a (Miklos Szeredi        2010-07-12 14:41:40 +0200 1788) 
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1789) 	case FUSE_NOTIFY_DELETE:
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1790) 		return fuse_notify_delete(fc, size, cs);
451d0f599934f (John Muir             2011-12-06 21:50:06 +0100 1791) 
8599396b5062b (Tejun Heo             2008-11-26 12:03:55 +0100 1792) 	default:
f6d47a1761896 (Miklos Szeredi        2009-01-26 15:00:59 +0100 1793) 		fuse_copy_finish(cs);
8599396b5062b (Tejun Heo             2008-11-26 12:03:55 +0100 1794) 		return -EINVAL;
8599396b5062b (Tejun Heo             2008-11-26 12:03:55 +0100 1795) 	}
8599396b5062b (Tejun Heo             2008-11-26 12:03:55 +0100 1796) }
8599396b5062b (Tejun Heo             2008-11-26 12:03:55 +0100 1797) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1798) /* Look up request on processing list by unique ID */
3a2b5b9cd9610 (Miklos Szeredi        2015-07-01 16:26:04 +0200 1799) static struct fuse_req *request_find(struct fuse_pqueue *fpq, u64 unique)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1800) {
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 1801) 	unsigned int hash = fuse_req_hash(unique);
05726acabef10 (Dong Fang             2013-07-30 22:50:01 -0400 1802) 	struct fuse_req *req;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1803) 
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 1804) 	list_for_each_entry(req, &fpq->processing[hash], list) {
3a5358d1a1b70 (Kirill Tkhai          2018-09-11 13:12:05 +0300 1805) 		if (req->in.h.unique == unique)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1806) 			return req;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1807) 	}
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1808) 	return NULL;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1809) }
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1810) 
d49937749fef2 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1811) static int copy_out_args(struct fuse_copy_state *cs, struct fuse_args *args,
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1812) 			 unsigned nbytes)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1813) {
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1814) 	unsigned reqsize = sizeof(struct fuse_out_header);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1815) 
14d46d7abc397 (Stefan Hajnoczi       2018-06-21 09:34:25 +0100 1816) 	reqsize += fuse_len_args(args->out_numargs, args->out_args);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1817) 
d49937749fef2 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1818) 	if (reqsize < nbytes || (reqsize > nbytes && !args->out_argvar))
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1819) 		return -EINVAL;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1820) 	else if (reqsize > nbytes) {
d49937749fef2 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1821) 		struct fuse_arg *lastarg = &args->out_args[args->out_numargs-1];
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1822) 		unsigned diffsize = reqsize - nbytes;
d49937749fef2 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1823) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1824) 		if (diffsize > lastarg->size)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1825) 			return -EINVAL;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1826) 		lastarg->size -= diffsize;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1827) 	}
d49937749fef2 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1828) 	return fuse_copy_args(cs, args->out_numargs, args->out_pages,
d49937749fef2 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1829) 			      args->out_args, args->page_zeroing);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1830) }
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1831) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1832) /*
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1833)  * Write a single reply to a request.  First the header is copied from
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1834)  * the write buffer.  The request is then searched on the processing
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1835)  * list by the unique ID found in the header.  If found, then remove
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1836)  * it from the list and copy the rest of the buffer to the request.
04ec5af0776e9 (Stefan Hajnoczi       2018-06-21 09:33:40 +0100 1837)  * The request is finished by calling fuse_request_end().
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1838)  */
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 1839) static ssize_t fuse_dev_do_write(struct fuse_dev *fud,
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1840) 				 struct fuse_copy_state *cs, size_t nbytes)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1841) {
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1842) 	int err;
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 1843) 	struct fuse_conn *fc = fud->fc;
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 1844) 	struct fuse_pqueue *fpq = &fud->pq;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1845) 	struct fuse_req *req;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1846) 	struct fuse_out_header oh;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1847) 
7407a10de57f5 (Kirill Tkhai          2018-11-08 12:05:36 +0300 1848) 	err = -EINVAL;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1849) 	if (nbytes < sizeof(struct fuse_out_header))
7407a10de57f5 (Kirill Tkhai          2018-11-08 12:05:36 +0300 1850) 		goto out;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1851) 
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1852) 	err = fuse_copy_one(cs, &oh, sizeof(oh));
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1853) 	if (err)
7407a10de57f5 (Kirill Tkhai          2018-11-08 12:05:36 +0300 1854) 		goto copy_finish;
8599396b5062b (Tejun Heo             2008-11-26 12:03:55 +0100 1855) 
8599396b5062b (Tejun Heo             2008-11-26 12:03:55 +0100 1856) 	err = -EINVAL;
8599396b5062b (Tejun Heo             2008-11-26 12:03:55 +0100 1857) 	if (oh.len != nbytes)
7407a10de57f5 (Kirill Tkhai          2018-11-08 12:05:36 +0300 1858) 		goto copy_finish;
8599396b5062b (Tejun Heo             2008-11-26 12:03:55 +0100 1859) 
8599396b5062b (Tejun Heo             2008-11-26 12:03:55 +0100 1860) 	/*
8599396b5062b (Tejun Heo             2008-11-26 12:03:55 +0100 1861) 	 * Zero oh.unique indicates unsolicited notification message
8599396b5062b (Tejun Heo             2008-11-26 12:03:55 +0100 1862) 	 * and error contains notification code.
8599396b5062b (Tejun Heo             2008-11-26 12:03:55 +0100 1863) 	 */
8599396b5062b (Tejun Heo             2008-11-26 12:03:55 +0100 1864) 	if (!oh.unique) {
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1865) 		err = fuse_notify(fc, oh.error, nbytes - sizeof(oh), cs);
7407a10de57f5 (Kirill Tkhai          2018-11-08 12:05:36 +0300 1866) 		goto out;
8599396b5062b (Tejun Heo             2008-11-26 12:03:55 +0100 1867) 	}
8599396b5062b (Tejun Heo             2008-11-26 12:03:55 +0100 1868) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1869) 	err = -EINVAL;
0c1678f223daf (Miklos Szeredi        2021-06-22 09:15:35 +0200 1870) 	if (oh.error <= -512 || oh.error > 0)
7407a10de57f5 (Kirill Tkhai          2018-11-08 12:05:36 +0300 1871) 		goto copy_finish;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1872) 
45a91cb1a4fd9 (Miklos Szeredi        2015-07-01 16:26:06 +0200 1873) 	spin_lock(&fpq->lock);
7407a10de57f5 (Kirill Tkhai          2018-11-08 12:05:36 +0300 1874) 	req = NULL;
7407a10de57f5 (Kirill Tkhai          2018-11-08 12:05:36 +0300 1875) 	if (fpq->connected)
7407a10de57f5 (Kirill Tkhai          2018-11-08 12:05:36 +0300 1876) 		req = request_find(fpq, oh.unique & ~FUSE_INT_REQ_BIT);
69a53bf267fa5 (Miklos Szeredi        2006-01-16 22:14:41 -0800 1877) 
7407a10de57f5 (Kirill Tkhai          2018-11-08 12:05:36 +0300 1878) 	err = -ENOENT;
7407a10de57f5 (Kirill Tkhai          2018-11-08 12:05:36 +0300 1879) 	if (!req) {
7407a10de57f5 (Kirill Tkhai          2018-11-08 12:05:36 +0300 1880) 		spin_unlock(&fpq->lock);
7407a10de57f5 (Kirill Tkhai          2018-11-08 12:05:36 +0300 1881) 		goto copy_finish;
7407a10de57f5 (Kirill Tkhai          2018-11-08 12:05:36 +0300 1882) 	}
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1883) 
3a5358d1a1b70 (Kirill Tkhai          2018-09-11 13:12:05 +0300 1884) 	/* Is it an interrupt reply ID? */
3a5358d1a1b70 (Kirill Tkhai          2018-09-11 13:12:05 +0300 1885) 	if (oh.unique & FUSE_INT_REQ_BIT) {
d2d2d4fb1f54e (Kirill Tkhai          2018-09-25 12:52:42 +0300 1886) 		__fuse_get_request(req);
45a91cb1a4fd9 (Miklos Szeredi        2015-07-01 16:26:06 +0200 1887) 		spin_unlock(&fpq->lock);
45a91cb1a4fd9 (Miklos Szeredi        2015-07-01 16:26:06 +0200 1888) 
7407a10de57f5 (Kirill Tkhai          2018-11-08 12:05:36 +0300 1889) 		err = 0;
7407a10de57f5 (Kirill Tkhai          2018-11-08 12:05:36 +0300 1890) 		if (nbytes != sizeof(struct fuse_out_header))
7407a10de57f5 (Kirill Tkhai          2018-11-08 12:05:36 +0300 1891) 			err = -EINVAL;
7407a10de57f5 (Kirill Tkhai          2018-11-08 12:05:36 +0300 1892) 		else if (oh.error == -ENOSYS)
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1893) 			fc->no_interrupt = 1;
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1894) 		else if (oh.error == -EAGAIN)
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200 1895) 			err = queue_interrupt(req);
7407a10de57f5 (Kirill Tkhai          2018-11-08 12:05:36 +0300 1896) 
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200 1897) 		fuse_put_request(req);
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1898) 
7407a10de57f5 (Kirill Tkhai          2018-11-08 12:05:36 +0300 1899) 		goto copy_finish;
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1900) 	}
a4d27e75ffb7b (Miklos Szeredi        2006-06-25 05:48:54 -0700 1901) 
33e14b4dfdc47 (Miklos Szeredi        2015-07-01 16:26:01 +0200 1902) 	clear_bit(FR_SENT, &req->flags);
3a2b5b9cd9610 (Miklos Szeredi        2015-07-01 16:26:04 +0200 1903) 	list_move(&req->list, &fpq->io);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1904) 	req->out.h = oh;
825d6d3395e88 (Miklos Szeredi        2015-07-01 16:25:58 +0200 1905) 	set_bit(FR_LOCKED, &req->flags);
45a91cb1a4fd9 (Miklos Szeredi        2015-07-01 16:26:06 +0200 1906) 	spin_unlock(&fpq->lock);
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1907) 	cs->req = req;
d49937749fef2 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1908) 	if (!req->args->page_replace)
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200 1909) 		cs->move_pages = 0;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1910) 
d49937749fef2 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1911) 	if (oh.error)
d49937749fef2 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1912) 		err = nbytes != sizeof(oh) ? -EINVAL : 0;
d49937749fef2 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1913) 	else
d49937749fef2 (Miklos Szeredi        2019-09-10 15:04:11 +0200 1914) 		err = copy_out_args(cs, req->args, nbytes);
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1915) 	fuse_copy_finish(cs);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1916) 
45a91cb1a4fd9 (Miklos Szeredi        2015-07-01 16:26:06 +0200 1917) 	spin_lock(&fpq->lock);
825d6d3395e88 (Miklos Szeredi        2015-07-01 16:25:58 +0200 1918) 	clear_bit(FR_LOCKED, &req->flags);
e96edd94d0887 (Miklos Szeredi        2015-07-01 16:26:04 +0200 1919) 	if (!fpq->connected)
0d8e84b0432be (Miklos Szeredi        2015-07-01 16:25:58 +0200 1920) 		err = -ENOENT;
0d8e84b0432be (Miklos Szeredi        2015-07-01 16:25:58 +0200 1921) 	else if (err)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1922) 		req->out.h.error = -EIO;
77cd9d488b32d (Miklos Szeredi        2015-07-01 16:26:06 +0200 1923) 	if (!test_bit(FR_PRIVATE, &req->flags))
77cd9d488b32d (Miklos Szeredi        2015-07-01 16:26:06 +0200 1924) 		list_del_init(&req->list);
45a91cb1a4fd9 (Miklos Szeredi        2015-07-01 16:26:06 +0200 1925) 	spin_unlock(&fpq->lock);
46c34a348b0ac (Miklos Szeredi        2015-07-01 16:26:07 +0200 1926) 
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200 1927) 	fuse_request_end(req);
7407a10de57f5 (Kirill Tkhai          2018-11-08 12:05:36 +0300 1928) out:
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1929) 	return err ? err : nbytes;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1930) 
7407a10de57f5 (Kirill Tkhai          2018-11-08 12:05:36 +0300 1931) copy_finish:
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1932) 	fuse_copy_finish(cs);
7407a10de57f5 (Kirill Tkhai          2018-11-08 12:05:36 +0300 1933) 	goto out;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1934) }
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1935) 
fbdbacca61531 (Al Viro               2015-04-03 21:53:39 -0400 1936) static ssize_t fuse_dev_write(struct kiocb *iocb, struct iov_iter *from)
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1937) {
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1938) 	struct fuse_copy_state cs;
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1939) 	struct fuse_dev *fud = fuse_get_dev(iocb->ki_filp);
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1940) 
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1941) 	if (!fud)
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1942) 		return -EPERM;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1943) 
fbdbacca61531 (Al Viro               2015-04-03 21:53:39 -0400 1944) 	if (!iter_is_iovec(from))
fbdbacca61531 (Al Viro               2015-04-03 21:53:39 -0400 1945) 		return -EINVAL;
fbdbacca61531 (Al Viro               2015-04-03 21:53:39 -0400 1946) 
dc00809a53edd (Miklos Szeredi        2015-07-01 16:25:58 +0200 1947) 	fuse_copy_init(&cs, 0, from);
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1948) 
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 1949) 	return fuse_dev_do_write(fud, &cs, iov_iter_count(from));
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1950) }
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1951) 
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1952) static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1953) 				     struct file *out, loff_t *ppos,
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1954) 				     size_t len, unsigned int flags)
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1955) {
8cefc107ca54c (David Howells         2019-11-15 13:30:32 +0000 1956) 	unsigned int head, tail, mask, count;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1957) 	unsigned nbuf;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1958) 	unsigned idx;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1959) 	struct pipe_buffer *bufs;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1960) 	struct fuse_copy_state cs;
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1961) 	struct fuse_dev *fud;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1962) 	size_t rem;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1963) 	ssize_t ret;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1964) 
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1965) 	fud = fuse_get_dev(out);
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1966) 	if (!fud)
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1967) 		return -EPERM;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1968) 
a2477b0e67c52 (Andrey Ryabinin       2018-07-17 19:00:33 +0300 1969) 	pipe_lock(pipe);
a2477b0e67c52 (Andrey Ryabinin       2018-07-17 19:00:33 +0300 1970) 
8cefc107ca54c (David Howells         2019-11-15 13:30:32 +0000 1971) 	head = pipe->head;
8cefc107ca54c (David Howells         2019-11-15 13:30:32 +0000 1972) 	tail = pipe->tail;
8cefc107ca54c (David Howells         2019-11-15 13:30:32 +0000 1973) 	mask = pipe->ring_size - 1;
8cefc107ca54c (David Howells         2019-11-15 13:30:32 +0000 1974) 	count = head - tail;
8cefc107ca54c (David Howells         2019-11-15 13:30:32 +0000 1975) 
8cefc107ca54c (David Howells         2019-11-15 13:30:32 +0000 1976) 	bufs = kvmalloc_array(count, sizeof(struct pipe_buffer), GFP_KERNEL);
a2477b0e67c52 (Andrey Ryabinin       2018-07-17 19:00:33 +0300 1977) 	if (!bufs) {
a2477b0e67c52 (Andrey Ryabinin       2018-07-17 19:00:33 +0300 1978) 		pipe_unlock(pipe);
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1979) 		return -ENOMEM;
a2477b0e67c52 (Andrey Ryabinin       2018-07-17 19:00:33 +0300 1980) 	}
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1981) 
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1982) 	nbuf = 0;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1983) 	rem = 0;
76f6777c9cc04 (David Howells         2019-12-06 21:34:51 +0000 1984) 	for (idx = tail; idx != head && rem < len; idx++)
8cefc107ca54c (David Howells         2019-11-15 13:30:32 +0000 1985) 		rem += pipe->bufs[idx & mask].len;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1986) 
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1987) 	ret = -EINVAL;
15fab63e1e57b (Matthew Wilcox        2019-04-05 14:02:10 -0700 1988) 	if (rem < len)
15fab63e1e57b (Matthew Wilcox        2019-04-05 14:02:10 -0700 1989) 		goto out_free;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1990) 
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1991) 	rem = len;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1992) 	while (rem) {
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1993) 		struct pipe_buffer *ibuf;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1994) 		struct pipe_buffer *obuf;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 1995) 
0e9fb6f17ad5b (Vasily Averin         2019-08-19 09:53:50 +0300 1996) 		if (WARN_ON(nbuf >= count || tail == head))
0e9fb6f17ad5b (Vasily Averin         2019-08-19 09:53:50 +0300 1997) 			goto out_free;
0e9fb6f17ad5b (Vasily Averin         2019-08-19 09:53:50 +0300 1998) 
8cefc107ca54c (David Howells         2019-11-15 13:30:32 +0000 1999) 		ibuf = &pipe->bufs[tail & mask];
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 2000) 		obuf = &bufs[nbuf];
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 2001) 
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 2002) 		if (rem >= ibuf->len) {
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 2003) 			*obuf = *ibuf;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 2004) 			ibuf->ops = NULL;
8cefc107ca54c (David Howells         2019-11-15 13:30:32 +0000 2005) 			tail++;
8cefc107ca54c (David Howells         2019-11-15 13:30:32 +0000 2006) 			pipe->tail = tail;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 2007) 		} else {
15fab63e1e57b (Matthew Wilcox        2019-04-05 14:02:10 -0700 2008) 			if (!pipe_buf_get(pipe, ibuf))
15fab63e1e57b (Matthew Wilcox        2019-04-05 14:02:10 -0700 2009) 				goto out_free;
15fab63e1e57b (Matthew Wilcox        2019-04-05 14:02:10 -0700 2010) 
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 2011) 			*obuf = *ibuf;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 2012) 			obuf->flags &= ~PIPE_BUF_FLAG_GIFT;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 2013) 			obuf->len = rem;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 2014) 			ibuf->offset += obuf->len;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 2015) 			ibuf->len -= obuf->len;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 2016) 		}
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 2017) 		nbuf++;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 2018) 		rem -= obuf->len;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 2019) 	}
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 2020) 	pipe_unlock(pipe);
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 2021) 
dc00809a53edd (Miklos Szeredi        2015-07-01 16:25:58 +0200 2022) 	fuse_copy_init(&cs, 0, NULL);
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 2023) 	cs.pipebufs = bufs;
6c09e94a32e10 (Al Viro               2015-04-03 22:06:08 -0400 2024) 	cs.nr_segs = nbuf;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 2025) 	cs.pipe = pipe;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 2026) 
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200 2027) 	if (flags & SPLICE_F_MOVE)
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200 2028) 		cs.move_pages = 1;
ce534fb052928 (Miklos Szeredi        2010-05-25 15:06:07 +0200 2029) 
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 2030) 	ret = fuse_dev_do_write(fud, &cs, len);
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 2031) 
9509941e9c534 (Jann Horn             2019-01-12 02:39:05 +0100 2032) 	pipe_lock(pipe);
15fab63e1e57b (Matthew Wilcox        2019-04-05 14:02:10 -0700 2033) out_free:
a779638cf622f (Miklos Szeredi        2016-09-27 10:45:12 +0200 2034) 	for (idx = 0; idx < nbuf; idx++)
a779638cf622f (Miklos Szeredi        2016-09-27 10:45:12 +0200 2035) 		pipe_buf_release(pipe, &bufs[idx]);
9509941e9c534 (Jann Horn             2019-01-12 02:39:05 +0100 2036) 	pipe_unlock(pipe);
a779638cf622f (Miklos Szeredi        2016-09-27 10:45:12 +0200 2037) 
d6d931adce119 (Andrey Ryabinin       2018-07-17 19:00:34 +0300 2038) 	kvfree(bufs);
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 2039) 	return ret;
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 2040) }
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 2041) 
076ccb76e1a6c (Al Viro               2017-07-03 01:02:18 -0400 2042) static __poll_t fuse_dev_poll(struct file *file, poll_table *wait)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2043) {
a9a08845e9acb (Linus Torvalds        2018-02-11 14:34:03 -0800 2044) 	__poll_t mask = EPOLLOUT | EPOLLWRNORM;
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200 2045) 	struct fuse_iqueue *fiq;
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 2046) 	struct fuse_dev *fud = fuse_get_dev(file);
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 2047) 
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 2048) 	if (!fud)
a9a08845e9acb (Linus Torvalds        2018-02-11 14:34:03 -0800 2049) 		return EPOLLERR;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2050) 
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 2051) 	fiq = &fud->fc->iq;
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200 2052) 	poll_wait(file, &fiq->waitq, wait);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2053) 
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 2054) 	spin_lock(&fiq->lock);
e16714d8756dc (Miklos Szeredi        2015-07-01 16:26:01 +0200 2055) 	if (!fiq->connected)
a9a08845e9acb (Linus Torvalds        2018-02-11 14:34:03 -0800 2056) 		mask = EPOLLERR;
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200 2057) 	else if (request_pending(fiq))
a9a08845e9acb (Linus Torvalds        2018-02-11 14:34:03 -0800 2058) 		mask |= EPOLLIN | EPOLLRDNORM;
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 2059) 	spin_unlock(&fiq->lock);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2060) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2061) 	return mask;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2062) }
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2063) 
340617508d24d (Kirill Tkhai          2018-11-06 12:15:20 +0300 2064) /* Abort all requests on the given list (pending or processing) */
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200 2065) static void end_requests(struct list_head *head)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2066) {
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2067) 	while (!list_empty(head)) {
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2068) 		struct fuse_req *req;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2069) 		req = list_entry(head->next, struct fuse_req, list);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2070) 		req->out.h.error = -ECONNABORTED;
33e14b4dfdc47 (Miklos Szeredi        2015-07-01 16:26:01 +0200 2071) 		clear_bit(FR_SENT, &req->flags);
f377cb799e4f6 (Miklos Szeredi        2015-07-01 16:26:04 +0200 2072) 		list_del_init(&req->list);
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200 2073) 		fuse_request_end(req);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2074) 	}
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2075) }
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2076) 
357ccf2b69bce (Bryan Green           2011-03-01 16:43:52 -0800 2077) static void end_polls(struct fuse_conn *fc)
357ccf2b69bce (Bryan Green           2011-03-01 16:43:52 -0800 2078) {
357ccf2b69bce (Bryan Green           2011-03-01 16:43:52 -0800 2079) 	struct rb_node *p;
357ccf2b69bce (Bryan Green           2011-03-01 16:43:52 -0800 2080) 
357ccf2b69bce (Bryan Green           2011-03-01 16:43:52 -0800 2081) 	p = rb_first(&fc->polled_files);
357ccf2b69bce (Bryan Green           2011-03-01 16:43:52 -0800 2082) 
357ccf2b69bce (Bryan Green           2011-03-01 16:43:52 -0800 2083) 	while (p) {
357ccf2b69bce (Bryan Green           2011-03-01 16:43:52 -0800 2084) 		struct fuse_file *ff;
357ccf2b69bce (Bryan Green           2011-03-01 16:43:52 -0800 2085) 		ff = rb_entry(p, struct fuse_file, polled_node);
357ccf2b69bce (Bryan Green           2011-03-01 16:43:52 -0800 2086) 		wake_up_interruptible_all(&ff->poll_wait);
357ccf2b69bce (Bryan Green           2011-03-01 16:43:52 -0800 2087) 
357ccf2b69bce (Bryan Green           2011-03-01 16:43:52 -0800 2088) 		p = rb_next(p);
357ccf2b69bce (Bryan Green           2011-03-01 16:43:52 -0800 2089) 	}
357ccf2b69bce (Bryan Green           2011-03-01 16:43:52 -0800 2090) }
357ccf2b69bce (Bryan Green           2011-03-01 16:43:52 -0800 2091) 
69a53bf267fa5 (Miklos Szeredi        2006-01-16 22:14:41 -0800 2092) /*
69a53bf267fa5 (Miklos Szeredi        2006-01-16 22:14:41 -0800 2093)  * Abort all requests.
69a53bf267fa5 (Miklos Szeredi        2006-01-16 22:14:41 -0800 2094)  *
b716d425385ed (Miklos Szeredi        2015-07-01 16:25:59 +0200 2095)  * Emergency exit in case of a malicious or accidental deadlock, or just a hung
b716d425385ed (Miklos Szeredi        2015-07-01 16:25:59 +0200 2096)  * filesystem.
b716d425385ed (Miklos Szeredi        2015-07-01 16:25:59 +0200 2097)  *
b716d425385ed (Miklos Szeredi        2015-07-01 16:25:59 +0200 2098)  * The same effect is usually achievable through killing the filesystem daemon
b716d425385ed (Miklos Szeredi        2015-07-01 16:25:59 +0200 2099)  * and all users of the filesystem.  The exception is the combination of an
b716d425385ed (Miklos Szeredi        2015-07-01 16:25:59 +0200 2100)  * asynchronous request and the tricky deadlock (see
72ef5e52b3f74 (Mauro Carvalho Chehab 2020-04-14 18:48:35 +0200 2101)  * Documentation/filesystems/fuse.rst).
69a53bf267fa5 (Miklos Szeredi        2006-01-16 22:14:41 -0800 2102)  *
b716d425385ed (Miklos Szeredi        2015-07-01 16:25:59 +0200 2103)  * Aborting requests under I/O goes as follows: 1: Separate out unlocked
b716d425385ed (Miklos Szeredi        2015-07-01 16:25:59 +0200 2104)  * requests, they should be finished off immediately.  Locked requests will be
b716d425385ed (Miklos Szeredi        2015-07-01 16:25:59 +0200 2105)  * finished after unlock; see unlock_request(). 2: Finish off the unlocked
b716d425385ed (Miklos Szeredi        2015-07-01 16:25:59 +0200 2106)  * requests.  It is possible that some request will finish before we can.  This
b716d425385ed (Miklos Szeredi        2015-07-01 16:25:59 +0200 2107)  * is OK, the request will in that case be removed from the list before we touch
b716d425385ed (Miklos Szeredi        2015-07-01 16:25:59 +0200 2108)  * it.
69a53bf267fa5 (Miklos Szeredi        2006-01-16 22:14:41 -0800 2109)  */
eb98e3bdf3aa7 (Miklos Szeredi        2019-01-24 10:40:16 +0100 2110) void fuse_abort_conn(struct fuse_conn *fc)
69a53bf267fa5 (Miklos Szeredi        2006-01-16 22:14:41 -0800 2111) {
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200 2112) 	struct fuse_iqueue *fiq = &fc->iq;
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200 2113) 
d713311464bcc (Miklos Szeredi        2006-04-10 22:54:55 -0700 2114) 	spin_lock(&fc->lock);
69a53bf267fa5 (Miklos Szeredi        2006-01-16 22:14:41 -0800 2115) 	if (fc->connected) {
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 2116) 		struct fuse_dev *fud;
b716d425385ed (Miklos Szeredi        2015-07-01 16:25:59 +0200 2117) 		struct fuse_req *req, *next;
75f3ee4c288d9 (Miklos Szeredi        2018-07-26 16:13:12 +0200 2118) 		LIST_HEAD(to_end);
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 2119) 		unsigned int i;
b716d425385ed (Miklos Szeredi        2015-07-01 16:25:59 +0200 2120) 
63825b4e1da5a (Kirill Tkhai          2018-08-27 18:29:56 +0300 2121) 		/* Background queuing checks fc->connected under bg_lock */
63825b4e1da5a (Kirill Tkhai          2018-08-27 18:29:56 +0300 2122) 		spin_lock(&fc->bg_lock);
69a53bf267fa5 (Miklos Szeredi        2006-01-16 22:14:41 -0800 2123) 		fc->connected = 0;
63825b4e1da5a (Kirill Tkhai          2018-08-27 18:29:56 +0300 2124) 		spin_unlock(&fc->bg_lock);
63825b4e1da5a (Kirill Tkhai          2018-08-27 18:29:56 +0300 2125) 
9759bd5189945 (Miklos Szeredi        2015-01-06 10:45:35 +0100 2126) 		fuse_set_initialized(fc);
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 2127) 		list_for_each_entry(fud, &fc->devices, entry) {
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 2128) 			struct fuse_pqueue *fpq = &fud->pq;
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 2129) 
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 2130) 			spin_lock(&fpq->lock);
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 2131) 			fpq->connected = 0;
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 2132) 			list_for_each_entry_safe(req, next, &fpq->io, list) {
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 2133) 				req->out.h.error = -ECONNABORTED;
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 2134) 				spin_lock(&req->waitq.lock);
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 2135) 				set_bit(FR_ABORTED, &req->flags);
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 2136) 				if (!test_bit(FR_LOCKED, &req->flags)) {
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 2137) 					set_bit(FR_PRIVATE, &req->flags);
87114373ea507 (Miklos Szeredi        2018-07-26 16:13:11 +0200 2138) 					__fuse_get_request(req);
75f3ee4c288d9 (Miklos Szeredi        2018-07-26 16:13:12 +0200 2139) 					list_move(&req->list, &to_end);
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 2140) 				}
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 2141) 				spin_unlock(&req->waitq.lock);
77cd9d488b32d (Miklos Szeredi        2015-07-01 16:26:06 +0200 2142) 			}
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 2143) 			for (i = 0; i < FUSE_PQ_HASH_SIZE; i++)
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 2144) 				list_splice_tail_init(&fpq->processing[i],
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 2145) 						      &to_end);
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 2146) 			spin_unlock(&fpq->lock);
b716d425385ed (Miklos Szeredi        2015-07-01 16:25:59 +0200 2147) 		}
ae2dffa39485c (Kirill Tkhai          2018-08-27 18:29:46 +0300 2148) 		spin_lock(&fc->bg_lock);
ae2dffa39485c (Kirill Tkhai          2018-08-27 18:29:46 +0300 2149) 		fc->blocked = 0;
41f982747e817 (Miklos Szeredi        2015-07-01 16:25:59 +0200 2150) 		fc->max_background = UINT_MAX;
41f982747e817 (Miklos Szeredi        2015-07-01 16:25:59 +0200 2151) 		flush_bg_queue(fc);
ae2dffa39485c (Kirill Tkhai          2018-08-27 18:29:46 +0300 2152) 		spin_unlock(&fc->bg_lock);
8c91189a2a8f5 (Miklos Szeredi        2015-07-01 16:26:02 +0200 2153) 
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 2154) 		spin_lock(&fiq->lock);
8c91189a2a8f5 (Miklos Szeredi        2015-07-01 16:26:02 +0200 2155) 		fiq->connected = 0;
75f3ee4c288d9 (Miklos Szeredi        2018-07-26 16:13:12 +0200 2156) 		list_for_each_entry(req, &fiq->pending, list)
a8a86d78d673b (Tahsin Erdogan        2017-01-12 12:04:04 -0800 2157) 			clear_bit(FR_PENDING, &req->flags);
75f3ee4c288d9 (Miklos Szeredi        2018-07-26 16:13:12 +0200 2158) 		list_splice_tail_init(&fiq->pending, &to_end);
8c91189a2a8f5 (Miklos Szeredi        2015-07-01 16:26:02 +0200 2159) 		while (forget_pending(fiq))
4388c5aac4bae (Vivek Goyal           2019-06-05 15:50:43 -0400 2160) 			kfree(fuse_dequeue_forget(fiq, 1, NULL));
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 2161) 		wake_up_all(&fiq->waitq);
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700 2162) 		spin_unlock(&fiq->lock);
8c91189a2a8f5 (Miklos Szeredi        2015-07-01 16:26:02 +0200 2163) 		kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
ee314a870e402 (Miklos Szeredi        2015-07-01 16:26:08 +0200 2164) 		end_polls(fc);
ee314a870e402 (Miklos Szeredi        2015-07-01 16:26:08 +0200 2165) 		wake_up_all(&fc->blocked_waitq);
ee314a870e402 (Miklos Szeredi        2015-07-01 16:26:08 +0200 2166) 		spin_unlock(&fc->lock);
8c91189a2a8f5 (Miklos Szeredi        2015-07-01 16:26:02 +0200 2167) 
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200 2168) 		end_requests(&to_end);
ee314a870e402 (Miklos Szeredi        2015-07-01 16:26:08 +0200 2169) 	} else {
ee314a870e402 (Miklos Szeredi        2015-07-01 16:26:08 +0200 2170) 		spin_unlock(&fc->lock);
69a53bf267fa5 (Miklos Szeredi        2006-01-16 22:14:41 -0800 2171) 	}
69a53bf267fa5 (Miklos Szeredi        2006-01-16 22:14:41 -0800 2172) }
08cbf542bf24f (Tejun Heo             2009-04-14 10:54:53 +0900 2173) EXPORT_SYMBOL_GPL(fuse_abort_conn);
69a53bf267fa5 (Miklos Szeredi        2006-01-16 22:14:41 -0800 2174) 
b8f95e5d13f5f (Miklos Szeredi        2018-07-26 16:13:11 +0200 2175) void fuse_wait_aborted(struct fuse_conn *fc)
b8f95e5d13f5f (Miklos Szeredi        2018-07-26 16:13:11 +0200 2176) {
2d84a2d19b615 (Miklos Szeredi        2018-11-09 15:52:16 +0100 2177) 	/* matches implicit memory barrier in fuse_drop_waiting() */
2d84a2d19b615 (Miklos Szeredi        2018-11-09 15:52:16 +0100 2178) 	smp_mb();
b8f95e5d13f5f (Miklos Szeredi        2018-07-26 16:13:11 +0200 2179) 	wait_event(fc->blocked_waitq, atomic_read(&fc->num_waiting) == 0);
b8f95e5d13f5f (Miklos Szeredi        2018-07-26 16:13:11 +0200 2180) }
b8f95e5d13f5f (Miklos Szeredi        2018-07-26 16:13:11 +0200 2181) 
08cbf542bf24f (Tejun Heo             2009-04-14 10:54:53 +0900 2182) int fuse_dev_release(struct inode *inode, struct file *file)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2183) {
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 2184) 	struct fuse_dev *fud = fuse_get_dev(file);
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 2185) 
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 2186) 	if (fud) {
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 2187) 		struct fuse_conn *fc = fud->fc;
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 2188) 		struct fuse_pqueue *fpq = &fud->pq;
45ff350bbd9d0 (Miklos Szeredi        2018-07-26 16:13:11 +0200 2189) 		LIST_HEAD(to_end);
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 2190) 		unsigned int i;
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 2191) 
45ff350bbd9d0 (Miklos Szeredi        2018-07-26 16:13:11 +0200 2192) 		spin_lock(&fpq->lock);
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 2193) 		WARN_ON(!list_empty(&fpq->io));
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 2194) 		for (i = 0; i < FUSE_PQ_HASH_SIZE; i++)
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 2195) 			list_splice_init(&fpq->processing[i], &to_end);
45ff350bbd9d0 (Miklos Szeredi        2018-07-26 16:13:11 +0200 2196) 		spin_unlock(&fpq->lock);
45ff350bbd9d0 (Miklos Szeredi        2018-07-26 16:13:11 +0200 2197) 
8f622e9497bbb (Max Reitz             2020-04-20 17:59:34 +0200 2198) 		end_requests(&to_end);
45ff350bbd9d0 (Miklos Szeredi        2018-07-26 16:13:11 +0200 2199) 
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 2200) 		/* Are we the last open device? */
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 2201) 		if (atomic_dec_and_test(&fc->dev_count)) {
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 2202) 			WARN_ON(fc->iq.fasync != NULL);
eb98e3bdf3aa7 (Miklos Szeredi        2019-01-24 10:40:16 +0100 2203) 			fuse_abort_conn(fc);
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 2204) 		}
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 2205) 		fuse_dev_free(fud);
385a17bfc3cb0 (Jeff Dike             2006-04-10 22:54:52 -0700 2206) 	}
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2207) 	return 0;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2208) }
08cbf542bf24f (Tejun Heo             2009-04-14 10:54:53 +0900 2209) EXPORT_SYMBOL_GPL(fuse_dev_release);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2210) 
385a17bfc3cb0 (Jeff Dike             2006-04-10 22:54:52 -0700 2211) static int fuse_dev_fasync(int fd, struct file *file, int on)
385a17bfc3cb0 (Jeff Dike             2006-04-10 22:54:52 -0700 2212) {
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 2213) 	struct fuse_dev *fud = fuse_get_dev(file);
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 2214) 
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 2215) 	if (!fud)
a87046d822f2d (Miklos Szeredi        2006-04-10 22:54:56 -0700 2216) 		return -EPERM;
385a17bfc3cb0 (Jeff Dike             2006-04-10 22:54:52 -0700 2217) 
385a17bfc3cb0 (Jeff Dike             2006-04-10 22:54:52 -0700 2218) 	/* No locking - fasync_helper does its own locking */
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 2219) 	return fasync_helper(fd, file, on, &fud->fc->iq.fasync);
385a17bfc3cb0 (Jeff Dike             2006-04-10 22:54:52 -0700 2220) }
385a17bfc3cb0 (Jeff Dike             2006-04-10 22:54:52 -0700 2221) 
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2222) static int fuse_device_clone(struct fuse_conn *fc, struct file *new)
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2223) {
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 2224) 	struct fuse_dev *fud;
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 2225) 
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2226) 	if (new->private_data)
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2227) 		return -EINVAL;
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2228) 
0cd1eb9a4160a (Vivek Goyal           2019-03-06 16:51:40 -0500 2229) 	fud = fuse_dev_alloc_install(fc);
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 2230) 	if (!fud)
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 2231) 		return -ENOMEM;
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 2232) 
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 2233) 	new->private_data = fud;
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200 2234) 	atomic_inc(&fc->dev_count);
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2235) 
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2236) 	return 0;
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2237) }
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2238) 
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2239) static long fuse_dev_ioctl(struct file *file, unsigned int cmd,
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2240) 			   unsigned long arg)
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2241) {
f8425c9396639 (Alessio Balsini       2021-01-25 15:30:51 +0000 2242) 	int res;
f8425c9396639 (Alessio Balsini       2021-01-25 15:30:51 +0000 2243) 	int oldfd;
f8425c9396639 (Alessio Balsini       2021-01-25 15:30:51 +0000 2244) 	struct fuse_dev *fud = NULL;
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2245) 
6076f5f341e61 (Alessio Balsini       2021-03-19 15:05:14 +0000 2246) 	switch (cmd) {
6076f5f341e61 (Alessio Balsini       2021-03-19 15:05:14 +0000 2247) 	case FUSE_DEV_IOC_CLONE:
f8425c9396639 (Alessio Balsini       2021-01-25 15:30:51 +0000 2248) 		res = -EFAULT;
f8425c9396639 (Alessio Balsini       2021-01-25 15:30:51 +0000 2249) 		if (!get_user(oldfd, (__u32 __user *)arg)) {
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2250) 			struct file *old = fget(oldfd);
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2251) 
f8425c9396639 (Alessio Balsini       2021-01-25 15:30:51 +0000 2252) 			res = -EINVAL;
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2253) 			if (old) {
8ed1f0e22f49e (Jann Horn             2015-08-16 20:27:01 +0200 2254) 				/*
8ed1f0e22f49e (Jann Horn             2015-08-16 20:27:01 +0200 2255) 				 * Check against file->f_op because CUSE
8ed1f0e22f49e (Jann Horn             2015-08-16 20:27:01 +0200 2256) 				 * uses the same ioctl handler.
8ed1f0e22f49e (Jann Horn             2015-08-16 20:27:01 +0200 2257) 				 */
8ed1f0e22f49e (Jann Horn             2015-08-16 20:27:01 +0200 2258) 				if (old->f_op == file->f_op &&
8ed1f0e22f49e (Jann Horn             2015-08-16 20:27:01 +0200 2259) 				    old->f_cred->user_ns == file->f_cred->user_ns)
8ed1f0e22f49e (Jann Horn             2015-08-16 20:27:01 +0200 2260) 					fud = fuse_get_dev(old);
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2261) 
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 2262) 				if (fud) {
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2263) 					mutex_lock(&fuse_mutex);
f8425c9396639 (Alessio Balsini       2021-01-25 15:30:51 +0000 2264) 					res = fuse_device_clone(fud->fc, file);
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2265) 					mutex_unlock(&fuse_mutex);
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2266) 				}
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2267) 				fput(old);
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2268) 			}
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2269) 		}
f8425c9396639 (Alessio Balsini       2021-01-25 15:30:51 +0000 2270) 		break;
f8425c9396639 (Alessio Balsini       2021-01-25 15:30:51 +0000 2271) 	default:
f8425c9396639 (Alessio Balsini       2021-01-25 15:30:51 +0000 2272) 		res = -ENOTTY;
f8425c9396639 (Alessio Balsini       2021-01-25 15:30:51 +0000 2273) 		break;
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2274) 	}
f8425c9396639 (Alessio Balsini       2021-01-25 15:30:51 +0000 2275) 	return res;
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2276) }
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2277) 
4b6f5d20b04dc (Arjan van de Ven      2006-03-28 01:56:42 -0800 2278) const struct file_operations fuse_dev_operations = {
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2279) 	.owner		= THIS_MODULE,
94e4fe2cab3d4 (Tom Van Braeckel      2015-01-12 05:22:16 +0100 2280) 	.open		= fuse_dev_open,
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2281) 	.llseek		= no_llseek,
fbdbacca61531 (Al Viro               2015-04-03 21:53:39 -0400 2282) 	.read_iter	= fuse_dev_read,
c3021629a0d82 (Miklos Szeredi        2010-05-25 15:06:07 +0200 2283) 	.splice_read	= fuse_dev_splice_read,
fbdbacca61531 (Al Viro               2015-04-03 21:53:39 -0400 2284) 	.write_iter	= fuse_dev_write,
dd3bb14f44a63 (Miklos Szeredi        2010-05-25 15:06:06 +0200 2285) 	.splice_write	= fuse_dev_splice_write,
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2286) 	.poll		= fuse_dev_poll,
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2287) 	.release	= fuse_dev_release,
385a17bfc3cb0 (Jeff Dike             2006-04-10 22:54:52 -0700 2288) 	.fasync		= fuse_dev_fasync,
00c570f4ba43a (Miklos Szeredi        2015-07-01 16:26:08 +0200 2289) 	.unlocked_ioctl = fuse_dev_ioctl,
1832f2d8ff691 (Arnd Bergmann         2018-09-11 21:59:08 +0200 2290) 	.compat_ioctl   = compat_ptr_ioctl,
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2291) };
08cbf542bf24f (Tejun Heo             2009-04-14 10:54:53 +0900 2292) EXPORT_SYMBOL_GPL(fuse_dev_operations);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2293) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2294) static struct miscdevice fuse_miscdevice = {
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2295) 	.minor = FUSE_MINOR,
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2296) 	.name  = "fuse",
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2297) 	.fops = &fuse_dev_operations,
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2298) };
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2299) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2300) int __init fuse_dev_init(void)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2301) {
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2302) 	int err = -ENOMEM;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2303) 	fuse_req_cachep = kmem_cache_create("fuse_request",
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2304) 					    sizeof(struct fuse_req),
20c2df83d25c6 (Paul Mundt            2007-07-20 10:11:58 +0900 2305) 					    0, 0, NULL);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2306) 	if (!fuse_req_cachep)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2307) 		goto out;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2308) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2309) 	err = misc_register(&fuse_miscdevice);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2310) 	if (err)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2311) 		goto out_cache_clean;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2312) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2313) 	return 0;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2314) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2315)  out_cache_clean:
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2316) 	kmem_cache_destroy(fuse_req_cachep);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2317)  out:
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2318) 	return err;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2319) }
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2320) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2321) void fuse_dev_cleanup(void)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2322) {
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2323) 	misc_deregister(&fuse_miscdevice);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2324) 	kmem_cache_destroy(fuse_req_cachep);
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 2325) }