diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-11-23 02:00:47 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-11-23 02:00:47 +0000 |
commit | 06615f62b17d7de6e12d2f5ec6b88cf30af08413 (patch) | |
tree | 8766f208847d4876a6db619aebbf54d53b76eb44 /fs/lockd | |
parent | fa9bdb574f4febb751848a685d9a9017e04e1d53 (diff) |
Merge with Linux 2.4.0-test10.
Diffstat (limited to 'fs/lockd')
-rw-r--r-- | fs/lockd/clntlock.c | 2 | ||||
-rw-r--r-- | fs/lockd/clntproc.c | 11 | ||||
-rw-r--r-- | fs/lockd/mon.c | 2 | ||||
-rw-r--r-- | fs/lockd/svclock.c | 47 |
4 files changed, 42 insertions, 20 deletions
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index 820bc4c7b..249e7514d 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c @@ -41,7 +41,7 @@ struct nlm_wait { u32 b_status; /* grant callback status */ }; -static struct nlm_wait * nlm_blocked = NULL; +static struct nlm_wait * nlm_blocked; /* * Block on a lock diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index c60f48da1..dbe3f69b5 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c @@ -11,6 +11,7 @@ #include <linux/fs.h> #include <linux/nfs_fs.h> #include <linux/utsname.h> +#include <linux/smp_lock.h> #include <linux/sunrpc/clnt.h> #include <linux/sunrpc/svc.h> #include <linux/lockd/lockd.h> @@ -64,11 +65,11 @@ nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl) int nlmclnt_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock) { - nlmclnt_next_cookie(&call->a_args.cookie); - call->a_args.lock = *lock; + locks_copy_lock(&call->a_args.lock.fl, &lock->fl); + memcpy(&call->a_args.lock.fh, &lock->fh, sizeof(call->a_args.lock.fh)); call->a_args.lock.caller = system_utsname.nodename; + call->a_args.lock.oh.len = lock->oh.len; - init_waitqueue_head(&call->a_args.lock.fl.fl_wait); /* set default data area */ call->a_args.lock.oh.data = call->a_owner; @@ -406,15 +407,19 @@ nlmclnt_test(struct nlm_rqst *req, struct file_lock *fl) static void nlmclnt_insert_lock_callback(struct file_lock *fl) { + lock_kernel(); nlm_get_host(fl->fl_u.nfs_fl.host); + unlock_kernel(); } static void nlmclnt_remove_lock_callback(struct file_lock *fl) { + lock_kernel(); if (fl->fl_u.nfs_fl.host) { nlm_release_host(fl->fl_u.nfs_fl.host); fl->fl_u.nfs_fl.host = NULL; } + unlock_kernel(); } /* diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index 283d66e97..9fcbad317 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c @@ -24,7 +24,7 @@ extern struct rpc_program nsm_program; /* * Local NSM state */ -u32 nsm_local_state = 0; +u32 nsm_local_state; /* * Common procedure for SM_MON/SM_UNMON calls diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index a175d39eb..5460e8c9f 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c @@ -24,6 +24,8 @@ #include <linux/types.h> #include <linux/errno.h> #include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/smp_lock.h> #include <linux/sunrpc/clnt.h> #include <linux/sunrpc/svc.h> #include <linux/lockd/nlm.h> @@ -40,7 +42,7 @@ static void nlmsvc_notify_blocked(struct file_lock *); /* * The list of blocked locks to retry */ -static struct nlm_block * nlm_blocked = NULL; +static struct nlm_block * nlm_blocked; /* * Insert a blocked lock into the global list @@ -53,9 +55,15 @@ nlmsvc_insert_block(struct nlm_block *block, unsigned long when) dprintk("lockd: nlmsvc_insert_block(%p, %ld)\n", block, when); if (block->b_queued) nlmsvc_remove_block(block); - for (bp = &nlm_blocked; (b = *bp); bp = &b->b_next) - if (when < b->b_when) - break; + bp = &nlm_blocked; + if (when != NLM_NEVER) { + if ((when += jiffies) == NLM_NEVER) + when ++; + while ((b = *bp) && time_before_eq(b->b_when,when)) + bp = &b->b_next; + } else + while ((b = *bp)) + bp = &b->b_next; block->b_queued = 1; block->b_when = when; @@ -106,8 +114,10 @@ nlmsvc_lookup_block(struct nlm_file *file, struct nlm_lock *lock, int remove) (long long)fl->fl_end, fl->fl_type, *(unsigned int*)(block->b_call.a_args.cookie.data)); if (block->b_file == file && nlm_compare_locks(fl, &lock->fl)) { - if (remove) + if (remove) { *head = block->b_next; + block->b_queued = 0; + } return block; } } @@ -173,10 +183,11 @@ nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file, locks_init_lock(&block->b_call.a_args.lock.fl); locks_init_lock(&block->b_call.a_res.lock.fl); - /* Set notifier function for VFS, and init args */ - lock->fl.fl_notify = nlmsvc_notify_blocked; if (!nlmclnt_setgrantargs(&block->b_call, lock)) goto failed_free; + + /* Set notifier function for VFS, and init args */ + block->b_call.a_args.lock.fl.fl_notify = nlmsvc_notify_blocked; block->b_call.a_args.cookie = *cookie; /* see above */ dprintk("lockd: created block %p...\n", block); @@ -349,7 +360,7 @@ again: /* Append to list of blocked */ nlmsvc_insert_block(block, NLM_NEVER); - if (list_empty(&block->b_call.a_args.lock.fl.fl_list)) { + if (list_empty(&block->b_call.a_args.lock.fl.fl_block)) { /* Now add block to block list of the conflicting lock if we haven't done so. */ dprintk("lockd: blocking on this lock.\n"); @@ -457,13 +468,15 @@ nlmsvc_notify_blocked(struct file_lock *fl) dprintk("lockd: VFS unblock notification for block %p\n", fl); posix_unblock_lock(fl); + lock_kernel(); for (bp = &nlm_blocked; (block = *bp); bp = &block->b_next) { if (nlm_compare_locks(&block->b_call.a_args.lock.fl, fl)) { - svc_wake_up(block->b_daemon); nlmsvc_insert_block(block, 0); + svc_wake_up(block->b_daemon); return; } } + unlock_kernel(); printk(KERN_WARNING "lockd: notification for unknown block!\n"); } @@ -520,7 +533,7 @@ nlmsvc_grant_blocked(struct nlm_block *block) if ((error = posix_lock_file(&file->f_file, &lock->fl, 0)) < 0) { printk(KERN_WARNING "lockd: unexpected error %d in %s!\n", -error, __FUNCTION__); - nlmsvc_insert_block(block, jiffies + 10 * HZ); + nlmsvc_insert_block(block, 10 * HZ); up(&file->f_sema); return; } @@ -532,7 +545,7 @@ callback: block->b_incall = 1; /* Schedule next grant callback in 30 seconds */ - nlmsvc_insert_block(block, jiffies + 30 * HZ); + nlmsvc_insert_block(block, 30 * HZ); /* Call the client */ nlm_get_host(block->b_call.a_host); @@ -570,13 +583,13 @@ nlmsvc_grant_callback(struct rpc_task *task) * can be done, though. */ if (task->tk_status < 0) { /* RPC error: Re-insert for retransmission */ - timeout = jiffies + 10 * HZ; + timeout = 10 * HZ; } else if (block->b_done) { /* Block already removed, kill it for real */ timeout = 0; } else { /* Call was successful, now wait for client callback */ - timeout = jiffies + 60 * HZ; + timeout = 60 * HZ; } nlmsvc_insert_block(block, timeout); svc_wake_up(block->b_daemon); @@ -604,7 +617,7 @@ nlmsvc_grant_reply(struct nlm_cookie *cookie, u32 status) if ((block = nlmsvc_find_block(cookie)) != NULL) { if (status == NLM_LCK_DENIED_GRACE_PERIOD) { /* Try again in a couple of seconds */ - nlmsvc_insert_block(block, jiffies + 10 * HZ); + nlmsvc_insert_block(block, 10 * HZ); block = NULL; } else { /* Lock is now held by client, or has been rejected. @@ -635,7 +648,11 @@ nlmsvc_retry_blocked(void) dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n", nlm_blocked, nlm_blocked? nlm_blocked->b_when : 0); - while ((block = nlm_blocked) && block->b_when <= jiffies) { + while ((block = nlm_blocked)) { + if (block->b_when == NLM_NEVER) + break; + if (time_after(block->b_when,jiffies)) + break; dprintk("nlmsvc_retry_blocked(%p, when=%ld, done=%d)\n", block, block->b_when, block->b_done); if (block->b_done) |