cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

main.c (6154B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/* AFS client file system
      3 *
      4 * Copyright (C) 2002,5 Red Hat, Inc. All Rights Reserved.
      5 * Written by David Howells (dhowells@redhat.com)
      6 */
      7
      8#include <linux/module.h>
      9#include <linux/moduleparam.h>
     10#include <linux/init.h>
     11#include <linux/completion.h>
     12#include <linux/sched.h>
     13#include <linux/random.h>
     14#include <linux/proc_fs.h>
     15#define CREATE_TRACE_POINTS
     16#include "internal.h"
     17
     18MODULE_DESCRIPTION("AFS Client File System");
     19MODULE_AUTHOR("Red Hat, Inc.");
     20MODULE_LICENSE("GPL");
     21
     22unsigned afs_debug;
     23module_param_named(debug, afs_debug, uint, S_IWUSR | S_IRUGO);
     24MODULE_PARM_DESC(debug, "AFS debugging mask");
     25
     26static char *rootcell;
     27
     28module_param(rootcell, charp, 0);
     29MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list");
     30
     31struct workqueue_struct *afs_wq;
     32static struct proc_dir_entry *afs_proc_symlink;
     33
     34#if defined(CONFIG_ALPHA)
     35const char afs_init_sysname[] = "alpha_linux26";
     36#elif defined(CONFIG_X86_64)
     37const char afs_init_sysname[] = "amd64_linux26";
     38#elif defined(CONFIG_ARM)
     39const char afs_init_sysname[] = "arm_linux26";
     40#elif defined(CONFIG_ARM64)
     41const char afs_init_sysname[] = "aarch64_linux26";
     42#elif defined(CONFIG_X86_32)
     43const char afs_init_sysname[] = "i386_linux26";
     44#elif defined(CONFIG_IA64)
     45const char afs_init_sysname[] = "ia64_linux26";
     46#elif defined(CONFIG_PPC64)
     47const char afs_init_sysname[] = "ppc64_linux26";
     48#elif defined(CONFIG_PPC32)
     49const char afs_init_sysname[] = "ppc_linux26";
     50#elif defined(CONFIG_S390)
     51#ifdef CONFIG_64BIT
     52const char afs_init_sysname[] = "s390x_linux26";
     53#else
     54const char afs_init_sysname[] = "s390_linux26";
     55#endif
     56#elif defined(CONFIG_SPARC64)
     57const char afs_init_sysname[] = "sparc64_linux26";
     58#elif defined(CONFIG_SPARC32)
     59const char afs_init_sysname[] = "sparc_linux26";
     60#else
     61const char afs_init_sysname[] = "unknown_linux26";
     62#endif
     63
     64/*
     65 * Initialise an AFS network namespace record.
     66 */
     67static int __net_init afs_net_init(struct net *net_ns)
     68{
     69	struct afs_sysnames *sysnames;
     70	struct afs_net *net = afs_net(net_ns);
     71	int ret;
     72
     73	net->net = net_ns;
     74	net->live = true;
     75	generate_random_uuid((unsigned char *)&net->uuid);
     76
     77	INIT_WORK(&net->charge_preallocation_work, afs_charge_preallocation);
     78	mutex_init(&net->socket_mutex);
     79
     80	net->cells = RB_ROOT;
     81	init_rwsem(&net->cells_lock);
     82	INIT_WORK(&net->cells_manager, afs_manage_cells);
     83	timer_setup(&net->cells_timer, afs_cells_timer, 0);
     84
     85	mutex_init(&net->cells_alias_lock);
     86	mutex_init(&net->proc_cells_lock);
     87	INIT_HLIST_HEAD(&net->proc_cells);
     88
     89	seqlock_init(&net->fs_lock);
     90	net->fs_servers = RB_ROOT;
     91	INIT_LIST_HEAD(&net->fs_probe_fast);
     92	INIT_LIST_HEAD(&net->fs_probe_slow);
     93	INIT_HLIST_HEAD(&net->fs_proc);
     94
     95	INIT_HLIST_HEAD(&net->fs_addresses4);
     96	INIT_HLIST_HEAD(&net->fs_addresses6);
     97	seqlock_init(&net->fs_addr_lock);
     98
     99	INIT_WORK(&net->fs_manager, afs_manage_servers);
    100	timer_setup(&net->fs_timer, afs_servers_timer, 0);
    101	INIT_WORK(&net->fs_prober, afs_fs_probe_dispatcher);
    102	timer_setup(&net->fs_probe_timer, afs_fs_probe_timer, 0);
    103	atomic_set(&net->servers_outstanding, 1);
    104
    105	ret = -ENOMEM;
    106	sysnames = kzalloc(sizeof(*sysnames), GFP_KERNEL);
    107	if (!sysnames)
    108		goto error_sysnames;
    109	sysnames->subs[0] = (char *)&afs_init_sysname;
    110	sysnames->nr = 1;
    111	refcount_set(&sysnames->usage, 1);
    112	net->sysnames = sysnames;
    113	rwlock_init(&net->sysnames_lock);
    114
    115	/* Register the /proc stuff */
    116	ret = afs_proc_init(net);
    117	if (ret < 0)
    118		goto error_proc;
    119
    120	/* Initialise the cell DB */
    121	ret = afs_cell_init(net, rootcell);
    122	if (ret < 0)
    123		goto error_cell_init;
    124
    125	/* Create the RxRPC transport */
    126	ret = afs_open_socket(net);
    127	if (ret < 0)
    128		goto error_open_socket;
    129
    130	return 0;
    131
    132error_open_socket:
    133	net->live = false;
    134	afs_fs_probe_cleanup(net);
    135	afs_cell_purge(net);
    136	afs_purge_servers(net);
    137error_cell_init:
    138	net->live = false;
    139	afs_proc_cleanup(net);
    140error_proc:
    141	afs_put_sysnames(net->sysnames);
    142error_sysnames:
    143	net->live = false;
    144	return ret;
    145}
    146
    147/*
    148 * Clean up and destroy an AFS network namespace record.
    149 */
    150static void __net_exit afs_net_exit(struct net *net_ns)
    151{
    152	struct afs_net *net = afs_net(net_ns);
    153
    154	net->live = false;
    155	afs_fs_probe_cleanup(net);
    156	afs_cell_purge(net);
    157	afs_purge_servers(net);
    158	afs_close_socket(net);
    159	afs_proc_cleanup(net);
    160	afs_put_sysnames(net->sysnames);
    161}
    162
    163static struct pernet_operations afs_net_ops = {
    164	.init	= afs_net_init,
    165	.exit	= afs_net_exit,
    166	.id	= &afs_net_id,
    167	.size	= sizeof(struct afs_net),
    168};
    169
    170/*
    171 * initialise the AFS client FS module
    172 */
    173static int __init afs_init(void)
    174{
    175	int ret = -ENOMEM;
    176
    177	printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 registering.\n");
    178
    179	afs_wq = alloc_workqueue("afs", 0, 0);
    180	if (!afs_wq)
    181		goto error_afs_wq;
    182	afs_async_calls = alloc_workqueue("kafsd", WQ_MEM_RECLAIM, 0);
    183	if (!afs_async_calls)
    184		goto error_async;
    185	afs_lock_manager = alloc_workqueue("kafs_lockd", WQ_MEM_RECLAIM, 0);
    186	if (!afs_lock_manager)
    187		goto error_lockmgr;
    188
    189	ret = register_pernet_device(&afs_net_ops);
    190	if (ret < 0)
    191		goto error_net;
    192
    193	/* register the filesystems */
    194	ret = afs_fs_init();
    195	if (ret < 0)
    196		goto error_fs;
    197
    198	afs_proc_symlink = proc_symlink("fs/afs", NULL, "../self/net/afs");
    199	if (!afs_proc_symlink) {
    200		ret = -ENOMEM;
    201		goto error_proc;
    202	}
    203
    204	return ret;
    205
    206error_proc:
    207	afs_fs_exit();
    208error_fs:
    209	unregister_pernet_device(&afs_net_ops);
    210error_net:
    211	destroy_workqueue(afs_lock_manager);
    212error_lockmgr:
    213	destroy_workqueue(afs_async_calls);
    214error_async:
    215	destroy_workqueue(afs_wq);
    216error_afs_wq:
    217	rcu_barrier();
    218	printk(KERN_ERR "kAFS: failed to register: %d\n", ret);
    219	return ret;
    220}
    221
    222/* XXX late_initcall is kludgy, but the only alternative seems to create
    223 * a transport upon the first mount, which is worse. Or is it?
    224 */
    225late_initcall(afs_init);	/* must be called after net/ to create socket */
    226
    227/*
    228 * clean up on module removal
    229 */
    230static void __exit afs_exit(void)
    231{
    232	printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 unregistering.\n");
    233
    234	proc_remove(afs_proc_symlink);
    235	afs_fs_exit();
    236	unregister_pernet_device(&afs_net_ops);
    237	destroy_workqueue(afs_lock_manager);
    238	destroy_workqueue(afs_async_calls);
    239	destroy_workqueue(afs_wq);
    240	afs_clean_up_permit_cache();
    241	rcu_barrier();
    242}
    243
    244module_exit(afs_exit);