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