VisionFive2 Linux kernel

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

More than 9999 Commits   32 Branches   54 Tags
ec26815ad847d (David Howells      2007-04-26 15:49:28 -0700   1) /* AFS superblock handling
ec26815ad847d (David Howells      2007-04-26 15:49:28 -0700   2)  *
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000   3)  * Copyright (c) 2002, 2007, 2018 Red Hat, Inc. All rights reserved.
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   4)  *
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   5)  * This software may be freely redistributed under the terms of the
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   6)  * GNU General Public License.
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   7)  *
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   8)  * You should have received a copy of the GNU General Public License
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   9)  * along with this program; if not, write to the Free Software
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  10)  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  11)  *
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  12)  * Authors: David Howells <dhowells@redhat.com>
44d1b980c72db (David Woodhouse    2008-06-05 22:46:18 -0700  13)  *          David Woodhouse <dwmw2@infradead.org>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  14)  *
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  15)  */
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  16) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  17) #include <linux/kernel.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  18) #include <linux/module.h>
bec5eb6141308 (wanglei            2010-08-11 09:38:04 +0100  19) #include <linux/mount.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  20) #include <linux/init.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  21) #include <linux/slab.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  22) #include <linux/fs.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  23) #include <linux/pagemap.h>
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000  24) #include <linux/fs_parser.h>
45222b9e02fb2 (David Howells      2007-05-10 22:22:20 -0700  25) #include <linux/statfs.h>
e8edc6e03a5c8 (Alexey Dobriyan    2007-05-21 01:22:52 +0400  26) #include <linux/sched.h>
f74f70f8b10b4 (Eric W. Biederman  2013-01-31 04:23:54 -0800  27) #include <linux/nsproxy.h>
f044c8847bb61 (David Howells      2017-11-02 15:27:45 +0000  28) #include <linux/magic.h>
f74f70f8b10b4 (Eric W. Biederman  2013-01-31 04:23:54 -0800  29) #include <net/net_namespace.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  30) #include "internal.h"
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  31) 
51cc50685a427 (Alexey Dobriyan    2008-07-25 19:45:34 -0700  32) static void afs_i_init_once(void *foo);
dde194a64bb5c (Al Viro            2011-06-12 16:01:21 -0400  33) static void afs_kill_super(struct super_block *sb);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  34) static struct inode *afs_alloc_inode(struct super_block *sb);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  35) static void afs_destroy_inode(struct inode *inode);
51b9fe48c411b (Al Viro            2019-04-10 15:05:06 -0400  36) static void afs_free_inode(struct inode *inode);
45222b9e02fb2 (David Howells      2007-05-10 22:22:20 -0700  37) static int afs_statfs(struct dentry *dentry, struct kstatfs *buf);
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100  38) static int afs_show_devname(struct seq_file *m, struct dentry *root);
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100  39) static int afs_show_options(struct seq_file *m, struct dentry *root);
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000  40) static int afs_init_fs_context(struct fs_context *fc);
d7167b149943e (Al Viro            2019-09-07 07:23:15 -0400  41) static const struct fs_parameter_spec afs_fs_parameters[];
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  42) 
1f5ce9e93aa96 (Trond Myklebust    2006-06-09 09:34:16 -0400  43) struct file_system_type afs_fs_type = {
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000  44) 	.owner			= THIS_MODULE,
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000  45) 	.name			= "afs",
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000  46) 	.init_fs_context	= afs_init_fs_context,
d7167b149943e (Al Viro            2019-09-07 07:23:15 -0400  47) 	.parameters		= afs_fs_parameters,
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000  48) 	.kill_sb		= afs_kill_super,
79ddbfa500b37 (David Howells      2019-04-25 14:26:51 +0100  49) 	.fs_flags		= FS_RENAME_DOES_D_MOVE,
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  50) };
7f78e03513940 (Eric W. Biederman  2013-03-02 19:39:14 -0800  51) MODULE_ALIAS_FS("afs");
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  52) 
5b86d4ff5dce3 (David Howells      2018-05-18 11:46:15 +0100  53) int afs_net_id;
5b86d4ff5dce3 (David Howells      2018-05-18 11:46:15 +0100  54) 
ee9b6d61a2a43 (Josef 'Jeff' Sipek 2007-02-12 00:55:41 -0800  55) static const struct super_operations afs_super_ops = {
45222b9e02fb2 (David Howells      2007-05-10 22:22:20 -0700  56) 	.statfs		= afs_statfs,
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  57) 	.alloc_inode	= afs_alloc_inode,
bec5eb6141308 (wanglei            2010-08-11 09:38:04 +0100  58) 	.drop_inode	= afs_drop_inode,
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  59) 	.destroy_inode	= afs_destroy_inode,
51b9fe48c411b (Al Viro            2019-04-10 15:05:06 -0400  60) 	.free_inode	= afs_free_inode,
b57922d97fd6f (Al Viro            2010-06-07 14:34:48 -0400  61) 	.evict_inode	= afs_evict_inode,
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100  62) 	.show_devname	= afs_show_devname,
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100  63) 	.show_options	= afs_show_options,
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  64) };
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  65) 
e18b890bb0881 (Christoph Lameter  2006-12-06 20:33:20 -0800  66) static struct kmem_cache *afs_inode_cachep;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  67) static atomic_t afs_count_active_inodes;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  68) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000  69) enum afs_param {
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000  70) 	Opt_autocell,
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000  71) 	Opt_dyn,
6c6c1d63c2430 (David Howells      2019-04-25 14:26:52 +0100  72) 	Opt_flock,
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000  73) 	Opt_source,
80c72fe415698 (David Howells      2007-05-03 03:11:29 -0700  74) };
80c72fe415698 (David Howells      2007-05-03 03:11:29 -0700  75) 
5eede625297f4 (Al Viro            2019-12-16 13:33:32 -0500  76) static const struct constant_table afs_param_flock[] = {
2710c957a8ef4 (Al Viro            2019-09-06 22:12:08 -0400  77) 	{"local",	afs_flock_mode_local },
2710c957a8ef4 (Al Viro            2019-09-06 22:12:08 -0400  78) 	{"openafs",	afs_flock_mode_openafs },
2710c957a8ef4 (Al Viro            2019-09-06 22:12:08 -0400  79) 	{"strict",	afs_flock_mode_strict },
2710c957a8ef4 (Al Viro            2019-09-06 22:12:08 -0400  80) 	{"write",	afs_flock_mode_write },
2710c957a8ef4 (Al Viro            2019-09-06 22:12:08 -0400  81) 	{}
2710c957a8ef4 (Al Viro            2019-09-06 22:12:08 -0400  82) };
2710c957a8ef4 (Al Viro            2019-09-06 22:12:08 -0400  83) 
d7167b149943e (Al Viro            2019-09-07 07:23:15 -0400  84) static const struct fs_parameter_spec afs_fs_parameters[] = {
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000  85) 	fsparam_flag  ("autocell",	Opt_autocell),
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000  86) 	fsparam_flag  ("dyn",		Opt_dyn),
2710c957a8ef4 (Al Viro            2019-09-06 22:12:08 -0400  87) 	fsparam_enum  ("flock",		Opt_flock, afs_param_flock),
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000  88) 	fsparam_string("source",	Opt_source),
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000  89) 	{}
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000  90) };
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000  91) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  92) /*
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  93)  * initialise the filesystem
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  94)  */
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  95) int __init afs_fs_init(void)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  96) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  97) 	int ret;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  98) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  99) 	_enter("");
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 100) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 101) 	/* create ourselves an inode cache */
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 102) 	atomic_set(&afs_count_active_inodes, 0);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 103) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 104) 	ret = -ENOMEM;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 105) 	afs_inode_cachep = kmem_cache_create("afs_inode_cache",
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 106) 					     sizeof(struct afs_vnode),
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 107) 					     0,
5d097056c9a01 (Vladimir Davydov   2016-01-14 15:18:21 -0800 108) 					     SLAB_HWCACHE_ALIGN|SLAB_ACCOUNT,
20c2df83d25c6 (Paul Mundt         2007-07-20 10:11:58 +0900 109) 					     afs_i_init_once);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 110) 	if (!afs_inode_cachep) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 111) 		printk(KERN_NOTICE "kAFS: Failed to allocate inode cache\n");
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 112) 		return ret;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 113) 	}
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 114) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 115) 	/* now export our filesystem to lesser mortals */
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 116) 	ret = register_filesystem(&afs_fs_type);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 117) 	if (ret < 0) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 118) 		kmem_cache_destroy(afs_inode_cachep);
08e0e7c82eead (David Howells      2007-04-26 15:55:03 -0700 119) 		_leave(" = %d", ret);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 120) 		return ret;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 121) 	}
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 122) 
08e0e7c82eead (David Howells      2007-04-26 15:55:03 -0700 123) 	_leave(" = 0");
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 124) 	return 0;
ec26815ad847d (David Howells      2007-04-26 15:49:28 -0700 125) }
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 126) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 127) /*
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 128)  * clean up the filesystem
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 129)  */
5b86d4ff5dce3 (David Howells      2018-05-18 11:46:15 +0100 130) void afs_fs_exit(void)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 131) {
08e0e7c82eead (David Howells      2007-04-26 15:55:03 -0700 132) 	_enter("");
08e0e7c82eead (David Howells      2007-04-26 15:55:03 -0700 133) 
08e0e7c82eead (David Howells      2007-04-26 15:55:03 -0700 134) 	afs_mntpt_kill_timer();
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 135) 	unregister_filesystem(&afs_fs_type);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 136) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 137) 	if (atomic_read(&afs_count_active_inodes) != 0) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 138) 		printk("kAFS: %d active inode objects still present\n",
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 139) 		       atomic_read(&afs_count_active_inodes));
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 140) 		BUG();
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 141) 	}
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 142) 
8c0a85377048b (Kirill A. Shutemov 2012-09-26 11:33:07 +1000 143) 	/*
8c0a85377048b (Kirill A. Shutemov 2012-09-26 11:33:07 +1000 144) 	 * Make sure all delayed rcu free inodes are flushed before we
8c0a85377048b (Kirill A. Shutemov 2012-09-26 11:33:07 +1000 145) 	 * destroy cache.
8c0a85377048b (Kirill A. Shutemov 2012-09-26 11:33:07 +1000 146) 	 */
8c0a85377048b (Kirill A. Shutemov 2012-09-26 11:33:07 +1000 147) 	rcu_barrier();
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 148) 	kmem_cache_destroy(afs_inode_cachep);
08e0e7c82eead (David Howells      2007-04-26 15:55:03 -0700 149) 	_leave("");
ec26815ad847d (David Howells      2007-04-26 15:49:28 -0700 150) }
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 151) 
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 152) /*
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 153)  * Display the mount device name in /proc/mounts.
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 154)  */
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 155) static int afs_show_devname(struct seq_file *m, struct dentry *root)
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 156) {
d2ddc776a4581 (David Howells      2017-11-02 15:27:50 +0000 157) 	struct afs_super_info *as = AFS_FS_S(root->d_sb);
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 158) 	struct afs_volume *volume = as->volume;
d2ddc776a4581 (David Howells      2017-11-02 15:27:50 +0000 159) 	struct afs_cell *cell = as->cell;
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 160) 	const char *suf = "";
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 161) 	char pref = '%';
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 162) 
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 163) 	if (as->dyn_root) {
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 164) 		seq_puts(m, "none");
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 165) 		return 0;
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 166) 	}
66c7e1d319a5b (David Howells      2018-04-06 14:17:25 +0100 167) 
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 168) 	switch (volume->type) {
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 169) 	case AFSVL_RWVOL:
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 170) 		break;
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 171) 	case AFSVL_ROVOL:
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 172) 		pref = '#';
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 173) 		if (volume->type_force)
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 174) 			suf = ".readonly";
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 175) 		break;
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 176) 	case AFSVL_BACKVOL:
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 177) 		pref = '#';
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 178) 		suf = ".backup";
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 179) 		break;
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 180) 	}
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 181) 
d2ddc776a4581 (David Howells      2017-11-02 15:27:50 +0000 182) 	seq_printf(m, "%c%s:%s%s", pref, cell->name, volume->name, suf);
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 183) 	return 0;
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 184) }
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 185) 
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 186) /*
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 187)  * Display the mount options in /proc/mounts.
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 188)  */
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 189) static int afs_show_options(struct seq_file *m, struct dentry *root)
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 190) {
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 191) 	struct afs_super_info *as = AFS_FS_S(root->d_sb);
6c6c1d63c2430 (David Howells      2019-04-25 14:26:52 +0100 192) 	const char *p = NULL;
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 193) 
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 194) 	if (as->dyn_root)
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 195) 		seq_puts(m, ",dyn");
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 196) 	if (test_bit(AFS_VNODE_AUTOCELL, &AFS_FS_I(d_inode(root))->flags))
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 197) 		seq_puts(m, ",autocell");
6c6c1d63c2430 (David Howells      2019-04-25 14:26:52 +0100 198) 	switch (as->flock_mode) {
6c6c1d63c2430 (David Howells      2019-04-25 14:26:52 +0100 199) 	case afs_flock_mode_unset:	break;
6c6c1d63c2430 (David Howells      2019-04-25 14:26:52 +0100 200) 	case afs_flock_mode_local:	p = "local";	break;
6c6c1d63c2430 (David Howells      2019-04-25 14:26:52 +0100 201) 	case afs_flock_mode_openafs:	p = "openafs";	break;
6c6c1d63c2430 (David Howells      2019-04-25 14:26:52 +0100 202) 	case afs_flock_mode_strict:	p = "strict";	break;
6c6c1d63c2430 (David Howells      2019-04-25 14:26:52 +0100 203) 	case afs_flock_mode_write:	p = "write";	break;
6c6c1d63c2430 (David Howells      2019-04-25 14:26:52 +0100 204) 	}
6c6c1d63c2430 (David Howells      2019-04-25 14:26:52 +0100 205) 	if (p)
6c6c1d63c2430 (David Howells      2019-04-25 14:26:52 +0100 206) 		seq_printf(m, ",flock=%s", p);
6c6c1d63c2430 (David Howells      2019-04-25 14:26:52 +0100 207) 
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 208) 	return 0;
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 209) }
677018a6ce620 (David Howells      2017-07-05 16:25:23 +0100 210) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 211) /*
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 212)  * Parse the source name to get cell name, volume name, volume type and R/W
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 213)  * selector.
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 214)  *
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 215)  * This can be one of the following:
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 216)  *	"%[cell:]volume[.]"		R/W volume
c99c2171fc614 (David Howells      2018-11-01 23:07:27 +0000 217)  *	"#[cell:]volume[.]"		R/O or R/W volume (R/O parent),
c99c2171fc614 (David Howells      2018-11-01 23:07:27 +0000 218)  *					 or R/W (R/W parent) volume
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 219)  *	"%[cell:]volume.readonly"	R/O volume
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 220)  *	"#[cell:]volume.readonly"	R/O volume
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 221)  *	"%[cell:]volume.backup"		Backup volume
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 222)  *	"#[cell:]volume.backup"		Backup volume
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 223)  */
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 224) static int afs_parse_source(struct fs_context *fc, struct fs_parameter *param)
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 225) {
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 226) 	struct afs_fs_context *ctx = fc->fs_private;
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 227) 	struct afs_cell *cell;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 228) 	const char *cellname, *suffix, *name = param->string;
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 229) 	int cellnamesz;
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 230) 
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 231) 	_enter(",%s", name);
66c7e1d319a5b (David Howells      2018-04-06 14:17:25 +0100 232) 
4cb682964706d (David Howells      2020-12-08 23:52:03 +0000 233) 	if (fc->source)
4cb682964706d (David Howells      2020-12-08 23:52:03 +0000 234) 		return invalf(fc, "kAFS: Multiple sources not supported");
4cb682964706d (David Howells      2020-12-08 23:52:03 +0000 235) 
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 236) 	if (!name) {
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 237) 		printk(KERN_ERR "kAFS: no volume name specified\n");
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 238) 		return -EINVAL;
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 239) 	}
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 240) 
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 241) 	if ((name[0] != '%' && name[0] != '#') || !name[1]) {
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 242) 		/* To use dynroot, we don't want to have to provide a source */
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 243) 		if (strcmp(name, "none") == 0) {
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 244) 			ctx->no_cell = true;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 245) 			return 0;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 246) 		}
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 247) 		printk(KERN_ERR "kAFS: unparsable volume name\n");
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 248) 		return -EINVAL;
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 249) 	}
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 250) 
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 251) 	/* determine the type of volume we're looking for */
c99c2171fc614 (David Howells      2018-11-01 23:07:27 +0000 252) 	if (name[0] == '%') {
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 253) 		ctx->type = AFSVL_RWVOL;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 254) 		ctx->force = true;
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 255) 	}
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 256) 	name++;
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 257) 
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 258) 	/* split the cell name out if there is one */
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 259) 	ctx->volname = strchr(name, ':');
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 260) 	if (ctx->volname) {
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 261) 		cellname = name;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 262) 		cellnamesz = ctx->volname - name;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 263) 		ctx->volname++;
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 264) 	} else {
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 265) 		ctx->volname = name;
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 266) 		cellname = NULL;
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 267) 		cellnamesz = 0;
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 268) 	}
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 269) 
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 270) 	/* the volume type is further affected by a possible suffix */
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 271) 	suffix = strrchr(ctx->volname, '.');
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 272) 	if (suffix) {
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 273) 		if (strcmp(suffix, ".readonly") == 0) {
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 274) 			ctx->type = AFSVL_ROVOL;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 275) 			ctx->force = true;
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 276) 		} else if (strcmp(suffix, ".backup") == 0) {
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 277) 			ctx->type = AFSVL_BACKVOL;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 278) 			ctx->force = true;
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 279) 		} else if (suffix[1] == 0) {
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 280) 		} else {
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 281) 			suffix = NULL;
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 282) 		}
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 283) 	}
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 284) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 285) 	ctx->volnamesz = suffix ?
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 286) 		suffix - ctx->volname : strlen(ctx->volname);
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 287) 
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 288) 	_debug("cell %*.*s [%p]",
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 289) 	       cellnamesz, cellnamesz, cellname ?: "", ctx->cell);
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 290) 
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 291) 	/* lookup the cell record */
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 292) 	if (cellname) {
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 293) 		cell = afs_lookup_cell(ctx->net, cellname, cellnamesz,
989782dcdc91a (David Howells      2017-11-02 15:27:50 +0000 294) 				       NULL, false);
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 295) 		if (IS_ERR(cell)) {
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 296) 			pr_err("kAFS: unable to lookup cell '%*.*s'\n",
bec5eb6141308 (wanglei            2010-08-11 09:38:04 +0100 297) 			       cellnamesz, cellnamesz, cellname ?: "");
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 298) 			return PTR_ERR(cell);
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 299) 		}
dca54a7bbb8ca (David Howells      2020-10-13 20:51:59 +0100 300) 		afs_unuse_cell(ctx->net, ctx->cell, afs_cell_trace_unuse_parse);
dca54a7bbb8ca (David Howells      2020-10-13 20:51:59 +0100 301) 		afs_see_cell(cell, afs_cell_trace_see_source);
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 302) 		ctx->cell = cell;
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 303) 	}
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 304) 
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 305) 	_debug("CELL:%s [%p] VOLUME:%*.*s SUFFIX:%s TYPE:%d%s",
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 306) 	       ctx->cell->name, ctx->cell,
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 307) 	       ctx->volnamesz, ctx->volnamesz, ctx->volname,
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 308) 	       suffix ?: "-", ctx->type, ctx->force ? " FORCE" : "");
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 309) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 310) 	fc->source = param->string;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 311) 	param->string = NULL;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 312) 	return 0;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 313) }
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 314) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 315) /*
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 316)  * Parse a single mount parameter.
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 317)  */
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 318) static int afs_parse_param(struct fs_context *fc, struct fs_parameter *param)
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 319) {
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 320) 	struct fs_parse_result result;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 321) 	struct afs_fs_context *ctx = fc->fs_private;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 322) 	int opt;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 323) 
d7167b149943e (Al Viro            2019-09-07 07:23:15 -0400 324) 	opt = fs_parse(fc, afs_fs_parameters, param, &result);
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 325) 	if (opt < 0)
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 326) 		return opt;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 327) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 328) 	switch (opt) {
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 329) 	case Opt_source:
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 330) 		return afs_parse_source(fc, param);
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 331) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 332) 	case Opt_autocell:
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 333) 		ctx->autocell = true;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 334) 		break;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 335) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 336) 	case Opt_dyn:
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 337) 		ctx->dyn_root = true;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 338) 		break;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 339) 
6c6c1d63c2430 (David Howells      2019-04-25 14:26:52 +0100 340) 	case Opt_flock:
6c6c1d63c2430 (David Howells      2019-04-25 14:26:52 +0100 341) 		ctx->flock_mode = result.uint_32;
6c6c1d63c2430 (David Howells      2019-04-25 14:26:52 +0100 342) 		break;
6c6c1d63c2430 (David Howells      2019-04-25 14:26:52 +0100 343) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 344) 	default:
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 345) 		return -EINVAL;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 346) 	}
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 347) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 348) 	_leave(" = 0");
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 349) 	return 0;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 350) }
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 351) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 352) /*
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 353)  * Validate the options, get the cell key and look up the volume.
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 354)  */
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 355) static int afs_validate_fc(struct fs_context *fc)
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 356) {
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 357) 	struct afs_fs_context *ctx = fc->fs_private;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 358) 	struct afs_volume *volume;
8a070a964877c (David Howells      2020-04-25 10:26:02 +0100 359) 	struct afs_cell *cell;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 360) 	struct key *key;
8a070a964877c (David Howells      2020-04-25 10:26:02 +0100 361) 	int ret;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 362) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 363) 	if (!ctx->dyn_root) {
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 364) 		if (ctx->no_cell) {
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 365) 			pr_warn("kAFS: Can only specify source 'none' with -o dyn\n");
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 366) 			return -EINVAL;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 367) 		}
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 368) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 369) 		if (!ctx->cell) {
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 370) 			pr_warn("kAFS: No cell specified\n");
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 371) 			return -EDESTADDRREQ;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 372) 		}
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 373) 
8a070a964877c (David Howells      2020-04-25 10:26:02 +0100 374) 	reget_key:
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 375) 		/* We try to do the mount securely. */
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 376) 		key = afs_request_key(ctx->cell);
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 377) 		if (IS_ERR(key))
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 378) 			return PTR_ERR(key);
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 379) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 380) 		ctx->key = key;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 381) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 382) 		if (ctx->volume) {
cca37d45d5474 (David Howells      2020-04-29 17:02:04 +0100 383) 			afs_put_volume(ctx->net, ctx->volume,
cca37d45d5474 (David Howells      2020-04-29 17:02:04 +0100 384) 				       afs_volume_trace_put_validate_fc);
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 385) 			ctx->volume = NULL;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 386) 		}
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 387) 
8a070a964877c (David Howells      2020-04-25 10:26:02 +0100 388) 		if (test_bit(AFS_CELL_FL_CHECK_ALIAS, &ctx->cell->flags)) {
8a070a964877c (David Howells      2020-04-25 10:26:02 +0100 389) 			ret = afs_cell_detect_alias(ctx->cell, key);
8a070a964877c (David Howells      2020-04-25 10:26:02 +0100 390) 			if (ret < 0)
8a070a964877c (David Howells      2020-04-25 10:26:02 +0100 391) 				return ret;
8a070a964877c (David Howells      2020-04-25 10:26:02 +0100 392) 			if (ret == 1) {
8a070a964877c (David Howells      2020-04-25 10:26:02 +0100 393) 				_debug("switch to alias");
8a070a964877c (David Howells      2020-04-25 10:26:02 +0100 394) 				key_put(ctx->key);
8a070a964877c (David Howells      2020-04-25 10:26:02 +0100 395) 				ctx->key = NULL;
dca54a7bbb8ca (David Howells      2020-10-13 20:51:59 +0100 396) 				cell = afs_use_cell(ctx->cell->alias_of,
dca54a7bbb8ca (David Howells      2020-10-13 20:51:59 +0100 397) 						    afs_cell_trace_use_fc_alias);
dca54a7bbb8ca (David Howells      2020-10-13 20:51:59 +0100 398) 				afs_unuse_cell(ctx->net, ctx->cell, afs_cell_trace_unuse_fc);
8a070a964877c (David Howells      2020-04-25 10:26:02 +0100 399) 				ctx->cell = cell;
8a070a964877c (David Howells      2020-04-25 10:26:02 +0100 400) 				goto reget_key;
8a070a964877c (David Howells      2020-04-25 10:26:02 +0100 401) 			}
8a070a964877c (David Howells      2020-04-25 10:26:02 +0100 402) 		}
8a070a964877c (David Howells      2020-04-25 10:26:02 +0100 403) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 404) 		volume = afs_create_volume(ctx);
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 405) 		if (IS_ERR(volume))
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 406) 			return PTR_ERR(volume);
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 407) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 408) 		ctx->volume = volume;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 409) 	}
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 410) 
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 411) 	return 0;
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 412) }
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 413) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 414) /*
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 415)  * check a superblock to see if it's the one we're looking for
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 416)  */
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 417) static int afs_test_super(struct super_block *sb, struct fs_context *fc)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 418) {
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 419) 	struct afs_fs_context *ctx = fc->fs_private;
d2ddc776a4581 (David Howells      2017-11-02 15:27:50 +0000 420) 	struct afs_super_info *as = AFS_FS_S(sb);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 421) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 422) 	return (as->net_ns == fc->net_ns &&
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 423) 		as->volume &&
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 424) 		as->volume->vid == ctx->volume->vid &&
106bc79843c3c (David Howells      2019-12-11 08:06:08 +0000 425) 		as->cell == ctx->cell &&
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 426) 		!as->dyn_root);
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 427) }
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 428) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 429) static int afs_dynroot_test_super(struct super_block *sb, struct fs_context *fc)
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 430) {
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 431) 	struct afs_super_info *as = AFS_FS_S(sb);
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 432) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 433) 	return (as->net_ns == fc->net_ns &&
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 434) 		as->dyn_root);
dde194a64bb5c (Al Viro            2011-06-12 16:01:21 -0400 435) }
dde194a64bb5c (Al Viro            2011-06-12 16:01:21 -0400 436) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 437) static int afs_set_super(struct super_block *sb, struct fs_context *fc)
dde194a64bb5c (Al Viro            2011-06-12 16:01:21 -0400 438) {
dde194a64bb5c (Al Viro            2011-06-12 16:01:21 -0400 439) 	return set_anon_super(sb, NULL);
ec26815ad847d (David Howells      2007-04-26 15:49:28 -0700 440) }
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 441) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 442) /*
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 443)  * fill in the superblock
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 444)  */
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 445) static int afs_fill_super(struct super_block *sb, struct afs_fs_context *ctx)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 446) {
d2ddc776a4581 (David Howells      2017-11-02 15:27:50 +0000 447) 	struct afs_super_info *as = AFS_FS_S(sb);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 448) 	struct inode *inode = NULL;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 449) 	int ret;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 450) 
08e0e7c82eead (David Howells      2007-04-26 15:55:03 -0700 451) 	_enter("");
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 452) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 453) 	/* fill in the superblock */
09cbfeaf1a5a6 (Kirill A. Shutemov 2016-04-01 15:29:47 +0300 454) 	sb->s_blocksize		= PAGE_SIZE;
09cbfeaf1a5a6 (Kirill A. Shutemov 2016-04-01 15:29:47 +0300 455) 	sb->s_blocksize_bits	= PAGE_SHIFT;
b485275f1aca8 (Marc Dionne        2019-11-21 15:37:26 +0000 456) 	sb->s_maxbytes		= MAX_LFS_FILESIZE;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 457) 	sb->s_magic		= AFS_FS_MAGIC;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 458) 	sb->s_op		= &afs_super_ops;
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 459) 	if (!as->dyn_root)
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 460) 		sb->s_xattr	= afs_xattr_handlers;
edd3ba94c4e5e (Jan Kara           2017-04-12 12:24:36 +0200 461) 	ret = super_setup_bdi(sb);
edd3ba94c4e5e (Jan Kara           2017-04-12 12:24:36 +0200 462) 	if (ret)
edd3ba94c4e5e (Jan Kara           2017-04-12 12:24:36 +0200 463) 		return ret;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 464) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 465) 	/* allocate the root inode and dentry */
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 466) 	if (as->dyn_root) {
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 467) 		inode = afs_iget_pseudo_dir(sb, true);
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 468) 	} else {
3b6492df4153b (David Howells      2018-10-20 00:57:57 +0100 469) 		sprintf(sb->s_id, "%llu", as->volume->vid);
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 470) 		afs_activate_volume(as->volume);
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 471) 		inode = afs_root_iget(sb, ctx->key);
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 472) 	}
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 473) 
08e0e7c82eead (David Howells      2007-04-26 15:55:03 -0700 474) 	if (IS_ERR(inode))
dde194a64bb5c (Al Viro            2011-06-12 16:01:21 -0400 475) 		return PTR_ERR(inode);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 476) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 477) 	if (ctx->autocell || as->dyn_root)
bec5eb6141308 (wanglei            2010-08-11 09:38:04 +0100 478) 		set_bit(AFS_VNODE_AUTOCELL, &AFS_FS_I(inode)->flags);
bec5eb6141308 (wanglei            2010-08-11 09:38:04 +0100 479) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 480) 	ret = -ENOMEM;
48fde701aff66 (Al Viro            2012-01-08 22:15:13 -0500 481) 	sb->s_root = d_make_root(inode);
48fde701aff66 (Al Viro            2012-01-08 22:15:13 -0500 482) 	if (!sb->s_root)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 483) 		goto error;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 484) 
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 485) 	if (as->dyn_root) {
66c7e1d319a5b (David Howells      2018-04-06 14:17:25 +0100 486) 		sb->s_d_op = &afs_dynroot_dentry_operations;
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 487) 		ret = afs_dynroot_populate(sb);
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 488) 		if (ret < 0)
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 489) 			goto error;
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 490) 	} else {
66c7e1d319a5b (David Howells      2018-04-06 14:17:25 +0100 491) 		sb->s_d_op = &afs_fs_dentry_operations;
20325960f8750 (David Howells      2020-04-30 01:03:49 +0100 492) 		rcu_assign_pointer(as->volume->sb, sb);
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 493) 	}
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 494) 
08e0e7c82eead (David Howells      2007-04-26 15:55:03 -0700 495) 	_leave(" = 0");
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 496) 	return 0;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 497) 
ec26815ad847d (David Howells      2007-04-26 15:49:28 -0700 498) error:
08e0e7c82eead (David Howells      2007-04-26 15:55:03 -0700 499) 	_leave(" = %d", ret);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 500) 	return ret;
ec26815ad847d (David Howells      2007-04-26 15:49:28 -0700 501) }
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 502) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 503) static struct afs_super_info *afs_alloc_sbi(struct fs_context *fc)
49566f6f06b38 (David Howells      2017-11-02 15:27:46 +0000 504) {
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 505) 	struct afs_fs_context *ctx = fc->fs_private;
49566f6f06b38 (David Howells      2017-11-02 15:27:46 +0000 506) 	struct afs_super_info *as;
49566f6f06b38 (David Howells      2017-11-02 15:27:46 +0000 507) 
49566f6f06b38 (David Howells      2017-11-02 15:27:46 +0000 508) 	as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL);
49566f6f06b38 (David Howells      2017-11-02 15:27:46 +0000 509) 	if (as) {
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 510) 		as->net_ns = get_net(fc->net_ns);
6c6c1d63c2430 (David Howells      2019-04-25 14:26:52 +0100 511) 		as->flock_mode = ctx->flock_mode;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 512) 		if (ctx->dyn_root) {
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 513) 			as->dyn_root = true;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 514) 		} else {
dca54a7bbb8ca (David Howells      2020-10-13 20:51:59 +0100 515) 			as->cell = afs_use_cell(ctx->cell, afs_cell_trace_use_sbi);
cca37d45d5474 (David Howells      2020-04-29 17:02:04 +0100 516) 			as->volume = afs_get_volume(ctx->volume,
cca37d45d5474 (David Howells      2020-04-29 17:02:04 +0100 517) 						    afs_volume_trace_get_alloc_sbi);
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 518) 		}
49566f6f06b38 (David Howells      2017-11-02 15:27:46 +0000 519) 	}
49566f6f06b38 (David Howells      2017-11-02 15:27:46 +0000 520) 	return as;
49566f6f06b38 (David Howells      2017-11-02 15:27:46 +0000 521) }
49566f6f06b38 (David Howells      2017-11-02 15:27:46 +0000 522) 
49566f6f06b38 (David Howells      2017-11-02 15:27:46 +0000 523) static void afs_destroy_sbi(struct afs_super_info *as)
49566f6f06b38 (David Howells      2017-11-02 15:27:46 +0000 524) {
49566f6f06b38 (David Howells      2017-11-02 15:27:46 +0000 525) 	if (as) {
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 526) 		struct afs_net *net = afs_net(as->net_ns);
cca37d45d5474 (David Howells      2020-04-29 17:02:04 +0100 527) 		afs_put_volume(net, as->volume, afs_volume_trace_put_destroy_sbi);
dca54a7bbb8ca (David Howells      2020-10-13 20:51:59 +0100 528) 		afs_unuse_cell(net, as->cell, afs_cell_trace_unuse_sbi);
5b86d4ff5dce3 (David Howells      2018-05-18 11:46:15 +0100 529) 		put_net(as->net_ns);
49566f6f06b38 (David Howells      2017-11-02 15:27:46 +0000 530) 		kfree(as);
49566f6f06b38 (David Howells      2017-11-02 15:27:46 +0000 531) 	}
49566f6f06b38 (David Howells      2017-11-02 15:27:46 +0000 532) }
49566f6f06b38 (David Howells      2017-11-02 15:27:46 +0000 533) 
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 534) static void afs_kill_super(struct super_block *sb)
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 535) {
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 536) 	struct afs_super_info *as = AFS_FS_S(sb);
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 537) 
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 538) 	if (as->dyn_root)
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 539) 		afs_dynroot_depopulate(sb);
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 540) 
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 541) 	/* Clear the callback interests (which will do ilookup5) before
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 542) 	 * deactivating the superblock.
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 543) 	 */
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 544) 	if (as->volume)
20325960f8750 (David Howells      2020-04-30 01:03:49 +0100 545) 		rcu_assign_pointer(as->volume->sb, NULL);
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 546) 	kill_anon_super(sb);
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 547) 	if (as->volume)
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 548) 		afs_deactivate_volume(as->volume);
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 549) 	afs_destroy_sbi(as);
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 550) }
0da0b7fd73e4f (David Howells      2018-06-15 15:19:22 +0100 551) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 552) /*
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 553)  * Get an AFS superblock and root directory.
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 554)  */
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 555) static int afs_get_tree(struct fs_context *fc)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 556) {
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 557) 	struct afs_fs_context *ctx = fc->fs_private;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 558) 	struct super_block *sb;
dde194a64bb5c (Al Viro            2011-06-12 16:01:21 -0400 559) 	struct afs_super_info *as;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 560) 	int ret;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 561) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 562) 	ret = afs_validate_fc(fc);
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 563) 	if (ret)
f74f70f8b10b4 (Eric W. Biederman  2013-01-31 04:23:54 -0800 564) 		goto error;
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 565) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 566) 	_enter("");
00d3b7a4533e3 (David Howells      2007-04-26 15:57:07 -0700 567) 
49566f6f06b38 (David Howells      2017-11-02 15:27:46 +0000 568) 	/* allocate a superblock info record */
49566f6f06b38 (David Howells      2017-11-02 15:27:46 +0000 569) 	ret = -ENOMEM;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 570) 	as = afs_alloc_sbi(fc);
49566f6f06b38 (David Howells      2017-11-02 15:27:46 +0000 571) 	if (!as)
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 572) 		goto error;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 573) 	fc->s_fs_info = as;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 574) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 575) 	/* allocate a deviceless superblock */
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 576) 	sb = sget_fc(fc,
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 577) 		     as->dyn_root ? afs_dynroot_test_super : afs_test_super,
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 578) 		     afs_set_super);
08e0e7c82eead (David Howells      2007-04-26 15:55:03 -0700 579) 	if (IS_ERR(sb)) {
08e0e7c82eead (David Howells      2007-04-26 15:55:03 -0700 580) 		ret = PTR_ERR(sb);
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 581) 		goto error;
08e0e7c82eead (David Howells      2007-04-26 15:55:03 -0700 582) 	}
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 583) 
436058a49e0fb (David Howells      2007-04-26 15:56:24 -0700 584) 	if (!sb->s_root) {
436058a49e0fb (David Howells      2007-04-26 15:56:24 -0700 585) 		/* initial superblock/root creation */
436058a49e0fb (David Howells      2007-04-26 15:56:24 -0700 586) 		_debug("create");
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 587) 		ret = afs_fill_super(sb, ctx);
f044c8847bb61 (David Howells      2017-11-02 15:27:45 +0000 588) 		if (ret < 0)
f044c8847bb61 (David Howells      2017-11-02 15:27:45 +0000 589) 			goto error_sb;
1751e8a6cb935 (Linus Torvalds     2017-11-27 13:05:09 -0800 590) 		sb->s_flags |= SB_ACTIVE;
436058a49e0fb (David Howells      2007-04-26 15:56:24 -0700 591) 	} else {
436058a49e0fb (David Howells      2007-04-26 15:56:24 -0700 592) 		_debug("reuse");
1751e8a6cb935 (Linus Torvalds     2017-11-27 13:05:09 -0800 593) 		ASSERTCMP(sb->s_flags, &, SB_ACTIVE);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 594) 	}
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 595) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 596) 	fc->root = dget(sb->s_root);
80548b03991f5 (David Howells      2019-04-25 14:26:51 +0100 597) 	trace_afs_get_tree(as->cell, as->volume);
08e0e7c82eead (David Howells      2007-04-26 15:55:03 -0700 598) 	_leave(" = 0 [%p]", sb);
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 599) 	return 0;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 600) 
f044c8847bb61 (David Howells      2017-11-02 15:27:45 +0000 601) error_sb:
f044c8847bb61 (David Howells      2017-11-02 15:27:45 +0000 602) 	deactivate_locked_super(sb);
ec26815ad847d (David Howells      2007-04-26 15:49:28 -0700 603) error:
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 604) 	_leave(" = %d", ret);
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 605) 	return ret;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 606) }
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 607) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 608) static void afs_free_fc(struct fs_context *fc)
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 609) {
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 610) 	struct afs_fs_context *ctx = fc->fs_private;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 611) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 612) 	afs_destroy_sbi(fc->s_fs_info);
cca37d45d5474 (David Howells      2020-04-29 17:02:04 +0100 613) 	afs_put_volume(ctx->net, ctx->volume, afs_volume_trace_put_free_fc);
dca54a7bbb8ca (David Howells      2020-10-13 20:51:59 +0100 614) 	afs_unuse_cell(ctx->net, ctx->cell, afs_cell_trace_unuse_fc);
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 615) 	key_put(ctx->key);
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 616) 	kfree(ctx);
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 617) }
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 618) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 619) static const struct fs_context_operations afs_context_ops = {
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 620) 	.free		= afs_free_fc,
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 621) 	.parse_param	= afs_parse_param,
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 622) 	.get_tree	= afs_get_tree,
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 623) };
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 624) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 625) /*
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 626)  * Set up the filesystem mount context.
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 627)  */
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 628) static int afs_init_fs_context(struct fs_context *fc)
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 629) {
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 630) 	struct afs_fs_context *ctx;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 631) 	struct afs_cell *cell;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 632) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 633) 	ctx = kzalloc(sizeof(struct afs_fs_context), GFP_KERNEL);
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 634) 	if (!ctx)
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 635) 		return -ENOMEM;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 636) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 637) 	ctx->type = AFSVL_ROVOL;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 638) 	ctx->net = afs_net(fc->net_ns);
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 639) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 640) 	/* Default to the workstation cell. */
dca54a7bbb8ca (David Howells      2020-10-13 20:51:59 +0100 641) 	cell = afs_find_cell(ctx->net, NULL, 0, afs_cell_trace_use_fc);
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 642) 	if (IS_ERR(cell))
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 643) 		cell = NULL;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 644) 	ctx->cell = cell;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 645) 
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 646) 	fc->fs_private = ctx;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 647) 	fc->ops = &afs_context_ops;
13fcc6837049f (David Howells      2018-11-01 23:07:27 +0000 648) 	return 0;
ec26815ad847d (David Howells      2007-04-26 15:49:28 -0700 649) }
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 650) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 651) /*
f8de483e7440b (David Howells      2017-12-01 11:40:43 +0000 652)  * Initialise an inode cache slab element prior to any use.  Note that
f8de483e7440b (David Howells      2017-12-01 11:40:43 +0000 653)  * afs_alloc_inode() *must* reset anything that could incorrectly leak from one
f8de483e7440b (David Howells      2017-12-01 11:40:43 +0000 654)  * inode to another.
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 655)  */
51cc50685a427 (Alexey Dobriyan    2008-07-25 19:45:34 -0700 656) static void afs_i_init_once(void *_vnode)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 657) {
ec26815ad847d (David Howells      2007-04-26 15:49:28 -0700 658) 	struct afs_vnode *vnode = _vnode;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 659) 
a35afb830f8d7 (Christoph Lameter  2007-05-16 22:10:57 -0700 660) 	memset(vnode, 0, sizeof(*vnode));
a35afb830f8d7 (Christoph Lameter  2007-05-16 22:10:57 -0700 661) 	inode_init_once(&vnode->vfs_inode);
d2ddc776a4581 (David Howells      2017-11-02 15:27:50 +0000 662) 	mutex_init(&vnode->io_lock);
b61f7dcf4eb26 (David Howells      2018-04-27 20:46:22 +0100 663) 	init_rwsem(&vnode->validate_lock);
4343d00872e1d (David Howells      2017-11-02 15:27:52 +0000 664) 	spin_lock_init(&vnode->wb_lock);
a35afb830f8d7 (Christoph Lameter  2007-05-16 22:10:57 -0700 665) 	spin_lock_init(&vnode->lock);
4343d00872e1d (David Howells      2017-11-02 15:27:52 +0000 666) 	INIT_LIST_HEAD(&vnode->wb_keys);
e8d6c554126b8 (David Howells      2007-07-15 23:40:12 -0700 667) 	INIT_LIST_HEAD(&vnode->pending_locks);
e8d6c554126b8 (David Howells      2007-07-15 23:40:12 -0700 668) 	INIT_LIST_HEAD(&vnode->granted_locks);
e8d6c554126b8 (David Howells      2007-07-15 23:40:12 -0700 669) 	INIT_DELAYED_WORK(&vnode->lock_work, afs_lock_work);
c435ee34551e1 (David Howells      2017-11-02 15:27:49 +0000 670) 	seqlock_init(&vnode->cb_lock);
ec26815ad847d (David Howells      2007-04-26 15:49:28 -0700 671) }
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 672) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 673) /*
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 674)  * allocate an AFS inode struct from our slab cache
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 675)  */
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 676) static struct inode *afs_alloc_inode(struct super_block *sb)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 677) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 678) 	struct afs_vnode *vnode;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 679) 
ec26815ad847d (David Howells      2007-04-26 15:49:28 -0700 680) 	vnode = kmem_cache_alloc(afs_inode_cachep, GFP_KERNEL);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 681) 	if (!vnode)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 682) 		return NULL;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 683) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 684) 	atomic_inc(&afs_count_active_inodes);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 685) 
f8de483e7440b (David Howells      2017-12-01 11:40:43 +0000 686) 	/* Reset anything that shouldn't leak from one inode to the next. */
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 687) 	memset(&vnode->fid, 0, sizeof(vnode->fid));
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 688) 	memset(&vnode->status, 0, sizeof(vnode->status));
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 689) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 690) 	vnode->volume		= NULL;
f8de483e7440b (David Howells      2017-12-01 11:40:43 +0000 691) 	vnode->lock_key		= NULL;
f8de483e7440b (David Howells      2017-12-01 11:40:43 +0000 692) 	vnode->permit_cache	= NULL;
f8de483e7440b (David Howells      2017-12-01 11:40:43 +0000 693) #ifdef CONFIG_AFS_FSCACHE
f8de483e7440b (David Howells      2017-12-01 11:40:43 +0000 694) 	vnode->cache		= NULL;
f8de483e7440b (David Howells      2017-12-01 11:40:43 +0000 695) #endif
f8de483e7440b (David Howells      2017-12-01 11:40:43 +0000 696) 
260a980317dac (David Howells      2007-04-26 15:59:35 -0700 697) 	vnode->flags		= 1 << AFS_VNODE_UNSET;
f8de483e7440b (David Howells      2017-12-01 11:40:43 +0000 698) 	vnode->lock_state	= AFS_VNODE_LOCK_NONE;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 699) 
79ddbfa500b37 (David Howells      2019-04-25 14:26:51 +0100 700) 	init_rwsem(&vnode->rmdir_lock);
79ddbfa500b37 (David Howells      2019-04-25 14:26:51 +0100 701) 
0f300ca9284ca (David Howells      2007-05-10 22:22:20 -0700 702) 	_leave(" = %p", &vnode->vfs_inode);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 703) 	return &vnode->vfs_inode;
ec26815ad847d (David Howells      2007-04-26 15:49:28 -0700 704) }
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 705) 
51b9fe48c411b (Al Viro            2019-04-10 15:05:06 -0400 706) static void afs_free_inode(struct inode *inode)
fa0d7e3de6d6f (Nicholas Piggin    2011-01-07 17:49:49 +1100 707) {
51b9fe48c411b (Al Viro            2019-04-10 15:05:06 -0400 708) 	kmem_cache_free(afs_inode_cachep, AFS_FS_I(inode));
fa0d7e3de6d6f (Nicholas Piggin    2011-01-07 17:49:49 +1100 709) }
fa0d7e3de6d6f (Nicholas Piggin    2011-01-07 17:49:49 +1100 710) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 711) /*
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 712)  * destroy an AFS inode struct
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 713)  */
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 714) static void afs_destroy_inode(struct inode *inode)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 715) {
08e0e7c82eead (David Howells      2007-04-26 15:55:03 -0700 716) 	struct afs_vnode *vnode = AFS_FS_I(inode);
08e0e7c82eead (David Howells      2007-04-26 15:55:03 -0700 717) 
3b6492df4153b (David Howells      2018-10-20 00:57:57 +0100 718) 	_enter("%p{%llx:%llu}", inode, vnode->fid.vid, vnode->fid.vnode);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 719) 
08e0e7c82eead (David Howells      2007-04-26 15:55:03 -0700 720) 	_debug("DESTROY INODE %p", inode);
08e0e7c82eead (David Howells      2007-04-26 15:55:03 -0700 721) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 722) 	atomic_dec(&afs_count_active_inodes);
ec26815ad847d (David Howells      2007-04-26 15:49:28 -0700 723) }
45222b9e02fb2 (David Howells      2007-05-10 22:22:20 -0700 724) 
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 725) static void afs_get_volume_status_success(struct afs_operation *op)
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 726) {
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 727) 	struct afs_volume_status *vs = &op->volstatus.vs;
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 728) 	struct kstatfs *buf = op->volstatus.buf;
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 729) 
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 730) 	if (vs->max_quota == 0)
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 731) 		buf->f_blocks = vs->part_max_blocks;
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 732) 	else
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 733) 		buf->f_blocks = vs->max_quota;
f11a016a852f3 (David Howells      2020-05-01 22:06:02 +0100 734) 
f11a016a852f3 (David Howells      2020-05-01 22:06:02 +0100 735) 	if (buf->f_blocks > vs->blocks_in_use)
f11a016a852f3 (David Howells      2020-05-01 22:06:02 +0100 736) 		buf->f_bavail = buf->f_bfree =
f11a016a852f3 (David Howells      2020-05-01 22:06:02 +0100 737) 			buf->f_blocks - vs->blocks_in_use;
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 738) }
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 739) 
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 740) static const struct afs_operation_ops afs_get_volume_status_operation = {
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 741) 	.issue_afs_rpc	= afs_fs_get_volume_status,
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 742) 	.issue_yfs_rpc	= yfs_fs_get_volume_status,
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 743) 	.success	= afs_get_volume_status_success,
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 744) };
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 745) 
45222b9e02fb2 (David Howells      2007-05-10 22:22:20 -0700 746) /*
45222b9e02fb2 (David Howells      2007-05-10 22:22:20 -0700 747)  * return information about an AFS volume
45222b9e02fb2 (David Howells      2007-05-10 22:22:20 -0700 748)  */
45222b9e02fb2 (David Howells      2007-05-10 22:22:20 -0700 749) static int afs_statfs(struct dentry *dentry, struct kstatfs *buf)
45222b9e02fb2 (David Howells      2007-05-10 22:22:20 -0700 750) {
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 751) 	struct afs_super_info *as = AFS_FS_S(dentry->d_sb);
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 752) 	struct afs_operation *op;
2b0143b5c986b (David Howells      2015-03-17 22:25:59 +0000 753) 	struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry));
45222b9e02fb2 (David Howells      2007-05-10 22:22:20 -0700 754) 
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 755) 	buf->f_type	= dentry->d_sb->s_magic;
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 756) 	buf->f_bsize	= AFS_BLOCK_SIZE;
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 757) 	buf->f_namelen	= AFSNAMEMAX - 1;
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 758) 
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 759) 	if (as->dyn_root) {
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 760) 		buf->f_blocks	= 1;
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 761) 		buf->f_bavail	= 0;
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 762) 		buf->f_bfree	= 0;
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 763) 		return 0;
4d673da14533b (David Howells      2018-02-06 06:26:30 +0000 764) 	}
66c7e1d319a5b (David Howells      2018-04-06 14:17:25 +0100 765) 
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 766) 	op = afs_alloc_operation(NULL, as->volume);
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 767) 	if (IS_ERR(op))
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 768) 		return PTR_ERR(op);
45222b9e02fb2 (David Howells      2007-05-10 22:22:20 -0700 769) 
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 770) 	afs_op_set_vnode(op, 0, vnode);
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 771) 	op->nr_files		= 1;
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 772) 	op->volstatus.buf	= buf;
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 773) 	op->ops			= &afs_get_volume_status_operation;
e49c7b2f6de7f (David Howells      2020-04-10 20:51:51 +0100 774) 	return afs_do_sync_operation(op);
45222b9e02fb2 (David Howells      2007-05-10 22:22:20 -0700 775) }