diff options
Diffstat (limited to 'fs/afs/main.c')
-rw-r--r-- | fs/afs/main.c | 145 |
1 files changed, 97 insertions, 48 deletions
diff --git a/fs/afs/main.c b/fs/afs/main.c index 9944770849da..15a02a05ff40 100644 --- a/fs/afs/main.c +++ b/fs/afs/main.c @@ -31,57 +31,112 @@ static char *rootcell; module_param(rootcell, charp, 0); MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list"); -struct afs_uuid afs_uuid; struct workqueue_struct *afs_wq; +struct afs_net __afs_net; /* - * initialise the AFS client FS module + * Initialise an AFS network namespace record. */ -static int __init afs_init(void) +static int __net_init afs_net_init(struct afs_net *net) { int ret; - printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 registering.\n"); + net->live = true; + generate_random_uuid((unsigned char *)&net->uuid); - generate_random_uuid((unsigned char *)&afs_uuid); + INIT_WORK(&net->charge_preallocation_work, afs_charge_preallocation); + mutex_init(&net->socket_mutex); - /* create workqueue */ - ret = -ENOMEM; - afs_wq = alloc_workqueue("afs", 0, 0); - if (!afs_wq) - return ret; + net->cells = RB_ROOT; + seqlock_init(&net->cells_lock); + INIT_WORK(&net->cells_manager, afs_manage_cells); + timer_setup(&net->cells_timer, afs_cells_timer, 0); - /* register the /proc stuff */ - ret = afs_proc_init(); - if (ret < 0) - goto error_proc; + spin_lock_init(&net->proc_cells_lock); + INIT_LIST_HEAD(&net->proc_cells); -#ifdef CONFIG_AFS_FSCACHE - /* we want to be able to cache */ - ret = fscache_register_netfs(&afs_cache_netfs); + seqlock_init(&net->fs_lock); + net->fs_servers = RB_ROOT; + INIT_LIST_HEAD(&net->fs_updates); + INIT_HLIST_HEAD(&net->fs_proc); + + INIT_HLIST_HEAD(&net->fs_addresses4); + INIT_HLIST_HEAD(&net->fs_addresses6); + seqlock_init(&net->fs_addr_lock); + + INIT_WORK(&net->fs_manager, afs_manage_servers); + timer_setup(&net->fs_timer, afs_servers_timer, 0); + + /* Register the /proc stuff */ + ret = afs_proc_init(net); if (ret < 0) - goto error_cache; -#endif + goto error_proc; - /* initialise the cell DB */ - ret = afs_cell_init(rootcell); + /* Initialise the cell DB */ + ret = afs_cell_init(net, rootcell); if (ret < 0) goto error_cell_init; - /* initialise the VL update process */ - ret = afs_vlocation_update_init(); + /* Create the RxRPC transport */ + ret = afs_open_socket(net); if (ret < 0) - goto error_vl_update_init; + goto error_open_socket; - /* initialise the callback update process */ - ret = afs_callback_update_init(); + return 0; + +error_open_socket: + net->live = false; + afs_cell_purge(net); + afs_purge_servers(net); +error_cell_init: + net->live = false; + afs_proc_cleanup(net); +error_proc: + net->live = false; + 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_cell_purge(net); + afs_purge_servers(net); + afs_close_socket(net); + afs_proc_cleanup(net); +} + +/* + * initialise the AFS client FS module + */ +static int __init afs_init(void) +{ + int ret = -ENOMEM; + + printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 registering.\n"); + + afs_wq = alloc_workqueue("afs", 0, 0); + if (!afs_wq) + goto error_afs_wq; + afs_async_calls = alloc_workqueue("kafsd", WQ_MEM_RECLAIM, 0); + if (!afs_async_calls) + goto error_async; + afs_lock_manager = alloc_workqueue("kafs_lockd", WQ_MEM_RECLAIM, 0); + if (!afs_lock_manager) + goto error_lockmgr; + +#ifdef CONFIG_AFS_FSCACHE + /* we want to be able to cache */ + ret = fscache_register_netfs(&afs_cache_netfs); if (ret < 0) - goto error_callback_update_init; + goto error_cache; +#endif - /* create the RxRPC transport */ - ret = afs_open_socket(); + ret = afs_net_init(&__afs_net); if (ret < 0) - goto error_open_socket; + goto error_net; /* register the filesystems */ ret = afs_fs_init(); @@ -91,21 +146,18 @@ static int __init afs_init(void) return ret; error_fs: - afs_close_socket(); -error_open_socket: - afs_callback_update_kill(); -error_callback_update_init: - afs_vlocation_purge(); -error_vl_update_init: - afs_cell_purge(); -error_cell_init: + afs_net_exit(&__afs_net); +error_net: #ifdef CONFIG_AFS_FSCACHE fscache_unregister_netfs(&afs_cache_netfs); error_cache: #endif - afs_proc_cleanup(); -error_proc: + destroy_workqueue(afs_lock_manager); +error_lockmgr: + destroy_workqueue(afs_async_calls); +error_async: destroy_workqueue(afs_wq); +error_afs_wq: rcu_barrier(); printk(KERN_ERR "kAFS: failed to register: %d\n", ret); return ret; @@ -124,17 +176,14 @@ static void __exit afs_exit(void) printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 unregistering.\n"); afs_fs_exit(); - afs_kill_lock_manager(); - afs_close_socket(); - afs_purge_servers(); - afs_callback_update_kill(); - afs_vlocation_purge(); - destroy_workqueue(afs_wq); - afs_cell_purge(); + afs_net_exit(&__afs_net); #ifdef CONFIG_AFS_FSCACHE fscache_unregister_netfs(&afs_cache_netfs); #endif - afs_proc_cleanup(); + destroy_workqueue(afs_lock_manager); + destroy_workqueue(afs_async_calls); + destroy_workqueue(afs_wq); + afs_clean_up_permit_cache(); rcu_barrier(); } |