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 "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 34 /* 35 * get a client UUID 36 */ 37 static int __init afs_get_client_UUID(void) 38 { 39 struct timespec ts; 40 u64 uuidtime; 41 u16 clockseq; 42 int ret; 43 44 /* read the MAC address of one of the external interfaces and construct 45 * a UUID from it */ 46 ret = afs_get_MAC_address(afs_uuid.node, sizeof(afs_uuid.node)); 47 if (ret < 0) 48 return ret; 49 50 getnstimeofday(&ts); 51 uuidtime = (u64) ts.tv_sec * 1000 * 1000 * 10; 52 uuidtime += ts.tv_nsec / 100; 53 uuidtime += AFS_UUID_TO_UNIX_TIME; 54 afs_uuid.time_low = uuidtime; 55 afs_uuid.time_mid = uuidtime >> 32; 56 afs_uuid.time_hi_and_version = (uuidtime >> 48) & AFS_UUID_TIMEHI_MASK; 57 afs_uuid.time_hi_and_version = AFS_UUID_VERSION_TIME; 58 59 get_random_bytes(&clockseq, 2); 60 afs_uuid.clock_seq_low = clockseq; 61 afs_uuid.clock_seq_hi_and_reserved = 62 (clockseq >> 8) & AFS_UUID_CLOCKHI_MASK; 63 afs_uuid.clock_seq_hi_and_reserved = AFS_UUID_VARIANT_STD; 64 65 _debug("AFS UUID: %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", 66 afs_uuid.time_low, 67 afs_uuid.time_mid, 68 afs_uuid.time_hi_and_version, 69 afs_uuid.clock_seq_hi_and_reserved, 70 afs_uuid.clock_seq_low, 71 afs_uuid.node[0], afs_uuid.node[1], afs_uuid.node[2], 72 afs_uuid.node[3], afs_uuid.node[4], afs_uuid.node[5]); 73 74 return 0; 75 } 76 77 /* 78 * initialise the AFS client FS module 79 */ 80 static int __init afs_init(void) 81 { 82 int ret; 83 84 printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 registering.\n"); 85 86 ret = afs_get_client_UUID(); 87 if (ret < 0) 88 return ret; 89 90 /* register the /proc stuff */ 91 ret = afs_proc_init(); 92 if (ret < 0) 93 return ret; 94 95 #ifdef CONFIG_AFS_FSCACHE 96 /* we want to be able to cache */ 97 ret = fscache_register_netfs(&afs_cache_netfs); 98 if (ret < 0) 99 goto error_cache; 100 #endif 101 102 /* initialise the cell DB */ 103 ret = afs_cell_init(rootcell); 104 if (ret < 0) 105 goto error_cell_init; 106 107 /* initialise the VL update process */ 108 ret = afs_vlocation_update_init(); 109 if (ret < 0) 110 goto error_vl_update_init; 111 112 /* initialise the callback update process */ 113 ret = afs_callback_update_init(); 114 115 /* create the RxRPC transport */ 116 ret = afs_open_socket(); 117 if (ret < 0) 118 goto error_open_socket; 119 120 /* register the filesystems */ 121 ret = afs_fs_init(); 122 if (ret < 0) 123 goto error_fs; 124 125 return ret; 126 127 error_fs: 128 afs_close_socket(); 129 error_open_socket: 130 error_vl_update_init: 131 error_cell_init: 132 #ifdef CONFIG_AFS_FSCACHE 133 fscache_unregister_netfs(&afs_cache_netfs); 134 error_cache: 135 #endif 136 afs_callback_update_kill(); 137 afs_vlocation_purge(); 138 afs_cell_purge(); 139 afs_proc_cleanup(); 140 rcu_barrier(); 141 printk(KERN_ERR "kAFS: failed to register: %d\n", ret); 142 return ret; 143 } 144 145 /* XXX late_initcall is kludgy, but the only alternative seems to create 146 * a transport upon the first mount, which is worse. Or is it? 147 */ 148 late_initcall(afs_init); /* must be called after net/ to create socket */ 149 150 /* 151 * clean up on module removal 152 */ 153 static void __exit afs_exit(void) 154 { 155 printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 unregistering.\n"); 156 157 afs_fs_exit(); 158 afs_kill_lock_manager(); 159 afs_close_socket(); 160 afs_purge_servers(); 161 afs_callback_update_kill(); 162 afs_vlocation_purge(); 163 flush_scheduled_work(); 164 afs_cell_purge(); 165 #ifdef CONFIG_AFS_FSCACHE 166 fscache_unregister_netfs(&afs_cache_netfs); 167 #endif 168 afs_proc_cleanup(); 169 rcu_barrier(); 170 } 171 172 module_exit(afs_exit); 173