ext4: avoid online resizing failures due to oversized flex bg
[platform/kernel/linux-starfive.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;
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 }