aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs/main.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-04-27 12:26:46 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-04-27 12:26:46 -0400
commit15c54033964a943de7b0763efd3bd0ede7326395 (patch)
tree840b292612d1b5396d5bab5bde537a9013db3ceb /fs/afs/main.c
parentad5da3cf39a5b11a198929be1f2644e17ecd767e (diff)
parent912a41a4ab935ce8c4308428ec13fc7f8b1f18f4 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (448 commits) [IPV4] nl_fib_lookup: Initialise res.r before fib_res_put(&res) [IPV6]: Fix thinko in ipv6_rthdr_rcv() changes. [IPV4]: Add multipath cached to feature-removal-schedule.txt [WIRELESS] cfg80211: Clarify locking comment. [WIRELESS] cfg80211: Fix locking in wiphy_new. [WEXT] net_device: Don't include wext bits if not required. [WEXT]: Misc code cleanups. [WEXT]: Reduce inline abuse. [WEXT]: Move EXPORT_SYMBOL statements where they belong. [WEXT]: Cleanup early ioctl call path. [WEXT]: Remove options. [WEXT]: Remove dead debug code. [WEXT]: Clean up how wext is called. [WEXT]: Move to net/wireless [AFS]: Eliminate cmpxchg() usage in vlocation code. [RXRPC]: Fix pointers passed to bitops. [RXRPC]: Remove bogus atomic_* overrides. [AFS]: Fix u64 printing in debug logging. [AFS]: Add "directory write" support. [AFS]: Implement the CB.InitCallBackState3 operation. ...
Diffstat (limited to 'fs/afs/main.c')
-rw-r--r--fs/afs/main.c262
1 files changed, 79 insertions, 183 deletions
diff --git a/fs/afs/main.c b/fs/afs/main.c
index f2704ba53857..40c2704e7557 100644
--- a/fs/afs/main.c
+++ b/fs/afs/main.c
@@ -1,4 +1,4 @@
1/* main.c: AFS client file system 1/* AFS client file system
2 * 2 *
3 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
@@ -13,43 +13,21 @@
13#include <linux/moduleparam.h> 13#include <linux/moduleparam.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/completion.h> 15#include <linux/completion.h>
16#include <rxrpc/rxrpc.h>
17#include <rxrpc/transport.h>
18#include <rxrpc/call.h>
19#include <rxrpc/peer.h>
20#include "cache.h"
21#include "cell.h"
22#include "server.h"
23#include "fsclient.h"
24#include "cmservice.h"
25#include "kafstimod.h"
26#include "kafsasyncd.h"
27#include "internal.h" 16#include "internal.h"
28 17
29struct rxrpc_transport *afs_transport;
30
31static int afs_adding_peer(struct rxrpc_peer *peer);
32static void afs_discarding_peer(struct rxrpc_peer *peer);
33
34
35MODULE_DESCRIPTION("AFS Client File System"); 18MODULE_DESCRIPTION("AFS Client File System");
36MODULE_AUTHOR("Red Hat, Inc."); 19MODULE_AUTHOR("Red Hat, Inc.");
37MODULE_LICENSE("GPL"); 20MODULE_LICENSE("GPL");
38 21
22unsigned afs_debug;
23module_param_named(debug, afs_debug, uint, S_IWUSR | S_IRUGO);
24MODULE_PARM_DESC(afs_debug, "AFS debugging mask");
25
39static char *rootcell; 26static char *rootcell;
40 27
41module_param(rootcell, charp, 0); 28module_param(rootcell, charp, 0);
42MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list"); 29MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list");
43 30
44
45static struct rxrpc_peer_ops afs_peer_ops = {
46 .adding = afs_adding_peer,
47 .discarding = afs_discarding_peer,
48};
49
50struct list_head afs_cb_hash_tbl[AFS_CB_HASH_COUNT];
51DEFINE_SPINLOCK(afs_cb_hash_lock);
52
53#ifdef AFS_CACHING_SUPPORT 31#ifdef AFS_CACHING_SUPPORT
54static struct cachefs_netfs_operations afs_cache_ops = { 32static struct cachefs_netfs_operations afs_cache_ops = {
55 .get_page_cookie = afs_cache_get_page_cookie, 33 .get_page_cookie = afs_cache_get_page_cookie,
@@ -62,20 +40,63 @@ struct cachefs_netfs afs_cache_netfs = {
62}; 40};
63#endif 41#endif
64 42
65/*****************************************************************************/ 43struct afs_uuid afs_uuid;
44
45/*
46 * get a client UUID
47 */
48static int __init afs_get_client_UUID(void)
49{
50 struct timespec ts;
51 u64 uuidtime;
52 u16 clockseq;
53 int ret;
54
55 /* read the MAC address of one of the external interfaces and construct
56 * a UUID from it */
57 ret = afs_get_MAC_address(afs_uuid.node);
58 if (ret < 0)
59 return ret;
60
61 getnstimeofday(&ts);
62 uuidtime = (u64) ts.tv_sec * 1000 * 1000 * 10;
63 uuidtime += ts.tv_nsec / 100;
64 uuidtime += AFS_UUID_TO_UNIX_TIME;
65 afs_uuid.time_low = uuidtime;
66 afs_uuid.time_mid = uuidtime >> 32;
67 afs_uuid.time_hi_and_version = (uuidtime >> 48) & AFS_UUID_TIMEHI_MASK;
68 afs_uuid.time_hi_and_version = AFS_UUID_VERSION_TIME;
69
70 get_random_bytes(&clockseq, 2);
71 afs_uuid.clock_seq_low = clockseq;
72 afs_uuid.clock_seq_hi_and_reserved =
73 (clockseq >> 8) & AFS_UUID_CLOCKHI_MASK;
74 afs_uuid.clock_seq_hi_and_reserved = AFS_UUID_VARIANT_STD;
75
76 _debug("AFS UUID: %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
77 afs_uuid.time_low,
78 afs_uuid.time_mid,
79 afs_uuid.time_hi_and_version,
80 afs_uuid.clock_seq_hi_and_reserved,
81 afs_uuid.clock_seq_low,
82 afs_uuid.node[0], afs_uuid.node[1], afs_uuid.node[2],
83 afs_uuid.node[3], afs_uuid.node[4], afs_uuid.node[5]);
84
85 return 0;
86}
87
66/* 88/*
67 * initialise the AFS client FS module 89 * initialise the AFS client FS module
68 */ 90 */
69static int __init afs_init(void) 91static int __init afs_init(void)
70{ 92{
71 int loop, ret; 93 int ret;
72 94
73 printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 registering.\n"); 95 printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 registering.\n");
74 96
75 /* initialise the callback hash table */ 97 ret = afs_get_client_UUID();
76 spin_lock_init(&afs_cb_hash_lock); 98 if (ret < 0)
77 for (loop = AFS_CB_HASH_COUNT - 1; loop >= 0; loop--) 99 return ret;
78 INIT_LIST_HEAD(&afs_cb_hash_tbl[loop]);
79 100
80 /* register the /proc stuff */ 101 /* register the /proc stuff */
81 ret = afs_proc_init(); 102 ret = afs_proc_init();
@@ -87,70 +108,56 @@ static int __init afs_init(void)
87 ret = cachefs_register_netfs(&afs_cache_netfs, 108 ret = cachefs_register_netfs(&afs_cache_netfs,
88 &afs_cache_cell_index_def); 109 &afs_cache_cell_index_def);
89 if (ret < 0) 110 if (ret < 0)
90 goto error;
91#endif
92
93#ifdef CONFIG_KEYS_TURNED_OFF
94 ret = afs_key_register();
95 if (ret < 0)
96 goto error_cache; 111 goto error_cache;
97#endif 112#endif
98 113
99 /* initialise the cell DB */ 114 /* initialise the cell DB */
100 ret = afs_cell_init(rootcell); 115 ret = afs_cell_init(rootcell);
101 if (ret < 0) 116 if (ret < 0)
102 goto error_keys; 117 goto error_cell_init;
103 118
104 /* start the timeout daemon */ 119 /* initialise the VL update process */
105 ret = afs_kafstimod_start(); 120 ret = afs_vlocation_update_init();
106 if (ret < 0) 121 if (ret < 0)
107 goto error_keys; 122 goto error_vl_update_init;
108 123
109 /* start the async operation daemon */ 124 /* initialise the callback update process */
110 ret = afs_kafsasyncd_start(); 125 ret = afs_callback_update_init();
111 if (ret < 0)
112 goto error_kafstimod;
113 126
114 /* create the RxRPC transport */ 127 /* create the RxRPC transport */
115 ret = rxrpc_create_transport(7001, &afs_transport); 128 ret = afs_open_socket();
116 if (ret < 0) 129 if (ret < 0)
117 goto error_kafsasyncd; 130 goto error_open_socket;
118
119 afs_transport->peer_ops = &afs_peer_ops;
120 131
121 /* register the filesystems */ 132 /* register the filesystems */
122 ret = afs_fs_init(); 133 ret = afs_fs_init();
123 if (ret < 0) 134 if (ret < 0)
124 goto error_transport; 135 goto error_fs;
125 136
126 return ret; 137 return ret;
127 138
128 error_transport: 139error_fs:
129 rxrpc_put_transport(afs_transport); 140 afs_close_socket();
130 error_kafsasyncd: 141error_open_socket:
131 afs_kafsasyncd_stop(); 142error_vl_update_init:
132 error_kafstimod: 143error_cell_init:
133 afs_kafstimod_stop();
134 error_keys:
135#ifdef CONFIG_KEYS_TURNED_OFF
136 afs_key_unregister();
137 error_cache:
138#endif
139#ifdef AFS_CACHING_SUPPORT 144#ifdef AFS_CACHING_SUPPORT
140 cachefs_unregister_netfs(&afs_cache_netfs); 145 cachefs_unregister_netfs(&afs_cache_netfs);
141 error: 146error_cache:
142#endif 147#endif
148 afs_callback_update_kill();
149 afs_vlocation_purge();
143 afs_cell_purge(); 150 afs_cell_purge();
144 afs_proc_cleanup(); 151 afs_proc_cleanup();
145 printk(KERN_ERR "kAFS: failed to register: %d\n", ret); 152 printk(KERN_ERR "kAFS: failed to register: %d\n", ret);
146 return ret; 153 return ret;
147} /* end afs_init() */ 154}
148 155
149/* XXX late_initcall is kludgy, but the only alternative seems to create 156/* XXX late_initcall is kludgy, but the only alternative seems to create
150 * a transport upon the first mount, which is worse. Or is it? 157 * a transport upon the first mount, which is worse. Or is it?
151 */ 158 */
152late_initcall(afs_init); /* must be called after net/ to create socket */ 159late_initcall(afs_init); /* must be called after net/ to create socket */
153/*****************************************************************************/ 160
154/* 161/*
155 * clean up on module removal 162 * clean up on module removal
156 */ 163 */
@@ -159,127 +166,16 @@ static void __exit afs_exit(void)
159 printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 unregistering.\n"); 166 printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 unregistering.\n");
160 167
161 afs_fs_exit(); 168 afs_fs_exit();
162 rxrpc_put_transport(afs_transport); 169 afs_close_socket();
163 afs_kafstimod_stop(); 170 afs_purge_servers();
164 afs_kafsasyncd_stop(); 171 afs_callback_update_kill();
172 afs_vlocation_purge();
173 flush_scheduled_work();
165 afs_cell_purge(); 174 afs_cell_purge();
166#ifdef CONFIG_KEYS_TURNED_OFF
167 afs_key_unregister();
168#endif
169#ifdef AFS_CACHING_SUPPORT 175#ifdef AFS_CACHING_SUPPORT
170 cachefs_unregister_netfs(&afs_cache_netfs); 176 cachefs_unregister_netfs(&afs_cache_netfs);
171#endif 177#endif
172 afs_proc_cleanup(); 178 afs_proc_cleanup();
173
174} /* end afs_exit() */
175
176module_exit(afs_exit);
177
178/*****************************************************************************/
179/*
180 * notification that new peer record is being added
181 * - called from krxsecd
182 * - return an error to induce an abort
183 * - mustn't sleep (caller holds an rwlock)
184 */
185static int afs_adding_peer(struct rxrpc_peer *peer)
186{
187 struct afs_server *server;
188 int ret;
189
190 _debug("kAFS: Adding new peer %08x\n", ntohl(peer->addr.s_addr));
191
192 /* determine which server the peer resides in (if any) */
193 ret = afs_server_find_by_peer(peer, &server);
194 if (ret < 0)
195 return ret; /* none that we recognise, so abort */
196
197 _debug("Server %p{u=%d}\n", server, atomic_read(&server->usage));
198
199 _debug("Cell %p{u=%d}\n",
200 server->cell, atomic_read(&server->cell->usage));
201
202 /* cross-point the structs under a global lock */
203 spin_lock(&afs_server_peer_lock);
204 peer->user = server;
205 server->peer = peer;
206 spin_unlock(&afs_server_peer_lock);
207
208 afs_put_server(server);
209
210 return 0;
211} /* end afs_adding_peer() */
212
213/*****************************************************************************/
214/*
215 * notification that a peer record is being discarded
216 * - called from krxiod or krxsecd
217 */
218static void afs_discarding_peer(struct rxrpc_peer *peer)
219{
220 struct afs_server *server;
221
222 _enter("%p",peer);
223
224 _debug("Discarding peer %08x (rtt=%lu.%lumS)\n",
225 ntohl(peer->addr.s_addr),
226 (long) (peer->rtt / 1000),
227 (long) (peer->rtt % 1000));
228
229 /* uncross-point the structs under a global lock */
230 spin_lock(&afs_server_peer_lock);
231 server = peer->user;
232 if (server) {
233 peer->user = NULL;
234 server->peer = NULL;
235 }
236 spin_unlock(&afs_server_peer_lock);
237
238 _leave("");
239
240} /* end afs_discarding_peer() */
241
242/*****************************************************************************/
243/*
244 * clear the dead space between task_struct and kernel stack
245 * - called by supplying -finstrument-functions to gcc
246 */
247#if 0
248void __cyg_profile_func_enter (void *this_fn, void *call_site)
249__attribute__((no_instrument_function));
250
251void __cyg_profile_func_enter (void *this_fn, void *call_site)
252{
253 asm volatile(" movl %%esp,%%edi \n"
254 " andl %0,%%edi \n"
255 " addl %1,%%edi \n"
256 " movl %%esp,%%ecx \n"
257 " subl %%edi,%%ecx \n"
258 " shrl $2,%%ecx \n"
259 " movl $0xedededed,%%eax \n"
260 " rep stosl \n"
261 :
262 : "i"(~(THREAD_SIZE - 1)), "i"(sizeof(struct thread_info))
263 : "eax", "ecx", "edi", "memory", "cc"
264 );
265} 179}
266 180
267void __cyg_profile_func_exit(void *this_fn, void *call_site) 181module_exit(afs_exit);
268__attribute__((no_instrument_function));
269
270void __cyg_profile_func_exit(void *this_fn, void *call_site)
271{
272 asm volatile(" movl %%esp,%%edi \n"
273 " andl %0,%%edi \n"
274 " addl %1,%%edi \n"
275 " movl %%esp,%%ecx \n"
276 " subl %%edi,%%ecx \n"
277 " shrl $2,%%ecx \n"
278 " movl $0xdadadada,%%eax \n"
279 " rep stosl \n"
280 :
281 : "i"(~(THREAD_SIZE - 1)), "i"(sizeof(struct thread_info))
282 : "eax", "ecx", "edi", "memory", "cc"
283 );
284}
285#endif