Root/fs/lockd/svclock.c

1/*
2 * linux/fs/lockd/svclock.c
3 *
4 * Handling of server-side locks, mostly of the blocked variety.
5 * This is the ugliest part of lockd because we tread on very thin ice.
6 * GRANT and CANCEL calls may get stuck, meet in mid-flight, etc.
7 * IMNSHO introducing the grant callback into the NLM protocol was one
8 * of the worst ideas Sun ever had. Except maybe for the idea of doing
9 * NFS file locking at all.
10 *
11 * I'm trying hard to avoid race conditions by protecting most accesses
12 * to a file's list of blocked locks through a semaphore. The global
13 * list of blocked locks is not protected in this fashion however.
14 * Therefore, some functions (such as the RPC callback for the async grant
15 * call) move blocked locks towards the head of the list *while some other
16 * process might be traversing it*. This should not be a problem in
17 * practice, because this will only cause functions traversing the list
18 * to visit some blocks twice.
19 *
20 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
21 */
22
23#include <linux/types.h>
24#include <linux/slab.h>
25#include <linux/errno.h>
26#include <linux/kernel.h>
27#include <linux/sched.h>
28#include <linux/sunrpc/clnt.h>
29#include <linux/sunrpc/svc.h>
30#include <linux/lockd/nlm.h>
31#include <linux/lockd/lockd.h>
32#include <linux/kthread.h>
33
34#define NLMDBG_FACILITY NLMDBG_SVCLOCK
35
36#ifdef CONFIG_LOCKD_V4
37#define nlm_deadlock nlm4_deadlock
38#else
39#define nlm_deadlock nlm_lck_denied
40#endif
41
42static void nlmsvc_release_block(struct nlm_block *block);
43static void nlmsvc_insert_block(struct nlm_block *block, unsigned long);
44static void nlmsvc_remove_block(struct nlm_block *block);
45
46static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock);
47static void nlmsvc_freegrantargs(struct nlm_rqst *call);
48static const struct rpc_call_ops nlmsvc_grant_ops;
49static const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie);
50
51/*
52 * The list of blocked locks to retry
53 */
54static LIST_HEAD(nlm_blocked);
55static DEFINE_SPINLOCK(nlm_blocked_lock);
56
57/*
58 * Insert a blocked lock into the global list
59 */
60static void
61nlmsvc_insert_block_locked(struct nlm_block *block, unsigned long when)
62{
63    struct nlm_block *b;
64    struct list_head *pos;
65
66    dprintk("lockd: nlmsvc_insert_block(%p, %ld)\n", block, when);
67    if (list_empty(&block->b_list)) {
68        kref_get(&block->b_count);
69    } else {
70        list_del_init(&block->b_list);
71    }
72
73    pos = &nlm_blocked;
74    if (when != NLM_NEVER) {
75        if ((when += jiffies) == NLM_NEVER)
76            when ++;
77        list_for_each(pos, &nlm_blocked) {
78            b = list_entry(pos, struct nlm_block, b_list);
79            if (time_after(b->b_when,when) || b->b_when == NLM_NEVER)
80                break;
81        }
82        /* On normal exit from the loop, pos == &nlm_blocked,
83         * so we will be adding to the end of the list - good
84         */
85    }
86
87    list_add_tail(&block->b_list, pos);
88    block->b_when = when;
89}
90
91static void nlmsvc_insert_block(struct nlm_block *block, unsigned long when)
92{
93    spin_lock(&nlm_blocked_lock);
94    nlmsvc_insert_block_locked(block, when);
95    spin_unlock(&nlm_blocked_lock);
96}
97
98/*
99 * Remove a block from the global list
100 */
101static inline void
102nlmsvc_remove_block(struct nlm_block *block)
103{
104    if (!list_empty(&block->b_list)) {
105        spin_lock(&nlm_blocked_lock);
106        list_del_init(&block->b_list);
107        spin_unlock(&nlm_blocked_lock);
108        nlmsvc_release_block(block);
109    }
110}
111
112/*
113 * Find a block for a given lock
114 */
115static struct nlm_block *
116nlmsvc_lookup_block(struct nlm_file *file, struct nlm_lock *lock)
117{
118    struct nlm_block *block;
119    struct file_lock *fl;
120
121    dprintk("lockd: nlmsvc_lookup_block f=%p pd=%d %Ld-%Ld ty=%d\n",
122                file, lock->fl.fl_pid,
123                (long long)lock->fl.fl_start,
124                (long long)lock->fl.fl_end, lock->fl.fl_type);
125    list_for_each_entry(block, &nlm_blocked, b_list) {
126        fl = &block->b_call->a_args.lock.fl;
127        dprintk("lockd: check f=%p pd=%d %Ld-%Ld ty=%d cookie=%s\n",
128                block->b_file, fl->fl_pid,
129                (long long)fl->fl_start,
130                (long long)fl->fl_end, fl->fl_type,
131                nlmdbg_cookie2a(&block->b_call->a_args.cookie));
132        if (block->b_file == file && nlm_compare_locks(fl, &lock->fl)) {
133            kref_get(&block->b_count);
134            return block;
135        }
136    }
137
138    return NULL;
139}
140
141static inline int nlm_cookie_match(struct nlm_cookie *a, struct nlm_cookie *b)
142{
143    if (a->len != b->len)
144        return 0;
145    if (memcmp(a->data, b->data, a->len))
146        return 0;
147    return 1;
148}
149
150/*
151 * Find a block with a given NLM cookie.
152 */
153static inline struct nlm_block *
154nlmsvc_find_block(struct nlm_cookie *cookie)
155{
156    struct nlm_block *block;
157
158    list_for_each_entry(block, &nlm_blocked, b_list) {
159        if (nlm_cookie_match(&block->b_call->a_args.cookie,cookie))
160            goto found;
161    }
162
163    return NULL;
164
165found:
166    dprintk("nlmsvc_find_block(%s): block=%p\n", nlmdbg_cookie2a(cookie), block);
167    kref_get(&block->b_count);
168    return block;
169}
170
171/*
172 * Create a block and initialize it.
173 *
174 * Note: we explicitly set the cookie of the grant reply to that of
175 * the blocked lock request. The spec explicitly mentions that the client
176 * should _not_ rely on the callback containing the same cookie as the
177 * request, but (as I found out later) that's because some implementations
178 * do just this. Never mind the standards comittees, they support our
179 * logging industries.
180 *
181 * 10 years later: I hope we can safely ignore these old and broken
182 * clients by now. Let's fix this so we can uniquely identify an incoming
183 * GRANTED_RES message by cookie, without having to rely on the client's IP
184 * address. --okir
185 */
186static struct nlm_block *
187nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_host *host,
188            struct nlm_file *file, struct nlm_lock *lock,
189            struct nlm_cookie *cookie)
190{
191    struct nlm_block *block;
192    struct nlm_rqst *call = NULL;
193
194    nlm_get_host(host);
195    call = nlm_alloc_call(host);
196    if (call == NULL)
197        return NULL;
198
199    /* Allocate memory for block, and initialize arguments */
200    block = kzalloc(sizeof(*block), GFP_KERNEL);
201    if (block == NULL)
202        goto failed;
203    kref_init(&block->b_count);
204    INIT_LIST_HEAD(&block->b_list);
205    INIT_LIST_HEAD(&block->b_flist);
206
207    if (!nlmsvc_setgrantargs(call, lock))
208        goto failed_free;
209
210    /* Set notifier function for VFS, and init args */
211    call->a_args.lock.fl.fl_flags |= FL_SLEEP;
212    call->a_args.lock.fl.fl_lmops = &nlmsvc_lock_operations;
213    nlmclnt_next_cookie(&call->a_args.cookie);
214
215    dprintk("lockd: created block %p...\n", block);
216
217    /* Create and initialize the block */
218    block->b_daemon = rqstp->rq_server;
219    block->b_host = host;
220    block->b_file = file;
221    block->b_fl = NULL;
222    file->f_count++;
223
224    /* Add to file's list of blocks */
225    list_add(&block->b_flist, &file->f_blocks);
226
227    /* Set up RPC arguments for callback */
228    block->b_call = call;
229    call->a_flags = RPC_TASK_ASYNC;
230    call->a_block = block;
231
232    return block;
233
234failed_free:
235    kfree(block);
236failed:
237    nlmsvc_release_call(call);
238    return NULL;
239}
240
241/*
242 * Delete a block.
243 * It is the caller's responsibility to check whether the file
244 * can be closed hereafter.
245 */
246static int nlmsvc_unlink_block(struct nlm_block *block)
247{
248    int status;
249    dprintk("lockd: unlinking block %p...\n", block);
250
251    /* Remove block from list */
252    status = posix_unblock_lock(block->b_file->f_file, &block->b_call->a_args.lock.fl);
253    nlmsvc_remove_block(block);
254    return status;
255}
256
257static void nlmsvc_free_block(struct kref *kref)
258{
259    struct nlm_block *block = container_of(kref, struct nlm_block, b_count);
260    struct nlm_file *file = block->b_file;
261
262    dprintk("lockd: freeing block %p...\n", block);
263
264    /* Remove block from file's list of blocks */
265    mutex_lock(&file->f_mutex);
266    list_del_init(&block->b_flist);
267    mutex_unlock(&file->f_mutex);
268
269    nlmsvc_freegrantargs(block->b_call);
270    nlmsvc_release_call(block->b_call);
271    nlm_release_file(block->b_file);
272    kfree(block->b_fl);
273    kfree(block);
274}
275
276static void nlmsvc_release_block(struct nlm_block *block)
277{
278    if (block != NULL)
279        kref_put(&block->b_count, nlmsvc_free_block);
280}
281
282/*
283 * Loop over all blocks and delete blocks held by
284 * a matching host.
285 */
286void nlmsvc_traverse_blocks(struct nlm_host *host,
287            struct nlm_file *file,
288            nlm_host_match_fn_t match)
289{
290    struct nlm_block *block, *next;
291
292restart:
293    mutex_lock(&file->f_mutex);
294    list_for_each_entry_safe(block, next, &file->f_blocks, b_flist) {
295        if (!match(block->b_host, host))
296            continue;
297        /* Do not destroy blocks that are not on
298         * the global retry list - why? */
299        if (list_empty(&block->b_list))
300            continue;
301        kref_get(&block->b_count);
302        mutex_unlock(&file->f_mutex);
303        nlmsvc_unlink_block(block);
304        nlmsvc_release_block(block);
305        goto restart;
306    }
307    mutex_unlock(&file->f_mutex);
308}
309
310/*
311 * Initialize arguments for GRANTED call. The nlm_rqst structure
312 * has been cleared already.
313 */
314static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock)
315{
316    locks_copy_lock(&call->a_args.lock.fl, &lock->fl);
317    memcpy(&call->a_args.lock.fh, &lock->fh, sizeof(call->a_args.lock.fh));
318    call->a_args.lock.caller = utsname()->nodename;
319    call->a_args.lock.oh.len = lock->oh.len;
320
321    /* set default data area */
322    call->a_args.lock.oh.data = call->a_owner;
323    call->a_args.lock.svid = lock->fl.fl_pid;
324
325    if (lock->oh.len > NLMCLNT_OHSIZE) {
326        void *data = kmalloc(lock->oh.len, GFP_KERNEL);
327        if (!data)
328            return 0;
329        call->a_args.lock.oh.data = (u8 *) data;
330    }
331
332    memcpy(call->a_args.lock.oh.data, lock->oh.data, lock->oh.len);
333    return 1;
334}
335
336static void nlmsvc_freegrantargs(struct nlm_rqst *call)
337{
338    if (call->a_args.lock.oh.data != call->a_owner)
339        kfree(call->a_args.lock.oh.data);
340
341    locks_release_private(&call->a_args.lock.fl);
342}
343
344/*
345 * Deferred lock request handling for non-blocking lock
346 */
347static __be32
348nlmsvc_defer_lock_rqst(struct svc_rqst *rqstp, struct nlm_block *block)
349{
350    __be32 status = nlm_lck_denied_nolocks;
351
352    block->b_flags |= B_QUEUED;
353
354    nlmsvc_insert_block(block, NLM_TIMEOUT);
355
356    block->b_cache_req = &rqstp->rq_chandle;
357    if (rqstp->rq_chandle.defer) {
358        block->b_deferred_req =
359            rqstp->rq_chandle.defer(block->b_cache_req);
360        if (block->b_deferred_req != NULL)
361            status = nlm_drop_reply;
362    }
363    dprintk("lockd: nlmsvc_defer_lock_rqst block %p flags %d status %d\n",
364        block, block->b_flags, ntohl(status));
365
366    return status;
367}
368
369/*
370 * Attempt to establish a lock, and if it can't be granted, block it
371 * if required.
372 */
373__be32
374nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
375        struct nlm_host *host, struct nlm_lock *lock, int wait,
376        struct nlm_cookie *cookie, int reclaim)
377{
378    struct nlm_block *block = NULL;
379    int error;
380    __be32 ret;
381
382    dprintk("lockd: nlmsvc_lock(%s/%ld, ty=%d, pi=%d, %Ld-%Ld, bl=%d)\n",
383                file->f_file->f_path.dentry->d_inode->i_sb->s_id,
384                file->f_file->f_path.dentry->d_inode->i_ino,
385                lock->fl.fl_type, lock->fl.fl_pid,
386                (long long)lock->fl.fl_start,
387                (long long)lock->fl.fl_end,
388                wait);
389
390    /* Lock file against concurrent access */
391    mutex_lock(&file->f_mutex);
392    /* Get existing block (in case client is busy-waiting)
393     * or create new block
394     */
395    block = nlmsvc_lookup_block(file, lock);
396    if (block == NULL) {
397        block = nlmsvc_create_block(rqstp, host, file, lock, cookie);
398        ret = nlm_lck_denied_nolocks;
399        if (block == NULL)
400            goto out;
401        lock = &block->b_call->a_args.lock;
402    } else
403        lock->fl.fl_flags &= ~FL_SLEEP;
404
405    if (block->b_flags & B_QUEUED) {
406        dprintk("lockd: nlmsvc_lock deferred block %p flags %d\n",
407                            block, block->b_flags);
408        if (block->b_granted) {
409            nlmsvc_unlink_block(block);
410            ret = nlm_granted;
411            goto out;
412        }
413        if (block->b_flags & B_TIMED_OUT) {
414            nlmsvc_unlink_block(block);
415            ret = nlm_lck_denied;
416            goto out;
417        }
418        ret = nlm_drop_reply;
419        goto out;
420    }
421
422    if (locks_in_grace() && !reclaim) {
423        ret = nlm_lck_denied_grace_period;
424        goto out;
425    }
426    if (reclaim && !locks_in_grace()) {
427        ret = nlm_lck_denied_grace_period;
428        goto out;
429    }
430
431    if (!wait)
432        lock->fl.fl_flags &= ~FL_SLEEP;
433    error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL);
434    lock->fl.fl_flags &= ~FL_SLEEP;
435
436    dprintk("lockd: vfs_lock_file returned %d\n", error);
437    switch (error) {
438        case 0:
439            ret = nlm_granted;
440            goto out;
441        case -EAGAIN:
442            /*
443             * If this is a blocking request for an
444             * already pending lock request then we need
445             * to put it back on lockd's block list
446             */
447            if (wait)
448                break;
449            ret = nlm_lck_denied;
450            goto out;
451        case FILE_LOCK_DEFERRED:
452            if (wait)
453                break;
454            /* Filesystem lock operation is in progress
455               Add it to the queue waiting for callback */
456            ret = nlmsvc_defer_lock_rqst(rqstp, block);
457            goto out;
458        case -EDEADLK:
459            ret = nlm_deadlock;
460            goto out;
461        default: /* includes ENOLCK */
462            ret = nlm_lck_denied_nolocks;
463            goto out;
464    }
465
466    ret = nlm_lck_blocked;
467
468    /* Append to list of blocked */
469    nlmsvc_insert_block(block, NLM_NEVER);
470out:
471    mutex_unlock(&file->f_mutex);
472    nlmsvc_release_block(block);
473    dprintk("lockd: nlmsvc_lock returned %u\n", ret);
474    return ret;
475}
476
477/*
478 * Test for presence of a conflicting lock.
479 */
480__be32
481nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
482        struct nlm_host *host, struct nlm_lock *lock,
483        struct nlm_lock *conflock, struct nlm_cookie *cookie)
484{
485    struct nlm_block *block = NULL;
486    int error;
487    __be32 ret;
488
489    dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n",
490                file->f_file->f_path.dentry->d_inode->i_sb->s_id,
491                file->f_file->f_path.dentry->d_inode->i_ino,
492                lock->fl.fl_type,
493                (long long)lock->fl.fl_start,
494                (long long)lock->fl.fl_end);
495
496    /* Get existing block (in case client is busy-waiting) */
497    block = nlmsvc_lookup_block(file, lock);
498
499    if (block == NULL) {
500        struct file_lock *conf = kzalloc(sizeof(*conf), GFP_KERNEL);
501
502        if (conf == NULL)
503            return nlm_granted;
504        block = nlmsvc_create_block(rqstp, host, file, lock, cookie);
505        if (block == NULL) {
506            kfree(conf);
507            return nlm_granted;
508        }
509        block->b_fl = conf;
510    }
511    if (block->b_flags & B_QUEUED) {
512        dprintk("lockd: nlmsvc_testlock deferred block %p flags %d fl %p\n",
513            block, block->b_flags, block->b_fl);
514        if (block->b_flags & B_TIMED_OUT) {
515            nlmsvc_unlink_block(block);
516            ret = nlm_lck_denied;
517            goto out;
518        }
519        if (block->b_flags & B_GOT_CALLBACK) {
520            nlmsvc_unlink_block(block);
521            if (block->b_fl != NULL
522                    && block->b_fl->fl_type != F_UNLCK) {
523                lock->fl = *block->b_fl;
524                goto conf_lock;
525            } else {
526                ret = nlm_granted;
527                goto out;
528            }
529        }
530        ret = nlm_drop_reply;
531        goto out;
532    }
533
534    if (locks_in_grace()) {
535        ret = nlm_lck_denied_grace_period;
536        goto out;
537    }
538    error = vfs_test_lock(file->f_file, &lock->fl);
539    if (error == FILE_LOCK_DEFERRED) {
540        ret = nlmsvc_defer_lock_rqst(rqstp, block);
541        goto out;
542    }
543    if (error) {
544        ret = nlm_lck_denied_nolocks;
545        goto out;
546    }
547    if (lock->fl.fl_type == F_UNLCK) {
548        ret = nlm_granted;
549        goto out;
550    }
551
552conf_lock:
553    dprintk("lockd: conflicting lock(ty=%d, %Ld-%Ld)\n",
554        lock->fl.fl_type, (long long)lock->fl.fl_start,
555        (long long)lock->fl.fl_end);
556    conflock->caller = "somehost"; /* FIXME */
557    conflock->len = strlen(conflock->caller);
558    conflock->oh.len = 0; /* don't return OH info */
559    conflock->svid = lock->fl.fl_pid;
560    conflock->fl.fl_type = lock->fl.fl_type;
561    conflock->fl.fl_start = lock->fl.fl_start;
562    conflock->fl.fl_end = lock->fl.fl_end;
563    ret = nlm_lck_denied;
564out:
565    if (block)
566        nlmsvc_release_block(block);
567    return ret;
568}
569
570/*
571 * Remove a lock.
572 * This implies a CANCEL call: We send a GRANT_MSG, the client replies
573 * with a GRANT_RES call which gets lost, and calls UNLOCK immediately
574 * afterwards. In this case the block will still be there, and hence
575 * must be removed.
576 */
577__be32
578nlmsvc_unlock(struct nlm_file *file, struct nlm_lock *lock)
579{
580    int error;
581
582    dprintk("lockd: nlmsvc_unlock(%s/%ld, pi=%d, %Ld-%Ld)\n",
583                file->f_file->f_path.dentry->d_inode->i_sb->s_id,
584                file->f_file->f_path.dentry->d_inode->i_ino,
585                lock->fl.fl_pid,
586                (long long)lock->fl.fl_start,
587                (long long)lock->fl.fl_end);
588
589    /* First, cancel any lock that might be there */
590    nlmsvc_cancel_blocked(file, lock);
591
592    lock->fl.fl_type = F_UNLCK;
593    error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL);
594
595    return (error < 0)? nlm_lck_denied_nolocks : nlm_granted;
596}
597
598/*
599 * Cancel a previously blocked request.
600 *
601 * A cancel request always overrides any grant that may currently
602 * be in progress.
603 * The calling procedure must check whether the file can be closed.
604 */
605__be32
606nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock)
607{
608    struct nlm_block *block;
609    int status = 0;
610
611    dprintk("lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)\n",
612                file->f_file->f_path.dentry->d_inode->i_sb->s_id,
613                file->f_file->f_path.dentry->d_inode->i_ino,
614                lock->fl.fl_pid,
615                (long long)lock->fl.fl_start,
616                (long long)lock->fl.fl_end);
617
618    if (locks_in_grace())
619        return nlm_lck_denied_grace_period;
620
621    mutex_lock(&file->f_mutex);
622    block = nlmsvc_lookup_block(file, lock);
623    mutex_unlock(&file->f_mutex);
624    if (block != NULL) {
625        vfs_cancel_lock(block->b_file->f_file,
626                &block->b_call->a_args.lock.fl);
627        status = nlmsvc_unlink_block(block);
628        nlmsvc_release_block(block);
629    }
630    return status ? nlm_lck_denied : nlm_granted;
631}
632
633/*
634 * This is a callback from the filesystem for VFS file lock requests.
635 * It will be used if fl_grant is defined and the filesystem can not
636 * respond to the request immediately.
637 * For GETLK request it will copy the reply to the nlm_block.
638 * For SETLK or SETLKW request it will get the local posix lock.
639 * In all cases it will move the block to the head of nlm_blocked q where
640 * nlmsvc_retry_blocked() can send back a reply for SETLKW or revisit the
641 * deferred rpc for GETLK and SETLK.
642 */
643static void
644nlmsvc_update_deferred_block(struct nlm_block *block, struct file_lock *conf,
645                 int result)
646{
647    block->b_flags |= B_GOT_CALLBACK;
648    if (result == 0)
649        block->b_granted = 1;
650    else
651        block->b_flags |= B_TIMED_OUT;
652    if (conf) {
653        if (block->b_fl)
654            __locks_copy_lock(block->b_fl, conf);
655    }
656}
657
658static int nlmsvc_grant_deferred(struct file_lock *fl, struct file_lock *conf,
659                    int result)
660{
661    struct nlm_block *block;
662    int rc = -ENOENT;
663
664    spin_lock(&nlm_blocked_lock);
665    list_for_each_entry(block, &nlm_blocked, b_list) {
666        if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) {
667            dprintk("lockd: nlmsvc_notify_blocked block %p flags %d\n",
668                            block, block->b_flags);
669            if (block->b_flags & B_QUEUED) {
670                if (block->b_flags & B_TIMED_OUT) {
671                    rc = -ENOLCK;
672                    break;
673                }
674                nlmsvc_update_deferred_block(block, conf, result);
675            } else if (result == 0)
676                block->b_granted = 1;
677
678            nlmsvc_insert_block_locked(block, 0);
679            svc_wake_up(block->b_daemon);
680            rc = 0;
681            break;
682        }
683    }
684    spin_unlock(&nlm_blocked_lock);
685    if (rc == -ENOENT)
686        printk(KERN_WARNING "lockd: grant for unknown block\n");
687    return rc;
688}
689
690/*
691 * Unblock a blocked lock request. This is a callback invoked from the
692 * VFS layer when a lock on which we blocked is removed.
693 *
694 * This function doesn't grant the blocked lock instantly, but rather moves
695 * the block to the head of nlm_blocked where it can be picked up by lockd.
696 */
697static void
698nlmsvc_notify_blocked(struct file_lock *fl)
699{
700    struct nlm_block *block;
701
702    dprintk("lockd: VFS unblock notification for block %p\n", fl);
703    spin_lock(&nlm_blocked_lock);
704    list_for_each_entry(block, &nlm_blocked, b_list) {
705        if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) {
706            nlmsvc_insert_block_locked(block, 0);
707            spin_unlock(&nlm_blocked_lock);
708            svc_wake_up(block->b_daemon);
709            return;
710        }
711    }
712    spin_unlock(&nlm_blocked_lock);
713    printk(KERN_WARNING "lockd: notification for unknown block!\n");
714}
715
716static int nlmsvc_same_owner(struct file_lock *fl1, struct file_lock *fl2)
717{
718    return fl1->fl_owner == fl2->fl_owner && fl1->fl_pid == fl2->fl_pid;
719}
720
721const struct lock_manager_operations nlmsvc_lock_operations = {
722    .fl_compare_owner = nlmsvc_same_owner,
723    .fl_notify = nlmsvc_notify_blocked,
724    .fl_grant = nlmsvc_grant_deferred,
725};
726
727/*
728 * Try to claim a lock that was previously blocked.
729 *
730 * Note that we use both the RPC_GRANTED_MSG call _and_ an async
731 * RPC thread when notifying the client. This seems like overkill...
732 * Here's why:
733 * - we don't want to use a synchronous RPC thread, otherwise
734 * we might find ourselves hanging on a dead portmapper.
735 * - Some lockd implementations (e.g. HP) don't react to
736 * RPC_GRANTED calls; they seem to insist on RPC_GRANTED_MSG calls.
737 */
738static void
739nlmsvc_grant_blocked(struct nlm_block *block)
740{
741    struct nlm_file *file = block->b_file;
742    struct nlm_lock *lock = &block->b_call->a_args.lock;
743    int error;
744
745    dprintk("lockd: grant blocked lock %p\n", block);
746
747    kref_get(&block->b_count);
748
749    /* Unlink block request from list */
750    nlmsvc_unlink_block(block);
751
752    /* If b_granted is true this means we've been here before.
753     * Just retry the grant callback, possibly refreshing the RPC
754     * binding */
755    if (block->b_granted) {
756        nlm_rebind_host(block->b_host);
757        goto callback;
758    }
759
760    /* Try the lock operation again */
761    lock->fl.fl_flags |= FL_SLEEP;
762    error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL);
763    lock->fl.fl_flags &= ~FL_SLEEP;
764
765    switch (error) {
766    case 0:
767        break;
768    case FILE_LOCK_DEFERRED:
769        dprintk("lockd: lock still blocked error %d\n", error);
770        nlmsvc_insert_block(block, NLM_NEVER);
771        nlmsvc_release_block(block);
772        return;
773    default:
774        printk(KERN_WARNING "lockd: unexpected error %d in %s!\n",
775                -error, __func__);
776        nlmsvc_insert_block(block, 10 * HZ);
777        nlmsvc_release_block(block);
778        return;
779    }
780
781callback:
782    /* Lock was granted by VFS. */
783    dprintk("lockd: GRANTing blocked lock.\n");
784    block->b_granted = 1;
785
786    /* keep block on the list, but don't reattempt until the RPC
787     * completes or the submission fails
788     */
789    nlmsvc_insert_block(block, NLM_NEVER);
790
791    /* Call the client -- use a soft RPC task since nlmsvc_retry_blocked
792     * will queue up a new one if this one times out
793     */
794    error = nlm_async_call(block->b_call, NLMPROC_GRANTED_MSG,
795                &nlmsvc_grant_ops);
796
797    /* RPC submission failed, wait a bit and retry */
798    if (error < 0)
799        nlmsvc_insert_block(block, 10 * HZ);
800}
801
802/*
803 * This is the callback from the RPC layer when the NLM_GRANTED_MSG
804 * RPC call has succeeded or timed out.
805 * Like all RPC callbacks, it is invoked by the rpciod process, so it
806 * better not sleep. Therefore, we put the blocked lock on the nlm_blocked
807 * chain once more in order to have it removed by lockd itself (which can
808 * then sleep on the file semaphore without disrupting e.g. the nfs client).
809 */
810static void nlmsvc_grant_callback(struct rpc_task *task, void *data)
811{
812    struct nlm_rqst *call = data;
813    struct nlm_block *block = call->a_block;
814    unsigned long timeout;
815
816    dprintk("lockd: GRANT_MSG RPC callback\n");
817
818    spin_lock(&nlm_blocked_lock);
819    /* if the block is not on a list at this point then it has
820     * been invalidated. Don't try to requeue it.
821     *
822     * FIXME: it's possible that the block is removed from the list
823     * after this check but before the nlmsvc_insert_block. In that
824     * case it will be added back. Perhaps we need better locking
825     * for nlm_blocked?
826     */
827    if (list_empty(&block->b_list))
828        goto out;
829
830    /* Technically, we should down the file semaphore here. Since we
831     * move the block towards the head of the queue only, no harm
832     * can be done, though. */
833    if (task->tk_status < 0) {
834        /* RPC error: Re-insert for retransmission */
835        timeout = 10 * HZ;
836    } else {
837        /* Call was successful, now wait for client callback */
838        timeout = 60 * HZ;
839    }
840    nlmsvc_insert_block_locked(block, timeout);
841    svc_wake_up(block->b_daemon);
842out:
843    spin_unlock(&nlm_blocked_lock);
844}
845
846/*
847 * FIXME: nlmsvc_release_block() grabs a mutex. This is not allowed for an
848 * .rpc_release rpc_call_op
849 */
850static void nlmsvc_grant_release(void *data)
851{
852    struct nlm_rqst *call = data;
853    nlmsvc_release_block(call->a_block);
854}
855
856static const struct rpc_call_ops nlmsvc_grant_ops = {
857    .rpc_call_done = nlmsvc_grant_callback,
858    .rpc_release = nlmsvc_grant_release,
859};
860
861/*
862 * We received a GRANT_RES callback. Try to find the corresponding
863 * block.
864 */
865void
866nlmsvc_grant_reply(struct nlm_cookie *cookie, __be32 status)
867{
868    struct nlm_block *block;
869
870    dprintk("grant_reply: looking for cookie %x, s=%d \n",
871        *(unsigned int *)(cookie->data), status);
872    if (!(block = nlmsvc_find_block(cookie)))
873        return;
874
875    if (block) {
876        if (status == nlm_lck_denied_grace_period) {
877            /* Try again in a couple of seconds */
878            nlmsvc_insert_block(block, 10 * HZ);
879        } else {
880            /* Lock is now held by client, or has been rejected.
881             * In both cases, the block should be removed. */
882            nlmsvc_unlink_block(block);
883        }
884    }
885    nlmsvc_release_block(block);
886}
887
888/* Helper function to handle retry of a deferred block.
889 * If it is a blocking lock, call grant_blocked.
890 * For a non-blocking lock or test lock, revisit the request.
891 */
892static void
893retry_deferred_block(struct nlm_block *block)
894{
895    if (!(block->b_flags & B_GOT_CALLBACK))
896        block->b_flags |= B_TIMED_OUT;
897    nlmsvc_insert_block(block, NLM_TIMEOUT);
898    dprintk("revisit block %p flags %d\n", block, block->b_flags);
899    if (block->b_deferred_req) {
900        block->b_deferred_req->revisit(block->b_deferred_req, 0);
901        block->b_deferred_req = NULL;
902    }
903}
904
905/*
906 * Retry all blocked locks that have been notified. This is where lockd
907 * picks up locks that can be granted, or grant notifications that must
908 * be retransmitted.
909 */
910unsigned long
911nlmsvc_retry_blocked(void)
912{
913    unsigned long timeout = MAX_SCHEDULE_TIMEOUT;
914    struct nlm_block *block;
915
916    while (!list_empty(&nlm_blocked) && !kthread_should_stop()) {
917        block = list_entry(nlm_blocked.next, struct nlm_block, b_list);
918
919        if (block->b_when == NLM_NEVER)
920            break;
921        if (time_after(block->b_when, jiffies)) {
922            timeout = block->b_when - jiffies;
923            break;
924        }
925
926        dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n",
927            block, block->b_when);
928        if (block->b_flags & B_QUEUED) {
929            dprintk("nlmsvc_retry_blocked delete block (%p, granted=%d, flags=%d)\n",
930                block, block->b_granted, block->b_flags);
931            retry_deferred_block(block);
932        } else
933            nlmsvc_grant_blocked(block);
934    }
935
936    return timeout;
937}
938
939#ifdef RPC_DEBUG
940static const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie)
941{
942    /*
943     * We can get away with a static buffer because we're only
944     * called with BKL held.
945     */
946    static char buf[2*NLM_MAXCOOKIELEN+1];
947    unsigned int i, len = sizeof(buf);
948    char *p = buf;
949
950    len--; /* allow for trailing \0 */
951    if (len < 3)
952        return "???";
953    for (i = 0 ; i < cookie->len ; i++) {
954        if (len < 2) {
955            strcpy(p-3, "...");
956            break;
957        }
958        sprintf(p, "%02x", cookie->data[i]);
959        p += 2;
960        len -= 2;
961    }
962    *p = '\0';
963
964    return buf;
965}
966#endif
967

Archive Download this file



interactive