VisionFive2 Linux kernel

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

More than 9999 Commits   32 Branches   54 Tags
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700    1) /*
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -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>
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700    4) 
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700    5)   This program can be distributed under the terms of the GNU GPL.
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700    6)   See the file COPYING.
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700    7) */
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700    8) 
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700    9) #include "fuse_i.h"
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700   10) 
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700   11) #include <linux/pagemap.h>
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700   12) #include <linux/slab.h>
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700   13) #include <linux/file.h>
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700   14) #include <linux/seq_file.h>
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700   15) #include <linux/init.h>
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700   16) #include <linux/module.h>
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200   17) #include <linux/moduleparam.h>
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000   18) #include <linux/fs_context.h>
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000   19) #include <linux/fs_parser.h>
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700   20) #include <linux/statfs.h>
9c8ef5614da22 (Miklos Szeredi        2006-06-25 05:48:55 -0700   21) #include <linux/random.h>
e8edc6e03a5c8 (Alexey Dobriyan       2007-05-21 01:22:52 +0400   22) #include <linux/sched.h>
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700   23) #include <linux/exportfs.h>
60bcc88ad185d (Seth Forshee          2016-08-29 08:46:37 -0500   24) #include <linux/posix_acl.h>
0b6e9ea041e6c (Seth Forshee          2014-07-02 16:29:19 -0500   25) #include <linux/pid_namespace.h>
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700   26) 
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700   27) MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>");
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700   28) MODULE_DESCRIPTION("Filesystem in Userspace");
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700   29) MODULE_LICENSE("GPL");
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700   30) 
e18b890bb0881 (Christoph Lameter     2006-12-06 20:33:20 -0800   31) static struct kmem_cache *fuse_inode_cachep;
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700   32) struct list_head fuse_conn_list;
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700   33) DEFINE_MUTEX(fuse_mutex);
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700   34) 
e4dca7b7aa08b (Kees Cook             2017-10-17 19:04:42 -0700   35) static int set_global_limit(const char *val, const struct kernel_param *kp);
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200   36) 
79a9d99434b10 (Csaba Henk            2009-08-26 19:18:24 +0200   37) unsigned max_user_bgreq;
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200   38) module_param_call(max_user_bgreq, set_global_limit, param_get_uint,
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200   39) 		  &max_user_bgreq, 0644);
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200   40) __MODULE_PARM_TYPE(max_user_bgreq, "uint");
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200   41) MODULE_PARM_DESC(max_user_bgreq,
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200   42)  "Global limit for the maximum number of backgrounded requests an "
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200   43)  "unprivileged user can set");
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200   44) 
79a9d99434b10 (Csaba Henk            2009-08-26 19:18:24 +0200   45) unsigned max_user_congthresh;
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200   46) module_param_call(max_user_congthresh, set_global_limit, param_get_uint,
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200   47) 		  &max_user_congthresh, 0644);
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200   48) __MODULE_PARM_TYPE(max_user_congthresh, "uint");
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200   49) MODULE_PARM_DESC(max_user_congthresh,
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200   50)  "Global limit for the maximum congestion threshold an "
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200   51)  "unprivileged user can set");
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200   52) 
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700   53) #define FUSE_SUPER_MAGIC 0x65735546
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700   54) 
d1875dbaa58e4 (Miklos Szeredi        2008-02-08 04:21:43 -0800   55) #define FUSE_DEFAULT_BLKSIZE 512
d1875dbaa58e4 (Miklos Szeredi        2008-02-08 04:21:43 -0800   56) 
7a6d3c8b3049d (Csaba Henk            2009-07-01 17:28:41 -0700   57) /** Maximum number of outstanding background requests */
7a6d3c8b3049d (Csaba Henk            2009-07-01 17:28:41 -0700   58) #define FUSE_DEFAULT_MAX_BACKGROUND 12
7a6d3c8b3049d (Csaba Henk            2009-07-01 17:28:41 -0700   59) 
7a6d3c8b3049d (Csaba Henk            2009-07-01 17:28:41 -0700   60) /** Congestion starts at 75% of maximum */
7a6d3c8b3049d (Csaba Henk            2009-07-01 17:28:41 -0700   61) #define FUSE_DEFAULT_CONGESTION_THRESHOLD (FUSE_DEFAULT_MAX_BACKGROUND * 3 / 4)
7a6d3c8b3049d (Csaba Henk            2009-07-01 17:28:41 -0700   62) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000   63) #ifdef CONFIG_BLOCK
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000   64) static struct file_system_type fuseblk_fs_type;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000   65) #endif
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000   66) 
a2daff6803a38 (Randy Dunlap          2011-05-31 14:09:00 -0700   67) struct fuse_forget_link *fuse_alloc_forget(void)
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100   68) {
dc69e98c241e1 (Khazhismel Kumykov    2019-09-17 12:35:33 -0700   69) 	return kzalloc(sizeof(struct fuse_forget_link), GFP_KERNEL_ACCOUNT);
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100   70) }
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100   71) 
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700   72) static struct inode *fuse_alloc_inode(struct super_block *sb)
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700   73) {
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700   74) 	struct fuse_inode *fi;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700   75) 
9031a69cf9f02 (zhangliguang          2019-05-06 16:52:25 +0800   76) 	fi = kmem_cache_alloc(fuse_inode_cachep, GFP_KERNEL);
9031a69cf9f02 (zhangliguang          2019-05-06 16:52:25 +0800   77) 	if (!fi)
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700   78) 		return NULL;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700   79) 
0a0898cf41387 (Miklos Szeredi        2006-07-30 03:04:10 -0700   80) 	fi->i_time = 0;
2f1e81965fd0f (Miklos Szeredi        2018-10-15 15:43:06 +0200   81) 	fi->inval_mask = 0;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700   82) 	fi->nodeid = 0;
9e6268db496a2 (Miklos Szeredi        2005-09-09 13:10:29 -0700   83) 	fi->nlookup = 0;
fbee36b92abc9 (John Muir             2007-11-28 16:22:02 -0800   84) 	fi->attr_version = 0;
45c72cd73c788 (Pavel Shilovsky       2012-05-10 19:49:38 +0400   85) 	fi->orig_ino = 0;
4582a4ab2a0e7 (Feng Shuo             2013-01-15 11:23:28 +0800   86) 	fi->state = 0;
5c672ab3f0ee0 (Miklos Szeredi        2016-06-30 13:10:49 +0200   87) 	mutex_init(&fi->mutex);
6ae330cad6ef2 (Vivek Goyal           2020-08-19 18:19:54 -0400   88) 	init_rwsem(&fi->i_mmap_sem);
f15ecfef058d9 (Kirill Tkhai          2018-11-09 13:33:22 +0300   89) 	spin_lock_init(&fi->lock);
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100   90) 	fi->forget = fuse_alloc_forget();
c2d0ad00d948d (Vivek Goyal           2020-08-19 18:19:51 -0400   91) 	if (!fi->forget)
c2d0ad00d948d (Vivek Goyal           2020-08-19 18:19:51 -0400   92) 		goto out_free;
c2d0ad00d948d (Vivek Goyal           2020-08-19 18:19:51 -0400   93) 
c2d0ad00d948d (Vivek Goyal           2020-08-19 18:19:51 -0400   94) 	if (IS_ENABLED(CONFIG_FUSE_DAX) && !fuse_dax_inode_alloc(sb, fi))
c2d0ad00d948d (Vivek Goyal           2020-08-19 18:19:51 -0400   95) 		goto out_free_forget;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700   96) 
9031a69cf9f02 (zhangliguang          2019-05-06 16:52:25 +0800   97) 	return &fi->inode;
c2d0ad00d948d (Vivek Goyal           2020-08-19 18:19:51 -0400   98) 
c2d0ad00d948d (Vivek Goyal           2020-08-19 18:19:51 -0400   99) out_free_forget:
c2d0ad00d948d (Vivek Goyal           2020-08-19 18:19:51 -0400  100) 	kfree(fi->forget);
c2d0ad00d948d (Vivek Goyal           2020-08-19 18:19:51 -0400  101) out_free:
c2d0ad00d948d (Vivek Goyal           2020-08-19 18:19:51 -0400  102) 	kmem_cache_free(fuse_inode_cachep, fi);
c2d0ad00d948d (Vivek Goyal           2020-08-19 18:19:51 -0400  103) 	return NULL;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  104) }
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  105) 
9baf28bbfea16 (Al Viro               2019-04-15 19:37:09 -0400  106) static void fuse_free_inode(struct inode *inode)
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  107) {
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  108) 	struct fuse_inode *fi = get_fuse_inode(inode);
9baf28bbfea16 (Al Viro               2019-04-15 19:37:09 -0400  109) 
5c672ab3f0ee0 (Miklos Szeredi        2016-06-30 13:10:49 +0200  110) 	mutex_destroy(&fi->mutex);
07e77dca8a1f1 (Miklos Szeredi        2010-12-07 20:16:56 +0100  111) 	kfree(fi->forget);
c2d0ad00d948d (Vivek Goyal           2020-08-19 18:19:51 -0400  112) #ifdef CONFIG_FUSE_DAX
c2d0ad00d948d (Vivek Goyal           2020-08-19 18:19:51 -0400  113) 	kfree(fi->dax);
c2d0ad00d948d (Vivek Goyal           2020-08-19 18:19:51 -0400  114) #endif
9baf28bbfea16 (Al Viro               2019-04-15 19:37:09 -0400  115) 	kmem_cache_free(fuse_inode_cachep, fi);
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  116) }
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  117) 
b57922d97fd6f (Al Viro               2010-06-07 14:34:48 -0400  118) static void fuse_evict_inode(struct inode *inode)
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  119) {
9baf28bbfea16 (Al Viro               2019-04-15 19:37:09 -0400  120) 	struct fuse_inode *fi = get_fuse_inode(inode);
9baf28bbfea16 (Al Viro               2019-04-15 19:37:09 -0400  121) 
91b0abe36a7b2 (Johannes Weiner       2014-04-03 14:47:49 -0700  122) 	truncate_inode_pages_final(&inode->i_data);
dbd5768f87ff6 (Jan Kara              2012-05-03 14:48:02 +0200  123) 	clear_inode(inode);
1751e8a6cb935 (Linus Torvalds        2017-11-27 13:05:09 -0800  124) 	if (inode->i_sb->s_flags & SB_ACTIVE) {
1e9a4ed9396e9 (Miklos Szeredi        2005-09-09 13:10:31 -0700  125) 		struct fuse_conn *fc = get_fuse_conn(inode);
c2d0ad00d948d (Vivek Goyal           2020-08-19 18:19:51 -0400  126) 
c2d0ad00d948d (Vivek Goyal           2020-08-19 18:19:51 -0400  127) 		if (FUSE_IS_DAX(inode))
c2d0ad00d948d (Vivek Goyal           2020-08-19 18:19:51 -0400  128) 			fuse_dax_inode_cleanup(inode);
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200  129) 		if (fi->nlookup) {
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200  130) 			fuse_queue_forget(fc, fi->forget, fi->nodeid,
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200  131) 					  fi->nlookup);
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200  132) 			fi->forget = NULL;
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200  133) 		}
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  134) 	}
5d069dbe8aaf2 (Miklos Szeredi        2020-12-10 15:33:14 +0100  135) 	if (S_ISREG(inode->i_mode) && !fuse_is_bad(inode)) {
9baf28bbfea16 (Al Viro               2019-04-15 19:37:09 -0400  136) 		WARN_ON(!list_empty(&fi->write_files));
9baf28bbfea16 (Al Viro               2019-04-15 19:37:09 -0400  137) 		WARN_ON(!list_empty(&fi->queued_writes));
9baf28bbfea16 (Al Viro               2019-04-15 19:37:09 -0400  138) 	}
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  139) }
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  140) 
0189a2d367f49 (Miklos Szeredi        2020-07-14 14:45:41 +0200  141) static int fuse_reconfigure(struct fs_context *fc)
7142125937e14 (Miklos Szeredi        2006-06-25 05:48:52 -0700  142) {
0189a2d367f49 (Miklos Szeredi        2020-07-14 14:45:41 +0200  143) 	struct super_block *sb = fc->root->d_sb;
0189a2d367f49 (Miklos Szeredi        2020-07-14 14:45:41 +0200  144) 
02b9984d64087 (Theodore Ts'o         2014-03-13 10:14:33 -0400  145) 	sync_filesystem(sb);
0189a2d367f49 (Miklos Szeredi        2020-07-14 14:45:41 +0200  146) 	if (fc->sb_flags & SB_MANDLOCK)
7142125937e14 (Miklos Szeredi        2006-06-25 05:48:52 -0700  147) 		return -EINVAL;
7142125937e14 (Miklos Szeredi        2006-06-25 05:48:52 -0700  148) 
7142125937e14 (Miklos Szeredi        2006-06-25 05:48:52 -0700  149) 	return 0;
7142125937e14 (Miklos Szeredi        2006-06-25 05:48:52 -0700  150) }
7142125937e14 (Miklos Szeredi        2006-06-25 05:48:52 -0700  151) 
45c72cd73c788 (Pavel Shilovsky       2012-05-10 19:49:38 +0400  152) /*
45c72cd73c788 (Pavel Shilovsky       2012-05-10 19:49:38 +0400  153)  * ino_t is 32-bits on 32-bit arch. We have to squash the 64-bit value down
45c72cd73c788 (Pavel Shilovsky       2012-05-10 19:49:38 +0400  154)  * so that it will fit.
45c72cd73c788 (Pavel Shilovsky       2012-05-10 19:49:38 +0400  155)  */
45c72cd73c788 (Pavel Shilovsky       2012-05-10 19:49:38 +0400  156) static ino_t fuse_squash_ino(u64 ino64)
45c72cd73c788 (Pavel Shilovsky       2012-05-10 19:49:38 +0400  157) {
45c72cd73c788 (Pavel Shilovsky       2012-05-10 19:49:38 +0400  158) 	ino_t ino = (ino_t) ino64;
45c72cd73c788 (Pavel Shilovsky       2012-05-10 19:49:38 +0400  159) 	if (sizeof(ino_t) < sizeof(u64))
45c72cd73c788 (Pavel Shilovsky       2012-05-10 19:49:38 +0400  160) 		ino ^= ino64 >> (sizeof(u64) - sizeof(ino_t)) * 8;
45c72cd73c788 (Pavel Shilovsky       2012-05-10 19:49:38 +0400  161) 	return ino;
45c72cd73c788 (Pavel Shilovsky       2012-05-10 19:49:38 +0400  162) }
45c72cd73c788 (Pavel Shilovsky       2012-05-10 19:49:38 +0400  163) 
3be5a52b30aa5 (Miklos Szeredi        2008-04-30 00:54:41 -0700  164) void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr,
3be5a52b30aa5 (Miklos Szeredi        2008-04-30 00:54:41 -0700  165) 				   u64 attr_valid)
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  166) {
9ffbb9162312f (Miklos Szeredi        2006-10-17 00:10:06 -0700  167) 	struct fuse_conn *fc = get_fuse_conn(inode);
ebc14c4dbeb56 (Miklos Szeredi        2007-10-16 23:31:03 -0700  168) 	struct fuse_inode *fi = get_fuse_inode(inode);
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  169) 
f15ecfef058d9 (Kirill Tkhai          2018-11-09 13:33:22 +0300  170) 	lockdep_assert_held(&fi->lock);
f15ecfef058d9 (Kirill Tkhai          2018-11-09 13:33:22 +0300  171) 
4510d86fbbb36 (Kirill Tkhai          2018-11-09 13:33:17 +0300  172) 	fi->attr_version = atomic64_inc_return(&fc->attr_version);
1fb69e7817296 (Miklos Szeredi        2007-10-18 03:06:58 -0700  173) 	fi->i_time = attr_valid;
2f1e81965fd0f (Miklos Szeredi        2018-10-15 15:43:06 +0200  174) 	WRITE_ONCE(fi->inval_mask, 0);
1fb69e7817296 (Miklos Szeredi        2007-10-18 03:06:58 -0700  175) 
45c72cd73c788 (Pavel Shilovsky       2012-05-10 19:49:38 +0400  176) 	inode->i_ino     = fuse_squash_ino(attr->ino);
ebc14c4dbeb56 (Miklos Szeredi        2007-10-16 23:31:03 -0700  177) 	inode->i_mode    = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
bfe8684869601 (Miklos Szeredi        2011-10-28 14:13:29 +0200  178) 	set_nlink(inode, attr->nlink);
8cb08329b0809 (Eric W. Biederman     2018-02-21 11:18:07 -0600  179) 	inode->i_uid     = make_kuid(fc->user_ns, attr->uid);
8cb08329b0809 (Eric W. Biederman     2018-02-21 11:18:07 -0600  180) 	inode->i_gid     = make_kgid(fc->user_ns, attr->gid);
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  181) 	inode->i_blocks  = attr->blocks;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  182) 	inode->i_atime.tv_sec   = attr->atime;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  183) 	inode->i_atime.tv_nsec  = attr->atimensec;
b0aa760652179 (Maxim Patlasov        2013-12-26 19:51:11 +0400  184) 	/* mtime from server may be stale due to local buffered write */
b0aa760652179 (Maxim Patlasov        2013-12-26 19:51:11 +0400  185) 	if (!fc->writeback_cache || !S_ISREG(inode->i_mode)) {
b0aa760652179 (Maxim Patlasov        2013-12-26 19:51:11 +0400  186) 		inode->i_mtime.tv_sec   = attr->mtime;
b0aa760652179 (Maxim Patlasov        2013-12-26 19:51:11 +0400  187) 		inode->i_mtime.tv_nsec  = attr->mtimensec;
31f3267b4ba16 (Maxim Patlasov        2014-04-28 14:19:24 +0200  188) 		inode->i_ctime.tv_sec   = attr->ctime;
31f3267b4ba16 (Maxim Patlasov        2014-04-28 14:19:24 +0200  189) 		inode->i_ctime.tv_nsec  = attr->ctimensec;
b0aa760652179 (Maxim Patlasov        2013-12-26 19:51:11 +0400  190) 	}
e00d2c2d4aead (Miklos Szeredi        2007-10-16 23:31:01 -0700  191) 
0e9663ee452ff (Miklos Szeredi        2007-10-18 03:07:05 -0700  192) 	if (attr->blksize != 0)
0e9663ee452ff (Miklos Szeredi        2007-10-18 03:07:05 -0700  193) 		inode->i_blkbits = ilog2(attr->blksize);
0e9663ee452ff (Miklos Szeredi        2007-10-18 03:07:05 -0700  194) 	else
0e9663ee452ff (Miklos Szeredi        2007-10-18 03:07:05 -0700  195) 		inode->i_blkbits = inode->i_sb->s_blocksize_bits;
0e9663ee452ff (Miklos Szeredi        2007-10-18 03:07:05 -0700  196) 
ebc14c4dbeb56 (Miklos Szeredi        2007-10-16 23:31:03 -0700  197) 	/*
ebc14c4dbeb56 (Miklos Szeredi        2007-10-16 23:31:03 -0700  198) 	 * Don't set the sticky bit in i_mode, unless we want the VFS
ebc14c4dbeb56 (Miklos Szeredi        2007-10-16 23:31:03 -0700  199) 	 * to check permissions.  This prevents failures due to the
ebc14c4dbeb56 (Miklos Szeredi        2007-10-16 23:31:03 -0700  200) 	 * check in may_delete().
ebc14c4dbeb56 (Miklos Szeredi        2007-10-16 23:31:03 -0700  201) 	 */
ebc14c4dbeb56 (Miklos Szeredi        2007-10-16 23:31:03 -0700  202) 	fi->orig_i_mode = inode->i_mode;
29433a2991fa6 (Miklos Szeredi        2016-10-01 07:32:32 +0200  203) 	if (!fc->default_permissions)
ebc14c4dbeb56 (Miklos Szeredi        2007-10-16 23:31:03 -0700  204) 		inode->i_mode &= ~S_ISVTX;
45c72cd73c788 (Pavel Shilovsky       2012-05-10 19:49:38 +0400  205) 
45c72cd73c788 (Pavel Shilovsky       2012-05-10 19:49:38 +0400  206) 	fi->orig_ino = attr->ino;
9d769e6aa2524 (Vivek Goyal           2020-10-09 14:15:12 -0400  207) 
9d769e6aa2524 (Vivek Goyal           2020-10-09 14:15:12 -0400  208) 	/*
9d769e6aa2524 (Vivek Goyal           2020-10-09 14:15:12 -0400  209) 	 * We are refreshing inode data and it is possible that another
9d769e6aa2524 (Vivek Goyal           2020-10-09 14:15:12 -0400  210) 	 * client set suid/sgid or security.capability xattr. So clear
9d769e6aa2524 (Vivek Goyal           2020-10-09 14:15:12 -0400  211) 	 * S_NOSEC. Ideally, we could have cleared it only if suid/sgid
9d769e6aa2524 (Vivek Goyal           2020-10-09 14:15:12 -0400  212) 	 * was set or if security.capability xattr was set. But we don't
9d769e6aa2524 (Vivek Goyal           2020-10-09 14:15:12 -0400  213) 	 * know if security.capability has been set or not. So clear it
9d769e6aa2524 (Vivek Goyal           2020-10-09 14:15:12 -0400  214) 	 * anyway. Its less efficient but should be safe.
9d769e6aa2524 (Vivek Goyal           2020-10-09 14:15:12 -0400  215) 	 */
9d769e6aa2524 (Vivek Goyal           2020-10-09 14:15:12 -0400  216) 	inode->i_flags &= ~S_NOSEC;
3be5a52b30aa5 (Miklos Szeredi        2008-04-30 00:54:41 -0700  217) }
3be5a52b30aa5 (Miklos Szeredi        2008-04-30 00:54:41 -0700  218) 
3be5a52b30aa5 (Miklos Szeredi        2008-04-30 00:54:41 -0700  219) void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
3be5a52b30aa5 (Miklos Szeredi        2008-04-30 00:54:41 -0700  220) 			    u64 attr_valid, u64 attr_version)
3be5a52b30aa5 (Miklos Szeredi        2008-04-30 00:54:41 -0700  221) {
3be5a52b30aa5 (Miklos Szeredi        2008-04-30 00:54:41 -0700  222) 	struct fuse_conn *fc = get_fuse_conn(inode);
3be5a52b30aa5 (Miklos Szeredi        2008-04-30 00:54:41 -0700  223) 	struct fuse_inode *fi = get_fuse_inode(inode);
8373200b124d0 (Pavel Emelyanov       2013-10-10 17:10:46 +0400  224) 	bool is_wb = fc->writeback_cache;
3be5a52b30aa5 (Miklos Szeredi        2008-04-30 00:54:41 -0700  225) 	loff_t oldsize;
a64ba10f65bfe (Arnd Bergmann         2018-07-13 16:35:10 +0200  226) 	struct timespec64 old_mtime;
3be5a52b30aa5 (Miklos Szeredi        2008-04-30 00:54:41 -0700  227) 
f15ecfef058d9 (Kirill Tkhai          2018-11-09 13:33:22 +0300  228) 	spin_lock(&fi->lock);
06a7c3c278140 (Maxim Patlasov        2013-08-30 17:06:04 +0400  229) 	if ((attr_version != 0 && fi->attr_version > attr_version) ||
06a7c3c278140 (Maxim Patlasov        2013-08-30 17:06:04 +0400  230) 	    test_bit(FUSE_I_SIZE_UNSTABLE, &fi->state)) {
f15ecfef058d9 (Kirill Tkhai          2018-11-09 13:33:22 +0300  231) 		spin_unlock(&fi->lock);
3be5a52b30aa5 (Miklos Szeredi        2008-04-30 00:54:41 -0700  232) 		return;
3be5a52b30aa5 (Miklos Szeredi        2008-04-30 00:54:41 -0700  233) 	}
3be5a52b30aa5 (Miklos Szeredi        2008-04-30 00:54:41 -0700  234) 
a64ba10f65bfe (Arnd Bergmann         2018-07-13 16:35:10 +0200  235) 	old_mtime = inode->i_mtime;
3be5a52b30aa5 (Miklos Szeredi        2008-04-30 00:54:41 -0700  236) 	fuse_change_attributes_common(inode, attr, attr_valid);
ebc14c4dbeb56 (Miklos Szeredi        2007-10-16 23:31:03 -0700  237) 
e00d2c2d4aead (Miklos Szeredi        2007-10-16 23:31:01 -0700  238) 	oldsize = inode->i_size;
8373200b124d0 (Pavel Emelyanov       2013-10-10 17:10:46 +0400  239) 	/*
8373200b124d0 (Pavel Emelyanov       2013-10-10 17:10:46 +0400  240) 	 * In case of writeback_cache enabled, the cached writes beyond EOF
8373200b124d0 (Pavel Emelyanov       2013-10-10 17:10:46 +0400  241) 	 * extend local i_size without keeping userspace server in sync. So,
8373200b124d0 (Pavel Emelyanov       2013-10-10 17:10:46 +0400  242) 	 * attr->size coming from server can be stale. We cannot trust it.
8373200b124d0 (Pavel Emelyanov       2013-10-10 17:10:46 +0400  243) 	 */
8373200b124d0 (Pavel Emelyanov       2013-10-10 17:10:46 +0400  244) 	if (!is_wb || !S_ISREG(inode->i_mode))
8373200b124d0 (Pavel Emelyanov       2013-10-10 17:10:46 +0400  245) 		i_size_write(inode, attr->size);
f15ecfef058d9 (Kirill Tkhai          2018-11-09 13:33:22 +0300  246) 	spin_unlock(&fi->lock);
e00d2c2d4aead (Miklos Szeredi        2007-10-16 23:31:01 -0700  247) 
8373200b124d0 (Pavel Emelyanov       2013-10-10 17:10:46 +0400  248) 	if (!is_wb && S_ISREG(inode->i_mode)) {
eed2179efe1aa (Brian Foster          2012-07-16 15:23:49 -0400  249) 		bool inval = false;
eed2179efe1aa (Brian Foster          2012-07-16 15:23:49 -0400  250) 
eed2179efe1aa (Brian Foster          2012-07-16 15:23:49 -0400  251) 		if (oldsize != attr->size) {
7caef26767c17 (Kirill A. Shutemov    2013-09-12 15:13:56 -0700  252) 			truncate_pagecache(inode, attr->size);
ad2ba64dd4898 (Kirill Smelkov        2019-03-27 11:14:15 +0000  253) 			if (!fc->explicit_inval_data)
ad2ba64dd4898 (Kirill Smelkov        2019-03-27 11:14:15 +0000  254) 				inval = true;
eed2179efe1aa (Brian Foster          2012-07-16 15:23:49 -0400  255) 		} else if (fc->auto_inval_data) {
a64ba10f65bfe (Arnd Bergmann         2018-07-13 16:35:10 +0200  256) 			struct timespec64 new_mtime = {
eed2179efe1aa (Brian Foster          2012-07-16 15:23:49 -0400  257) 				.tv_sec = attr->mtime,
eed2179efe1aa (Brian Foster          2012-07-16 15:23:49 -0400  258) 				.tv_nsec = attr->mtimensec,
eed2179efe1aa (Brian Foster          2012-07-16 15:23:49 -0400  259) 			};
eed2179efe1aa (Brian Foster          2012-07-16 15:23:49 -0400  260) 
eed2179efe1aa (Brian Foster          2012-07-16 15:23:49 -0400  261) 			/*
eed2179efe1aa (Brian Foster          2012-07-16 15:23:49 -0400  262) 			 * Auto inval mode also checks and invalidates if mtime
eed2179efe1aa (Brian Foster          2012-07-16 15:23:49 -0400  263) 			 * has changed.
eed2179efe1aa (Brian Foster          2012-07-16 15:23:49 -0400  264) 			 */
a64ba10f65bfe (Arnd Bergmann         2018-07-13 16:35:10 +0200  265) 			if (!timespec64_equal(&old_mtime, &new_mtime))
eed2179efe1aa (Brian Foster          2012-07-16 15:23:49 -0400  266) 				inval = true;
eed2179efe1aa (Brian Foster          2012-07-16 15:23:49 -0400  267) 		}
eed2179efe1aa (Brian Foster          2012-07-16 15:23:49 -0400  268) 
eed2179efe1aa (Brian Foster          2012-07-16 15:23:49 -0400  269) 		if (inval)
eed2179efe1aa (Brian Foster          2012-07-16 15:23:49 -0400  270) 			invalidate_inode_pages2(inode->i_mapping);
e00d2c2d4aead (Miklos Szeredi        2007-10-16 23:31:01 -0700  271) 	}
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  272) }
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  273) 
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  274) static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr)
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  275) {
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  276) 	inode->i_mode = attr->mode & S_IFMT;
9ffbb9162312f (Miklos Szeredi        2006-10-17 00:10:06 -0700  277) 	inode->i_size = attr->size;
b0aa760652179 (Maxim Patlasov        2013-12-26 19:51:11 +0400  278) 	inode->i_mtime.tv_sec  = attr->mtime;
b0aa760652179 (Maxim Patlasov        2013-12-26 19:51:11 +0400  279) 	inode->i_mtime.tv_nsec = attr->mtimensec;
31f3267b4ba16 (Maxim Patlasov        2014-04-28 14:19:24 +0200  280) 	inode->i_ctime.tv_sec  = attr->ctime;
31f3267b4ba16 (Maxim Patlasov        2014-04-28 14:19:24 +0200  281) 	inode->i_ctime.tv_nsec = attr->ctimensec;
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  282) 	if (S_ISREG(inode->i_mode)) {
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  283) 		fuse_init_common(inode);
b6aeadeda22a9 (Miklos Szeredi        2005-09-09 13:10:30 -0700  284) 		fuse_init_file_inode(inode);
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  285) 	} else if (S_ISDIR(inode->i_mode))
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  286) 		fuse_init_dir(inode);
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  287) 	else if (S_ISLNK(inode->i_mode))
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  288) 		fuse_init_symlink(inode);
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  289) 	else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) ||
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  290) 		 S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  291) 		fuse_init_common(inode);
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  292) 		init_special_inode(inode, inode->i_mode,
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  293) 				   new_decode_dev(attr->rdev));
39ee059affaf5 (Miklos Szeredi        2006-01-06 00:19:43 -0800  294) 	} else
39ee059affaf5 (Miklos Szeredi        2006-01-06 00:19:43 -0800  295) 		BUG();
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  296) }
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  297) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  298) static int fuse_inode_eq(struct inode *inode, void *_nodeidp)
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  299) {
b48badf013018 (Miklos Szeredi        2008-04-30 00:54:44 -0700  300) 	u64 nodeid = *(u64 *) _nodeidp;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  301) 	if (get_node_id(inode) == nodeid)
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  302) 		return 1;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  303) 	else
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  304) 		return 0;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  305) }
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  306) 
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  307) static int fuse_inode_set(struct inode *inode, void *_nodeidp)
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  308) {
b48badf013018 (Miklos Szeredi        2008-04-30 00:54:44 -0700  309) 	u64 nodeid = *(u64 *) _nodeidp;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  310) 	get_fuse_inode(inode)->nodeid = nodeid;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  311) 	return 0;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  312) }
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  313) 
b48badf013018 (Miklos Szeredi        2008-04-30 00:54:44 -0700  314) struct inode *fuse_iget(struct super_block *sb, u64 nodeid,
1fb69e7817296 (Miklos Szeredi        2007-10-18 03:06:58 -0700  315) 			int generation, struct fuse_attr *attr,
1fb69e7817296 (Miklos Szeredi        2007-10-18 03:06:58 -0700  316) 			u64 attr_valid, u64 attr_version)
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  317) {
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  318) 	struct inode *inode;
9e6268db496a2 (Miklos Szeredi        2005-09-09 13:10:29 -0700  319) 	struct fuse_inode *fi;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  320) 	struct fuse_conn *fc = get_fuse_conn_super(sb);
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  321) 
bf109c64040f5 (Max Reitz             2020-04-21 14:47:15 +0200  322) 	/*
bf109c64040f5 (Max Reitz             2020-04-21 14:47:15 +0200  323) 	 * Auto mount points get their node id from the submount root, which is
bf109c64040f5 (Max Reitz             2020-04-21 14:47:15 +0200  324) 	 * not a unique identifier within this filesystem.
bf109c64040f5 (Max Reitz             2020-04-21 14:47:15 +0200  325) 	 *
bf109c64040f5 (Max Reitz             2020-04-21 14:47:15 +0200  326) 	 * To avoid conflicts, do not place submount points into the inode hash
bf109c64040f5 (Max Reitz             2020-04-21 14:47:15 +0200  327) 	 * table.
bf109c64040f5 (Max Reitz             2020-04-21 14:47:15 +0200  328) 	 */
bf109c64040f5 (Max Reitz             2020-04-21 14:47:15 +0200  329) 	if (fc->auto_submounts && (attr->flags & FUSE_ATTR_SUBMOUNT) &&
bf109c64040f5 (Max Reitz             2020-04-21 14:47:15 +0200  330) 	    S_ISDIR(attr->mode)) {
bf109c64040f5 (Max Reitz             2020-04-21 14:47:15 +0200  331) 		inode = new_inode(sb);
bf109c64040f5 (Max Reitz             2020-04-21 14:47:15 +0200  332) 		if (!inode)
bf109c64040f5 (Max Reitz             2020-04-21 14:47:15 +0200  333) 			return NULL;
bf109c64040f5 (Max Reitz             2020-04-21 14:47:15 +0200  334) 
bf109c64040f5 (Max Reitz             2020-04-21 14:47:15 +0200  335) 		fuse_init_inode(inode, attr);
bf109c64040f5 (Max Reitz             2020-04-21 14:47:15 +0200  336) 		get_fuse_inode(inode)->nodeid = nodeid;
bf109c64040f5 (Max Reitz             2020-04-21 14:47:15 +0200  337) 		inode->i_flags |= S_AUTOMOUNT;
bf109c64040f5 (Max Reitz             2020-04-21 14:47:15 +0200  338) 		goto done;
bf109c64040f5 (Max Reitz             2020-04-21 14:47:15 +0200  339) 	}
bf109c64040f5 (Max Reitz             2020-04-21 14:47:15 +0200  340) 
bf109c64040f5 (Max Reitz             2020-04-21 14:47:15 +0200  341) retry:
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  342) 	inode = iget5_locked(sb, nodeid, fuse_inode_eq, fuse_inode_set, &nodeid);
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  343) 	if (!inode)
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  344) 		return NULL;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  345) 
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  346) 	if ((inode->i_state & I_NEW)) {
b0aa760652179 (Maxim Patlasov        2013-12-26 19:51:11 +0400  347) 		inode->i_flags |= S_NOATIME;
d31433c8b06d4 (Maxim Patlasov        2014-04-28 14:19:21 +0200  348) 		if (!fc->writeback_cache || !S_ISREG(attr->mode))
b0aa760652179 (Maxim Patlasov        2013-12-26 19:51:11 +0400  349) 			inode->i_flags |= S_NOCMTIME;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  350) 		inode->i_generation = generation;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  351) 		fuse_init_inode(inode, attr);
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  352) 		unlock_new_inode(inode);
c09a4ad6251f9 (Amir Goldstein        2021-06-21 14:03:53 +0300  353) 	} else if (fuse_stale_inode(inode, generation, attr)) {
c09a4ad6251f9 (Amir Goldstein        2021-06-21 14:03:53 +0300  354) 		/* nodeid was reused, any I/O on the old inode should fail */
5d069dbe8aaf2 (Miklos Szeredi        2020-12-10 15:33:14 +0100  355) 		fuse_make_bad(inode);
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  356) 		iput(inode);
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  357) 		goto retry;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  358) 	}
bf109c64040f5 (Max Reitz             2020-04-21 14:47:15 +0200  359) done:
9e6268db496a2 (Miklos Szeredi        2005-09-09 13:10:29 -0700  360) 	fi = get_fuse_inode(inode);
c9d8f5f0692d5 (Kirill Tkhai          2018-11-09 13:33:27 +0300  361) 	spin_lock(&fi->lock);
1729a16c2c92b (Miklos Szeredi        2008-11-26 12:03:54 +0100  362) 	fi->nlookup++;
c9d8f5f0692d5 (Kirill Tkhai          2018-11-09 13:33:27 +0300  363) 	spin_unlock(&fi->lock);
1fb69e7817296 (Miklos Szeredi        2007-10-18 03:06:58 -0700  364) 	fuse_change_attributes(inode, attr, attr_valid, attr_version);
1fb69e7817296 (Miklos Szeredi        2007-10-18 03:06:58 -0700  365) 
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  366) 	return inode;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  367) }
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  368) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  369) struct inode *fuse_ilookup(struct fuse_conn *fc, u64 nodeid,
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  370) 			   struct fuse_mount **fm)
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  371) {
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  372) 	struct fuse_mount *fm_iter;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  373) 	struct inode *inode;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  374) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  375) 	WARN_ON(!rwsem_is_locked(&fc->killsb));
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  376) 	list_for_each_entry(fm_iter, &fc->mounts, fc_entry) {
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  377) 		if (!fm_iter->sb)
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  378) 			continue;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  379) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  380) 		inode = ilookup5(fm_iter->sb, nodeid, fuse_inode_eq, &nodeid);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  381) 		if (inode) {
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  382) 			if (fm)
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  383) 				*fm = fm_iter;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  384) 			return inode;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  385) 		}
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  386) 	}
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  387) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  388) 	return NULL;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  389) }
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  390) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  391) int fuse_reverse_inval_inode(struct fuse_conn *fc, u64 nodeid,
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400  392) 			     loff_t offset, loff_t len)
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400  393) {
5ddd9ced9aef6 (Miklos Szeredi        2020-05-19 14:50:38 +0200  394) 	struct fuse_inode *fi;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400  395) 	struct inode *inode;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400  396) 	pgoff_t pg_start;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400  397) 	pgoff_t pg_end;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400  398) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  399) 	inode = fuse_ilookup(fc, nodeid, NULL);
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400  400) 	if (!inode)
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400  401) 		return -ENOENT;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400  402) 
5ddd9ced9aef6 (Miklos Szeredi        2020-05-19 14:50:38 +0200  403) 	fi = get_fuse_inode(inode);
5ddd9ced9aef6 (Miklos Szeredi        2020-05-19 14:50:38 +0200  404) 	spin_lock(&fi->lock);
5ddd9ced9aef6 (Miklos Szeredi        2020-05-19 14:50:38 +0200  405) 	fi->attr_version = atomic64_inc_return(&fc->attr_version);
5ddd9ced9aef6 (Miklos Szeredi        2020-05-19 14:50:38 +0200  406) 	spin_unlock(&fi->lock);
5ddd9ced9aef6 (Miklos Szeredi        2020-05-19 14:50:38 +0200  407) 
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400  408) 	fuse_invalidate_attr(inode);
60bcc88ad185d (Seth Forshee          2016-08-29 08:46:37 -0500  409) 	forget_all_cached_acls(inode);
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400  410) 	if (offset >= 0) {
09cbfeaf1a5a6 (Kirill A. Shutemov    2016-04-01 15:29:47 +0300  411) 		pg_start = offset >> PAGE_SHIFT;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400  412) 		if (len <= 0)
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400  413) 			pg_end = -1;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400  414) 		else
09cbfeaf1a5a6 (Kirill A. Shutemov    2016-04-01 15:29:47 +0300  415) 			pg_end = (offset + len - 1) >> PAGE_SHIFT;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400  416) 		invalidate_inode_pages2_range(inode->i_mapping,
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400  417) 					      pg_start, pg_end);
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400  418) 	}
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400  419) 	iput(inode);
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400  420) 	return 0;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400  421) }
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400  422) 
63576c13bd178 (Miklos Szeredi        2018-07-26 16:13:11 +0200  423) bool fuse_lock_inode(struct inode *inode)
5c672ab3f0ee0 (Miklos Szeredi        2016-06-30 13:10:49 +0200  424) {
63576c13bd178 (Miklos Szeredi        2018-07-26 16:13:11 +0200  425) 	bool locked = false;
63576c13bd178 (Miklos Szeredi        2018-07-26 16:13:11 +0200  426) 
63576c13bd178 (Miklos Szeredi        2018-07-26 16:13:11 +0200  427) 	if (!get_fuse_conn(inode)->parallel_dirops) {
5c672ab3f0ee0 (Miklos Szeredi        2016-06-30 13:10:49 +0200  428) 		mutex_lock(&get_fuse_inode(inode)->mutex);
63576c13bd178 (Miklos Szeredi        2018-07-26 16:13:11 +0200  429) 		locked = true;
63576c13bd178 (Miklos Szeredi        2018-07-26 16:13:11 +0200  430) 	}
63576c13bd178 (Miklos Szeredi        2018-07-26 16:13:11 +0200  431) 
63576c13bd178 (Miklos Szeredi        2018-07-26 16:13:11 +0200  432) 	return locked;
5c672ab3f0ee0 (Miklos Szeredi        2016-06-30 13:10:49 +0200  433) }
5c672ab3f0ee0 (Miklos Szeredi        2016-06-30 13:10:49 +0200  434) 
63576c13bd178 (Miklos Szeredi        2018-07-26 16:13:11 +0200  435) void fuse_unlock_inode(struct inode *inode, bool locked)
5c672ab3f0ee0 (Miklos Szeredi        2016-06-30 13:10:49 +0200  436) {
63576c13bd178 (Miklos Szeredi        2018-07-26 16:13:11 +0200  437) 	if (locked)
5c672ab3f0ee0 (Miklos Szeredi        2016-06-30 13:10:49 +0200  438) 		mutex_unlock(&get_fuse_inode(inode)->mutex);
5c672ab3f0ee0 (Miklos Szeredi        2016-06-30 13:10:49 +0200  439) }
5c672ab3f0ee0 (Miklos Szeredi        2016-06-30 13:10:49 +0200  440) 
42faad99658ee (Al Viro               2008-04-24 07:21:56 -0400  441) static void fuse_umount_begin(struct super_block *sb)
69a53bf267fa5 (Miklos Szeredi        2006-01-16 22:14:41 -0800  442) {
15c8e72e88e0b (Vivek Goyal           2019-05-06 15:35:43 -0400  443) 	struct fuse_conn *fc = get_fuse_conn_super(sb);
15c8e72e88e0b (Vivek Goyal           2019-05-06 15:35:43 -0400  444) 
15c8e72e88e0b (Vivek Goyal           2019-05-06 15:35:43 -0400  445) 	if (!fc->no_force_umount)
15c8e72e88e0b (Vivek Goyal           2019-05-06 15:35:43 -0400  446) 		fuse_abort_conn(fc);
69a53bf267fa5 (Miklos Szeredi        2006-01-16 22:14:41 -0800  447) }
69a53bf267fa5 (Miklos Szeredi        2006-01-16 22:14:41 -0800  448) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  449) static void fuse_send_destroy(struct fuse_mount *fm)
0ec7ca41f6f0f (Miklos Szeredi        2006-12-06 20:35:52 -0800  450) {
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  451) 	if (fm->fc->conn_init) {
1ccd1ea249622 (Miklos Szeredi        2019-09-10 15:04:09 +0200  452) 		FUSE_ARGS(args);
1ccd1ea249622 (Miklos Szeredi        2019-09-10 15:04:09 +0200  453) 
1ccd1ea249622 (Miklos Szeredi        2019-09-10 15:04:09 +0200  454) 		args.opcode = FUSE_DESTROY;
1ccd1ea249622 (Miklos Szeredi        2019-09-10 15:04:09 +0200  455) 		args.force = true;
1ccd1ea249622 (Miklos Szeredi        2019-09-10 15:04:09 +0200  456) 		args.nocreds = true;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  457) 		fuse_simple_request(fm, &args);
0ec7ca41f6f0f (Miklos Szeredi        2006-12-06 20:35:52 -0800  458) 	}
0ec7ca41f6f0f (Miklos Szeredi        2006-12-06 20:35:52 -0800  459) }
0ec7ca41f6f0f (Miklos Szeredi        2006-12-06 20:35:52 -0800  460) 
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900  461) static void fuse_put_super(struct super_block *sb)
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900  462) {
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  463) 	struct fuse_mount *fm = get_fuse_mount_super(sb);
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900  464) 
514b5e3ff45e6 (Miklos Szeredi        2020-11-11 17:22:32 +0100  465) 	fuse_conn_put(fm->fc);
514b5e3ff45e6 (Miklos Szeredi        2020-11-11 17:22:32 +0100  466) 	kfree(fm);
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  467) }
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  468) 
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  469) static void convert_fuse_statfs(struct kstatfs *stbuf, struct fuse_kstatfs *attr)
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  470) {
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  471) 	stbuf->f_type    = FUSE_SUPER_MAGIC;
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  472) 	stbuf->f_bsize   = attr->bsize;
de5f12025572e (Miklos Szeredi        2006-01-06 00:19:37 -0800  473) 	stbuf->f_frsize  = attr->frsize;
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  474) 	stbuf->f_blocks  = attr->blocks;
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  475) 	stbuf->f_bfree   = attr->bfree;
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  476) 	stbuf->f_bavail  = attr->bavail;
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  477) 	stbuf->f_files   = attr->files;
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  478) 	stbuf->f_ffree   = attr->ffree;
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  479) 	stbuf->f_namelen = attr->namelen;
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  480) 	/* fsid is left zero */
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  481) }
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  482) 
726c334223180 (David Howells         2006-06-23 02:02:58 -0700  483) static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf)
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  484) {
726c334223180 (David Howells         2006-06-23 02:02:58 -0700  485) 	struct super_block *sb = dentry->d_sb;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  486) 	struct fuse_mount *fm = get_fuse_mount_super(sb);
7078187a795f8 (Miklos Szeredi        2014-12-12 09:49:05 +0100  487) 	FUSE_ARGS(args);
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  488) 	struct fuse_statfs_out outarg;
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  489) 	int err;
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  490) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  491) 	if (!fuse_allow_current_process(fm->fc)) {
e57ac68378a28 (Miklos Szeredi        2007-10-18 03:06:58 -0700  492) 		buf->f_type = FUSE_SUPER_MAGIC;
e57ac68378a28 (Miklos Szeredi        2007-10-18 03:06:58 -0700  493) 		return 0;
e57ac68378a28 (Miklos Szeredi        2007-10-18 03:06:58 -0700  494) 	}
e57ac68378a28 (Miklos Szeredi        2007-10-18 03:06:58 -0700  495) 
de5f12025572e (Miklos Szeredi        2006-01-06 00:19:37 -0800  496) 	memset(&outarg, 0, sizeof(outarg));
d5b4854357f47 (Miklos Szeredi        2019-09-10 15:04:08 +0200  497) 	args.in_numargs = 0;
d5b4854357f47 (Miklos Szeredi        2019-09-10 15:04:08 +0200  498) 	args.opcode = FUSE_STATFS;
d5b4854357f47 (Miklos Szeredi        2019-09-10 15:04:08 +0200  499) 	args.nodeid = get_node_id(d_inode(dentry));
d5b4854357f47 (Miklos Szeredi        2019-09-10 15:04:08 +0200  500) 	args.out_numargs = 1;
d5b4854357f47 (Miklos Szeredi        2019-09-10 15:04:08 +0200  501) 	args.out_args[0].size = sizeof(outarg);
d5b4854357f47 (Miklos Szeredi        2019-09-10 15:04:08 +0200  502) 	args.out_args[0].value = &outarg;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  503) 	err = fuse_simple_request(fm, &args);
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  504) 	if (!err)
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  505) 		convert_fuse_statfs(buf, &outarg.st);
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  506) 	return err;
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  507) }
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  508) 
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  509) static int fuse_sync_fs(struct super_block *sb, int wait)
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  510) {
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  511) 	struct fuse_mount *fm = get_fuse_mount_super(sb);
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  512) 	struct fuse_conn *fc = fm->fc;
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  513) 	struct fuse_syncfs_in inarg;
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  514) 	FUSE_ARGS(args);
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  515) 	int err;
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  516) 
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  517) 	/*
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  518) 	 * Userspace cannot handle the wait == 0 case.  Avoid a
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  519) 	 * gratuitous roundtrip.
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  520) 	 */
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  521) 	if (!wait)
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  522) 		return 0;
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  523) 
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  524) 	/* The filesystem is being unmounted.  Nothing to do. */
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  525) 	if (!sb->s_root)
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  526) 		return 0;
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  527) 
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  528) 	if (!fc->sync_fs)
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  529) 		return 0;
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  530) 
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  531) 	memset(&inarg, 0, sizeof(inarg));
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  532) 	args.in_numargs = 1;
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  533) 	args.in_args[0].size = sizeof(inarg);
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  534) 	args.in_args[0].value = &inarg;
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  535) 	args.opcode = FUSE_SYNCFS;
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  536) 	args.nodeid = get_node_id(sb->s_root->d_inode);
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  537) 	args.out_numargs = 0;
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  538) 
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  539) 	err = fuse_simple_request(fm, &args);
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  540) 	if (err == -ENOSYS) {
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  541) 		fc->sync_fs = 0;
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  542) 		err = 0;
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  543) 	}
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  544) 
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  545) 	return err;
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  546) }
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  547) 
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  548) enum {
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  549) 	OPT_SOURCE,
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  550) 	OPT_SUBTYPE,
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  551) 	OPT_FD,
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  552) 	OPT_ROOTMODE,
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  553) 	OPT_USER_ID,
87729a5514e85 (Miklos Szeredi        2005-09-09 13:10:34 -0700  554) 	OPT_GROUP_ID,
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  555) 	OPT_DEFAULT_PERMISSIONS,
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  556) 	OPT_ALLOW_OTHER,
db50b96c0f28a (Miklos Szeredi        2005-09-09 13:10:33 -0700  557) 	OPT_MAX_READ,
d809161402e9f (Miklos Szeredi        2006-12-06 20:35:48 -0800  558) 	OPT_BLKSIZE,
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  559) 	OPT_ERR
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  560) };
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  561) 
d7167b149943e (Al Viro               2019-09-07 07:23:15 -0400  562) static const struct fs_parameter_spec fuse_fs_parameters[] = {
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  563) 	fsparam_string	("source",		OPT_SOURCE),
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  564) 	fsparam_u32	("fd",			OPT_FD),
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  565) 	fsparam_u32oct	("rootmode",		OPT_ROOTMODE),
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  566) 	fsparam_u32	("user_id",		OPT_USER_ID),
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  567) 	fsparam_u32	("group_id",		OPT_GROUP_ID),
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  568) 	fsparam_flag	("default_permissions",	OPT_DEFAULT_PERMISSIONS),
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  569) 	fsparam_flag	("allow_other",		OPT_ALLOW_OTHER),
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  570) 	fsparam_u32	("max_read",		OPT_MAX_READ),
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  571) 	fsparam_u32	("blksize",		OPT_BLKSIZE),
c7eb6869632a5 (David Howells         2019-03-25 16:38:31 +0000  572) 	fsparam_string	("subtype",		OPT_SUBTYPE),
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  573) 	{}
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  574) };
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  575) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  576) static int fuse_parse_param(struct fs_context *fc, struct fs_parameter *param)
233a01fa9c4c7 (Miklos Szeredi        2014-07-07 15:28:51 +0200  577) {
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  578) 	struct fs_parse_result result;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  579) 	struct fuse_fs_context *ctx = fc->fs_private;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  580) 	int opt;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  581) 
b330966f79fb4 (Miklos Szeredi        2020-07-14 14:45:41 +0200  582) 	if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE) {
b330966f79fb4 (Miklos Szeredi        2020-07-14 14:45:41 +0200  583) 		/*
b330966f79fb4 (Miklos Szeredi        2020-07-14 14:45:41 +0200  584) 		 * Ignore options coming from mount(MS_REMOUNT) for backward
b330966f79fb4 (Miklos Szeredi        2020-07-14 14:45:41 +0200  585) 		 * compatibility.
b330966f79fb4 (Miklos Szeredi        2020-07-14 14:45:41 +0200  586) 		 */
b330966f79fb4 (Miklos Szeredi        2020-07-14 14:45:41 +0200  587) 		if (fc->oldapi)
b330966f79fb4 (Miklos Szeredi        2020-07-14 14:45:41 +0200  588) 			return 0;
b330966f79fb4 (Miklos Szeredi        2020-07-14 14:45:41 +0200  589) 
b330966f79fb4 (Miklos Szeredi        2020-07-14 14:45:41 +0200  590) 		return invalfc(fc, "No changes allowed in reconfigure");
b330966f79fb4 (Miklos Szeredi        2020-07-14 14:45:41 +0200  591) 	}
e8b20a474cf2c (Miklos Szeredi        2020-07-14 14:45:41 +0200  592) 
d7167b149943e (Al Viro               2019-09-07 07:23:15 -0400  593) 	opt = fs_parse(fc, fuse_fs_parameters, param, &result);
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  594) 	if (opt < 0)
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  595) 		return opt;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  596) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  597) 	switch (opt) {
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  598) 	case OPT_SOURCE:
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  599) 		if (fc->source)
2e28c49ea648d (Al Viro               2019-12-21 21:32:51 -0500  600) 			return invalfc(fc, "Multiple sources specified");
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  601) 		fc->source = param->string;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  602) 		param->string = NULL;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  603) 		break;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  604) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  605) 	case OPT_SUBTYPE:
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  606) 		if (ctx->subtype)
2e28c49ea648d (Al Viro               2019-12-21 21:32:51 -0500  607) 			return invalfc(fc, "Multiple subtypes specified");
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  608) 		ctx->subtype = param->string;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  609) 		param->string = NULL;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  610) 		return 0;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  611) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  612) 	case OPT_FD:
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  613) 		ctx->fd = result.uint_32;
cabdb4fa2f666 (zhengbin              2020-01-14 20:39:45 +0800  614) 		ctx->fd_present = true;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  615) 		break;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  616) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  617) 	case OPT_ROOTMODE:
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  618) 		if (!fuse_valid_type(result.uint_32))
2e28c49ea648d (Al Viro               2019-12-21 21:32:51 -0500  619) 			return invalfc(fc, "Invalid rootmode");
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  620) 		ctx->rootmode = result.uint_32;
cabdb4fa2f666 (zhengbin              2020-01-14 20:39:45 +0800  621) 		ctx->rootmode_present = true;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  622) 		break;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  623) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  624) 	case OPT_USER_ID:
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  625) 		ctx->user_id = make_kuid(fc->user_ns, result.uint_32);
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  626) 		if (!uid_valid(ctx->user_id))
2e28c49ea648d (Al Viro               2019-12-21 21:32:51 -0500  627) 			return invalfc(fc, "Invalid user_id");
cabdb4fa2f666 (zhengbin              2020-01-14 20:39:45 +0800  628) 		ctx->user_id_present = true;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  629) 		break;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  630) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  631) 	case OPT_GROUP_ID:
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  632) 		ctx->group_id = make_kgid(fc->user_ns, result.uint_32);
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  633) 		if (!gid_valid(ctx->group_id))
2e28c49ea648d (Al Viro               2019-12-21 21:32:51 -0500  634) 			return invalfc(fc, "Invalid group_id");
cabdb4fa2f666 (zhengbin              2020-01-14 20:39:45 +0800  635) 		ctx->group_id_present = true;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  636) 		break;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  637) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  638) 	case OPT_DEFAULT_PERMISSIONS:
cabdb4fa2f666 (zhengbin              2020-01-14 20:39:45 +0800  639) 		ctx->default_permissions = true;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  640) 		break;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  641) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  642) 	case OPT_ALLOW_OTHER:
cabdb4fa2f666 (zhengbin              2020-01-14 20:39:45 +0800  643) 		ctx->allow_other = true;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  644) 		break;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  645) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  646) 	case OPT_MAX_READ:
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  647) 		ctx->max_read = result.uint_32;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  648) 		break;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  649) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  650) 	case OPT_BLKSIZE:
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  651) 		if (!ctx->is_bdev)
2e28c49ea648d (Al Viro               2019-12-21 21:32:51 -0500  652) 			return invalfc(fc, "blksize only supported for fuseblk");
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  653) 		ctx->blksize = result.uint_32;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  654) 		break;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  655) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  656) 	default:
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  657) 		return -EINVAL;
233a01fa9c4c7 (Miklos Szeredi        2014-07-07 15:28:51 +0200  658) 	}
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  659) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  660) 	return 0;
233a01fa9c4c7 (Miklos Szeredi        2014-07-07 15:28:51 +0200  661) }
233a01fa9c4c7 (Miklos Szeredi        2014-07-07 15:28:51 +0200  662) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  663) static void fuse_free_fc(struct fs_context *fc)
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  664) {
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  665) 	struct fuse_fs_context *ctx = fc->fs_private;
5a53368277efa (Miklos Szeredi        2005-09-09 13:10:34 -0700  666) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  667) 	if (ctx) {
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  668) 		kfree(ctx->subtype);
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  669) 		kfree(ctx);
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000  670) 	}
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  671) }
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  672) 
34c80b1d93e6e (Al Viro               2011-12-08 21:32:45 -0500  673) static int fuse_show_options(struct seq_file *m, struct dentry *root)
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  674) {
34c80b1d93e6e (Al Viro               2011-12-08 21:32:45 -0500  675) 	struct super_block *sb = root->d_sb;
34c80b1d93e6e (Al Viro               2011-12-08 21:32:45 -0500  676) 	struct fuse_conn *fc = get_fuse_conn_super(sb);
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  677) 
f4fd4ae354ba2 (Vivek Goyal           2020-08-19 18:19:45 -0400  678) 	if (fc->legacy_opts_show) {
f4fd4ae354ba2 (Vivek Goyal           2020-08-19 18:19:45 -0400  679) 		seq_printf(m, ",user_id=%u",
f4fd4ae354ba2 (Vivek Goyal           2020-08-19 18:19:45 -0400  680) 			   from_kuid_munged(fc->user_ns, fc->user_id));
f4fd4ae354ba2 (Vivek Goyal           2020-08-19 18:19:45 -0400  681) 		seq_printf(m, ",group_id=%u",
f4fd4ae354ba2 (Vivek Goyal           2020-08-19 18:19:45 -0400  682) 			   from_kgid_munged(fc->user_ns, fc->group_id));
f4fd4ae354ba2 (Vivek Goyal           2020-08-19 18:19:45 -0400  683) 		if (fc->default_permissions)
f4fd4ae354ba2 (Vivek Goyal           2020-08-19 18:19:45 -0400  684) 			seq_puts(m, ",default_permissions");
f4fd4ae354ba2 (Vivek Goyal           2020-08-19 18:19:45 -0400  685) 		if (fc->allow_other)
f4fd4ae354ba2 (Vivek Goyal           2020-08-19 18:19:45 -0400  686) 			seq_puts(m, ",allow_other");
f4fd4ae354ba2 (Vivek Goyal           2020-08-19 18:19:45 -0400  687) 		if (fc->max_read != ~0)
f4fd4ae354ba2 (Vivek Goyal           2020-08-19 18:19:45 -0400  688) 			seq_printf(m, ",max_read=%u", fc->max_read);
f4fd4ae354ba2 (Vivek Goyal           2020-08-19 18:19:45 -0400  689) 		if (sb->s_bdev && sb->s_blocksize != FUSE_DEFAULT_BLKSIZE)
f4fd4ae354ba2 (Vivek Goyal           2020-08-19 18:19:45 -0400  690) 			seq_printf(m, ",blksize=%lu", sb->s_blocksize);
f4fd4ae354ba2 (Vivek Goyal           2020-08-19 18:19:45 -0400  691) 	}
1dd539577c42b (Vivek Goyal           2020-08-19 18:19:47 -0400  692) #ifdef CONFIG_FUSE_DAX
1dd539577c42b (Vivek Goyal           2020-08-19 18:19:47 -0400  693) 	if (fc->dax)
1dd539577c42b (Vivek Goyal           2020-08-19 18:19:47 -0400  694) 		seq_puts(m, ",dax");
1dd539577c42b (Vivek Goyal           2020-08-19 18:19:47 -0400  695) #endif
3f22c7467136a (Miklos Szeredi        2019-10-15 16:11:41 +0200  696) 
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  697) 	return 0;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  698) }
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  699) 
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  700) static void fuse_iqueue_init(struct fuse_iqueue *fiq,
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  701) 			     const struct fuse_iqueue_ops *ops,
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  702) 			     void *priv)
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200  703) {
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200  704) 	memset(fiq, 0, sizeof(struct fuse_iqueue));
76e43c8ccaa35 (Eric Biggers          2019-09-08 20:15:18 -0700  705) 	spin_lock_init(&fiq->lock);
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200  706) 	init_waitqueue_head(&fiq->waitq);
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200  707) 	INIT_LIST_HEAD(&fiq->pending);
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200  708) 	INIT_LIST_HEAD(&fiq->interrupts);
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200  709) 	fiq->forget_list_tail = &fiq->forget_list_head;
e16714d8756dc (Miklos Szeredi        2015-07-01 16:26:01 +0200  710) 	fiq->connected = 1;
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  711) 	fiq->ops = ops;
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  712) 	fiq->priv = priv;
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200  713) }
f88996a933244 (Miklos Szeredi        2015-07-01 16:26:01 +0200  714) 
3a2b5b9cd9610 (Miklos Szeredi        2015-07-01 16:26:04 +0200  715) static void fuse_pqueue_init(struct fuse_pqueue *fpq)
3a2b5b9cd9610 (Miklos Szeredi        2015-07-01 16:26:04 +0200  716) {
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300  717) 	unsigned int i;
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300  718) 
45a91cb1a4fd9 (Miklos Szeredi        2015-07-01 16:26:06 +0200  719) 	spin_lock_init(&fpq->lock);
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300  720) 	for (i = 0; i < FUSE_PQ_HASH_SIZE; i++)
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300  721) 		INIT_LIST_HEAD(&fpq->processing[i]);
3a2b5b9cd9610 (Miklos Szeredi        2015-07-01 16:26:04 +0200  722) 	INIT_LIST_HEAD(&fpq->io);
e96edd94d0887 (Miklos Szeredi        2015-07-01 16:26:04 +0200  723) 	fpq->connected = 1;
3a2b5b9cd9610 (Miklos Szeredi        2015-07-01 16:26:04 +0200  724) }
3a2b5b9cd9610 (Miklos Szeredi        2015-07-01 16:26:04 +0200  725) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  726) void fuse_conn_init(struct fuse_conn *fc, struct fuse_mount *fm,
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  727) 		    struct user_namespace *user_ns,
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  728) 		    const struct fuse_iqueue_ops *fiq_ops, void *fiq_priv)
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  729) {
0d179aa59285c (Tejun Heo             2008-11-26 12:03:55 +0100  730) 	memset(fc, 0, sizeof(*fc));
0d179aa59285c (Tejun Heo             2008-11-26 12:03:55 +0100  731) 	spin_lock_init(&fc->lock);
ae2dffa39485c (Kirill Tkhai          2018-08-27 18:29:46 +0300  732) 	spin_lock_init(&fc->bg_lock);
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400  733) 	init_rwsem(&fc->killsb);
095fc40ace5ff (Elena Reshetova       2017-03-03 11:04:05 +0200  734) 	refcount_set(&fc->count, 1);
c3696046beb3a (Miklos Szeredi        2015-07-01 16:26:09 +0200  735) 	atomic_set(&fc->dev_count, 1);
0d179aa59285c (Tejun Heo             2008-11-26 12:03:55 +0100  736) 	init_waitqueue_head(&fc->blocked_waitq);
ae3aad77f46fb (Stefan Hajnoczi       2018-06-18 15:53:19 +0100  737) 	fuse_iqueue_init(&fc->iq, fiq_ops, fiq_priv);
0d179aa59285c (Tejun Heo             2008-11-26 12:03:55 +0100  738) 	INIT_LIST_HEAD(&fc->bg_queue);
0d179aa59285c (Tejun Heo             2008-11-26 12:03:55 +0100  739) 	INIT_LIST_HEAD(&fc->entry);
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200  740) 	INIT_LIST_HEAD(&fc->devices);
0d179aa59285c (Tejun Heo             2008-11-26 12:03:55 +0100  741) 	atomic_set(&fc->num_waiting, 0);
7a6d3c8b3049d (Csaba Henk            2009-07-01 17:28:41 -0700  742) 	fc->max_background = FUSE_DEFAULT_MAX_BACKGROUND;
7a6d3c8b3049d (Csaba Henk            2009-07-01 17:28:41 -0700  743) 	fc->congestion_threshold = FUSE_DEFAULT_CONGESTION_THRESHOLD;
75126f5504524 (Miklos Szeredi        2019-01-24 10:40:17 +0100  744) 	atomic64_set(&fc->khctr, 0);
0d179aa59285c (Tejun Heo             2008-11-26 12:03:55 +0100  745) 	fc->polled_files = RB_ROOT;
0aada88476a33 (Maxim Patlasov        2013-03-21 18:02:28 +0400  746) 	fc->blocked = 0;
796523fb24028 (Maxim Patlasov        2013-03-21 18:02:15 +0400  747) 	fc->initialized = 0;
e16714d8756dc (Miklos Szeredi        2015-07-01 16:26:01 +0200  748) 	fc->connected = 1;
4510d86fbbb36 (Kirill Tkhai          2018-11-09 13:33:17 +0300  749) 	atomic64_set(&fc->attr_version, 1);
0d179aa59285c (Tejun Heo             2008-11-26 12:03:55 +0100  750) 	get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key));
0b6e9ea041e6c (Seth Forshee          2014-07-02 16:29:19 -0500  751) 	fc->pid_ns = get_pid_ns(task_active_pid_ns(current));
8cb08329b0809 (Eric W. Biederman     2018-02-21 11:18:07 -0600  752) 	fc->user_ns = get_user_ns(user_ns);
8a3177db59cd6 (Miklos Szeredi        2019-01-16 10:27:59 +0100  753) 	fc->max_pages = FUSE_DEFAULT_MAX_PAGES_PER_REQ;
a7f0d7aab0b4f (Connor Kuehl          2021-03-18 08:52:22 -0500  754) 	fc->max_pages_limit = FUSE_MAX_MAX_PAGES;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  755) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  756) 	INIT_LIST_HEAD(&fc->mounts);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  757) 	list_add(&fm->fc_entry, &fc->mounts);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200  758) 	fm->fc = fc;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  759) }
0d179aa59285c (Tejun Heo             2008-11-26 12:03:55 +0100  760) EXPORT_SYMBOL_GPL(fuse_conn_init);
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  761) 
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700  762) void fuse_conn_put(struct fuse_conn *fc)
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700  763) {
095fc40ace5ff (Elena Reshetova       2017-03-03 11:04:05 +0200  764) 	if (refcount_dec_and_test(&fc->count)) {
a62a8ef9d97da (Stefan Hajnoczi       2018-06-12 09:41:17 +0100  765) 		struct fuse_iqueue *fiq = &fc->iq;
a62a8ef9d97da (Stefan Hajnoczi       2018-06-12 09:41:17 +0100  766) 
1dd539577c42b (Vivek Goyal           2020-08-19 18:19:47 -0400  767) 		if (IS_ENABLED(CONFIG_FUSE_DAX))
1dd539577c42b (Vivek Goyal           2020-08-19 18:19:47 -0400  768) 			fuse_dax_conn_free(fc);
a62a8ef9d97da (Stefan Hajnoczi       2018-06-12 09:41:17 +0100  769) 		if (fiq->ops->release)
a62a8ef9d97da (Stefan Hajnoczi       2018-06-12 09:41:17 +0100  770) 			fiq->ops->release(fiq);
0b6e9ea041e6c (Seth Forshee          2014-07-02 16:29:19 -0500  771) 		put_pid_ns(fc->pid_ns);
8cb08329b0809 (Eric W. Biederman     2018-02-21 11:18:07 -0600  772) 		put_user_ns(fc->user_ns);
43901aabd7a04 (Tejun Heo             2008-11-26 12:03:56 +0100  773) 		fc->release(fc);
d2a85164aaa8d (Miklos Szeredi        2006-10-17 00:10:11 -0700  774) 	}
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700  775) }
08cbf542bf24f (Tejun Heo             2009-04-14 10:54:53 +0900  776) EXPORT_SYMBOL_GPL(fuse_conn_put);
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700  777) 
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700  778) struct fuse_conn *fuse_conn_get(struct fuse_conn *fc)
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700  779) {
095fc40ace5ff (Elena Reshetova       2017-03-03 11:04:05 +0200  780) 	refcount_inc(&fc->count);
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700  781) 	return fc;
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700  782) }
08cbf542bf24f (Tejun Heo             2009-04-14 10:54:53 +0900  783) EXPORT_SYMBOL_GPL(fuse_conn_get);
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700  784) 
b93f858ab2a4b (Tejun Heo             2008-11-26 12:03:55 +0100  785) static struct inode *fuse_get_root_inode(struct super_block *sb, unsigned mode)
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  786) {
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  787) 	struct fuse_attr attr;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  788) 	memset(&attr, 0, sizeof(attr));
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  789) 
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  790) 	attr.mode = mode;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  791) 	attr.ino = FUSE_ROOT_ID;
074406fa6309a (Miklos Szeredi        2007-10-16 23:31:02 -0700  792) 	attr.nlink = 1;
1fb69e7817296 (Miklos Szeredi        2007-10-18 03:06:58 -0700  793) 	return fuse_iget(sb, 1, 0, &attr, 0, 0);
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  794) }
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  795) 
1729a16c2c92b (Miklos Szeredi        2008-11-26 12:03:54 +0100  796) struct fuse_inode_handle {
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  797) 	u64 nodeid;
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  798) 	u32 generation;
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  799) };
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  800) 
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  801) static struct dentry *fuse_get_dentry(struct super_block *sb,
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  802) 				      struct fuse_inode_handle *handle)
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  803) {
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  804) 	struct fuse_conn *fc = get_fuse_conn_super(sb);
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  805) 	struct inode *inode;
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  806) 	struct dentry *entry;
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  807) 	int err = -ESTALE;
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  808) 
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  809) 	if (handle->nodeid == 0)
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  810) 		goto out_err;
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  811) 
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  812) 	inode = ilookup5(sb, handle->nodeid, fuse_inode_eq, &handle->nodeid);
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  813) 	if (!inode) {
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  814) 		struct fuse_entry_out outarg;
13983d062f17f (Al Viro               2016-07-20 22:34:44 -0400  815) 		const struct qstr name = QSTR_INIT(".", 1);
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  816) 
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  817) 		if (!fc->export_support)
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  818) 			goto out_err;
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  819) 
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  820) 		err = fuse_lookup_name(sb, handle->nodeid, &name, &outarg,
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  821) 				       &inode);
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  822) 		if (err && err != -ENOENT)
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  823) 			goto out_err;
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  824) 		if (err || !inode) {
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  825) 			err = -ESTALE;
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  826) 			goto out_err;
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  827) 		}
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  828) 		err = -EIO;
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  829) 		if (get_node_id(inode) != handle->nodeid)
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  830) 			goto out_iput;
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  831) 	}
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  832) 	err = -ESTALE;
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  833) 	if (inode->i_generation != handle->generation)
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  834) 		goto out_iput;
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  835) 
440037287c5eb (Christoph Hellwig     2008-08-11 15:49:04 +0200  836) 	entry = d_obtain_alias(inode);
c35eebe9939f5 (Al Viro               2010-12-18 11:15:22 -0500  837) 	if (!IS_ERR(entry) && get_node_id(inode) != FUSE_ROOT_ID)
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  838) 		fuse_invalidate_entry_cache(entry);
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  839) 
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  840) 	return entry;
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  841) 
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  842)  out_iput:
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  843) 	iput(inode);
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  844)  out_err:
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  845) 	return ERR_PTR(err);
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  846) }
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  847) 
b0b0382bb4904 (Al Viro               2012-04-02 14:34:06 -0400  848) static int fuse_encode_fh(struct inode *inode, u32 *fh, int *max_len,
b0b0382bb4904 (Al Viro               2012-04-02 14:34:06 -0400  849) 			   struct inode *parent)
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  850) {
b0b0382bb4904 (Al Viro               2012-04-02 14:34:06 -0400  851) 	int len = parent ? 6 : 3;
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  852) 	u64 nodeid;
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  853) 	u32 generation;
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  854) 
5fe0c2378884e (Aneesh Kumar K.V      2011-01-29 18:43:25 +0530  855) 	if (*max_len < len) {
5fe0c2378884e (Aneesh Kumar K.V      2011-01-29 18:43:25 +0530  856) 		*max_len = len;
94e07a7590ae8 (Namjae Jeon           2013-02-17 15:48:11 +0900  857) 		return  FILEID_INVALID;
5fe0c2378884e (Aneesh Kumar K.V      2011-01-29 18:43:25 +0530  858) 	}
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  859) 
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  860) 	nodeid = get_fuse_inode(inode)->nodeid;
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  861) 	generation = inode->i_generation;
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  862) 
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  863) 	fh[0] = (u32)(nodeid >> 32);
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  864) 	fh[1] = (u32)(nodeid & 0xffffffff);
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  865) 	fh[2] = generation;
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  866) 
b0b0382bb4904 (Al Viro               2012-04-02 14:34:06 -0400  867) 	if (parent) {
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  868) 		nodeid = get_fuse_inode(parent)->nodeid;
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  869) 		generation = parent->i_generation;
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  870) 
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  871) 		fh[3] = (u32)(nodeid >> 32);
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  872) 		fh[4] = (u32)(nodeid & 0xffffffff);
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  873) 		fh[5] = generation;
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  874) 	}
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  875) 
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  876) 	*max_len = len;
b0b0382bb4904 (Al Viro               2012-04-02 14:34:06 -0400  877) 	return parent ? 0x82 : 0x81;
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  878) }
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  879) 
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  880) static struct dentry *fuse_fh_to_dentry(struct super_block *sb,
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  881) 		struct fid *fid, int fh_len, int fh_type)
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  882) {
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  883) 	struct fuse_inode_handle handle;
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  884) 
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  885) 	if ((fh_type != 0x81 && fh_type != 0x82) || fh_len < 3)
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  886) 		return NULL;
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  887) 
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  888) 	handle.nodeid = (u64) fid->raw[0] << 32;
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  889) 	handle.nodeid |= (u64) fid->raw[1];
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  890) 	handle.generation = fid->raw[2];
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  891) 	return fuse_get_dentry(sb, &handle);
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  892) }
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  893) 
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  894) static struct dentry *fuse_fh_to_parent(struct super_block *sb,
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  895) 		struct fid *fid, int fh_len, int fh_type)
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  896) {
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  897) 	struct fuse_inode_handle parent;
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  898) 
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  899) 	if (fh_type != 0x82 || fh_len < 6)
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  900) 		return NULL;
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  901) 
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  902) 	parent.nodeid = (u64) fid->raw[3] << 32;
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  903) 	parent.nodeid |= (u64) fid->raw[4];
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  904) 	parent.generation = fid->raw[5];
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  905) 	return fuse_get_dentry(sb, &parent);
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  906) }
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  907) 
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  908) static struct dentry *fuse_get_parent(struct dentry *child)
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  909) {
2b0143b5c986b (David Howells         2015-03-17 22:25:59 +0000  910) 	struct inode *child_inode = d_inode(child);
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  911) 	struct fuse_conn *fc = get_fuse_conn(child_inode);
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  912) 	struct inode *inode;
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  913) 	struct dentry *parent;
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  914) 	struct fuse_entry_out outarg;
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  915) 	int err;
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  916) 
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  917) 	if (!fc->export_support)
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  918) 		return ERR_PTR(-ESTALE);
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  919) 
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  920) 	err = fuse_lookup_name(child_inode->i_sb, get_node_id(child_inode),
80e5d1ff5d5f1 (Al Viro               2021-04-15 19:46:50 -0400  921) 			       &dotdot_name, &outarg, &inode);
440037287c5eb (Christoph Hellwig     2008-08-11 15:49:04 +0200  922) 	if (err) {
440037287c5eb (Christoph Hellwig     2008-08-11 15:49:04 +0200  923) 		if (err == -ENOENT)
440037287c5eb (Christoph Hellwig     2008-08-11 15:49:04 +0200  924) 			return ERR_PTR(-ESTALE);
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  925) 		return ERR_PTR(err);
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  926) 	}
440037287c5eb (Christoph Hellwig     2008-08-11 15:49:04 +0200  927) 
440037287c5eb (Christoph Hellwig     2008-08-11 15:49:04 +0200  928) 	parent = d_obtain_alias(inode);
c35eebe9939f5 (Al Viro               2010-12-18 11:15:22 -0500  929) 	if (!IS_ERR(parent) && get_node_id(inode) != FUSE_ROOT_ID)
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  930) 		fuse_invalidate_entry_cache(parent);
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  931) 
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  932) 	return parent;
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  933) }
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  934) 
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  935) static const struct export_operations fuse_export_operations = {
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  936) 	.fh_to_dentry	= fuse_fh_to_dentry,
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  937) 	.fh_to_parent	= fuse_fh_to_parent,
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  938) 	.encode_fh	= fuse_encode_fh,
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700  939) 	.get_parent	= fuse_get_parent,
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  940) };
dbd561d236ff1 (Miklos Szeredi        2008-07-25 01:49:00 -0700  941) 
ee9b6d61a2a43 (Josef 'Jeff' Sipek    2007-02-12 00:55:41 -0800  942) static const struct super_operations fuse_super_operations = {
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  943) 	.alloc_inode    = fuse_alloc_inode,
9baf28bbfea16 (Al Viro               2019-04-15 19:37:09 -0400  944) 	.free_inode     = fuse_free_inode,
b57922d97fd6f (Al Viro               2010-06-07 14:34:48 -0400  945) 	.evict_inode	= fuse_evict_inode,
1e18bda86e2dc (Miklos Szeredi        2014-04-28 14:19:23 +0200  946) 	.write_inode	= fuse_write_inode,
ead5f0b5fa41d (Miklos Szeredi        2007-05-23 13:57:54 -0700  947) 	.drop_inode	= generic_delete_inode,
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  948) 	.put_super	= fuse_put_super,
69a53bf267fa5 (Miklos Szeredi        2006-01-16 22:14:41 -0800  949) 	.umount_begin	= fuse_umount_begin,
e5e5558e923f3 (Miklos Szeredi        2005-09-09 13:10:28 -0700  950) 	.statfs		= fuse_statfs,
6ba041fc3c441 (Greg Kurz             2021-05-20 17:46:54 +0200  951) 	.sync_fs	= fuse_sync_fs,
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  952) 	.show_options	= fuse_show_options,
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  953) };
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700  954) 
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  955) static void sanitize_global_limit(unsigned *limit)
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  956) {
f22f812d5ce75 (Miklos Szeredi        2019-09-12 14:28:13 +0200  957) 	/*
f22f812d5ce75 (Miklos Szeredi        2019-09-12 14:28:13 +0200  958) 	 * The default maximum number of async requests is calculated to consume
f22f812d5ce75 (Miklos Szeredi        2019-09-12 14:28:13 +0200  959) 	 * 1/2^13 of the total memory, assuming 392 bytes per request.
f22f812d5ce75 (Miklos Szeredi        2019-09-12 14:28:13 +0200  960) 	 */
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  961) 	if (*limit == 0)
f22f812d5ce75 (Miklos Szeredi        2019-09-12 14:28:13 +0200  962) 		*limit = ((totalram_pages() << PAGE_SHIFT) >> 13) / 392;
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  963) 
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  964) 	if (*limit >= 1 << 16)
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  965) 		*limit = (1 << 16) - 1;
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  966) }
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  967) 
e4dca7b7aa08b (Kees Cook             2017-10-17 19:04:42 -0700  968) static int set_global_limit(const char *val, const struct kernel_param *kp)
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  969) {
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  970) 	int rv;
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  971) 
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  972) 	rv = param_set_uint(val, kp);
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  973) 	if (rv)
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  974) 		return rv;
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  975) 
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  976) 	sanitize_global_limit((unsigned *)kp->arg);
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  977) 
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  978) 	return 0;
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  979) }
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  980) 
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  981) static void process_init_limits(struct fuse_conn *fc, struct fuse_init_out *arg)
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  982) {
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  983) 	int cap_sys_admin = capable(CAP_SYS_ADMIN);
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  984) 
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  985) 	if (arg->minor < 13)
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  986) 		return;
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  987) 
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  988) 	sanitize_global_limit(&max_user_bgreq);
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  989) 	sanitize_global_limit(&max_user_congthresh);
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  990) 
ae2dffa39485c (Kirill Tkhai          2018-08-27 18:29:46 +0300  991) 	spin_lock(&fc->bg_lock);
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  992) 	if (arg->max_background) {
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  993) 		fc->max_background = arg->max_background;
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  994) 
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  995) 		if (!cap_sys_admin && fc->max_background > max_user_bgreq)
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  996) 			fc->max_background = max_user_bgreq;
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  997) 	}
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  998) 	if (arg->congestion_threshold) {
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200  999) 		fc->congestion_threshold = arg->congestion_threshold;
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200 1000) 
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200 1001) 		if (!cap_sys_admin &&
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200 1002) 		    fc->congestion_threshold > max_user_congthresh)
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200 1003) 			fc->congestion_threshold = max_user_congthresh;
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200 1004) 	}
ae2dffa39485c (Kirill Tkhai          2018-08-27 18:29:46 +0300 1005) 	spin_unlock(&fc->bg_lock);
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200 1006) }
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200 1007) 
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1008) struct fuse_init_args {
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1009) 	struct fuse_args args;
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1010) 	struct fuse_init_in in;
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1011) 	struct fuse_init_out out;
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1012) };
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1013) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1014) static void process_init_reply(struct fuse_mount *fm, struct fuse_args *args,
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1015) 			       int error)
9b9a04693fa2d (Miklos Szeredi        2006-01-16 22:14:44 -0800 1016) {
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1017) 	struct fuse_conn *fc = fm->fc;
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1018) 	struct fuse_init_args *ia = container_of(args, typeof(*ia), args);
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1019) 	struct fuse_init_out *arg = &ia->out;
fd1a1dc6f5aa7 (Stefan Hajnoczi       2020-08-19 18:19:49 -0400 1020) 	bool ok = true;
9b9a04693fa2d (Miklos Szeredi        2006-01-16 22:14:44 -0800 1021) 
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1022) 	if (error || arg->major != FUSE_KERNEL_VERSION)
fd1a1dc6f5aa7 (Stefan Hajnoczi       2020-08-19 18:19:49 -0400 1023) 		ok = false;
9b9a04693fa2d (Miklos Szeredi        2006-01-16 22:14:44 -0800 1024) 	else {
9cd684551124e (Miklos Szeredi        2006-02-01 03:04:40 -0800 1025) 		unsigned long ra_pages;
9cd684551124e (Miklos Szeredi        2006-02-01 03:04:40 -0800 1026) 
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200 1027) 		process_init_limits(fc, arg);
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200 1028) 
9cd684551124e (Miklos Szeredi        2006-02-01 03:04:40 -0800 1029) 		if (arg->minor >= 6) {
09cbfeaf1a5a6 (Kirill A. Shutemov    2016-04-01 15:29:47 +0300 1030) 			ra_pages = arg->max_readahead / PAGE_SIZE;
9cd684551124e (Miklos Szeredi        2006-02-01 03:04:40 -0800 1031) 			if (arg->flags & FUSE_ASYNC_READ)
9cd684551124e (Miklos Szeredi        2006-02-01 03:04:40 -0800 1032) 				fc->async_read = 1;
7142125937e14 (Miklos Szeredi        2006-06-25 05:48:52 -0700 1033) 			if (!(arg->flags & FUSE_POSIX_LOCKS))
7142125937e14 (Miklos Szeredi        2006-06-25 05:48:52 -0700 1034) 				fc->no_lock = 1;
37fb3a30b4623 (Miklos Szeredi        2011-08-08 16:08:08 +0200 1035) 			if (arg->minor >= 17) {
37fb3a30b4623 (Miklos Szeredi        2011-08-08 16:08:08 +0200 1036) 				if (!(arg->flags & FUSE_FLOCK_LOCKS))
37fb3a30b4623 (Miklos Szeredi        2011-08-08 16:08:08 +0200 1037) 					fc->no_flock = 1;
24114504c4d58 (Miklos Szeredi        2011-09-12 09:31:49 +0200 1038) 			} else {
24114504c4d58 (Miklos Szeredi        2011-09-12 09:31:49 +0200 1039) 				if (!(arg->flags & FUSE_POSIX_LOCKS))
24114504c4d58 (Miklos Szeredi        2011-09-12 09:31:49 +0200 1040) 					fc->no_flock = 1;
37fb3a30b4623 (Miklos Szeredi        2011-08-08 16:08:08 +0200 1041) 			}
6ff958edbf39c (Miklos Szeredi        2007-10-18 03:07:02 -0700 1042) 			if (arg->flags & FUSE_ATOMIC_O_TRUNC)
6ff958edbf39c (Miklos Szeredi        2007-10-18 03:07:02 -0700 1043) 				fc->atomic_o_trunc = 1;
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700 1044) 			if (arg->minor >= 9) {
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700 1045) 				/* LOOKUP has dependency on proto version */
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700 1046) 				if (arg->flags & FUSE_EXPORT_SUPPORT)
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700 1047) 					fc->export_support = 1;
33670fa296860 (Miklos Szeredi        2008-07-25 01:49:02 -0700 1048) 			}
78bb6cb9a890d (Miklos Szeredi        2008-05-12 14:02:32 -0700 1049) 			if (arg->flags & FUSE_BIG_WRITES)
78bb6cb9a890d (Miklos Szeredi        2008-05-12 14:02:32 -0700 1050) 				fc->big_writes = 1;
e0a43ddcc08c3 (Miklos Szeredi        2009-06-30 20:12:23 +0200 1051) 			if (arg->flags & FUSE_DONT_MASK)
e0a43ddcc08c3 (Miklos Szeredi        2009-06-30 20:12:23 +0200 1052) 				fc->dont_mask = 1;
72d0d248ca823 (Brian Foster          2012-07-16 15:23:48 -0400 1053) 			if (arg->flags & FUSE_AUTO_INVAL_DATA)
72d0d248ca823 (Brian Foster          2012-07-16 15:23:48 -0400 1054) 				fc->auto_inval_data = 1;
ad2ba64dd4898 (Kirill Smelkov        2019-03-27 11:14:15 +0000 1055) 			else if (arg->flags & FUSE_EXPLICIT_INVAL_DATA)
ad2ba64dd4898 (Kirill Smelkov        2019-03-27 11:14:15 +0000 1056) 				fc->explicit_inval_data = 1;
28420dad23352 (Miklos Szeredi        2013-06-03 14:40:22 +0200 1057) 			if (arg->flags & FUSE_DO_READDIRPLUS) {
0b05b18381eea (Anand V. Avati        2012-08-19 08:53:23 -0400 1058) 				fc->do_readdirplus = 1;
28420dad23352 (Miklos Szeredi        2013-06-03 14:40:22 +0200 1059) 				if (arg->flags & FUSE_READDIRPLUS_AUTO)
28420dad23352 (Miklos Szeredi        2013-06-03 14:40:22 +0200 1060) 					fc->readdirplus_auto = 1;
28420dad23352 (Miklos Szeredi        2013-06-03 14:40:22 +0200 1061) 			}
60b9df7a54804 (Miklos Szeredi        2013-05-01 14:37:21 +0200 1062) 			if (arg->flags & FUSE_ASYNC_DIO)
60b9df7a54804 (Miklos Szeredi        2013-05-01 14:37:21 +0200 1063) 				fc->async_dio = 1;
4d99ff8f12eb2 (Pavel Emelyanov       2013-10-10 17:12:18 +0400 1064) 			if (arg->flags & FUSE_WRITEBACK_CACHE)
4d99ff8f12eb2 (Pavel Emelyanov       2013-10-10 17:12:18 +0400 1065) 				fc->writeback_cache = 1;
5c672ab3f0ee0 (Miklos Szeredi        2016-06-30 13:10:49 +0200 1066) 			if (arg->flags & FUSE_PARALLEL_DIROPS)
5c672ab3f0ee0 (Miklos Szeredi        2016-06-30 13:10:49 +0200 1067) 				fc->parallel_dirops = 1;
5e940c1dd3c1f (Miklos Szeredi        2016-10-01 07:32:32 +0200 1068) 			if (arg->flags & FUSE_HANDLE_KILLPRIV)
5e940c1dd3c1f (Miklos Szeredi        2016-10-01 07:32:32 +0200 1069) 				fc->handle_killpriv = 1;
e27c9d3877a0d (Miklos Szeredi        2014-04-28 14:19:23 +0200 1070) 			if (arg->time_gran && arg->time_gran <= 1000000000)
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1071) 				fm->sb->s_time_gran = arg->time_gran;
60bcc88ad185d (Seth Forshee          2016-08-29 08:46:37 -0500 1072) 			if ((arg->flags & FUSE_POSIX_ACL)) {
29433a2991fa6 (Miklos Szeredi        2016-10-01 07:32:32 +0200 1073) 				fc->default_permissions = 1;
60bcc88ad185d (Seth Forshee          2016-08-29 08:46:37 -0500 1074) 				fc->posix_acl = 1;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1075) 				fm->sb->s_xattr = fuse_acl_xattr_handlers;
60bcc88ad185d (Seth Forshee          2016-08-29 08:46:37 -0500 1076) 			}
5571f1e65486b (Dan Schatzberg        2018-10-11 08:17:00 -0700 1077) 			if (arg->flags & FUSE_CACHE_SYMLINKS)
5571f1e65486b (Dan Schatzberg        2018-10-11 08:17:00 -0700 1078) 				fc->cache_symlinks = 1;
3b7008b226f3d (Szymon Lukasz         2017-11-09 21:23:35 +0100 1079) 			if (arg->flags & FUSE_ABORT_ERROR)
3b7008b226f3d (Szymon Lukasz         2017-11-09 21:23:35 +0100 1080) 				fc->abort_err = 1;
5da784cce4308 (Constantine Shulyupin 2018-09-06 15:37:06 +0300 1081) 			if (arg->flags & FUSE_MAX_PAGES) {
5da784cce4308 (Constantine Shulyupin 2018-09-06 15:37:06 +0300 1082) 				fc->max_pages =
a7f0d7aab0b4f (Connor Kuehl          2021-03-18 08:52:22 -0500 1083) 					min_t(unsigned int, fc->max_pages_limit,
5da784cce4308 (Constantine Shulyupin 2018-09-06 15:37:06 +0300 1084) 					max_t(unsigned int, arg->max_pages, 1));
5da784cce4308 (Constantine Shulyupin 2018-09-06 15:37:06 +0300 1085) 			}
fd1a1dc6f5aa7 (Stefan Hajnoczi       2020-08-19 18:19:49 -0400 1086) 			if (IS_ENABLED(CONFIG_FUSE_DAX) &&
fd1a1dc6f5aa7 (Stefan Hajnoczi       2020-08-19 18:19:49 -0400 1087) 			    arg->flags & FUSE_MAP_ALIGNMENT &&
fd1a1dc6f5aa7 (Stefan Hajnoczi       2020-08-19 18:19:49 -0400 1088) 			    !fuse_dax_check_alignment(fc, arg->map_alignment)) {
fd1a1dc6f5aa7 (Stefan Hajnoczi       2020-08-19 18:19:49 -0400 1089) 				ok = false;
fd1a1dc6f5aa7 (Stefan Hajnoczi       2020-08-19 18:19:49 -0400 1090) 			}
9d769e6aa2524 (Vivek Goyal           2020-10-09 14:15:12 -0400 1091) 			if (arg->flags & FUSE_HANDLE_KILLPRIV_V2) {
63f9909ff6020 (Vivek Goyal           2020-10-09 14:15:07 -0400 1092) 				fc->handle_killpriv_v2 = 1;
9d769e6aa2524 (Vivek Goyal           2020-10-09 14:15:12 -0400 1093) 				fm->sb->s_flags |= SB_NOSEC;
9d769e6aa2524 (Vivek Goyal           2020-10-09 14:15:12 -0400 1094) 			}
52a4c95f4d24b (Vivek Goyal           2021-03-25 11:18:22 -0400 1095) 			if (arg->flags & FUSE_SETXATTR_EXT)
52a4c95f4d24b (Vivek Goyal           2021-03-25 11:18:22 -0400 1096) 				fc->setxattr_ext = 1;
7142125937e14 (Miklos Szeredi        2006-06-25 05:48:52 -0700 1097) 		} else {
09cbfeaf1a5a6 (Kirill A. Shutemov    2016-04-01 15:29:47 +0300 1098) 			ra_pages = fc->max_read / PAGE_SIZE;
7142125937e14 (Miklos Szeredi        2006-06-25 05:48:52 -0700 1099) 			fc->no_lock = 1;
37fb3a30b4623 (Miklos Szeredi        2011-08-08 16:08:08 +0200 1100) 			fc->no_flock = 1;
7142125937e14 (Miklos Szeredi        2006-06-25 05:48:52 -0700 1101) 		}
9cd684551124e (Miklos Szeredi        2006-02-01 03:04:40 -0800 1102) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1103) 		fm->sb->s_bdi->ra_pages =
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1104) 				min(fm->sb->s_bdi->ra_pages, ra_pages);
9b9a04693fa2d (Miklos Szeredi        2006-01-16 22:14:44 -0800 1105) 		fc->minor = arg->minor;
9b9a04693fa2d (Miklos Szeredi        2006-01-16 22:14:44 -0800 1106) 		fc->max_write = arg->minor < 5 ? 4096 : arg->max_write;
f948d56435fc1 (Miklos Szeredi        2008-06-17 18:05:40 +0200 1107) 		fc->max_write = max_t(unsigned, 4096, fc->max_write);
0ec7ca41f6f0f (Miklos Szeredi        2006-12-06 20:35:52 -0800 1108) 		fc->conn_init = 1;
9b9a04693fa2d (Miklos Szeredi        2006-01-16 22:14:44 -0800 1109) 	}
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1110) 	kfree(ia);
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1111) 
fd1a1dc6f5aa7 (Stefan Hajnoczi       2020-08-19 18:19:49 -0400 1112) 	if (!ok) {
fd1a1dc6f5aa7 (Stefan Hajnoczi       2020-08-19 18:19:49 -0400 1113) 		fc->conn_init = 0;
fd1a1dc6f5aa7 (Stefan Hajnoczi       2020-08-19 18:19:49 -0400 1114) 		fc->conn_error = 1;
fd1a1dc6f5aa7 (Stefan Hajnoczi       2020-08-19 18:19:49 -0400 1115) 	}
fd1a1dc6f5aa7 (Stefan Hajnoczi       2020-08-19 18:19:49 -0400 1116) 
9759bd5189945 (Miklos Szeredi        2015-01-06 10:45:35 +0100 1117) 	fuse_set_initialized(fc);
08a53cdce62d3 (Miklos Szeredi        2006-04-10 22:54:59 -0700 1118) 	wake_up_all(&fc->blocked_waitq);
9b9a04693fa2d (Miklos Szeredi        2006-01-16 22:14:44 -0800 1119) }
9b9a04693fa2d (Miklos Szeredi        2006-01-16 22:14:44 -0800 1120) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1121) void fuse_send_init(struct fuse_mount *fm)
9b9a04693fa2d (Miklos Szeredi        2006-01-16 22:14:44 -0800 1122) {
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1123) 	struct fuse_init_args *ia;
095da6cbb6a1c (Miklos Szeredi        2006-01-16 22:14:52 -0800 1124) 
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1125) 	ia = kzalloc(sizeof(*ia), GFP_KERNEL | __GFP_NOFAIL);
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1126) 
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1127) 	ia->in.major = FUSE_KERNEL_VERSION;
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1128) 	ia->in.minor = FUSE_KERNEL_MINOR_VERSION;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1129) 	ia->in.max_readahead = fm->sb->s_bdi->ra_pages * PAGE_SIZE;
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1130) 	ia->in.flags |=
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1131) 		FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC |
37fb3a30b4623 (Miklos Szeredi        2011-08-08 16:08:08 +0200 1132) 		FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK |
69fe05c90ed58 (Miklos Szeredi        2012-07-18 16:09:40 +0200 1133) 		FUSE_SPLICE_WRITE | FUSE_SPLICE_MOVE | FUSE_SPLICE_READ |
9446385f05c9a (Wei Fang              2016-07-25 21:17:04 +0800 1134) 		FUSE_FLOCK_LOCKS | FUSE_HAS_IOCTL_DIR | FUSE_AUTO_INVAL_DATA |
4d99ff8f12eb2 (Pavel Emelyanov       2013-10-10 17:12:18 +0400 1135) 		FUSE_DO_READDIRPLUS | FUSE_READDIRPLUS_AUTO | FUSE_ASYNC_DIO |
5c672ab3f0ee0 (Miklos Szeredi        2016-06-30 13:10:49 +0200 1136) 		FUSE_WRITEBACK_CACHE | FUSE_NO_OPEN_SUPPORT |
3b7008b226f3d (Szymon Lukasz         2017-11-09 21:23:35 +0100 1137) 		FUSE_PARALLEL_DIROPS | FUSE_HANDLE_KILLPRIV | FUSE_POSIX_ACL |
d9a9ea94f748f (Chad Austin           2019-01-07 16:53:17 -0800 1138) 		FUSE_ABORT_ERROR | FUSE_MAX_PAGES | FUSE_CACHE_SYMLINKS |
63f9909ff6020 (Vivek Goyal           2020-10-09 14:15:07 -0400 1139) 		FUSE_NO_OPENDIR_SUPPORT | FUSE_EXPLICIT_INVAL_DATA |
52a4c95f4d24b (Vivek Goyal           2021-03-25 11:18:22 -0400 1140) 		FUSE_HANDLE_KILLPRIV_V2 | FUSE_SETXATTR_EXT;
fd1a1dc6f5aa7 (Stefan Hajnoczi       2020-08-19 18:19:49 -0400 1141) #ifdef CONFIG_FUSE_DAX
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1142) 	if (fm->fc->dax)
fd1a1dc6f5aa7 (Stefan Hajnoczi       2020-08-19 18:19:49 -0400 1143) 		ia->in.flags |= FUSE_MAP_ALIGNMENT;
fd1a1dc6f5aa7 (Stefan Hajnoczi       2020-08-19 18:19:49 -0400 1144) #endif
bf109c64040f5 (Max Reitz             2020-04-21 14:47:15 +0200 1145) 	if (fm->fc->auto_submounts)
bf109c64040f5 (Max Reitz             2020-04-21 14:47:15 +0200 1146) 		ia->in.flags |= FUSE_SUBMOUNTS;
bf109c64040f5 (Max Reitz             2020-04-21 14:47:15 +0200 1147) 
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1148) 	ia->args.opcode = FUSE_INIT;
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1149) 	ia->args.in_numargs = 1;
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1150) 	ia->args.in_args[0].size = sizeof(ia->in);
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1151) 	ia->args.in_args[0].value = &ia->in;
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1152) 	ia->args.out_numargs = 1;
3ad2f3fbb9614 (Daniel Mack           2010-02-03 08:01:28 +0800 1153) 	/* Variable length argument used for backward compatibility
9b9a04693fa2d (Miklos Szeredi        2006-01-16 22:14:44 -0800 1154) 	   with interface version < 7.5.  Rest of init_out is zeroed
9b9a04693fa2d (Miklos Szeredi        2006-01-16 22:14:44 -0800 1155) 	   by do_get_request(), so a short reply is not a problem */
cabdb4fa2f666 (zhengbin              2020-01-14 20:39:45 +0800 1156) 	ia->args.out_argvar = true;
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1157) 	ia->args.out_args[0].size = sizeof(ia->out);
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1158) 	ia->args.out_args[0].value = &ia->out;
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1159) 	ia->args.force = true;
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1160) 	ia->args.nocreds = true;
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1161) 	ia->args.end = process_init_reply;
615047eff1088 (Miklos Szeredi        2019-09-10 15:04:10 +0200 1162) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1163) 	if (fuse_simple_background(fm, &ia->args, GFP_KERNEL) != 0)
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1164) 		process_init_reply(fm, &ia->args, -ENOTCONN);
9b9a04693fa2d (Miklos Szeredi        2006-01-16 22:14:44 -0800 1165) }
95a84cdb11c26 (Vivek Goyal           2019-03-06 16:51:39 -0500 1166) EXPORT_SYMBOL_GPL(fuse_send_init);
9b9a04693fa2d (Miklos Szeredi        2006-01-16 22:14:44 -0800 1167) 
783863d6476ce (Miklos Szeredi        2019-08-29 11:01:20 +0200 1168) void fuse_free_conn(struct fuse_conn *fc)
43901aabd7a04 (Tejun Heo             2008-11-26 12:03:56 +0100 1169) {
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1170) 	WARN_ON(!list_empty(&fc->devices));
dd3e2c55a45fe (Al Viro               2013-10-03 21:21:39 -0400 1171) 	kfree_rcu(fc, rcu);
43901aabd7a04 (Tejun Heo             2008-11-26 12:03:56 +0100 1172) }
783863d6476ce (Miklos Szeredi        2019-08-29 11:01:20 +0200 1173) EXPORT_SYMBOL_GPL(fuse_free_conn);
43901aabd7a04 (Tejun Heo             2008-11-26 12:03:56 +0100 1174) 
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1175) static int fuse_bdi_init(struct fuse_conn *fc, struct super_block *sb)
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1176) {
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1177) 	int err;
5f7f7543f52ee (Jan Kara              2017-04-12 12:24:40 +0200 1178) 	char *suffix = "";
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1179) 
69c8ebf83213e (Jan Kara              2017-05-16 12:22:22 +0200 1180) 	if (sb->s_bdev) {
5f7f7543f52ee (Jan Kara              2017-04-12 12:24:40 +0200 1181) 		suffix = "-fuseblk";
69c8ebf83213e (Jan Kara              2017-05-16 12:22:22 +0200 1182) 		/*
69c8ebf83213e (Jan Kara              2017-05-16 12:22:22 +0200 1183) 		 * sb->s_bdi points to blkdev's bdi however we want to redirect
69c8ebf83213e (Jan Kara              2017-05-16 12:22:22 +0200 1184) 		 * it to our private bdi...
69c8ebf83213e (Jan Kara              2017-05-16 12:22:22 +0200 1185) 		 */
69c8ebf83213e (Jan Kara              2017-05-16 12:22:22 +0200 1186) 		bdi_put(sb->s_bdi);
69c8ebf83213e (Jan Kara              2017-05-16 12:22:22 +0200 1187) 		sb->s_bdi = &noop_backing_dev_info;
69c8ebf83213e (Jan Kara              2017-05-16 12:22:22 +0200 1188) 	}
5f7f7543f52ee (Jan Kara              2017-04-12 12:24:40 +0200 1189) 	err = super_setup_bdi_name(sb, "%u:%u%s", MAJOR(fc->dev),
5f7f7543f52ee (Jan Kara              2017-04-12 12:24:40 +0200 1190) 				   MINOR(fc->dev), suffix);
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1191) 	if (err)
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1192) 		return err;
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1193) 
5f7f7543f52ee (Jan Kara              2017-04-12 12:24:40 +0200 1194) 	/* fuse does it's own writeback accounting */
823423ef55f4d (Christoph Hellwig     2020-09-24 08:51:39 +0200 1195) 	sb->s_bdi->capabilities &= ~BDI_CAP_WRITEBACK_ACCT;
823423ef55f4d (Christoph Hellwig     2020-09-24 08:51:39 +0200 1196) 	sb->s_bdi->capabilities |= BDI_CAP_STRICTLIMIT;
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1197) 
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1198) 	/*
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1199) 	 * For a single fuse filesystem use max 1% of dirty +
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1200) 	 * writeback threshold.
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1201) 	 *
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1202) 	 * This gives about 1M of write buffer for memory maps on a
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1203) 	 * machine with 1G and 10% dirty_ratio, which should be more
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1204) 	 * than enough.
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1205) 	 *
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1206) 	 * Privileged users can raise it by writing to
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1207) 	 *
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1208) 	 *    /sys/class/bdi/<bdi>/max_ratio
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1209) 	 */
5f7f7543f52ee (Jan Kara              2017-04-12 12:24:40 +0200 1210) 	bdi_set_max_ratio(sb->s_bdi, 1);
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1211) 
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1212) 	return 0;
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1213) }
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1214) 
0cd1eb9a4160a (Vivek Goyal           2019-03-06 16:51:40 -0500 1215) struct fuse_dev *fuse_dev_alloc(void)
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1216) {
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1217) 	struct fuse_dev *fud;
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 1218) 	struct list_head *pq;
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1219) 
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1220) 	fud = kzalloc(sizeof(struct fuse_dev), GFP_KERNEL);
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 1221) 	if (!fud)
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 1222) 		return NULL;
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1223) 
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 1224) 	pq = kcalloc(FUSE_PQ_HASH_SIZE, sizeof(struct list_head), GFP_KERNEL);
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 1225) 	if (!pq) {
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 1226) 		kfree(fud);
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 1227) 		return NULL;
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1228) 	}
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1229) 
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 1230) 	fud->pq.processing = pq;
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 1231) 	fuse_pqueue_init(&fud->pq);
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 1232) 
0cd1eb9a4160a (Vivek Goyal           2019-03-06 16:51:40 -0500 1233) 	return fud;
0cd1eb9a4160a (Vivek Goyal           2019-03-06 16:51:40 -0500 1234) }
0cd1eb9a4160a (Vivek Goyal           2019-03-06 16:51:40 -0500 1235) EXPORT_SYMBOL_GPL(fuse_dev_alloc);
0cd1eb9a4160a (Vivek Goyal           2019-03-06 16:51:40 -0500 1236) 
0cd1eb9a4160a (Vivek Goyal           2019-03-06 16:51:40 -0500 1237) void fuse_dev_install(struct fuse_dev *fud, struct fuse_conn *fc)
0cd1eb9a4160a (Vivek Goyal           2019-03-06 16:51:40 -0500 1238) {
0cd1eb9a4160a (Vivek Goyal           2019-03-06 16:51:40 -0500 1239) 	fud->fc = fuse_conn_get(fc);
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 1240) 	spin_lock(&fc->lock);
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 1241) 	list_add_tail(&fud->entry, &fc->devices);
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 1242) 	spin_unlock(&fc->lock);
0cd1eb9a4160a (Vivek Goyal           2019-03-06 16:51:40 -0500 1243) }
0cd1eb9a4160a (Vivek Goyal           2019-03-06 16:51:40 -0500 1244) EXPORT_SYMBOL_GPL(fuse_dev_install);
be2ff42c5d6eb (Kirill Tkhai          2018-09-11 13:12:14 +0300 1245) 
0cd1eb9a4160a (Vivek Goyal           2019-03-06 16:51:40 -0500 1246) struct fuse_dev *fuse_dev_alloc_install(struct fuse_conn *fc)
0cd1eb9a4160a (Vivek Goyal           2019-03-06 16:51:40 -0500 1247) {
0cd1eb9a4160a (Vivek Goyal           2019-03-06 16:51:40 -0500 1248) 	struct fuse_dev *fud;
0cd1eb9a4160a (Vivek Goyal           2019-03-06 16:51:40 -0500 1249) 
0cd1eb9a4160a (Vivek Goyal           2019-03-06 16:51:40 -0500 1250) 	fud = fuse_dev_alloc();
0cd1eb9a4160a (Vivek Goyal           2019-03-06 16:51:40 -0500 1251) 	if (!fud)
0cd1eb9a4160a (Vivek Goyal           2019-03-06 16:51:40 -0500 1252) 		return NULL;
0cd1eb9a4160a (Vivek Goyal           2019-03-06 16:51:40 -0500 1253) 
0cd1eb9a4160a (Vivek Goyal           2019-03-06 16:51:40 -0500 1254) 	fuse_dev_install(fud, fc);
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1255) 	return fud;
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1256) }
0cd1eb9a4160a (Vivek Goyal           2019-03-06 16:51:40 -0500 1257) EXPORT_SYMBOL_GPL(fuse_dev_alloc_install);
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1258) 
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1259) void fuse_dev_free(struct fuse_dev *fud)
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1260) {
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1261) 	struct fuse_conn *fc = fud->fc;
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1262) 
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1263) 	if (fc) {
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1264) 		spin_lock(&fc->lock);
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1265) 		list_del(&fud->entry);
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1266) 		spin_unlock(&fc->lock);
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1267) 
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1268) 		fuse_conn_put(fc);
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1269) 	}
d72f70da60de1 (Takeshi Misawa        2018-12-09 14:30:15 +0900 1270) 	kfree(fud->pq.processing);
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1271) 	kfree(fud);
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1272) }
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1273) EXPORT_SYMBOL_GPL(fuse_dev_free);
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1274) 
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1275) static void fuse_fill_attr_from_inode(struct fuse_attr *attr,
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1276) 				      const struct fuse_inode *fi)
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1277) {
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1278) 	*attr = (struct fuse_attr){
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1279) 		.ino		= fi->inode.i_ino,
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1280) 		.size		= fi->inode.i_size,
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1281) 		.blocks		= fi->inode.i_blocks,
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1282) 		.atime		= fi->inode.i_atime.tv_sec,
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1283) 		.mtime		= fi->inode.i_mtime.tv_sec,
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1284) 		.ctime		= fi->inode.i_ctime.tv_sec,
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1285) 		.atimensec	= fi->inode.i_atime.tv_nsec,
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1286) 		.mtimensec	= fi->inode.i_mtime.tv_nsec,
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1287) 		.ctimensec	= fi->inode.i_ctime.tv_nsec,
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1288) 		.mode		= fi->inode.i_mode,
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1289) 		.nlink		= fi->inode.i_nlink,
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1290) 		.uid		= fi->inode.i_uid.val,
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1291) 		.gid		= fi->inode.i_gid.val,
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1292) 		.rdev		= fi->inode.i_rdev,
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1293) 		.blksize	= 1u << fi->inode.i_blkbits,
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1294) 	};
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1295) }
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1296) 
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1297) static void fuse_sb_defaults(struct super_block *sb)
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1298) {
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1299) 	sb->s_magic = FUSE_SUPER_MAGIC;
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1300) 	sb->s_op = &fuse_super_operations;
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1301) 	sb->s_xattr = fuse_xattr_handlers;
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1302) 	sb->s_maxbytes = MAX_LFS_FILESIZE;
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1303) 	sb->s_time_gran = 1;
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1304) 	sb->s_export_op = &fuse_export_operations;
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1305) 	sb->s_iflags |= SB_I_IMA_UNVERIFIABLE_SIGNATURE;
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1306) 	if (sb->s_user_ns != &init_user_ns)
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1307) 		sb->s_iflags |= SB_I_UNTRUSTED_MOUNTER;
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1308) 	sb->s_flags &= ~(SB_NOSEC | SB_I_VERSION);
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1309) 
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1310) 	/*
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1311) 	 * If we are not in the initial user namespace posix
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1312) 	 * acls must be translated.
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1313) 	 */
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1314) 	if (sb->s_user_ns != &init_user_ns)
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1315) 		sb->s_xattr = fuse_no_acl_xattr_handlers;
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1316) }
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1317) 
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1318) int fuse_fill_super_submount(struct super_block *sb,
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1319) 			     struct fuse_inode *parent_fi)
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1320) {
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1321) 	struct fuse_mount *fm = get_fuse_mount_super(sb);
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1322) 	struct super_block *parent_sb = parent_fi->inode.i_sb;
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1323) 	struct fuse_attr root_attr;
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1324) 	struct inode *root;
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1325) 
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1326) 	fuse_sb_defaults(sb);
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1327) 	fm->sb = sb;
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1328) 
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1329) 	WARN_ON(sb->s_bdi != &noop_backing_dev_info);
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1330) 	sb->s_bdi = bdi_get(parent_sb->s_bdi);
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1331) 
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1332) 	sb->s_xattr = parent_sb->s_xattr;
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1333) 	sb->s_time_gran = parent_sb->s_time_gran;
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1334) 	sb->s_blocksize = parent_sb->s_blocksize;
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1335) 	sb->s_blocksize_bits = parent_sb->s_blocksize_bits;
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1336) 	sb->s_subtype = kstrdup(parent_sb->s_subtype, GFP_KERNEL);
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1337) 	if (parent_sb->s_subtype && !sb->s_subtype)
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1338) 		return -ENOMEM;
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1339) 
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1340) 	fuse_fill_attr_from_inode(&root_attr, parent_fi);
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1341) 	root = fuse_iget(sb, parent_fi->nodeid, 0, &root_attr, 0, 0);
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1342) 	/*
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1343) 	 * This inode is just a duplicate, so it is not looked up and
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1344) 	 * its nlookup should not be incremented.  fuse_iget() does
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1345) 	 * that, though, so undo it here.
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1346) 	 */
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1347) 	get_fuse_inode(root)->nlookup--;
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1348) 	sb->s_d_op = &fuse_dentry_operations;
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1349) 	sb->s_root = d_make_root(root);
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1350) 	if (!sb->s_root)
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1351) 		return -ENOMEM;
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1352) 
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1353) 	return 0;
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1354) }
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1355) 
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1356) int fuse_fill_super_common(struct super_block *sb, struct fuse_fs_context *ctx)
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1357) {
7fd3abfa8dd7c (Vivek Goyal           2020-05-04 14:33:15 -0400 1358) 	struct fuse_dev *fud = NULL;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1359) 	struct fuse_mount *fm = get_fuse_mount_super(sb);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1360) 	struct fuse_conn *fc = fm->fc;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1361) 	struct inode *root;
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1362) 	struct dentry *root_dentry;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1363) 	int err;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1364) 
c2b8f006909b9 (Miklos Szeredi        2009-01-26 15:00:58 +0100 1365) 	err = -EINVAL;
1751e8a6cb935 (Linus Torvalds        2017-11-27 13:05:09 -0800 1366) 	if (sb->s_flags & SB_MANDLOCK)
c2b8f006909b9 (Miklos Szeredi        2009-01-26 15:00:58 +0100 1367) 		goto err;
7142125937e14 (Miklos Szeredi        2006-06-25 05:48:52 -0700 1368) 
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1369) 	fuse_sb_defaults(sb);
9e1f1de02c227 (Al Viro               2011-06-03 18:24:58 -0400 1370) 
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1371) 	if (ctx->is_bdev) {
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1372) #ifdef CONFIG_BLOCK
c2b8f006909b9 (Miklos Szeredi        2009-01-26 15:00:58 +0100 1373) 		err = -EINVAL;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1374) 		if (!sb_set_blocksize(sb, ctx->blksize))
c2b8f006909b9 (Miklos Szeredi        2009-01-26 15:00:58 +0100 1375) 			goto err;
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1376) #endif
d809161402e9f (Miklos Szeredi        2006-12-06 20:35:48 -0800 1377) 	} else {
09cbfeaf1a5a6 (Kirill A. Shutemov    2016-04-01 15:29:47 +0300 1378) 		sb->s_blocksize = PAGE_SIZE;
09cbfeaf1a5a6 (Kirill A. Shutemov    2016-04-01 15:29:47 +0300 1379) 		sb->s_blocksize_bits = PAGE_SHIFT;
d809161402e9f (Miklos Szeredi        2006-12-06 20:35:48 -0800 1380) 	}
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1381) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1382) 	sb->s_subtype = ctx->subtype;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1383) 	ctx->subtype = NULL;
1dd539577c42b (Vivek Goyal           2020-08-19 18:19:47 -0400 1384) 	if (IS_ENABLED(CONFIG_FUSE_DAX)) {
1dd539577c42b (Vivek Goyal           2020-08-19 18:19:47 -0400 1385) 		err = fuse_dax_conn_alloc(fc, ctx->dax_dev);
1dd539577c42b (Vivek Goyal           2020-08-19 18:19:47 -0400 1386) 		if (err)
1dd539577c42b (Vivek Goyal           2020-08-19 18:19:47 -0400 1387) 			goto err;
1dd539577c42b (Vivek Goyal           2020-08-19 18:19:47 -0400 1388) 	}
e45b2546e23c2 (Eric W. Biederman     2018-05-04 11:47:28 -0500 1389) 
7fd3abfa8dd7c (Vivek Goyal           2020-05-04 14:33:15 -0400 1390) 	if (ctx->fudptr) {
7fd3abfa8dd7c (Vivek Goyal           2020-05-04 14:33:15 -0400 1391) 		err = -ENOMEM;
7fd3abfa8dd7c (Vivek Goyal           2020-05-04 14:33:15 -0400 1392) 		fud = fuse_dev_alloc_install(fc);
7fd3abfa8dd7c (Vivek Goyal           2020-05-04 14:33:15 -0400 1393) 		if (!fud)
1dd539577c42b (Vivek Goyal           2020-08-19 18:19:47 -0400 1394) 			goto err_free_dax;
7fd3abfa8dd7c (Vivek Goyal           2020-05-04 14:33:15 -0400 1395) 	}
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1396) 
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1397) 	fc->dev = sb->s_dev;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1398) 	fm->sb = sb;
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1399) 	err = fuse_bdi_init(fc, sb);
a325f9b92273d (Tejun Heo             2009-04-14 10:54:52 +0900 1400) 	if (err)
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1401) 		goto err_dev_free;
0d179aa59285c (Tejun Heo             2008-11-26 12:03:55 +0100 1402) 
e0a43ddcc08c3 (Miklos Szeredi        2009-06-30 20:12:23 +0200 1403) 	/* Handle umasking inside the fuse code */
1751e8a6cb935 (Linus Torvalds        2017-11-27 13:05:09 -0800 1404) 	if (sb->s_flags & SB_POSIXACL)
e0a43ddcc08c3 (Miklos Szeredi        2009-06-30 20:12:23 +0200 1405) 		fc->dont_mask = 1;
1751e8a6cb935 (Linus Torvalds        2017-11-27 13:05:09 -0800 1406) 	sb->s_flags |= SB_POSIXACL;
e0a43ddcc08c3 (Miklos Szeredi        2009-06-30 20:12:23 +0200 1407) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1408) 	fc->default_permissions = ctx->default_permissions;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1409) 	fc->allow_other = ctx->allow_other;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1410) 	fc->user_id = ctx->user_id;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1411) 	fc->group_id = ctx->group_id;
f4fd4ae354ba2 (Vivek Goyal           2020-08-19 18:19:45 -0400 1412) 	fc->legacy_opts_show = ctx->legacy_opts_show;
1866d779d5d2a (Max Reitz             2020-09-09 17:52:17 +0200 1413) 	fc->max_read = max_t(unsigned int, 4096, ctx->max_read);
783863d6476ce (Miklos Szeredi        2019-08-29 11:01:20 +0200 1414) 	fc->destroy = ctx->destroy;
15c8e72e88e0b (Vivek Goyal           2019-05-06 15:35:43 -0400 1415) 	fc->no_control = ctx->no_control;
15c8e72e88e0b (Vivek Goyal           2019-05-06 15:35:43 -0400 1416) 	fc->no_force_umount = ctx->no_force_umount;
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1417) 
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1418) 	err = -ENOMEM;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1419) 	root = fuse_get_root_inode(sb, ctx->rootmode);
0ce267ff95a03 (Miklos Szeredi        2016-10-18 15:36:48 +0200 1420) 	sb->s_d_op = &fuse_root_dentry_operations;
48fde701aff66 (Al Viro               2012-01-08 22:15:13 -0500 1421) 	root_dentry = d_make_root(root);
48fde701aff66 (Al Viro               2012-01-08 22:15:13 -0500 1422) 	if (!root_dentry)
cc080e9e9be16 (Miklos Szeredi        2015-07-01 16:26:08 +0200 1423) 		goto err_dev_free;
0ce267ff95a03 (Miklos Szeredi        2016-10-18 15:36:48 +0200 1424) 	/* Root dentry doesn't have .d_revalidate */
c35eebe9939f5 (Al Viro               2010-12-18 11:15:22 -0500 1425) 	sb->s_d_op = &fuse_dentry_operations;
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1426) 
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700 1427) 	mutex_lock(&fuse_mutex);
8aa09a50b5d9d (Miklos Szeredi        2006-04-26 10:49:16 +0200 1428) 	err = -EINVAL;
7fd3abfa8dd7c (Vivek Goyal           2020-05-04 14:33:15 -0400 1429) 	if (ctx->fudptr && *ctx->fudptr)
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700 1430) 		goto err_unlock;
8aa09a50b5d9d (Miklos Szeredi        2006-04-26 10:49:16 +0200 1431) 
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700 1432) 	err = fuse_ctl_add_conn(fc);
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700 1433) 	if (err)
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700 1434) 		goto err_unlock;
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700 1435) 
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700 1436) 	list_add_tail(&fc->entry, &fuse_conn_list);
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1437) 	sb->s_root = root_dentry;
7fd3abfa8dd7c (Vivek Goyal           2020-05-04 14:33:15 -0400 1438) 	if (ctx->fudptr)
7fd3abfa8dd7c (Vivek Goyal           2020-05-04 14:33:15 -0400 1439) 		*ctx->fudptr = fud;
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700 1440) 	mutex_unlock(&fuse_mutex);
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1441) 	return 0;
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1442) 
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1443)  err_unlock:
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1444) 	mutex_unlock(&fuse_mutex);
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1445) 	dput(root_dentry);
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1446)  err_dev_free:
7fd3abfa8dd7c (Vivek Goyal           2020-05-04 14:33:15 -0400 1447) 	if (fud)
7fd3abfa8dd7c (Vivek Goyal           2020-05-04 14:33:15 -0400 1448) 		fuse_dev_free(fud);
1dd539577c42b (Vivek Goyal           2020-08-19 18:19:47 -0400 1449)  err_free_dax:
1dd539577c42b (Vivek Goyal           2020-08-19 18:19:47 -0400 1450) 	if (IS_ENABLED(CONFIG_FUSE_DAX))
1dd539577c42b (Vivek Goyal           2020-08-19 18:19:47 -0400 1451) 		fuse_dax_conn_free(fc);
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1452)  err:
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1453) 	return err;
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1454) }
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1455) EXPORT_SYMBOL_GPL(fuse_fill_super_common);
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1456) 
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1457) static int fuse_fill_super(struct super_block *sb, struct fs_context *fsc)
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1458) {
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1459) 	struct fuse_fs_context *ctx = fsc->fs_private;
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1460) 	struct file *file;
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1461) 	int err;
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1462) 	struct fuse_conn *fc;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1463) 	struct fuse_mount *fm;
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1464) 
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1465) 	err = -EINVAL;
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1466) 	file = fget(ctx->fd);
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1467) 	if (!file)
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1468) 		goto err;
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1469) 
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1470) 	/*
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1471) 	 * Require mount to happen from the same user namespace which
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1472) 	 * opened /dev/fuse to prevent potential attacks.
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1473) 	 */
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1474) 	if ((file->f_op != &fuse_dev_operations) ||
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1475) 	    (file->f_cred->user_ns != sb->s_user_ns))
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1476) 		goto err_fput;
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1477) 	ctx->fudptr = &file->private_data;
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1478) 
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1479) 	fc = kmalloc(sizeof(*fc), GFP_KERNEL);
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1480) 	err = -ENOMEM;
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1481) 	if (!fc)
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1482) 		goto err_fput;
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1483) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1484) 	fm = kzalloc(sizeof(*fm), GFP_KERNEL);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1485) 	if (!fm) {
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1486) 		kfree(fc);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1487) 		goto err_fput;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1488) 	}
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1489) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1490) 	fuse_conn_init(fc, fm, sb->s_user_ns, &fuse_dev_fiq_ops, NULL);
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1491) 	fc->release = fuse_free_conn;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1492) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1493) 	sb->s_fs_info = fm;
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1494) 
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1495) 	err = fuse_fill_super_common(sb, ctx);
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1496) 	if (err)
0cc2656cdb0b1 (Stefan Hajnoczi       2018-06-13 10:23:04 +0100 1497) 		goto err_put_conn;
0720b31597644 (Miklos Szeredi        2006-04-10 22:54:55 -0700 1498) 	/*
0720b31597644 (Miklos Szeredi        2006-04-10 22:54:55 -0700 1499) 	 * atomic_dec_and_test() in fput() provides the necessary
0720b31597644 (Miklos Szeredi        2006-04-10 22:54:55 -0700 1500) 	 * memory barrier for file->private_data to be visible on all
0720b31597644 (Miklos Szeredi        2006-04-10 22:54:55 -0700 1501) 	 * CPUs after this
0720b31597644 (Miklos Szeredi        2006-04-10 22:54:55 -0700 1502) 	 */
0720b31597644 (Miklos Szeredi        2006-04-10 22:54:55 -0700 1503) 	fput(file);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1504) 	fuse_send_init(get_fuse_mount_super(sb));
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1505) 	return 0;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1506) 
c2b8f006909b9 (Miklos Szeredi        2009-01-26 15:00:58 +0100 1507)  err_put_conn:
514b5e3ff45e6 (Miklos Szeredi        2020-11-11 17:22:32 +0100 1508) 	fuse_conn_put(fc);
514b5e3ff45e6 (Miklos Szeredi        2020-11-11 17:22:32 +0100 1509) 	kfree(fm);
543b8f8662fe6 (Tetsuo Handa          2018-05-01 13:12:14 +0900 1510) 	sb->s_fs_info = NULL;
c2b8f006909b9 (Miklos Szeredi        2009-01-26 15:00:58 +0100 1511)  err_fput:
c2b8f006909b9 (Miklos Szeredi        2009-01-26 15:00:58 +0100 1512) 	fput(file);
c2b8f006909b9 (Miklos Szeredi        2009-01-26 15:00:58 +0100 1513)  err:
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1514) 	return err;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1515) }
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1516) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1517) static int fuse_get_tree(struct fs_context *fc)
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1518) {
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1519) 	struct fuse_fs_context *ctx = fc->fs_private;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1520) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1521) 	if (!ctx->fd_present || !ctx->rootmode_present ||
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1522) 	    !ctx->user_id_present || !ctx->group_id_present)
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1523) 		return -EINVAL;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1524) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1525) #ifdef CONFIG_BLOCK
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1526) 	if (ctx->is_bdev)
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1527) 		return get_tree_bdev(fc, fuse_fill_super);
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1528) #endif
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1529) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1530) 	return get_tree_nodev(fc, fuse_fill_super);
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1531) }
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1532) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1533) static const struct fs_context_operations fuse_context_ops = {
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1534) 	.free		= fuse_free_fc,
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1535) 	.parse_param	= fuse_parse_param,
0189a2d367f49 (Miklos Szeredi        2020-07-14 14:45:41 +0200 1536) 	.reconfigure	= fuse_reconfigure,
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1537) 	.get_tree	= fuse_get_tree,
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1538) };
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1539) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1540) /*
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1541)  * Set up the filesystem mount context.
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1542)  */
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1543) static int fuse_init_fs_context(struct fs_context *fc)
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1544) {
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1545) 	struct fuse_fs_context *ctx;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1546) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1547) 	ctx = kzalloc(sizeof(struct fuse_fs_context), GFP_KERNEL);
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1548) 	if (!ctx)
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1549) 		return -ENOMEM;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1550) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1551) 	ctx->max_read = ~0;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1552) 	ctx->blksize = FUSE_DEFAULT_BLKSIZE;
f4fd4ae354ba2 (Vivek Goyal           2020-08-19 18:19:45 -0400 1553) 	ctx->legacy_opts_show = true;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1554) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1555) #ifdef CONFIG_BLOCK
783863d6476ce (Miklos Szeredi        2019-08-29 11:01:20 +0200 1556) 	if (fc->fs_type == &fuseblk_fs_type) {
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1557) 		ctx->is_bdev = true;
783863d6476ce (Miklos Szeredi        2019-08-29 11:01:20 +0200 1558) 		ctx->destroy = true;
783863d6476ce (Miklos Szeredi        2019-08-29 11:01:20 +0200 1559) 	}
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1560) #endif
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1561) 
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1562) 	fc->fs_private = ctx;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1563) 	fc->ops = &fuse_context_ops;
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1564) 	return 0;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1565) }
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1566) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1567) bool fuse_mount_remove(struct fuse_mount *fm)
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1568) {
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1569) 	struct fuse_conn *fc = fm->fc;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1570) 	bool last = false;
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1571) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1572) 	down_write(&fc->killsb);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1573) 	list_del_init(&fm->fc_entry);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1574) 	if (list_empty(&fc->mounts))
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1575) 		last = true;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1576) 	up_write(&fc->killsb);
e8f3bd773d22f (Miklos Szeredi        2018-07-26 16:13:11 +0200 1577) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1578) 	return last;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1579) }
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1580) EXPORT_SYMBOL_GPL(fuse_mount_remove);
e8f3bd773d22f (Miklos Szeredi        2018-07-26 16:13:11 +0200 1581) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1582) void fuse_conn_destroy(struct fuse_mount *fm)
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1583) {
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1584) 	struct fuse_conn *fc = fm->fc;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1585) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1586) 	if (fc->destroy)
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1587) 		fuse_send_destroy(fm);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1588) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1589) 	fuse_abort_conn(fc);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1590) 	fuse_wait_aborted(fc);
413daa1a3f4a5 (Miklos Szeredi        2020-10-09 12:40:11 +0200 1591) 
413daa1a3f4a5 (Miklos Szeredi        2020-10-09 12:40:11 +0200 1592) 	if (!list_empty(&fc->entry)) {
413daa1a3f4a5 (Miklos Szeredi        2020-10-09 12:40:11 +0200 1593) 		mutex_lock(&fuse_mutex);
413daa1a3f4a5 (Miklos Szeredi        2020-10-09 12:40:11 +0200 1594) 		list_del(&fc->entry);
413daa1a3f4a5 (Miklos Szeredi        2020-10-09 12:40:11 +0200 1595) 		fuse_ctl_remove_conn(fc);
413daa1a3f4a5 (Miklos Szeredi        2020-10-09 12:40:11 +0200 1596) 		mutex_unlock(&fuse_mutex);
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1597) 	}
e8f3bd773d22f (Miklos Szeredi        2018-07-26 16:13:11 +0200 1598) }
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1599) EXPORT_SYMBOL_GPL(fuse_conn_destroy);
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1600) 
6a68d1e1514d7 (Miklos Szeredi        2020-11-11 17:22:32 +0100 1601) static void fuse_sb_destroy(struct super_block *sb)
e8f3bd773d22f (Miklos Szeredi        2018-07-26 16:13:11 +0200 1602) {
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1603) 	struct fuse_mount *fm = get_fuse_mount_super(sb);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1604) 	bool last;
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1605) 
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1606) 	if (fm) {
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1607) 		last = fuse_mount_remove(fm);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1608) 		if (last)
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1609) 			fuse_conn_destroy(fm);
fcee216beb9c1 (Max Reitz             2020-05-06 17:44:12 +0200 1610) 	}
6a68d1e1514d7 (Miklos Szeredi        2020-11-11 17:22:32 +0100 1611) }
6a68d1e1514d7 (Miklos Szeredi        2020-11-11 17:22:32 +0100 1612) 
6a68d1e1514d7 (Miklos Szeredi        2020-11-11 17:22:32 +0100 1613) static void fuse_kill_sb_anon(struct super_block *sb)
6a68d1e1514d7 (Miklos Szeredi        2020-11-11 17:22:32 +0100 1614) {
6a68d1e1514d7 (Miklos Szeredi        2020-11-11 17:22:32 +0100 1615) 	fuse_sb_destroy(sb);
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1616) 	kill_anon_super(sb);
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1617) }
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1618) 
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1619) static struct file_system_type fuse_fs_type = {
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1620) 	.owner		= THIS_MODULE,
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1621) 	.name		= "fuse",
4ad769f3c346e (Eric W. Biederman     2018-05-29 09:04:46 -0500 1622) 	.fs_flags	= FS_HAS_SUBTYPE | FS_USERNS_MOUNT,
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1623) 	.init_fs_context = fuse_init_fs_context,
d7167b149943e (Al Viro               2019-09-07 07:23:15 -0400 1624) 	.parameters	= fuse_fs_parameters,
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1625) 	.kill_sb	= fuse_kill_sb_anon,
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1626) };
7f78e03513940 (Eric W. Biederman     2013-03-02 19:39:14 -0800 1627) MODULE_ALIAS_FS("fuse");
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1628) 
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1629) #ifdef CONFIG_BLOCK
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1630) static void fuse_kill_sb_blk(struct super_block *sb)
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1631) {
6a68d1e1514d7 (Miklos Szeredi        2020-11-11 17:22:32 +0100 1632) 	fuse_sb_destroy(sb);
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1633) 	kill_block_super(sb);
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1634) }
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1635) 
d6392f873f1d0 (Miklos Szeredi        2006-12-06 20:35:44 -0800 1636) static struct file_system_type fuseblk_fs_type = {
d6392f873f1d0 (Miklos Szeredi        2006-12-06 20:35:44 -0800 1637) 	.owner		= THIS_MODULE,
d6392f873f1d0 (Miklos Szeredi        2006-12-06 20:35:44 -0800 1638) 	.name		= "fuseblk",
c30da2e981a70 (David Howells         2019-03-25 16:38:31 +0000 1639) 	.init_fs_context = fuse_init_fs_context,
d7167b149943e (Al Viro               2019-09-07 07:23:15 -0400 1640) 	.parameters	= fuse_fs_parameters,
3b463ae0c6264 (John Muir             2009-05-31 11:13:57 -0400 1641) 	.kill_sb	= fuse_kill_sb_blk,
edad01e2a1c52 (Alexey Dobriyan       2007-06-16 10:16:05 -0700 1642) 	.fs_flags	= FS_REQUIRES_DEV | FS_HAS_SUBTYPE,
d6392f873f1d0 (Miklos Szeredi        2006-12-06 20:35:44 -0800 1643) };
7f78e03513940 (Eric W. Biederman     2013-03-02 19:39:14 -0800 1644) MODULE_ALIAS_FS("fuseblk");
d6392f873f1d0 (Miklos Szeredi        2006-12-06 20:35:44 -0800 1645) 
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1646) static inline int register_fuseblk(void)
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1647) {
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1648) 	return register_filesystem(&fuseblk_fs_type);
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1649) }
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1650) 
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1651) static inline void unregister_fuseblk(void)
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1652) {
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1653) 	unregister_filesystem(&fuseblk_fs_type);
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1654) }
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1655) #else
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1656) static inline int register_fuseblk(void)
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1657) {
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1658) 	return 0;
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1659) }
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1660) 
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1661) static inline void unregister_fuseblk(void)
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1662) {
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1663) }
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1664) #endif
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1665) 
51cc50685a427 (Alexey Dobriyan       2008-07-25 19:45:34 -0700 1666) static void fuse_inode_init_once(void *foo)
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1667) {
1729a16c2c92b (Miklos Szeredi        2008-11-26 12:03:54 +0100 1668) 	struct inode *inode = foo;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1669) 
a35afb830f8d7 (Christoph Lameter     2007-05-16 22:10:57 -0700 1670) 	inode_init_once(inode);
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1671) }
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1672) 
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1673) static int __init fuse_fs_init(void)
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1674) {
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1675) 	int err;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1676) 
d6392f873f1d0 (Miklos Szeredi        2006-12-06 20:35:44 -0800 1677) 	fuse_inode_cachep = kmem_cache_create("fuse_inode",
df206988e03e8 (Johannes Weiner       2017-11-15 17:38:34 -0800 1678) 			sizeof(struct fuse_inode), 0,
df206988e03e8 (Johannes Weiner       2017-11-15 17:38:34 -0800 1679) 			SLAB_HWCACHE_ALIGN|SLAB_ACCOUNT|SLAB_RECLAIM_ACCOUNT,
df206988e03e8 (Johannes Weiner       2017-11-15 17:38:34 -0800 1680) 			fuse_inode_init_once);
d6392f873f1d0 (Miklos Szeredi        2006-12-06 20:35:44 -0800 1681) 	err = -ENOMEM;
d6392f873f1d0 (Miklos Szeredi        2006-12-06 20:35:44 -0800 1682) 	if (!fuse_inode_cachep)
988f032567eab (Al Viro               2011-12-13 12:25:27 -0500 1683) 		goto out;
988f032567eab (Al Viro               2011-12-13 12:25:27 -0500 1684) 
988f032567eab (Al Viro               2011-12-13 12:25:27 -0500 1685) 	err = register_fuseblk();
988f032567eab (Al Viro               2011-12-13 12:25:27 -0500 1686) 	if (err)
988f032567eab (Al Viro               2011-12-13 12:25:27 -0500 1687) 		goto out2;
988f032567eab (Al Viro               2011-12-13 12:25:27 -0500 1688) 
988f032567eab (Al Viro               2011-12-13 12:25:27 -0500 1689) 	err = register_filesystem(&fuse_fs_type);
988f032567eab (Al Viro               2011-12-13 12:25:27 -0500 1690) 	if (err)
988f032567eab (Al Viro               2011-12-13 12:25:27 -0500 1691) 		goto out3;
d6392f873f1d0 (Miklos Szeredi        2006-12-06 20:35:44 -0800 1692) 
d6392f873f1d0 (Miklos Szeredi        2006-12-06 20:35:44 -0800 1693) 	return 0;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1694) 
988f032567eab (Al Viro               2011-12-13 12:25:27 -0500 1695)  out3:
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1696) 	unregister_fuseblk();
988f032567eab (Al Viro               2011-12-13 12:25:27 -0500 1697)  out2:
988f032567eab (Al Viro               2011-12-13 12:25:27 -0500 1698) 	kmem_cache_destroy(fuse_inode_cachep);
d6392f873f1d0 (Miklos Szeredi        2006-12-06 20:35:44 -0800 1699)  out:
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1700) 	return err;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1701) }
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1702) 
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1703) static void fuse_fs_cleanup(void)
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1704) {
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1705) 	unregister_filesystem(&fuse_fs_type);
875d95ec9eb69 (Miklos Szeredi        2006-12-06 20:35:54 -0800 1706) 	unregister_fuseblk();
8c0a85377048b (Kirill A. Shutemov    2012-09-26 11:33:07 +1000 1707) 
8c0a85377048b (Kirill A. Shutemov    2012-09-26 11:33:07 +1000 1708) 	/*
8c0a85377048b (Kirill A. Shutemov    2012-09-26 11:33:07 +1000 1709) 	 * Make sure all delayed rcu free inodes are flushed before we
8c0a85377048b (Kirill A. Shutemov    2012-09-26 11:33:07 +1000 1710) 	 * destroy cache.
8c0a85377048b (Kirill A. Shutemov    2012-09-26 11:33:07 +1000 1711) 	 */
8c0a85377048b (Kirill A. Shutemov    2012-09-26 11:33:07 +1000 1712) 	rcu_barrier();
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1713) 	kmem_cache_destroy(fuse_inode_cachep);
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1714) }
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1715) 
5c89e17e9c2bc (Greg Kroah-Hartman    2007-10-29 20:13:17 +0100 1716) static struct kobject *fuse_kobj;
5c89e17e9c2bc (Greg Kroah-Hartman    2007-10-29 20:13:17 +0100 1717) 
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1718) static int fuse_sysfs_init(void)
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1719) {
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1720) 	int err;
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1721) 
00d2666623368 (Greg Kroah-Hartman    2007-10-29 14:17:23 -0600 1722) 	fuse_kobj = kobject_create_and_add("fuse", fs_kobj);
5c89e17e9c2bc (Greg Kroah-Hartman    2007-10-29 20:13:17 +0100 1723) 	if (!fuse_kobj) {
5c89e17e9c2bc (Greg Kroah-Hartman    2007-10-29 20:13:17 +0100 1724) 		err = -ENOMEM;
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1725) 		goto out_err;
5c89e17e9c2bc (Greg Kroah-Hartman    2007-10-29 20:13:17 +0100 1726) 	}
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1727) 
f9bb48825a6b5 (Eric W. Biederman     2015-05-13 17:35:41 -0500 1728) 	err = sysfs_create_mount_point(fuse_kobj, "connections");
f9bb48825a6b5 (Eric W. Biederman     2015-05-13 17:35:41 -0500 1729) 	if (err)
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1730) 		goto out_fuse_unregister;
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1731) 
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1732) 	return 0;
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1733) 
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1734)  out_fuse_unregister:
197b12d6796a3 (Greg Kroah-Hartman    2007-12-20 08:13:05 -0800 1735) 	kobject_put(fuse_kobj);
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1736)  out_err:
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1737) 	return err;
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1738) }
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1739) 
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1740) static void fuse_sysfs_cleanup(void)
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1741) {
f9bb48825a6b5 (Eric W. Biederman     2015-05-13 17:35:41 -0500 1742) 	sysfs_remove_mount_point(fuse_kobj, "connections");
197b12d6796a3 (Greg Kroah-Hartman    2007-12-20 08:13:05 -0800 1743) 	kobject_put(fuse_kobj);
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1744) }
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1745) 
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1746) static int __init fuse_init(void)
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1747) {
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1748) 	int res;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1749) 
f2294482ff65d (Kirill Smelkov        2019-03-27 09:15:17 +0000 1750) 	pr_info("init (API version %i.%i)\n",
f2294482ff65d (Kirill Smelkov        2019-03-27 09:15:17 +0000 1751) 		FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1752) 
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700 1753) 	INIT_LIST_HEAD(&fuse_conn_list);
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1754) 	res = fuse_fs_init();
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1755) 	if (res)
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1756) 		goto err;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1757) 
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1758) 	res = fuse_dev_init();
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1759) 	if (res)
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1760) 		goto err_fs_cleanup;
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1761) 
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1762) 	res = fuse_sysfs_init();
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1763) 	if (res)
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1764) 		goto err_dev_cleanup;
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1765) 
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700 1766) 	res = fuse_ctl_init();
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700 1767) 	if (res)
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700 1768) 		goto err_sysfs_cleanup;
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700 1769) 
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200 1770) 	sanitize_global_limit(&max_user_bgreq);
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200 1771) 	sanitize_global_limit(&max_user_congthresh);
487ea5af6358c (Csaba Henk            2009-08-26 19:17:22 +0200 1772) 
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1773) 	return 0;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1774) 
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700 1775)  err_sysfs_cleanup:
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700 1776) 	fuse_sysfs_cleanup();
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1777)  err_dev_cleanup:
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1778) 	fuse_dev_cleanup();
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1779)  err_fs_cleanup:
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1780) 	fuse_fs_cleanup();
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1781)  err:
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1782) 	return res;
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1783) }
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1784) 
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1785) static void __exit fuse_exit(void)
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1786) {
f2294482ff65d (Kirill Smelkov        2019-03-27 09:15:17 +0000 1787) 	pr_debug("exit\n");
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1788) 
bafa96541b250 (Miklos Szeredi        2006-06-25 05:48:51 -0700 1789) 	fuse_ctl_cleanup();
f543f253f3aa7 (Miklos Szeredi        2006-01-16 22:14:35 -0800 1790) 	fuse_sysfs_cleanup();
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1791) 	fuse_fs_cleanup();
334f485df85ac (Miklos Szeredi        2005-09-09 13:10:27 -0700 1792) 	fuse_dev_cleanup();
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1793) }
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1794) 
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1795) module_init(fuse_init);
d8a5ba45457e4 (Miklos Szeredi        2005-09-09 13:10:26 -0700 1796) module_exit(fuse_exit);