main.c 4.7 KB
Newer Older
D
David Howells 已提交
1
/* AFS client file system
L
Linus Torvalds 已提交
2
 *
D
David Howells 已提交
3
 * Copyright (C) 2002,5 Red Hat, Inc. All Rights Reserved.
L
Linus Torvalds 已提交
4 5 6 7 8 9 10 11 12 13 14 15
 * Written by David Howells (dhowells@redhat.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/completion.h>
A
Alexey Dobriyan 已提交
16
#include <linux/sched.h>
D
David Howells 已提交
17
#include <linux/random.h>
D
David Howells 已提交
18
#define CREATE_TRACE_POINTS
L
Linus Torvalds 已提交
19 20 21 22 23 24
#include "internal.h"

MODULE_DESCRIPTION("AFS Client File System");
MODULE_AUTHOR("Red Hat, Inc.");
MODULE_LICENSE("GPL");

25 26
unsigned afs_debug;
module_param_named(debug, afs_debug, uint, S_IWUSR | S_IRUGO);
27
MODULE_PARM_DESC(debug, "AFS debugging mask");
28

L
Linus Torvalds 已提交
29 30 31 32 33
static char *rootcell;

module_param(rootcell, charp, 0);
MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list");

34
struct workqueue_struct *afs_wq;
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
struct afs_net __afs_net;

/*
 * Initialise an AFS network namespace record.
 */
static int __net_init afs_net_init(struct afs_net *net)
{
	int ret;

	net->live = true;
	generate_random_uuid((unsigned char *)&net->uuid);

	INIT_WORK(&net->charge_preallocation_work, afs_charge_preallocation);
	mutex_init(&net->socket_mutex);
	INIT_LIST_HEAD(&net->cells);
	rwlock_init(&net->cells_lock);
	init_rwsem(&net->cells_sem);
	init_waitqueue_head(&net->cells_freeable_wq);
	init_rwsem(&net->proc_cells_sem);
	INIT_LIST_HEAD(&net->proc_cells);
	INIT_LIST_HEAD(&net->vl_updates);
	INIT_LIST_HEAD(&net->vl_graveyard);
	INIT_DELAYED_WORK(&net->vl_reaper, afs_vlocation_reaper);
	INIT_DELAYED_WORK(&net->vl_updater, afs_vlocation_updater);
	spin_lock_init(&net->vl_updates_lock);
	spin_lock_init(&net->vl_graveyard_lock);
	net->servers = RB_ROOT;
	rwlock_init(&net->servers_lock);
	INIT_LIST_HEAD(&net->server_graveyard);
	spin_lock_init(&net->server_graveyard_lock);
D
David Howells 已提交
65 66
	INIT_WORK(&net->server_reaper, afs_reap_server);
	timer_setup(&net->server_timer, afs_server_timer, 0);
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102

	/* Register the /proc stuff */
	ret = afs_proc_init(net);
	if (ret < 0)
		goto error_proc;

	/* Initialise the cell DB */
	ret = afs_cell_init(net, rootcell);
	if (ret < 0)
		goto error_cell_init;

	/* Create the RxRPC transport */
	ret = afs_open_socket(net);
	if (ret < 0)
		goto error_open_socket;

	return 0;

error_open_socket:
	afs_vlocation_purge(net);
	afs_cell_purge(net);
error_cell_init:
	afs_proc_cleanup(net);
error_proc:
	return ret;
}

/*
 * Clean up and destroy an AFS network namespace record.
 */
static void __net_exit afs_net_exit(struct afs_net *net)
{
	net->live = false;
	afs_purge_servers(net);
	afs_vlocation_purge(net);
	afs_cell_purge(net);
103
	afs_close_socket(net);
104 105
	afs_proc_cleanup(net);
}
106

L
Linus Torvalds 已提交
107 108 109 110 111
/*
 * initialise the AFS client FS module
 */
static int __init afs_init(void)
{
112
	int ret = -ENOMEM;
L
Linus Torvalds 已提交
113 114 115

	printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 registering.\n");

116 117
	afs_wq = alloc_workqueue("afs", 0, 0);
	if (!afs_wq)
118 119 120 121 122 123 124 125 126 127 128
		goto error_afs_wq;
	afs_async_calls = alloc_workqueue("kafsd", WQ_MEM_RECLAIM, 0);
	if (!afs_async_calls)
		goto error_async;
	afs_vlocation_update_worker =
		alloc_workqueue("kafs_vlupdated", WQ_MEM_RECLAIM, 0);
	if (!afs_vlocation_update_worker)
		goto error_vl_up;
	afs_lock_manager = alloc_workqueue("kafs_lockd", WQ_MEM_RECLAIM, 0);
	if (!afs_lock_manager)
		goto error_lockmgr;
L
Linus Torvalds 已提交
129

D
David Howells 已提交
130
#ifdef CONFIG_AFS_FSCACHE
L
Linus Torvalds 已提交
131
	/* we want to be able to cache */
D
David Howells 已提交
132
	ret = fscache_register_netfs(&afs_cache_netfs);
L
Linus Torvalds 已提交
133 134 135 136
	if (ret < 0)
		goto error_cache;
#endif

137
	ret = afs_net_init(&__afs_net);
138
	if (ret < 0)
139
		goto error_net;
L
Linus Torvalds 已提交
140 141 142 143

	/* register the filesystems */
	ret = afs_fs_init();
	if (ret < 0)
D
David Howells 已提交
144
		goto error_fs;
L
Linus Torvalds 已提交
145 146 147

	return ret;

D
David Howells 已提交
148
error_fs:
149 150
	afs_net_exit(&__afs_net);
error_net:
D
David Howells 已提交
151 152
#ifdef CONFIG_AFS_FSCACHE
	fscache_unregister_netfs(&afs_cache_netfs);
D
David Howells 已提交
153
error_cache:
L
Linus Torvalds 已提交
154
#endif
155 156 157 158 159 160
	destroy_workqueue(afs_lock_manager);
error_lockmgr:
	destroy_workqueue(afs_vlocation_update_worker);
error_vl_up:
	destroy_workqueue(afs_async_calls);
error_async:
161
	destroy_workqueue(afs_wq);
162
error_afs_wq:
D
David Howells 已提交
163
	rcu_barrier();
L
Linus Torvalds 已提交
164 165
	printk(KERN_ERR "kAFS: failed to register: %d\n", ret);
	return ret;
D
David Howells 已提交
166
}
L
Linus Torvalds 已提交
167 168 169 170 171

/* XXX late_initcall is kludgy, but the only alternative seems to create
 * a transport upon the first mount, which is worse. Or is it?
 */
late_initcall(afs_init);	/* must be called after net/ to create socket */
D
David Howells 已提交
172

L
Linus Torvalds 已提交
173 174 175 176 177 178 179 180
/*
 * clean up on module removal
 */
static void __exit afs_exit(void)
{
	printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 unregistering.\n");

	afs_fs_exit();
181
	afs_net_exit(&__afs_net);
D
David Howells 已提交
182 183
#ifdef CONFIG_AFS_FSCACHE
	fscache_unregister_netfs(&afs_cache_netfs);
L
Linus Torvalds 已提交
184
#endif
185 186 187 188
	destroy_workqueue(afs_lock_manager);
	destroy_workqueue(afs_vlocation_update_worker);
	destroy_workqueue(afs_async_calls);
	destroy_workqueue(afs_wq);
D
David Howells 已提交
189
	rcu_barrier();
D
David Howells 已提交
190
}
L
Linus Torvalds 已提交
191 192

module_exit(afs_exit);