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