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