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>
34 #define NLMDBG_FACILITY NLMDBG_SVCLOCK
36 #ifdef CONFIG_LOCKD_V4
37 #define nlm_deadlock nlm4_deadlock
39 #define nlm_deadlock nlm_lck_denied
42 static void nlmsvc_release_block(
struct nlm_block *
block);
43 static void nlmsvc_insert_block(
struct nlm_block *
block,
unsigned long);
44 static void nlmsvc_remove_block(
struct nlm_block *
block);
46 static int nlmsvc_setgrantargs(
struct nlm_rqst *call,
struct nlm_lock *lock);
47 static void nlmsvc_freegrantargs(
struct nlm_rqst *call);
64 unsigned int i,
len =
sizeof(
buf);
70 for (i = 0 ; i < cookie->
len ; i++) {
89 nlmsvc_insert_block_locked(
struct nlm_block *
block,
unsigned long when)
94 dprintk(
"lockd: nlmsvc_insert_block(%p, %ld)\n", block, when);
95 if (list_empty(&block->b_list)) {
96 kref_get(&block->b_count);
98 list_del_init(&block->b_list);
102 if (when != NLM_NEVER) {
103 if ((when += jiffies) == NLM_NEVER)
106 b =
list_entry(pos,
struct nlm_block, b_list);
107 if (
time_after(b->b_when,when) || b->b_when == NLM_NEVER)
116 block->b_when = when;
119 static void nlmsvc_insert_block(
struct nlm_block *block,
unsigned long when)
121 spin_lock(&nlm_blocked_lock);
122 nlmsvc_insert_block_locked(block, when);
123 spin_unlock(&nlm_blocked_lock);
130 nlmsvc_remove_block(
struct nlm_block *block)
132 if (!list_empty(&block->b_list)) {
133 spin_lock(&nlm_blocked_lock);
134 list_del_init(&block->b_list);
135 spin_unlock(&nlm_blocked_lock);
136 nlmsvc_release_block(block);
143 static struct nlm_block *
144 nlmsvc_lookup_block(
struct nlm_file *
file,
struct nlm_lock *lock)
146 struct nlm_block *
block;
149 dprintk(
"lockd: nlmsvc_lookup_block f=%p pd=%d %Ld-%Ld ty=%d\n",
150 file, lock->
fl.fl_pid,
151 (
long long)lock->
fl.fl_start,
152 (
long long)lock->
fl.fl_end, lock->
fl.fl_type);
154 fl = &block->b_call->a_args.lock.fl;
155 dprintk(
"lockd: check f=%p pd=%d %Ld-%Ld ty=%d cookie=%s\n",
156 block->b_file, fl->
fl_pid,
159 nlmdbg_cookie2a(&block->b_call->a_args.cookie));
160 if (block->b_file == file && nlm_compare_locks(fl, &lock->
fl)) {
161 kref_get(&block->b_count);
181 static inline struct nlm_block *
184 struct nlm_block *
block;
187 if (nlm_cookie_match(&block->b_call->a_args.cookie,cookie))
194 dprintk(
"nlmsvc_find_block(%s): block=%p\n", nlmdbg_cookie2a(cookie), block);
195 kref_get(&block->b_count);
214 static struct nlm_block *
215 nlmsvc_create_block(
struct svc_rqst *rqstp,
struct nlm_host *
host,
216 struct nlm_file *file,
struct nlm_lock *lock,
219 struct nlm_block *
block;
220 struct nlm_rqst *call =
NULL;
230 kref_init(&block->b_count);
231 INIT_LIST_HEAD(&block->b_list);
232 INIT_LIST_HEAD(&block->b_flist);
234 if (!nlmsvc_setgrantargs(call, lock))
238 call->a_args.lock.fl.fl_flags |=
FL_SLEEP;
242 dprintk(
"lockd: created block %p...\n", block);
246 block->b_host = host;
247 block->b_file =
file;
252 list_add(&block->b_flist, &file->f_blocks);
255 block->b_call = call;
257 call->a_block =
block;
273 static int nlmsvc_unlink_block(
struct nlm_block *block)
276 dprintk(
"lockd: unlinking block %p...\n", block);
280 nlmsvc_remove_block(block);
284 static void nlmsvc_free_block(
struct kref *
kref)
286 struct nlm_block *block =
container_of(kref,
struct nlm_block, b_count);
287 struct nlm_file *file = block->b_file;
289 dprintk(
"lockd: freeing block %p...\n", block);
292 list_del_init(&block->b_flist);
295 nlmsvc_freegrantargs(block->b_call);
302 static void nlmsvc_release_block(
struct nlm_block *block)
305 kref_put_mutex(&block->b_count, nlmsvc_free_block, &block->b_file->f_mutex);
313 struct nlm_file *file,
314 nlm_host_match_fn_t
match)
321 if (!
match(block->b_host, host))
325 if (list_empty(&block->b_list))
327 kref_get(&block->b_count);
329 nlmsvc_unlink_block(block);
330 nlmsvc_release_block(block);
340 static int nlmsvc_setgrantargs(
struct nlm_rqst *call,
struct nlm_lock *lock)
343 memcpy(&call->a_args.lock.fh, &lock->
fh,
sizeof(call->a_args.lock.fh));
344 call->a_args.lock.caller = utsname()->nodename;
345 call->a_args.lock.oh.len = lock->
oh.len;
348 call->a_args.lock.oh.data = call->a_owner;
349 call->a_args.lock.svid = lock->
fl.fl_pid;
351 if (lock->
oh.len > NLMCLNT_OHSIZE) {
355 call->a_args.lock.oh.data = (
u8 *) data;
358 memcpy(call->a_args.lock.oh.data, lock->
oh.data, lock->
oh.len);
362 static void nlmsvc_freegrantargs(
struct nlm_rqst *call)
364 if (call->a_args.lock.oh.data != call->a_owner)
365 kfree(call->a_args.lock.oh.data);
374 nlmsvc_defer_lock_rqst(
struct svc_rqst *rqstp,
struct nlm_block *block)
378 block->b_flags |= B_QUEUED;
380 nlmsvc_insert_block(block, NLM_TIMEOUT);
384 block->b_deferred_req =
386 if (block->b_deferred_req !=
NULL)
389 dprintk(
"lockd: nlmsvc_defer_lock_rqst block %p flags %d status %d\n",
390 block, block->b_flags,
ntohl(status));
404 struct nlm_block *block =
NULL;
408 dprintk(
"lockd: nlmsvc_lock(%s/%ld, ty=%d, pi=%d, %Ld-%Ld, bl=%d)\n",
409 file->f_file->f_path.dentry->d_inode->i_sb->s_id,
410 file->f_file->f_path.dentry->d_inode->i_ino,
411 lock->
fl.fl_type, lock->
fl.fl_pid,
412 (
long long)lock->
fl.fl_start,
413 (
long long)lock->
fl.fl_end,
421 block = nlmsvc_lookup_block(file, lock);
423 block = nlmsvc_create_block(rqstp, host, file, lock, cookie);
427 lock = &block->b_call->a_args.lock;
431 if (block->b_flags & B_QUEUED) {
432 dprintk(
"lockd: nlmsvc_lock deferred block %p flags %d\n",
433 block, block->b_flags);
434 if (block->b_granted) {
435 nlmsvc_unlink_block(block);
439 if (block->b_flags & B_TIMED_OUT) {
440 nlmsvc_unlink_block(block);
462 dprintk(
"lockd: vfs_lock_file returned %d\n", error);
482 ret = nlmsvc_defer_lock_rqst(rqstp, block);
495 nlmsvc_insert_block(block, NLM_NEVER);
498 nlmsvc_release_block(block);
499 dprintk(
"lockd: nlmsvc_lock returned %u\n", ret);
508 struct nlm_host *host,
struct nlm_lock *lock,
511 struct nlm_block *block =
NULL;
515 dprintk(
"lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n",
516 file->f_file->f_path.dentry->d_inode->i_sb->s_id,
517 file->f_file->f_path.dentry->d_inode->i_ino,
519 (
long long)lock->
fl.fl_start,
520 (
long long)lock->
fl.fl_end);
523 block = nlmsvc_lookup_block(file, lock);
530 block = nlmsvc_create_block(rqstp, host, file, lock, cookie);
537 if (block->b_flags & B_QUEUED) {
538 dprintk(
"lockd: nlmsvc_testlock deferred block %p flags %d fl %p\n",
539 block, block->b_flags, block->b_fl);
540 if (block->b_flags & B_TIMED_OUT) {
541 nlmsvc_unlink_block(block);
545 if (block->b_flags & B_GOT_CALLBACK) {
546 nlmsvc_unlink_block(block);
547 if (block->b_fl !=
NULL
548 && block->b_fl->fl_type !=
F_UNLCK) {
549 lock->
fl = *block->b_fl;
566 ret = nlmsvc_defer_lock_rqst(rqstp, block);
579 dprintk(
"lockd: conflicting lock(ty=%d, %Ld-%Ld)\n",
580 lock->
fl.fl_type, (
long long)lock->
fl.fl_start,
581 (
long long)lock->
fl.fl_end);
582 conflock->
caller =
"somehost";
584 conflock->
oh.len = 0;
585 conflock->
svid = lock->
fl.fl_pid;
586 conflock->
fl.fl_type = lock->
fl.fl_type;
587 conflock->
fl.fl_start = lock->
fl.fl_start;
588 conflock->
fl.fl_end = lock->
fl.fl_end;
592 nlmsvc_release_block(block);
608 dprintk(
"lockd: nlmsvc_unlock(%s/%ld, pi=%d, %Ld-%Ld)\n",
609 file->f_file->f_path.dentry->d_inode->i_sb->s_id,
610 file->f_file->f_path.dentry->d_inode->i_ino,
612 (
long long)lock->
fl.fl_start,
613 (
long long)lock->
fl.fl_end);
634 struct nlm_block *
block;
637 dprintk(
"lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)\n",
638 file->f_file->f_path.dentry->d_inode->i_sb->s_id,
639 file->f_file->f_path.dentry->d_inode->i_ino,
641 (
long long)lock->
fl.fl_start,
642 (
long long)lock->
fl.fl_end);
648 block = nlmsvc_lookup_block(file, lock);
652 &block->b_call->a_args.lock.fl);
653 status = nlmsvc_unlink_block(block);
654 nlmsvc_release_block(block);
670 nlmsvc_update_deferred_block(
struct nlm_block *block,
struct file_lock *conf,
673 block->b_flags |= B_GOT_CALLBACK;
675 block->b_granted = 1;
677 block->b_flags |= B_TIMED_OUT;
687 struct nlm_block *
block;
690 spin_lock(&nlm_blocked_lock);
692 if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) {
693 dprintk(
"lockd: nlmsvc_notify_blocked block %p flags %d\n",
694 block, block->b_flags);
695 if (block->b_flags & B_QUEUED) {
696 if (block->b_flags & B_TIMED_OUT) {
700 nlmsvc_update_deferred_block(block, conf, result);
701 }
else if (result == 0)
702 block->b_granted = 1;
704 nlmsvc_insert_block_locked(block, 0);
710 spin_unlock(&nlm_blocked_lock);
724 nlmsvc_notify_blocked(
struct file_lock *fl)
726 struct nlm_block *
block;
728 dprintk(
"lockd: VFS unblock notification for block %p\n", fl);
729 spin_lock(&nlm_blocked_lock);
731 if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) {
732 nlmsvc_insert_block_locked(block, 0);
733 spin_unlock(&nlm_blocked_lock);
738 spin_unlock(&nlm_blocked_lock);
748 .lm_compare_owner = nlmsvc_same_owner,
749 .lm_notify = nlmsvc_notify_blocked,
750 .lm_grant = nlmsvc_grant_deferred,
765 nlmsvc_grant_blocked(
struct nlm_block *block)
767 struct nlm_file *file = block->b_file;
768 struct nlm_lock *lock = &block->b_call->a_args.lock;
771 dprintk(
"lockd: grant blocked lock %p\n", block);
773 kref_get(&block->b_count);
776 nlmsvc_unlink_block(block);
781 if (block->b_granted) {
795 dprintk(
"lockd: lock still blocked error %d\n", error);
796 nlmsvc_insert_block(block, NLM_NEVER);
797 nlmsvc_release_block(block);
802 nlmsvc_insert_block(block, 10 *
HZ);
803 nlmsvc_release_block(block);
809 dprintk(
"lockd: GRANTing blocked lock.\n");
810 block->b_granted = 1;
815 nlmsvc_insert_block(block, NLM_NEVER);
825 nlmsvc_insert_block(block, 10 *
HZ);
838 struct nlm_rqst *call =
data;
839 struct nlm_block *block = call->a_block;
842 dprintk(
"lockd: GRANT_MSG RPC callback\n");
844 spin_lock(&nlm_blocked_lock);
853 if (list_empty(&block->b_list))
866 nlmsvc_insert_block_locked(block, timeout);
869 spin_unlock(&nlm_blocked_lock);
876 static void nlmsvc_grant_release(
void *data)
878 struct nlm_rqst *call =
data;
879 nlmsvc_release_block(call->a_block);
883 .rpc_call_done = nlmsvc_grant_callback,
884 .rpc_release = nlmsvc_grant_release,
894 struct nlm_block *
block;
896 dprintk(
"grant_reply: looking for cookie %x, s=%d \n",
897 *(
unsigned int *)(cookie->
data), status);
898 if (!(block = nlmsvc_find_block(cookie)))
904 nlmsvc_insert_block(block, 10 *
HZ);
908 nlmsvc_unlink_block(block);
911 nlmsvc_release_block(block);
919 retry_deferred_block(
struct nlm_block *block)
921 if (!(block->b_flags & B_GOT_CALLBACK))
922 block->b_flags |= B_TIMED_OUT;
923 nlmsvc_insert_block(block, NLM_TIMEOUT);
924 dprintk(
"revisit block %p flags %d\n", block, block->b_flags);
925 if (block->b_deferred_req) {
926 block->b_deferred_req->revisit(block->b_deferred_req, 0);
927 block->b_deferred_req =
NULL;
940 struct nlm_block *
block;
943 block =
list_entry(nlm_blocked.next,
struct nlm_block, b_list);
945 if (block->b_when == NLM_NEVER)
948 timeout = block->b_when -
jiffies;
952 dprintk(
"nlmsvc_retry_blocked(%p, when=%ld)\n",
953 block, block->b_when);
954 if (block->b_flags & B_QUEUED) {
955 dprintk(
"nlmsvc_retry_blocked delete block (%p, granted=%d, flags=%d)\n",
956 block, block->b_granted, block->b_flags);
957 retry_deferred_block(block);
959 nlmsvc_grant_blocked(block);