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