net: core: another layer of lists, around PF_MEMALLOC skb handling
[linux-2.6-microblaze.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_mount_params *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_addr_cursor ac;
78         struct afs_vldb_entry *vldb;
79         int ret;
80
81         ret = afs_set_vl_cursor(&ac, cell);
82         if (ret < 0)
83                 return ERR_PTR(ret);
84
85         while (afs_iterate_addresses(&ac)) {
86                 if (!test_bit(ac.index, &ac.alist->probed)) {
87                         ret = afs_vl_get_capabilities(cell->net, &ac, key);
88                         switch (ret) {
89                         case VL_SERVICE:
90                                 clear_bit(ac.index, &ac.alist->yfs);
91                                 set_bit(ac.index, &ac.alist->probed);
92                                 ac.addr->srx_service = ret;
93                                 break;
94                         case YFS_VL_SERVICE:
95                                 set_bit(ac.index, &ac.alist->yfs);
96                                 set_bit(ac.index, &ac.alist->probed);
97                                 ac.addr->srx_service = ret;
98                                 break;
99                         }
100                 }
101                 
102                 vldb = afs_vl_get_entry_by_name_u(cell->net, &ac, key,
103                                                   volname, volnamesz);
104                 switch (ac.error) {
105                 case 0:
106                         afs_end_cursor(&ac);
107                         return vldb;
108                 case -ECONNABORTED:
109                         ac.error = afs_abort_to_error(ac.abort_code);
110                         goto error;
111                 case -ENOMEM:
112                 case -ENONET:
113                         goto error;
114                 case -ENETUNREACH:
115                 case -EHOSTUNREACH:
116                 case -ECONNREFUSED:
117                         break;
118                 default:
119                         ac.error = -EIO;
120                         goto error;
121                 }
122         }
123
124 error:
125         return ERR_PTR(afs_end_cursor(&ac));
126 }
127
128 /*
129  * Look up a volume in the VL server and create a candidate volume record for
130  * it.
131  *
132  * The volume name can be one of the following:
133  *      "%[cell:]volume[.]"             R/W volume
134  *      "#[cell:]volume[.]"             R/O or R/W volume (rwparent=0),
135  *                                       or R/W (rwparent=1) volume
136  *      "%[cell:]volume.readonly"       R/O volume
137  *      "#[cell:]volume.readonly"       R/O volume
138  *      "%[cell:]volume.backup"         Backup volume
139  *      "#[cell:]volume.backup"         Backup volume
140  *
141  * The cell name is optional, and defaults to the current cell.
142  *
143  * See "The Rules of Mount Point Traversal" in Chapter 5 of the AFS SysAdmin
144  * Guide
145  * - Rule 1: Explicit type suffix forces access of that type or nothing
146  *           (no suffix, then use Rule 2 & 3)
147  * - Rule 2: If parent volume is R/O, then mount R/O volume by preference, R/W
148  *           if not available
149  * - Rule 3: If parent volume is R/W, then only mount R/W volume unless
150  *           explicitly told otherwise
151  */
152 struct afs_volume *afs_create_volume(struct afs_mount_params *params)
153 {
154         struct afs_vldb_entry *vldb;
155         struct afs_volume *volume;
156         unsigned long type_mask = 1UL << params->type;
157
158         vldb = afs_vl_lookup_vldb(params->cell, params->key,
159                                   params->volname, params->volnamesz);
160         if (IS_ERR(vldb))
161                 return ERR_CAST(vldb);
162
163         if (test_bit(AFS_VLDB_QUERY_ERROR, &vldb->flags)) {
164                 volume = ERR_PTR(vldb->error);
165                 goto error;
166         }
167
168         /* Make the final decision on the type we want */
169         volume = ERR_PTR(-ENOMEDIUM);
170         if (params->force) {
171                 if (!(vldb->flags & type_mask))
172                         goto error;
173         } else if (test_bit(AFS_VLDB_HAS_RO, &vldb->flags)) {
174                 params->type = AFSVL_ROVOL;
175         } else if (test_bit(AFS_VLDB_HAS_RW, &vldb->flags)) {
176                 params->type = AFSVL_RWVOL;
177         } else {
178                 goto error;
179         }
180
181         type_mask = 1UL << params->type;
182         volume = afs_alloc_volume(params, vldb, type_mask);
183
184 error:
185         kfree(vldb);
186         return volume;
187 }
188
189 /*
190  * Destroy a volume record
191  */
192 static void afs_destroy_volume(struct afs_net *net, struct afs_volume *volume)
193 {
194         _enter("%p", volume);
195
196 #ifdef CONFIG_AFS_FSCACHE
197         ASSERTCMP(volume->cache, ==, NULL);
198 #endif
199
200         afs_put_serverlist(net, volume->servers);
201         afs_put_cell(net, volume->cell);
202         kfree(volume);
203
204         _leave(" [destroyed]");
205 }
206
207 /*
208  * Drop a reference on a volume record.
209  */
210 void afs_put_volume(struct afs_cell *cell, struct afs_volume *volume)
211 {
212         if (volume) {
213                 _enter("%s", volume->name);
214
215                 if (atomic_dec_and_test(&volume->usage))
216                         afs_destroy_volume(cell->net, volume);
217         }
218 }
219
220 /*
221  * Activate a volume.
222  */
223 void afs_activate_volume(struct afs_volume *volume)
224 {
225 #ifdef CONFIG_AFS_FSCACHE
226         volume->cache = fscache_acquire_cookie(volume->cell->cache,
227                                                &afs_volume_cache_index_def,
228                                                &volume->vid, sizeof(volume->vid),
229                                                NULL, 0,
230                                                volume, 0, true);
231 #endif
232
233         write_lock(&volume->cell->proc_lock);
234         list_add_tail(&volume->proc_link, &volume->cell->proc_volumes);
235         write_unlock(&volume->cell->proc_lock);
236 }
237
238 /*
239  * Deactivate a volume.
240  */
241 void afs_deactivate_volume(struct afs_volume *volume)
242 {
243         _enter("%s", volume->name);
244
245         write_lock(&volume->cell->proc_lock);
246         list_del_init(&volume->proc_link);
247         write_unlock(&volume->cell->proc_lock);
248
249 #ifdef CONFIG_AFS_FSCACHE
250         fscache_relinquish_cookie(volume->cache, NULL,
251                                   test_bit(AFS_VOLUME_DELETED, &volume->flags));
252         volume->cache = NULL;
253 #endif
254
255         _leave("");
256 }
257
258 /*
259  * Query the VL service to update the volume status.
260  */
261 static int afs_update_volume_status(struct afs_volume *volume, struct key *key)
262 {
263         struct afs_server_list *new, *old, *discard;
264         struct afs_vldb_entry *vldb;
265         char idbuf[16];
266         int ret, idsz;
267
268         _enter("");
269
270         /* We look up an ID by passing it as a decimal string in the
271          * operation's name parameter.
272          */
273         idsz = sprintf(idbuf, "%u", volume->vid);
274
275         vldb = afs_vl_lookup_vldb(volume->cell, key, idbuf, idsz);
276         if (IS_ERR(vldb)) {
277                 ret = PTR_ERR(vldb);
278                 goto error;
279         }
280
281         /* See if the volume got renamed. */
282         if (vldb->name_len != volume->name_len ||
283             memcmp(vldb->name, volume->name, vldb->name_len) != 0) {
284                 /* TODO: Use RCU'd string. */
285                 memcpy(volume->name, vldb->name, AFS_MAXVOLNAME);
286                 volume->name_len = vldb->name_len;
287         }
288
289         /* See if the volume's server list got updated. */
290         new = afs_alloc_server_list(volume->cell, key,
291                                     vldb, (1 << volume->type));
292         if (IS_ERR(new)) {
293                 ret = PTR_ERR(new);
294                 goto error_vldb;
295         }
296
297         write_lock(&volume->servers_lock);
298
299         discard = new;
300         old = volume->servers;
301         if (afs_annotate_server_list(new, old)) {
302                 new->seq = volume->servers_seq + 1;
303                 volume->servers = new;
304                 smp_wmb();
305                 volume->servers_seq++;
306                 discard = old;
307         }
308
309         volume->update_at = ktime_get_real_seconds() + afs_volume_record_life;
310         clear_bit(AFS_VOLUME_NEEDS_UPDATE, &volume->flags);
311         write_unlock(&volume->servers_lock);
312         ret = 0;
313
314         afs_put_serverlist(volume->cell->net, discard);
315 error_vldb:
316         kfree(vldb);
317 error:
318         _leave(" = %d", ret);
319         return ret;
320 }
321
322 /*
323  * Make sure the volume record is up to date.
324  */
325 int afs_check_volume_status(struct afs_volume *volume, struct key *key)
326 {
327         time64_t now = ktime_get_real_seconds();
328         int ret, retries = 0;
329
330         _enter("");
331
332         if (volume->update_at <= now)
333                 set_bit(AFS_VOLUME_NEEDS_UPDATE, &volume->flags);
334
335 retry:
336         if (!test_bit(AFS_VOLUME_NEEDS_UPDATE, &volume->flags) &&
337             !test_bit(AFS_VOLUME_WAIT, &volume->flags)) {
338                 _leave(" = 0");
339                 return 0;
340         }
341
342         if (!test_and_set_bit_lock(AFS_VOLUME_UPDATING, &volume->flags)) {
343                 ret = afs_update_volume_status(volume, key);
344                 clear_bit_unlock(AFS_VOLUME_WAIT, &volume->flags);
345                 clear_bit_unlock(AFS_VOLUME_UPDATING, &volume->flags);
346                 wake_up_bit(&volume->flags, AFS_VOLUME_WAIT);
347                 _leave(" = %d", ret);
348                 return ret;
349         }
350
351         if (!test_bit(AFS_VOLUME_WAIT, &volume->flags)) {
352                 _leave(" = 0 [no wait]");
353                 return 0;
354         }
355
356         ret = wait_on_bit(&volume->flags, AFS_VOLUME_WAIT, TASK_INTERRUPTIBLE);
357         if (ret == -ERESTARTSYS) {
358                 _leave(" = %d", ret);
359                 return ret;
360         }
361
362         retries++;
363         if (retries == 4) {
364                 _leave(" = -ESTALE");
365                 return -ESTALE;
366         }
367         goto retry;
368 }