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