Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/fs/afs/main.c
15109 views
1
/* AFS client file system
2
*
3
* Copyright (C) 2002,5 Red Hat, Inc. All Rights Reserved.
4
* Written by David Howells ([email protected])
5
*
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version
9
* 2 of the License, or (at your option) any later version.
10
*/
11
12
#include <linux/module.h>
13
#include <linux/moduleparam.h>
14
#include <linux/init.h>
15
#include <linux/completion.h>
16
#include <linux/sched.h>
17
#include "internal.h"
18
19
MODULE_DESCRIPTION("AFS Client File System");
20
MODULE_AUTHOR("Red Hat, Inc.");
21
MODULE_LICENSE("GPL");
22
23
unsigned afs_debug;
24
module_param_named(debug, afs_debug, uint, S_IWUSR | S_IRUGO);
25
MODULE_PARM_DESC(debug, "AFS debugging mask");
26
27
static char *rootcell;
28
29
module_param(rootcell, charp, 0);
30
MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list");
31
32
struct afs_uuid afs_uuid;
33
struct workqueue_struct *afs_wq;
34
35
/*
36
* get a client UUID
37
*/
38
static int __init afs_get_client_UUID(void)
39
{
40
struct timespec ts;
41
u64 uuidtime;
42
u16 clockseq;
43
int ret;
44
45
/* read the MAC address of one of the external interfaces and construct
46
* a UUID from it */
47
ret = afs_get_MAC_address(afs_uuid.node, sizeof(afs_uuid.node));
48
if (ret < 0)
49
return ret;
50
51
getnstimeofday(&ts);
52
uuidtime = (u64) ts.tv_sec * 1000 * 1000 * 10;
53
uuidtime += ts.tv_nsec / 100;
54
uuidtime += AFS_UUID_TO_UNIX_TIME;
55
afs_uuid.time_low = uuidtime;
56
afs_uuid.time_mid = uuidtime >> 32;
57
afs_uuid.time_hi_and_version = (uuidtime >> 48) & AFS_UUID_TIMEHI_MASK;
58
afs_uuid.time_hi_and_version = AFS_UUID_VERSION_TIME;
59
60
get_random_bytes(&clockseq, 2);
61
afs_uuid.clock_seq_low = clockseq;
62
afs_uuid.clock_seq_hi_and_reserved =
63
(clockseq >> 8) & AFS_UUID_CLOCKHI_MASK;
64
afs_uuid.clock_seq_hi_and_reserved = AFS_UUID_VARIANT_STD;
65
66
_debug("AFS UUID: %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
67
afs_uuid.time_low,
68
afs_uuid.time_mid,
69
afs_uuid.time_hi_and_version,
70
afs_uuid.clock_seq_hi_and_reserved,
71
afs_uuid.clock_seq_low,
72
afs_uuid.node[0], afs_uuid.node[1], afs_uuid.node[2],
73
afs_uuid.node[3], afs_uuid.node[4], afs_uuid.node[5]);
74
75
return 0;
76
}
77
78
/*
79
* initialise the AFS client FS module
80
*/
81
static int __init afs_init(void)
82
{
83
int ret;
84
85
printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 registering.\n");
86
87
ret = afs_get_client_UUID();
88
if (ret < 0)
89
return ret;
90
91
/* create workqueue */
92
ret = -ENOMEM;
93
afs_wq = alloc_workqueue("afs", 0, 0);
94
if (!afs_wq)
95
return ret;
96
97
/* register the /proc stuff */
98
ret = afs_proc_init();
99
if (ret < 0)
100
goto error_proc;
101
102
#ifdef CONFIG_AFS_FSCACHE
103
/* we want to be able to cache */
104
ret = fscache_register_netfs(&afs_cache_netfs);
105
if (ret < 0)
106
goto error_cache;
107
#endif
108
109
/* initialise the cell DB */
110
ret = afs_cell_init(rootcell);
111
if (ret < 0)
112
goto error_cell_init;
113
114
/* initialise the VL update process */
115
ret = afs_vlocation_update_init();
116
if (ret < 0)
117
goto error_vl_update_init;
118
119
/* initialise the callback update process */
120
ret = afs_callback_update_init();
121
if (ret < 0)
122
goto error_callback_update_init;
123
124
/* create the RxRPC transport */
125
ret = afs_open_socket();
126
if (ret < 0)
127
goto error_open_socket;
128
129
/* register the filesystems */
130
ret = afs_fs_init();
131
if (ret < 0)
132
goto error_fs;
133
134
return ret;
135
136
error_fs:
137
afs_close_socket();
138
error_open_socket:
139
afs_callback_update_kill();
140
error_callback_update_init:
141
afs_vlocation_purge();
142
error_vl_update_init:
143
afs_cell_purge();
144
error_cell_init:
145
#ifdef CONFIG_AFS_FSCACHE
146
fscache_unregister_netfs(&afs_cache_netfs);
147
error_cache:
148
#endif
149
afs_proc_cleanup();
150
error_proc:
151
destroy_workqueue(afs_wq);
152
rcu_barrier();
153
printk(KERN_ERR "kAFS: failed to register: %d\n", ret);
154
return ret;
155
}
156
157
/* XXX late_initcall is kludgy, but the only alternative seems to create
158
* a transport upon the first mount, which is worse. Or is it?
159
*/
160
late_initcall(afs_init); /* must be called after net/ to create socket */
161
162
/*
163
* clean up on module removal
164
*/
165
static void __exit afs_exit(void)
166
{
167
printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 unregistering.\n");
168
169
afs_fs_exit();
170
afs_kill_lock_manager();
171
afs_close_socket();
172
afs_purge_servers();
173
afs_callback_update_kill();
174
afs_vlocation_purge();
175
destroy_workqueue(afs_wq);
176
afs_cell_purge();
177
#ifdef CONFIG_AFS_FSCACHE
178
fscache_unregister_netfs(&afs_cache_netfs);
179
#endif
180
afs_proc_cleanup();
181
rcu_barrier();
182
}
183
184
module_exit(afs_exit);
185
186