9 #include <linux/module.h>
10 #include <linux/slab.h>
11 #include <linux/types.h>
12 #include <linux/errno.h>
14 #include <linux/nfs_fs.h>
15 #include <linux/utsname.h>
21 #define NLMDBG_FACILITY NLMDBG_CLIENT
22 #define NLMCLNT_GRACE_WAIT (5*HZ)
23 #define NLMCLNT_POLL_TIMEOUT (30*HZ)
24 #define NLMCLNT_MAX_RETRIES 3
26 static int nlmclnt_test(
struct nlm_rqst *,
struct file_lock *);
27 static int nlmclnt_lock(
struct nlm_rqst *,
struct file_lock *);
28 static int nlmclnt_unlock(
struct nlm_rqst *,
struct file_lock *);
30 static void nlmclnt_locks_init_private(
struct file_lock *
fl,
struct nlm_host *
host);
31 static int nlmclnt_cancel(
struct nlm_host *,
int ,
struct file_lock *);
49 static struct nlm_lockowner *nlm_get_lockowner(
struct nlm_lockowner *lockowner)
55 static void nlm_put_lockowner(
struct nlm_lockowner *lockowner)
60 spin_unlock(&lockowner->host->h_lock);
67 struct nlm_lockowner *lockowner;
69 if (lockowner->pid == pid)
75 static inline uint32_t __nlm_alloc_pid(
struct nlm_host *host)
79 res = host->h_pidcount++;
80 }
while (nlm_pidbusy(host, res) < 0);
84 static struct nlm_lockowner *__nlm_find_lockowner(
struct nlm_host *host,
fl_owner_t owner)
86 struct nlm_lockowner *lockowner;
88 if (lockowner->owner != owner)
90 return nlm_get_lockowner(lockowner);
95 static struct nlm_lockowner *nlm_find_lockowner(
struct nlm_host *host,
fl_owner_t owner)
97 struct nlm_lockowner *
res, *
new =
NULL;
99 spin_lock(&host->h_lock);
100 res = __nlm_find_lockowner(host, owner);
102 spin_unlock(&host->h_lock);
104 spin_lock(&host->h_lock);
105 res = __nlm_find_lockowner(host, owner);
110 new->pid = __nlm_alloc_pid(host);
112 list_add(&new->list, &host->h_lockowners);
116 spin_unlock(&host->h_lock);
124 static void nlmclnt_setlockargs(
struct nlm_rqst *
req,
struct file_lock *
fl)
131 lock->
caller = utsname()->nodename;
132 lock->
oh.data = req->a_owner;
133 lock->
oh.len =
snprintf(req->a_owner,
sizeof(req->a_owner),
"%u@%s",
135 utsname()->nodename);
142 static void nlmclnt_release_lockargs(
struct nlm_rqst *req)
156 struct nlm_rqst *call;
163 nlmclnt_locks_init_private(fl, host);
170 nlmclnt_setlockargs(call, fl);
174 call->a_args.block =
IS_SETLKW(cmd) ? 1 : 0;
175 status = nlmclnt_lock(call, fl);
177 status = nlmclnt_unlock(call, fl);
179 status = nlmclnt_test(call, fl);
182 fl->
fl_ops->fl_release_private(fl);
185 dprintk(
"lockd: clnt proc returns %d\n", status);
195 struct nlm_rqst *call;
208 printk(
"nlm_alloc_call: failed, waiting for memory\n");
219 nlmclnt_release_lockargs(call);
223 static void nlmclnt_rpc_release(
void *
data)
248 nlmclnt_call(
struct rpc_cred *
cred,
struct nlm_rqst *req,
u32 proc)
250 struct nlm_host *host = req->a_host;
252 struct nlm_args *argp = &req->a_args;
261 dprintk(
"lockd: call procedure %d on %s\n",
262 (
int)proc, host->h_name);
265 if (host->h_reclaiming && !argp->
reclaim)
266 goto in_grace_period;
275 dprintk(
"lockd: rpc_call returned error %d\n", -status);
294 dprintk(
"lockd: server in grace period\n");
297 "lockd: spurious grace period reject?!\n");
305 dprintk(
"lockd: server returns status %d\n",
317 status = nlm_wait_on_grace(&host->h_gracewait);
318 }
while (status == 0);
328 struct nlm_host *host = req->a_host;
332 .callback_ops = tk_ops,
333 .callback_data =
req,
337 dprintk(
"lockd: call procedure %d on %s (async)\n",
338 (
int)proc, host->h_name);
358 task = __nlm_async_call(req, proc, msg, tk_ops);
360 return PTR_ERR(task);
372 .rpc_resp = &req->a_res,
374 return nlm_do_async_call(req, proc, &msg, tk_ops);
382 return nlm_do_async_call(req, proc, &msg, tk_ops);
393 static int nlmclnt_async_call(
struct rpc_cred *cred,
struct nlm_rqst *req,
u32 proc,
const struct rpc_call_ops *tk_ops)
397 .rpc_resp = &req->a_res,
403 task = __nlm_async_call(req, proc, &msg, tk_ops);
405 return PTR_ERR(task);
406 err = rpc_wait_for_completion_task(task);
415 nlmclnt_test(
struct nlm_rqst *req,
struct file_lock *fl)
423 switch (req->a_res.status) {
431 fl->
fl_start = req->a_res.lock.fl.fl_start;
432 fl->
fl_end = req->a_res.lock.fl.fl_end;
433 fl->
fl_type = req->a_res.lock.fl.fl_type;
437 status = nlm_stat_to_errno(req->a_res.status);
446 spin_lock(&fl->
fl_u.
nfs_fl.owner->host->h_lock);
447 new->fl_u.nfs_fl.state = fl->
fl_u.
nfs_fl.state;
448 new->fl_u.nfs_fl.owner = nlm_get_lockowner(fl->
fl_u.
nfs_fl.owner);
450 spin_unlock(&fl->
fl_u.
nfs_fl.owner->host->h_lock);
453 static void nlmclnt_locks_release_private(
struct file_lock *fl)
455 spin_lock(&fl->
fl_u.
nfs_fl.owner->host->h_lock);
457 spin_unlock(&fl->
fl_u.
nfs_fl.owner->host->h_lock);
462 .fl_copy_lock = nlmclnt_locks_copy_lock,
463 .fl_release_private = nlmclnt_locks_release_private,
466 static void nlmclnt_locks_init_private(
struct file_lock *fl,
struct nlm_host *host)
472 fl->
fl_ops = &nlmclnt_lock_ops;
475 static int do_vfs_lock(
struct file_lock *fl)
512 nlmclnt_lock(
struct nlm_rqst *req,
struct file_lock *fl)
514 struct rpc_cred *cred = nfs_file_cred(fl->
fl_file);
515 struct nlm_host *host = req->a_host;
516 struct nlm_res *resp = &req->a_res;
518 unsigned char fl_flags = fl->
fl_flags;
519 unsigned char fl_type;
527 status = do_vfs_lock(fl);
562 if (!req->a_args.block)
564 if (nlmclnt_cancel(host, req->a_args.block, fl) == 0)
577 if (do_vfs_lock(fl) < 0)
593 status = nlm_stat_to_errno(resp->
status);
601 dprintk(
"lockd: lock attempt ended in fatal error.\n"
602 " Attempting to unlock.\n");
611 nlmclnt_async_call(cred, req,
NLMPROC_UNLOCK, &nlmclnt_unlock_ops);
621 struct nlm_rqst reqst, *
req;
625 memset(req, 0,
sizeof(*req));
632 nlmclnt_setlockargs(req, fl);
633 req->a_args.reclaim = 1;
636 if (status >= 0 && req->a_res.status ==
nlm_granted)
640 "(errno %d, status %d)\n", fl->
fl_pid,
641 status,
ntohl(req->a_res.status));
662 nlmclnt_unlock(
struct nlm_rqst *req,
struct file_lock *fl)
664 struct nlm_host *host = req->a_host;
665 struct nlm_res *resp = &req->a_res;
667 unsigned char fl_flags = fl->
fl_flags;
676 status = do_vfs_lock(fl);
685 status = nlmclnt_async_call(nfs_file_cred(fl->
fl_file), req,
694 printk(
"lockd: unexpected unlock status: %d\n",
703 static void nlmclnt_unlock_callback(
struct rpc_task *task,
void *
data)
705 struct nlm_rqst *req =
data;
706 u32 status =
ntohl(req->a_res.status);
736 .rpc_call_done = nlmclnt_unlock_callback,
737 .rpc_release = nlmclnt_rpc_release,
745 static int nlmclnt_cancel(
struct nlm_host *host,
int block,
struct file_lock *fl)
747 struct nlm_rqst *
req;
750 dprintk(
"lockd: blocking lock attempt was interrupted by a signal.\n"
751 " Attempting to cancel lock.\n");
758 nlmclnt_setlockargs(req, fl);
759 req->a_args.block =
block;
762 status = nlmclnt_async_call(nfs_file_cred(fl->
fl_file), req,
770 static void nlmclnt_cancel_callback(
struct rpc_task *task,
void *data)
772 struct nlm_rqst *req =
data;
773 u32 status =
ntohl(req->a_res.status);
779 dprintk(
"lockd: CANCEL call error %d, retrying.\n",
784 dprintk(
"lockd: cancel status %u (task %u)\n",
785 status, task->tk_pid);
794 dprintk(
"lockd: CANCEL failed (server has no locks)\n");
814 .rpc_call_done = nlmclnt_cancel_callback,
815 .rpc_release = nlmclnt_rpc_release,
822 nlm_stat_to_errno(
__be32 status)
824 switch(
ntohl(status)) {
835 #ifdef CONFIG_LOCKD_V4