afs: Use a dynamic port if 7001 is in use
[linux-2.6-block.git] / fs / afs / flock.c
CommitLineData
e8d6c554
DH
1/* AFS file locking support
2 *
3 * Copyright (C) 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
e8d6c554
DH
12#include "internal.h"
13
14#define AFS_LOCK_GRANTED 0
15#define AFS_LOCK_PENDING 1
16
f044c884
DH
17struct workqueue_struct *afs_lock_manager;
18
e8d6c554
DH
19static void afs_fl_copy_lock(struct file_lock *new, struct file_lock *fl);
20static void afs_fl_release_private(struct file_lock *fl);
21
6aed6285 22static const struct file_lock_operations afs_lock_ops = {
e8d6c554
DH
23 .fl_copy_lock = afs_fl_copy_lock,
24 .fl_release_private = afs_fl_release_private,
25};
26
e8d6c554
DH
27/*
28 * if the callback is broken on this vnode, then the lock may now be available
29 */
30void afs_lock_may_be_available(struct afs_vnode *vnode)
31{
32 _enter("{%x:%u}", vnode->fid.vid, vnode->fid.vnode);
33
34 queue_delayed_work(afs_lock_manager, &vnode->lock_work, 0);
35}
36
37/*
38 * the lock will time out in 5 minutes unless we extend it, so schedule
39 * extension in a bit less than that time
40 */
41static void afs_schedule_lock_extension(struct afs_vnode *vnode)
42{
43 queue_delayed_work(afs_lock_manager, &vnode->lock_work,
44 AFS_LOCKWAIT * HZ / 2);
45}
46
ff8e210a
DH
47/*
48 * grant one or more locks (readlocks are allowed to jump the queue if the
49 * first lock in the queue is itself a readlock)
50 * - the caller must hold the vnode lock
51 */
52static void afs_grant_locks(struct afs_vnode *vnode, struct file_lock *fl)
53{
54 struct file_lock *p, *_p;
55
56 list_move_tail(&fl->fl_u.afs.link, &vnode->granted_locks);
57 if (fl->fl_type == F_RDLCK) {
58 list_for_each_entry_safe(p, _p, &vnode->pending_locks,
59 fl_u.afs.link) {
60 if (p->fl_type == F_RDLCK) {
61 p->fl_u.afs.state = AFS_LOCK_GRANTED;
62 list_move_tail(&p->fl_u.afs.link,
63 &vnode->granted_locks);
64 wake_up(&p->fl_wait);
65 }
66 }
67 }
68}
69
d2ddc776
DH
70/*
71 * Get a lock on a file
72 */
73static int afs_set_lock(struct afs_vnode *vnode, struct key *key,
74 afs_lock_type_t type)
75{
76 struct afs_fs_cursor fc;
77 int ret;
78
79 _enter("%s{%x:%u.%u},%x,%u",
80 vnode->volume->name,
81 vnode->fid.vid,
82 vnode->fid.vnode,
83 vnode->fid.unique,
84 key_serial(key), type);
85
86 ret = -ERESTARTSYS;
87 if (afs_begin_vnode_operation(&fc, vnode, key)) {
88 while (afs_select_fileserver(&fc)) {
89 fc.cb_break = vnode->cb_break + vnode->cb_s_break;
90 afs_fs_set_lock(&fc, type);
91 }
92
93 afs_check_for_remote_deletion(&fc, fc.vnode);
94 afs_vnode_commit_status(&fc, vnode, fc.cb_break);
95 ret = afs_end_vnode_operation(&fc);
96 }
97
98 _leave(" = %d", ret);
99 return ret;
100}
101
102/*
103 * Extend a lock on a file
104 */
105static int afs_extend_lock(struct afs_vnode *vnode, struct key *key)
106{
107 struct afs_fs_cursor fc;
108 int ret;
109
110 _enter("%s{%x:%u.%u},%x",
111 vnode->volume->name,
112 vnode->fid.vid,
113 vnode->fid.vnode,
114 vnode->fid.unique,
115 key_serial(key));
116
117 ret = -ERESTARTSYS;
118 if (afs_begin_vnode_operation(&fc, vnode, key)) {
119 while (afs_select_current_fileserver(&fc)) {
120 fc.cb_break = vnode->cb_break + vnode->cb_s_break;
121 afs_fs_extend_lock(&fc);
122 }
123
124 afs_check_for_remote_deletion(&fc, fc.vnode);
125 afs_vnode_commit_status(&fc, vnode, fc.cb_break);
126 ret = afs_end_vnode_operation(&fc);
127 }
128
129 _leave(" = %d", ret);
130 return ret;
131}
132
133/*
134 * Release a lock on a file
135 */
136static int afs_release_lock(struct afs_vnode *vnode, struct key *key)
137{
138 struct afs_fs_cursor fc;
139 int ret;
140
141 _enter("%s{%x:%u.%u},%x",
142 vnode->volume->name,
143 vnode->fid.vid,
144 vnode->fid.vnode,
145 vnode->fid.unique,
146 key_serial(key));
147
148 ret = -ERESTARTSYS;
149 if (afs_begin_vnode_operation(&fc, vnode, key)) {
150 while (afs_select_current_fileserver(&fc)) {
151 fc.cb_break = vnode->cb_break + vnode->cb_s_break;
152 afs_fs_release_lock(&fc);
153 }
154
155 afs_check_for_remote_deletion(&fc, fc.vnode);
156 afs_vnode_commit_status(&fc, vnode, fc.cb_break);
157 ret = afs_end_vnode_operation(&fc);
158 }
159
160 _leave(" = %d", ret);
161 return ret;
162}
163
e8d6c554
DH
164/*
165 * do work for a lock, including:
166 * - probing for a lock we're waiting on but didn't get immediately
167 * - extending a lock that's close to timing out
168 */
169void afs_lock_work(struct work_struct *work)
170{
171 struct afs_vnode *vnode =
172 container_of(work, struct afs_vnode, lock_work.work);
173 struct file_lock *fl;
174 afs_lock_type_t type;
175 struct key *key;
176 int ret;
177
178 _enter("{%x:%u}", vnode->fid.vid, vnode->fid.vnode);
179
180 spin_lock(&vnode->lock);
181
182 if (test_bit(AFS_VNODE_UNLOCKING, &vnode->flags)) {
183 _debug("unlock");
184 spin_unlock(&vnode->lock);
185
186 /* attempt to release the server lock; if it fails, we just
187 * wait 5 minutes and it'll time out anyway */
d2ddc776 188 ret = afs_release_lock(vnode, vnode->unlock_key);
e8d6c554
DH
189 if (ret < 0)
190 printk(KERN_WARNING "AFS:"
191 " Failed to release lock on {%x:%x} error %d\n",
192 vnode->fid.vid, vnode->fid.vnode, ret);
193
194 spin_lock(&vnode->lock);
195 key_put(vnode->unlock_key);
196 vnode->unlock_key = NULL;
197 clear_bit(AFS_VNODE_UNLOCKING, &vnode->flags);
198 }
199
200 /* if we've got a lock, then it must be time to extend that lock as AFS
201 * locks time out after 5 minutes */
202 if (!list_empty(&vnode->granted_locks)) {
203 _debug("extend");
204
205 if (test_and_set_bit(AFS_VNODE_LOCKING, &vnode->flags))
206 BUG();
207 fl = list_entry(vnode->granted_locks.next,
208 struct file_lock, fl_u.afs.link);
209 key = key_get(fl->fl_file->private_data);
210 spin_unlock(&vnode->lock);
211
d2ddc776 212 ret = afs_extend_lock(vnode, key);
e8d6c554
DH
213 clear_bit(AFS_VNODE_LOCKING, &vnode->flags);
214 key_put(key);
215 switch (ret) {
216 case 0:
217 afs_schedule_lock_extension(vnode);
218 break;
219 default:
220 /* ummm... we failed to extend the lock - retry
221 * extension shortly */
222 printk(KERN_WARNING "AFS:"
223 " Failed to extend lock on {%x:%x} error %d\n",
224 vnode->fid.vid, vnode->fid.vnode, ret);
225 queue_delayed_work(afs_lock_manager, &vnode->lock_work,
226 HZ * 10);
227 break;
228 }
229 _leave(" [extend]");
230 return;
231 }
232
233 /* if we don't have a granted lock, then we must've been called back by
234 * the server, and so if might be possible to get a lock we're
235 * currently waiting for */
236 if (!list_empty(&vnode->pending_locks)) {
237 _debug("get");
238
239 if (test_and_set_bit(AFS_VNODE_LOCKING, &vnode->flags))
240 BUG();
241 fl = list_entry(vnode->pending_locks.next,
242 struct file_lock, fl_u.afs.link);
243 key = key_get(fl->fl_file->private_data);
244 type = (fl->fl_type == F_RDLCK) ?
245 AFS_LOCK_READ : AFS_LOCK_WRITE;
246 spin_unlock(&vnode->lock);
247
d2ddc776 248 ret = afs_set_lock(vnode, key, type);
e8d6c554
DH
249 clear_bit(AFS_VNODE_LOCKING, &vnode->flags);
250 switch (ret) {
251 case -EWOULDBLOCK:
252 _debug("blocked");
253 break;
254 case 0:
255 _debug("acquired");
256 if (type == AFS_LOCK_READ)
257 set_bit(AFS_VNODE_READLOCKED, &vnode->flags);
258 else
259 set_bit(AFS_VNODE_WRITELOCKED, &vnode->flags);
260 ret = AFS_LOCK_GRANTED;
261 default:
262 spin_lock(&vnode->lock);
263 /* the pending lock may have been withdrawn due to a
264 * signal */
265 if (list_entry(vnode->pending_locks.next,
266 struct file_lock, fl_u.afs.link) == fl) {
267 fl->fl_u.afs.state = ret;
268 if (ret == AFS_LOCK_GRANTED)
ff8e210a 269 afs_grant_locks(vnode, fl);
e8d6c554
DH
270 else
271 list_del_init(&fl->fl_u.afs.link);
272 wake_up(&fl->fl_wait);
273 spin_unlock(&vnode->lock);
274 } else {
275 _debug("withdrawn");
276 clear_bit(AFS_VNODE_READLOCKED, &vnode->flags);
277 clear_bit(AFS_VNODE_WRITELOCKED, &vnode->flags);
278 spin_unlock(&vnode->lock);
d2ddc776 279 afs_release_lock(vnode, key);
e8d6c554
DH
280 if (!list_empty(&vnode->pending_locks))
281 afs_lock_may_be_available(vnode);
282 }
283 break;
284 }
285 key_put(key);
286 _leave(" [pend]");
287 return;
288 }
289
290 /* looks like the lock request was withdrawn on a signal */
291 spin_unlock(&vnode->lock);
292 _leave(" [no locks]");
293}
294
295/*
296 * pass responsibility for the unlocking of a vnode on the server to the
297 * manager thread, lest a pending signal in the calling thread interrupt
298 * AF_RXRPC
299 * - the caller must hold the vnode lock
300 */
301static void afs_defer_unlock(struct afs_vnode *vnode, struct key *key)
302{
303 cancel_delayed_work(&vnode->lock_work);
304 if (!test_and_clear_bit(AFS_VNODE_READLOCKED, &vnode->flags) &&
305 !test_and_clear_bit(AFS_VNODE_WRITELOCKED, &vnode->flags))
306 BUG();
307 if (test_and_set_bit(AFS_VNODE_UNLOCKING, &vnode->flags))
308 BUG();
309 vnode->unlock_key = key_get(key);
310 afs_lock_may_be_available(vnode);
311}
312
313/*
314 * request a lock on a file on the server
315 */
316static int afs_do_setlk(struct file *file, struct file_lock *fl)
317{
1c8c601a
JL
318 struct inode *inode = file_inode(file);
319 struct afs_vnode *vnode = AFS_FS_I(inode);
e8d6c554
DH
320 afs_lock_type_t type;
321 struct key *key = file->private_data;
322 int ret;
323
324 _enter("{%x:%u},%u", vnode->fid.vid, vnode->fid.vnode, fl->fl_type);
325
326 /* only whole-file locks are supported */
327 if (fl->fl_start != 0 || fl->fl_end != OFFSET_MAX)
328 return -EINVAL;
329
e8d6c554
DH
330 fl->fl_ops = &afs_lock_ops;
331 INIT_LIST_HEAD(&fl->fl_u.afs.link);
332 fl->fl_u.afs.state = AFS_LOCK_PENDING;
333
334 type = (fl->fl_type == F_RDLCK) ? AFS_LOCK_READ : AFS_LOCK_WRITE;
335
1c8c601a 336 spin_lock(&inode->i_lock);
e8d6c554
DH
337
338 /* make sure we've got a callback on this file and that our view of the
339 * data version is up to date */
c435ee34 340 ret = afs_validate(vnode, key);
e8d6c554
DH
341 if (ret < 0)
342 goto error;
343
344 if (vnode->status.lock_count != 0 && !(fl->fl_flags & FL_SLEEP)) {
345 ret = -EAGAIN;
346 goto error;
347 }
348
349 spin_lock(&vnode->lock);
350
ff8e210a
DH
351 /* if we've already got a readlock on the server then we can instantly
352 * grant another readlock, irrespective of whether there are any
353 * pending writelocks */
354 if (type == AFS_LOCK_READ &&
355 vnode->flags & (1 << AFS_VNODE_READLOCKED)) {
356 _debug("instant readlock");
357 ASSERTCMP(vnode->flags &
358 ((1 << AFS_VNODE_LOCKING) |
359 (1 << AFS_VNODE_WRITELOCKED)), ==, 0);
360 ASSERT(!list_empty(&vnode->granted_locks));
361 goto sharing_existing_lock;
362 }
e8d6c554 363
ff8e210a
DH
364 /* if there's no-one else with a lock on this vnode, then we need to
365 * ask the server for a lock */
366 if (list_empty(&vnode->pending_locks) &&
367 list_empty(&vnode->granted_locks)) {
368 _debug("not locked");
369 ASSERTCMP(vnode->flags &
370 ((1 << AFS_VNODE_LOCKING) |
371 (1 << AFS_VNODE_READLOCKED) |
372 (1 << AFS_VNODE_WRITELOCKED)), ==, 0);
373 list_add_tail(&fl->fl_u.afs.link, &vnode->pending_locks);
374 set_bit(AFS_VNODE_LOCKING, &vnode->flags);
375 spin_unlock(&vnode->lock);
e8d6c554 376
d2ddc776 377 ret = afs_set_lock(vnode, key, type);
ff8e210a
DH
378 clear_bit(AFS_VNODE_LOCKING, &vnode->flags);
379 switch (ret) {
380 case 0:
381 _debug("acquired");
382 goto acquired_server_lock;
383 case -EWOULDBLOCK:
384 _debug("would block");
385 spin_lock(&vnode->lock);
386 ASSERT(list_empty(&vnode->granted_locks));
387 ASSERTCMP(vnode->pending_locks.next, ==,
388 &fl->fl_u.afs.link);
389 goto wait;
390 default:
391 spin_lock(&vnode->lock);
392 list_del_init(&fl->fl_u.afs.link);
393 spin_unlock(&vnode->lock);
394 goto error;
e8d6c554
DH
395 }
396 }
397
398 /* otherwise, we need to wait for a local lock to become available */
399 _debug("wait local");
400 list_add_tail(&fl->fl_u.afs.link, &vnode->pending_locks);
401wait:
402 if (!(fl->fl_flags & FL_SLEEP)) {
403 _debug("noblock");
404 ret = -EAGAIN;
405 goto abort_attempt;
406 }
407 spin_unlock(&vnode->lock);
408
409 /* now we need to sleep and wait for the lock manager thread to get the
410 * lock from the server */
411 _debug("sleep");
412 ret = wait_event_interruptible(fl->fl_wait,
413 fl->fl_u.afs.state <= AFS_LOCK_GRANTED);
414 if (fl->fl_u.afs.state <= AFS_LOCK_GRANTED) {
415 ret = fl->fl_u.afs.state;
416 if (ret < 0)
417 goto error;
418 spin_lock(&vnode->lock);
419 goto given_lock;
420 }
421
422 /* we were interrupted, but someone may still be in the throes of
423 * giving us the lock */
424 _debug("intr");
425 ASSERTCMP(ret, ==, -ERESTARTSYS);
426
427 spin_lock(&vnode->lock);
428 if (fl->fl_u.afs.state <= AFS_LOCK_GRANTED) {
429 ret = fl->fl_u.afs.state;
430 if (ret < 0) {
431 spin_unlock(&vnode->lock);
432 goto error;
433 }
434 goto given_lock;
435 }
436
437abort_attempt:
438 /* we aren't going to get the lock, either because we're unwilling to
439 * wait, or because some signal happened */
440 _debug("abort");
441 if (list_empty(&vnode->granted_locks) &&
442 vnode->pending_locks.next == &fl->fl_u.afs.link) {
443 if (vnode->pending_locks.prev != &fl->fl_u.afs.link) {
444 /* kick the next pending lock into having a go */
445 list_del_init(&fl->fl_u.afs.link);
446 afs_lock_may_be_available(vnode);
447 }
448 } else {
449 list_del_init(&fl->fl_u.afs.link);
450 }
451 spin_unlock(&vnode->lock);
452 goto error;
453
454acquired_server_lock:
455 /* we've acquired a server lock, but it needs to be renewed after 5
456 * mins */
457 spin_lock(&vnode->lock);
458 afs_schedule_lock_extension(vnode);
459 if (type == AFS_LOCK_READ)
460 set_bit(AFS_VNODE_READLOCKED, &vnode->flags);
461 else
462 set_bit(AFS_VNODE_WRITELOCKED, &vnode->flags);
463sharing_existing_lock:
464 /* the lock has been granted as far as we're concerned... */
465 fl->fl_u.afs.state = AFS_LOCK_GRANTED;
466 list_move_tail(&fl->fl_u.afs.link, &vnode->granted_locks);
467given_lock:
468 /* ... but we do still need to get the VFS's blessing */
469 ASSERT(!(vnode->flags & (1 << AFS_VNODE_LOCKING)));
470 ASSERT((vnode->flags & ((1 << AFS_VNODE_READLOCKED) |
471 (1 << AFS_VNODE_WRITELOCKED))) != 0);
472 ret = posix_lock_file(file, fl, NULL);
473 if (ret < 0)
474 goto vfs_rejected_lock;
475 spin_unlock(&vnode->lock);
476
477 /* again, make sure we've got a callback on this file and, again, make
478 * sure that our view of the data version is up to date (we ignore
479 * errors incurred here and deal with the consequences elsewhere) */
d2ddc776 480 afs_validate(vnode, key);
e8d6c554
DH
481
482error:
1c8c601a 483 spin_unlock(&inode->i_lock);
e8d6c554
DH
484 _leave(" = %d", ret);
485 return ret;
486
487vfs_rejected_lock:
488 /* the VFS rejected the lock we just obtained, so we have to discard
489 * what we just got */
490 _debug("vfs refused %d", ret);
491 list_del_init(&fl->fl_u.afs.link);
492 if (list_empty(&vnode->granted_locks))
493 afs_defer_unlock(vnode, key);
e8d6c554
DH
494 goto abort_attempt;
495}
496
497/*
498 * unlock on a file on the server
499 */
500static int afs_do_unlk(struct file *file, struct file_lock *fl)
501{
502 struct afs_vnode *vnode = AFS_FS_I(file->f_mapping->host);
503 struct key *key = file->private_data;
504 int ret;
505
506 _enter("{%x:%u},%u", vnode->fid.vid, vnode->fid.vnode, fl->fl_type);
507
508 /* only whole-file unlocks are supported */
509 if (fl->fl_start != 0 || fl->fl_end != OFFSET_MAX)
510 return -EINVAL;
511
512 fl->fl_ops = &afs_lock_ops;
513 INIT_LIST_HEAD(&fl->fl_u.afs.link);
514 fl->fl_u.afs.state = AFS_LOCK_PENDING;
515
516 spin_lock(&vnode->lock);
517 ret = posix_lock_file(file, fl, NULL);
518 if (ret < 0) {
519 spin_unlock(&vnode->lock);
520 _leave(" = %d [vfs]", ret);
521 return ret;
522 }
523
524 /* discard the server lock only if all granted locks are gone */
525 if (list_empty(&vnode->granted_locks))
526 afs_defer_unlock(vnode, key);
527 spin_unlock(&vnode->lock);
528 _leave(" = 0");
529 return 0;
530}
531
532/*
533 * return information about a lock we currently hold, if indeed we hold one
534 */
535static int afs_do_getlk(struct file *file, struct file_lock *fl)
536{
537 struct afs_vnode *vnode = AFS_FS_I(file->f_mapping->host);
538 struct key *key = file->private_data;
539 int ret, lock_count;
540
541 _enter("");
542
543 fl->fl_type = F_UNLCK;
544
5955102c 545 inode_lock(&vnode->vfs_inode);
e8d6c554
DH
546
547 /* check local lock records first */
548 ret = 0;
275afcac
AM
549 posix_test_lock(file, fl);
550 if (fl->fl_type == F_UNLCK) {
e8d6c554 551 /* no local locks; consult the server */
d2ddc776 552 ret = afs_fetch_status(vnode, key);
e8d6c554
DH
553 if (ret < 0)
554 goto error;
555 lock_count = vnode->status.lock_count;
556 if (lock_count) {
557 if (lock_count > 0)
558 fl->fl_type = F_RDLCK;
559 else
560 fl->fl_type = F_WRLCK;
561 fl->fl_start = 0;
562 fl->fl_end = OFFSET_MAX;
563 }
564 }
565
566error:
5955102c 567 inode_unlock(&vnode->vfs_inode);
e8d6c554
DH
568 _leave(" = %d [%hd]", ret, fl->fl_type);
569 return ret;
570}
571
572/*
573 * manage POSIX locks on a file
574 */
575int afs_lock(struct file *file, int cmd, struct file_lock *fl)
576{
496ad9aa 577 struct afs_vnode *vnode = AFS_FS_I(file_inode(file));
e8d6c554
DH
578
579 _enter("{%x:%u},%d,{t=%x,fl=%x,r=%Ld:%Ld}",
580 vnode->fid.vid, vnode->fid.vnode, cmd,
581 fl->fl_type, fl->fl_flags,
582 (long long) fl->fl_start, (long long) fl->fl_end);
583
584 /* AFS doesn't support mandatory locks */
fc5846e5 585 if (__mandatory_lock(&vnode->vfs_inode) && fl->fl_type != F_UNLCK)
e8d6c554
DH
586 return -ENOLCK;
587
588 if (IS_GETLK(cmd))
589 return afs_do_getlk(file, fl);
590 if (fl->fl_type == F_UNLCK)
591 return afs_do_unlk(file, fl);
592 return afs_do_setlk(file, fl);
593}
594
595/*
596 * manage FLOCK locks on a file
597 */
598int afs_flock(struct file *file, int cmd, struct file_lock *fl)
599{
496ad9aa 600 struct afs_vnode *vnode = AFS_FS_I(file_inode(file));
e8d6c554
DH
601
602 _enter("{%x:%u},%d,{t=%x,fl=%x}",
603 vnode->fid.vid, vnode->fid.vnode, cmd,
604 fl->fl_type, fl->fl_flags);
605
606 /*
607 * No BSD flocks over NFS allowed.
608 * Note: we could try to fake a POSIX lock request here by
609 * using ((u32) filp | 0x80000000) or some such as the pid.
610 * Not sure whether that would be unique, though, or whether
611 * that would break in other places.
612 */
613 if (!(fl->fl_flags & FL_FLOCK))
614 return -ENOLCK;
615
616 /* we're simulating flock() locks using posix locks on the server */
e8d6c554
DH
617 if (fl->fl_type == F_UNLCK)
618 return afs_do_unlk(file, fl);
619 return afs_do_setlk(file, fl);
620}
621
622/*
623 * the POSIX lock management core VFS code copies the lock record and adds the
624 * copy into its own list, so we need to add that copy to the vnode's lock
625 * queue in the same place as the original (which will be deleted shortly
626 * after)
627 */
628static void afs_fl_copy_lock(struct file_lock *new, struct file_lock *fl)
629{
630 _enter("");
631
632 list_add(&new->fl_u.afs.link, &fl->fl_u.afs.link);
633}
634
635/*
636 * need to remove this lock from the vnode queue when it's removed from the
637 * VFS's list
638 */
639static void afs_fl_release_private(struct file_lock *fl)
640{
641 _enter("");
642
643 list_del_init(&fl->fl_u.afs.link);
644}