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);