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