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