1 /* AFS client file system 2 * 3 * Copyright (C) 2002,5 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 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 <linux/random.h> 18 #define CREATE_TRACE_POINTS 19 #include "internal.h" 20 21 MODULE_DESCRIPTION("AFS Client File System"); 22 MODULE_AUTHOR("Red Hat, Inc."); 23 MODULE_LICENSE("GPL"); 24 25 unsigned afs_debug; 26 module_param_named(debug, afs_debug, uint, S_IWUSR | S_IRUGO); 27 MODULE_PARM_DESC(debug, "AFS debugging mask"); 28 29 static char *rootcell; 30 31 module_param(rootcell, charp, 0); 32 MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list"); 33 34 struct afs_uuid afs_uuid; 35 struct workqueue_struct *afs_wq; 36 37 /* 38 * initialise the AFS client FS module 39 */ 40 static int __init afs_init(void) 41 { 42 int ret; 43 44 printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 registering.\n"); 45 46 generate_random_uuid((unsigned char *)&afs_uuid); 47 48 /* create workqueue */ 49 ret = -ENOMEM; 50 afs_wq = alloc_workqueue("afs", 0, 0); 51 if (!afs_wq) 52 return ret; 53 54 /* register the /proc stuff */ 55 ret = afs_proc_init(); 56 if (ret < 0) 57 goto error_proc; 58 59 #ifdef CONFIG_AFS_FSCACHE 60 /* we want to be able to cache */ 61 ret = fscache_register_netfs(&afs_cache_netfs); 62 if (ret < 0) 63 goto error_cache; 64 #endif 65 66 /* initialise the cell DB */ 67 ret = afs_cell_init(rootcell); 68 if (ret < 0) 69 goto error_cell_init; 70 71 /* initialise the VL update process */ 72 ret = afs_vlocation_update_init(); 73 if (ret < 0) 74 goto error_vl_update_init; 75 76 /* initialise the callback update process */ 77 ret = afs_callback_update_init(); 78 if (ret < 0) 79 goto error_callback_update_init; 80 81 /* create the RxRPC transport */ 82 ret = afs_open_socket(); 83 if (ret < 0) 84 goto error_open_socket; 85 86 /* register the filesystems */ 87 ret = afs_fs_init(); 88 if (ret < 0) 89 goto error_fs; 90 91 return ret; 92 93 error_fs: 94 afs_close_socket(); 95 error_open_socket: 96 afs_callback_update_kill(); 97 error_callback_update_init: 98 afs_vlocation_purge(); 99 error_vl_update_init: 100 afs_cell_purge(); 101 error_cell_init: 102 #ifdef CONFIG_AFS_FSCACHE 103 fscache_unregister_netfs(&afs_cache_netfs); 104 error_cache: 105 #endif 106 afs_proc_cleanup(); 107 error_proc: 108 destroy_workqueue(afs_wq); 109 rcu_barrier(); 110 printk(KERN_ERR "kAFS: failed to register: %d\n", ret); 111 return ret; 112 } 113 114 /* XXX late_initcall is kludgy, but the only alternative seems to create 115 * a transport upon the first mount, which is worse. Or is it? 116 */ 117 late_initcall(afs_init); /* must be called after net/ to create socket */ 118 119 /* 120 * clean up on module removal 121 */ 122 static void __exit afs_exit(void) 123 { 124 printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 unregistering.\n"); 125 126 afs_fs_exit(); 127 afs_kill_lock_manager(); 128 afs_close_socket(); 129 afs_purge_servers(); 130 afs_callback_update_kill(); 131 afs_vlocation_purge(); 132 destroy_workqueue(afs_wq); 133 afs_cell_purge(); 134 #ifdef CONFIG_AFS_FSCACHE 135 fscache_unregister_netfs(&afs_cache_netfs); 136 #endif 137 afs_proc_cleanup(); 138 rcu_barrier(); 139 } 140 141 module_exit(afs_exit); 142