1 /* AFS volume management 2 * 3 * Copyright (C) 2002, 2007 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/kernel.h> 13 #include <linux/slab.h> 14 #include "internal.h" 15 16 unsigned __read_mostly afs_volume_gc_delay = 10; 17 unsigned __read_mostly afs_volume_record_life = 60 * 60; 18 19 static const char *const afs_voltypes[] = { "R/W", "R/O", "BAK" }; 20 21 /* 22 * Allocate a volume record and load it up from a vldb record. 23 */ 24 static struct afs_volume *afs_alloc_volume(struct afs_fs_context *params, 25 struct afs_vldb_entry *vldb, 26 unsigned long type_mask) 27 { 28 struct afs_server_list *slist; 29 struct afs_volume *volume; 30 int ret = -ENOMEM, nr_servers = 0, i; 31 32 for (i = 0; i < vldb->nr_servers; i++) 33 if (vldb->fs_mask[i] & type_mask) 34 nr_servers++; 35 36 volume = kzalloc(sizeof(struct afs_volume), GFP_KERNEL); 37 if (!volume) 38 goto error_0; 39 40 volume->vid = vldb->vid[params->type]; 41 volume->update_at = ktime_get_real_seconds() + afs_volume_record_life; 42 volume->cell = afs_get_cell(params->cell); 43 volume->type = params->type; 44 volume->type_force = params->force; 45 volume->name_len = vldb->name_len; 46 47 atomic_set(&volume->usage, 1); 48 INIT_LIST_HEAD(&volume->proc_link); 49 rwlock_init(&volume->servers_lock); 50 memcpy(volume->name, vldb->name, vldb->name_len + 1); 51 52 slist = afs_alloc_server_list(params->cell, params->key, vldb, type_mask); 53 if (IS_ERR(slist)) { 54 ret = PTR_ERR(slist); 55 goto error_1; 56 } 57 58 refcount_set(&slist->usage, 1); 59 volume->servers = slist; 60 return volume; 61 62 error_1: 63 afs_put_cell(params->net, volume->cell); 64 kfree(volume); 65 error_0: 66 return ERR_PTR(ret); 67 } 68 69 /* 70 * Look up a VLDB record for a volume. 71 */ 72 static struct afs_vldb_entry *afs_vl_lookup_vldb(struct afs_cell *cell, 73 struct key *key, 74 const char *volname, 75 size_t volnamesz) 76 { 77 struct afs_vldb_entry *vldb = ERR_PTR(-EDESTADDRREQ); 78 struct afs_vl_cursor vc; 79 int ret; 80 81 if (!afs_begin_vlserver_operation(&vc, cell, key)) 82 return ERR_PTR(-ERESTARTSYS); 83 84 while (afs_select_vlserver(&vc)) { 85 vldb = afs_vl_get_entry_by_name_u(&vc, volname, volnamesz); 86 } 87 88 ret = afs_end_vlserver_operation(&vc); 89 return ret < 0 ? ERR_PTR(ret) : vldb; 90 } 91 92 /* 93 * Look up a volume in the VL server and create a candidate volume record for 94 * it. 95 * 96 * The volume name can be one of the following: 97 * "%[cell:]volume[.]" R/W volume 98 * "#[cell:]volume[.]" R/O or R/W volume (rwparent=0), 99 * or R/W (rwparent=1) volume 100 * "%[cell:]volume.readonly" R/O volume 101 * "#[cell:]volume.readonly" R/O volume 102 * "%[cell:]volume.backup" Backup volume 103 * "#[cell:]volume.backup" Backup volume 104 * 105 * The cell name is optional, and defaults to the current cell. 106 * 107 * See "The Rules of Mount Point Traversal" in Chapter 5 of the AFS SysAdmin 108 * Guide 109 * - Rule 1: Explicit type suffix forces access of that type or nothing 110 * (no suffix, then use Rule 2 & 3) 111 * - Rule 2: If parent volume is R/O, then mount R/O volume by preference, R/W 112 * if not available 113 * - Rule 3: If parent volume is R/W, then only mount R/W volume unless 114 * explicitly told otherwise 115 */ 116 struct afs_volume *afs_create_volume(struct afs_fs_context *params) 117 { 118 struct afs_vldb_entry *vldb; 119 struct afs_volume *volume; 120 unsigned long type_mask = 1UL << params->type; 121 122 vldb = afs_vl_lookup_vldb(params->cell, params->key, 123 params->volname, params->volnamesz); 124 if (IS_ERR(vldb)) 125 return ERR_CAST(vldb); 126 127 if (test_bit(AFS_VLDB_QUERY_ERROR, &vldb->flags)) { 128 volume = ERR_PTR(vldb->error); 129 goto error; 130 } 131 132 /* Make the final decision on the type we want */ 133 volume = ERR_PTR(-ENOMEDIUM); 134 if (params->force) { 135 if (!(vldb->flags & type_mask)) 136 goto error; 137 } else if (test_bit(AFS_VLDB_HAS_RO, &vldb->flags)) { 138 params->type = AFSVL_ROVOL; 139 } else if (test_bit(AFS_VLDB_HAS_RW, &vldb->flags)) { 140 params->type = AFSVL_RWVOL; 141 } else { 142 goto error; 143 } 144 145 type_mask = 1UL << params->type; 146 volume = afs_alloc_volume(params, vldb, type_mask); 147 148 error: 149 kfree(vldb); 150 return volume; 151 } 152 153 /* 154 * Destroy a volume record 155 */ 156 static void afs_destroy_volume(struct afs_net *net, struct afs_volume *volume) 157 { 158 _enter("%p", volume); 159 160 #ifdef CONFIG_AFS_FSCACHE 161 ASSERTCMP(volume->cache, ==, NULL); 162 #endif 163 164 afs_put_serverlist(net, volume->servers); 165 afs_put_cell(net, volume->cell); 166 kfree(volume); 167 168 _leave(" [destroyed]"); 169 } 170 171 /* 172 * Drop a reference on a volume record. 173 */ 174 void afs_put_volume(struct afs_cell *cell, struct afs_volume *volume) 175 { 176 if (volume) { 177 _enter("%s", volume->name); 178 179 if (atomic_dec_and_test(&volume->usage)) 180 afs_destroy_volume(cell->net, volume); 181 } 182 } 183 184 /* 185 * Activate a volume. 186 */ 187 void afs_activate_volume(struct afs_volume *volume) 188 { 189 #ifdef CONFIG_AFS_FSCACHE 190 volume->cache = fscache_acquire_cookie(volume->cell->cache, 191 &afs_volume_cache_index_def, 192 &volume->vid, sizeof(volume->vid), 193 NULL, 0, 194 volume, 0, true); 195 #endif 196 197 write_lock(&volume->cell->proc_lock); 198 list_add_tail(&volume->proc_link, &volume->cell->proc_volumes); 199 write_unlock(&volume->cell->proc_lock); 200 } 201 202 /* 203 * Deactivate a volume. 204 */ 205 void afs_deactivate_volume(struct afs_volume *volume) 206 { 207 _enter("%s", volume->name); 208 209 write_lock(&volume->cell->proc_lock); 210 list_del_init(&volume->proc_link); 211 write_unlock(&volume->cell->proc_lock); 212 213 #ifdef CONFIG_AFS_FSCACHE 214 fscache_relinquish_cookie(volume->cache, NULL, 215 test_bit(AFS_VOLUME_DELETED, &volume->flags)); 216 volume->cache = NULL; 217 #endif 218 219 _leave(""); 220 } 221 222 /* 223 * Query the VL service to update the volume status. 224 */ 225 static int afs_update_volume_status(struct afs_volume *volume, struct key *key) 226 { 227 struct afs_server_list *new, *old, *discard; 228 struct afs_vldb_entry *vldb; 229 char idbuf[16]; 230 int ret, idsz; 231 232 _enter(""); 233 234 /* We look up an ID by passing it as a decimal string in the 235 * operation's name parameter. 236 */ 237 idsz = sprintf(idbuf, "%llu", volume->vid); 238 239 vldb = afs_vl_lookup_vldb(volume->cell, key, idbuf, idsz); 240 if (IS_ERR(vldb)) { 241 ret = PTR_ERR(vldb); 242 goto error; 243 } 244 245 /* See if the volume got renamed. */ 246 if (vldb->name_len != volume->name_len || 247 memcmp(vldb->name, volume->name, vldb->name_len) != 0) { 248 /* TODO: Use RCU'd string. */ 249 memcpy(volume->name, vldb->name, AFS_MAXVOLNAME); 250 volume->name_len = vldb->name_len; 251 } 252 253 /* See if the volume's server list got updated. */ 254 new = afs_alloc_server_list(volume->cell, key, 255 vldb, (1 << volume->type)); 256 if (IS_ERR(new)) { 257 ret = PTR_ERR(new); 258 goto error_vldb; 259 } 260 261 write_lock(&volume->servers_lock); 262 263 discard = new; 264 old = volume->servers; 265 if (afs_annotate_server_list(new, old)) { 266 new->seq = volume->servers_seq + 1; 267 volume->servers = new; 268 smp_wmb(); 269 volume->servers_seq++; 270 discard = old; 271 } 272 273 volume->update_at = ktime_get_real_seconds() + afs_volume_record_life; 274 clear_bit(AFS_VOLUME_NEEDS_UPDATE, &volume->flags); 275 write_unlock(&volume->servers_lock); 276 ret = 0; 277 278 afs_put_serverlist(volume->cell->net, discard); 279 error_vldb: 280 kfree(vldb); 281 error: 282 _leave(" = %d", ret); 283 return ret; 284 } 285 286 /* 287 * Make sure the volume record is up to date. 288 */ 289 int afs_check_volume_status(struct afs_volume *volume, struct key *key) 290 { 291 time64_t now = ktime_get_real_seconds(); 292 int ret, retries = 0; 293 294 _enter(""); 295 296 if (volume->update_at <= now) 297 set_bit(AFS_VOLUME_NEEDS_UPDATE, &volume->flags); 298 299 retry: 300 if (!test_bit(AFS_VOLUME_NEEDS_UPDATE, &volume->flags) && 301 !test_bit(AFS_VOLUME_WAIT, &volume->flags)) { 302 _leave(" = 0"); 303 return 0; 304 } 305 306 if (!test_and_set_bit_lock(AFS_VOLUME_UPDATING, &volume->flags)) { 307 ret = afs_update_volume_status(volume, key); 308 clear_bit_unlock(AFS_VOLUME_WAIT, &volume->flags); 309 clear_bit_unlock(AFS_VOLUME_UPDATING, &volume->flags); 310 wake_up_bit(&volume->flags, AFS_VOLUME_WAIT); 311 _leave(" = %d", ret); 312 return ret; 313 } 314 315 if (!test_bit(AFS_VOLUME_WAIT, &volume->flags)) { 316 _leave(" = 0 [no wait]"); 317 return 0; 318 } 319 320 ret = wait_on_bit(&volume->flags, AFS_VOLUME_WAIT, TASK_INTERRUPTIBLE); 321 if (ret == -ERESTARTSYS) { 322 _leave(" = %d", ret); 323 return ret; 324 } 325 326 retries++; 327 if (retries == 4) { 328 _leave(" = -ESTALE"); 329 return -ESTALE; 330 } 331 goto retry; 332 } 333