1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* AFS volume management 3 * 4 * Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved. 5 * Written by David Howells (dhowells@redhat.com) 6 */ 7 8 #include <linux/kernel.h> 9 #include <linux/slab.h> 10 #include "internal.h" 11 12 static unsigned __read_mostly afs_volume_record_life = 60 * 60; 13 14 /* 15 * Insert a volume into a cell. If there's an existing volume record, that is 16 * returned instead with a ref held. 17 */ 18 static struct afs_volume *afs_insert_volume_into_cell(struct afs_cell *cell, 19 struct afs_volume *volume) 20 { 21 struct afs_volume *p; 22 struct rb_node *parent = NULL, **pp; 23 24 write_seqlock(&cell->volume_lock); 25 26 pp = &cell->volumes.rb_node; 27 while (*pp) { 28 parent = *pp; 29 p = rb_entry(parent, struct afs_volume, cell_node); 30 if (p->vid < volume->vid) { 31 pp = &(*pp)->rb_left; 32 } else if (p->vid > volume->vid) { 33 pp = &(*pp)->rb_right; 34 } else { 35 if (afs_try_get_volume(p, afs_volume_trace_get_cell_insert)) { 36 volume = p; 37 goto found; 38 } 39 40 set_bit(AFS_VOLUME_RM_TREE, &volume->flags); 41 rb_replace_node_rcu(&p->cell_node, &volume->cell_node, &cell->volumes); 42 } 43 } 44 45 rb_link_node_rcu(&volume->cell_node, parent, pp); 46 rb_insert_color(&volume->cell_node, &cell->volumes); 47 hlist_add_head_rcu(&volume->proc_link, &cell->proc_volumes); 48 49 found: 50 write_sequnlock(&cell->volume_lock); 51 return volume; 52 53 } 54 55 static void afs_remove_volume_from_cell(struct afs_volume *volume) 56 { 57 struct afs_cell *cell = volume->cell; 58 59 if (!hlist_unhashed(&volume->proc_link)) { 60 trace_afs_volume(volume->vid, refcount_read(&cell->ref), 61 afs_volume_trace_remove); 62 write_seqlock(&cell->volume_lock); 63 hlist_del_rcu(&volume->proc_link); 64 if (!test_and_set_bit(AFS_VOLUME_RM_TREE, &volume->flags)) 65 rb_erase(&volume->cell_node, &cell->volumes); 66 write_sequnlock(&cell->volume_lock); 67 } 68 } 69 70 /* 71 * Allocate a volume record and load it up from a vldb record. 72 */ 73 static struct afs_volume *afs_alloc_volume(struct afs_fs_context *params, 74 struct afs_vldb_entry *vldb, 75 unsigned long type_mask) 76 { 77 struct afs_server_list *slist; 78 struct afs_volume *volume; 79 int ret = -ENOMEM; 80 81 volume = kzalloc(sizeof(struct afs_volume), GFP_KERNEL); 82 if (!volume) 83 goto error_0; 84 85 volume->vid = vldb->vid[params->type]; 86 volume->update_at = ktime_get_real_seconds() + afs_volume_record_life; 87 volume->cell = afs_get_cell(params->cell, afs_cell_trace_get_vol); 88 volume->type = params->type; 89 volume->type_force = params->force; 90 volume->name_len = vldb->name_len; 91 92 refcount_set(&volume->ref, 1); 93 INIT_HLIST_NODE(&volume->proc_link); 94 rwlock_init(&volume->servers_lock); 95 rwlock_init(&volume->cb_v_break_lock); 96 memcpy(volume->name, vldb->name, vldb->name_len + 1); 97 98 slist = afs_alloc_server_list(params->cell, params->key, vldb, type_mask); 99 if (IS_ERR(slist)) { 100 ret = PTR_ERR(slist); 101 goto error_1; 102 } 103 104 refcount_set(&slist->usage, 1); 105 rcu_assign_pointer(volume->servers, slist); 106 trace_afs_volume(volume->vid, 1, afs_volume_trace_alloc); 107 return volume; 108 109 error_1: 110 afs_put_cell(volume->cell, afs_cell_trace_put_vol); 111 kfree(volume); 112 error_0: 113 return ERR_PTR(ret); 114 } 115 116 /* 117 * Look up or allocate a volume record. 118 */ 119 static struct afs_volume *afs_lookup_volume(struct afs_fs_context *params, 120 struct afs_vldb_entry *vldb, 121 unsigned long type_mask) 122 { 123 struct afs_volume *candidate, *volume; 124 125 candidate = afs_alloc_volume(params, vldb, type_mask); 126 if (IS_ERR(candidate)) 127 return candidate; 128 129 volume = afs_insert_volume_into_cell(params->cell, candidate); 130 if (volume != candidate) 131 afs_put_volume(params->net, candidate, afs_volume_trace_put_cell_dup); 132 return volume; 133 } 134 135 /* 136 * Look up a VLDB record for a volume. 137 */ 138 static struct afs_vldb_entry *afs_vl_lookup_vldb(struct afs_cell *cell, 139 struct key *key, 140 const char *volname, 141 size_t volnamesz) 142 { 143 struct afs_vldb_entry *vldb = ERR_PTR(-EDESTADDRREQ); 144 struct afs_vl_cursor vc; 145 int ret; 146 147 if (!afs_begin_vlserver_operation(&vc, cell, key)) 148 return ERR_PTR(-ERESTARTSYS); 149 150 while (afs_select_vlserver(&vc)) { 151 vldb = afs_vl_get_entry_by_name_u(&vc, volname, volnamesz); 152 } 153 154 ret = afs_end_vlserver_operation(&vc); 155 return ret < 0 ? ERR_PTR(ret) : vldb; 156 } 157 158 /* 159 * Look up a volume in the VL server and create a candidate volume record for 160 * it. 161 * 162 * The volume name can be one of the following: 163 * "%[cell:]volume[.]" R/W volume 164 * "#[cell:]volume[.]" R/O or R/W volume (rwparent=0), 165 * or R/W (rwparent=1) volume 166 * "%[cell:]volume.readonly" R/O volume 167 * "#[cell:]volume.readonly" R/O volume 168 * "%[cell:]volume.backup" Backup volume 169 * "#[cell:]volume.backup" Backup volume 170 * 171 * The cell name is optional, and defaults to the current cell. 172 * 173 * See "The Rules of Mount Point Traversal" in Chapter 5 of the AFS SysAdmin 174 * Guide 175 * - Rule 1: Explicit type suffix forces access of that type or nothing 176 * (no suffix, then use Rule 2 & 3) 177 * - Rule 2: If parent volume is R/O, then mount R/O volume by preference, R/W 178 * if not available 179 * - Rule 3: If parent volume is R/W, then only mount R/W volume unless 180 * explicitly told otherwise 181 */ 182 struct afs_volume *afs_create_volume(struct afs_fs_context *params) 183 { 184 struct afs_vldb_entry *vldb; 185 struct afs_volume *volume; 186 unsigned long type_mask = 1UL << params->type; 187 188 vldb = afs_vl_lookup_vldb(params->cell, params->key, 189 params->volname, params->volnamesz); 190 if (IS_ERR(vldb)) 191 return ERR_CAST(vldb); 192 193 if (test_bit(AFS_VLDB_QUERY_ERROR, &vldb->flags)) { 194 volume = ERR_PTR(vldb->error); 195 goto error; 196 } 197 198 /* Make the final decision on the type we want */ 199 volume = ERR_PTR(-ENOMEDIUM); 200 if (params->force) { 201 if (!(vldb->flags & type_mask)) 202 goto error; 203 } else if (test_bit(AFS_VLDB_HAS_RO, &vldb->flags)) { 204 params->type = AFSVL_ROVOL; 205 } else if (test_bit(AFS_VLDB_HAS_RW, &vldb->flags)) { 206 params->type = AFSVL_RWVOL; 207 } else { 208 goto error; 209 } 210 211 type_mask = 1UL << params->type; 212 volume = afs_lookup_volume(params, vldb, type_mask); 213 214 error: 215 kfree(vldb); 216 return volume; 217 } 218 219 /* 220 * Destroy a volume record 221 */ 222 static void afs_destroy_volume(struct afs_net *net, struct afs_volume *volume) 223 { 224 _enter("%p", volume); 225 226 #ifdef CONFIG_AFS_FSCACHE 227 ASSERTCMP(volume->cache, ==, NULL); 228 #endif 229 230 afs_remove_volume_from_cell(volume); 231 afs_put_serverlist(net, rcu_access_pointer(volume->servers)); 232 afs_put_cell(volume->cell, afs_cell_trace_put_vol); 233 trace_afs_volume(volume->vid, refcount_read(&volume->ref), 234 afs_volume_trace_free); 235 kfree_rcu(volume, rcu); 236 237 _leave(" [destroyed]"); 238 } 239 240 /* 241 * Try to get a reference on a volume record. 242 */ 243 bool afs_try_get_volume(struct afs_volume *volume, enum afs_volume_trace reason) 244 { 245 int r; 246 247 if (__refcount_inc_not_zero(&volume->ref, &r)) { 248 trace_afs_volume(volume->vid, r + 1, reason); 249 return true; 250 } 251 return false; 252 } 253 254 /* 255 * Get a reference on a volume record. 256 */ 257 struct afs_volume *afs_get_volume(struct afs_volume *volume, 258 enum afs_volume_trace reason) 259 { 260 if (volume) { 261 int r; 262 263 __refcount_inc(&volume->ref, &r); 264 trace_afs_volume(volume->vid, r + 1, reason); 265 } 266 return volume; 267 } 268 269 270 /* 271 * Drop a reference on a volume record. 272 */ 273 void afs_put_volume(struct afs_net *net, struct afs_volume *volume, 274 enum afs_volume_trace reason) 275 { 276 if (volume) { 277 afs_volid_t vid = volume->vid; 278 bool zero; 279 int r; 280 281 zero = __refcount_dec_and_test(&volume->ref, &r); 282 trace_afs_volume(vid, r - 1, reason); 283 if (zero) 284 afs_destroy_volume(net, volume); 285 } 286 } 287 288 /* 289 * Activate a volume. 290 */ 291 int afs_activate_volume(struct afs_volume *volume) 292 { 293 #ifdef CONFIG_AFS_FSCACHE 294 struct fscache_volume *vcookie; 295 char *name; 296 297 name = kasprintf(GFP_KERNEL, "afs,%s,%llx", 298 volume->cell->name, volume->vid); 299 if (!name) 300 return -ENOMEM; 301 302 vcookie = fscache_acquire_volume(name, NULL, NULL, 0); 303 if (IS_ERR(vcookie)) { 304 if (vcookie != ERR_PTR(-EBUSY)) { 305 kfree(name); 306 return PTR_ERR(vcookie); 307 } 308 pr_err("AFS: Cache volume key already in use (%s)\n", name); 309 vcookie = NULL; 310 } 311 volume->cache = vcookie; 312 kfree(name); 313 #endif 314 return 0; 315 } 316 317 /* 318 * Deactivate a volume. 319 */ 320 void afs_deactivate_volume(struct afs_volume *volume) 321 { 322 _enter("%s", volume->name); 323 324 #ifdef CONFIG_AFS_FSCACHE 325 fscache_relinquish_volume(volume->cache, NULL, 326 test_bit(AFS_VOLUME_DELETED, &volume->flags)); 327 volume->cache = NULL; 328 #endif 329 330 _leave(""); 331 } 332 333 /* 334 * Query the VL service to update the volume status. 335 */ 336 static int afs_update_volume_status(struct afs_volume *volume, struct key *key) 337 { 338 struct afs_server_list *new, *old, *discard; 339 struct afs_vldb_entry *vldb; 340 char idbuf[16]; 341 int ret, idsz; 342 343 _enter(""); 344 345 /* We look up an ID by passing it as a decimal string in the 346 * operation's name parameter. 347 */ 348 idsz = sprintf(idbuf, "%llu", volume->vid); 349 350 vldb = afs_vl_lookup_vldb(volume->cell, key, idbuf, idsz); 351 if (IS_ERR(vldb)) { 352 ret = PTR_ERR(vldb); 353 goto error; 354 } 355 356 /* See if the volume got renamed. */ 357 if (vldb->name_len != volume->name_len || 358 memcmp(vldb->name, volume->name, vldb->name_len) != 0) { 359 /* TODO: Use RCU'd string. */ 360 memcpy(volume->name, vldb->name, AFS_MAXVOLNAME); 361 volume->name_len = vldb->name_len; 362 } 363 364 /* See if the volume's server list got updated. */ 365 new = afs_alloc_server_list(volume->cell, key, 366 vldb, (1 << volume->type)); 367 if (IS_ERR(new)) { 368 ret = PTR_ERR(new); 369 goto error_vldb; 370 } 371 372 write_lock(&volume->servers_lock); 373 374 discard = new; 375 old = rcu_dereference_protected(volume->servers, 376 lockdep_is_held(&volume->servers_lock)); 377 if (afs_annotate_server_list(new, old)) { 378 new->seq = volume->servers_seq + 1; 379 rcu_assign_pointer(volume->servers, new); 380 smp_wmb(); 381 volume->servers_seq++; 382 discard = old; 383 } 384 385 volume->update_at = ktime_get_real_seconds() + afs_volume_record_life; 386 write_unlock(&volume->servers_lock); 387 ret = 0; 388 389 afs_put_serverlist(volume->cell->net, discard); 390 error_vldb: 391 kfree(vldb); 392 error: 393 _leave(" = %d", ret); 394 return ret; 395 } 396 397 /* 398 * Make sure the volume record is up to date. 399 */ 400 int afs_check_volume_status(struct afs_volume *volume, struct afs_operation *op) 401 { 402 int ret, retries = 0; 403 404 _enter(""); 405 406 retry: 407 if (test_bit(AFS_VOLUME_WAIT, &volume->flags)) 408 goto wait; 409 if (volume->update_at <= ktime_get_real_seconds() || 410 test_bit(AFS_VOLUME_NEEDS_UPDATE, &volume->flags)) 411 goto update; 412 _leave(" = 0"); 413 return 0; 414 415 update: 416 if (!test_and_set_bit_lock(AFS_VOLUME_UPDATING, &volume->flags)) { 417 clear_bit(AFS_VOLUME_NEEDS_UPDATE, &volume->flags); 418 ret = afs_update_volume_status(volume, op->key); 419 if (ret < 0) 420 set_bit(AFS_VOLUME_NEEDS_UPDATE, &volume->flags); 421 clear_bit_unlock(AFS_VOLUME_WAIT, &volume->flags); 422 clear_bit_unlock(AFS_VOLUME_UPDATING, &volume->flags); 423 wake_up_bit(&volume->flags, AFS_VOLUME_WAIT); 424 _leave(" = %d", ret); 425 return ret; 426 } 427 428 wait: 429 if (!test_bit(AFS_VOLUME_WAIT, &volume->flags)) { 430 _leave(" = 0 [no wait]"); 431 return 0; 432 } 433 434 ret = wait_on_bit(&volume->flags, AFS_VOLUME_WAIT, 435 (op->flags & AFS_OPERATION_UNINTR) ? 436 TASK_UNINTERRUPTIBLE : TASK_INTERRUPTIBLE); 437 if (ret == -ERESTARTSYS) { 438 _leave(" = %d", ret); 439 return ret; 440 } 441 442 retries++; 443 if (retries == 4) { 444 _leave(" = -ESTALE"); 445 return -ESTALE; 446 } 447 goto retry; 448 } 449