X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Flockd%2Fsvc.c;h=fdb9412151f5abd3695067d8a64a67fb6a88ad2f;hb=9464c7cf61b9433057924c36e6e02f303a00e768;hp=815a3b5410176d2201a649d38d447cef71068bec;hpb=ec9397bab20a628530ce3051167d3d0fcc2c1af7;p=linux-2.6.git diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 815a3b541..fdb941215 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -38,15 +39,18 @@ #define LOCKD_BUFSIZE (1024 + NLMSVC_XDRSIZE) #define ALLOWED_SIGS (sigmask(SIGKILL)) -extern struct svc_program nlmsvc_program; +static struct svc_program nlmsvc_program; + struct nlmsvc_binding * nlmsvc_ops; -static DECLARE_MUTEX(nlmsvc_sema); +EXPORT_SYMBOL(nlmsvc_ops); + +static DEFINE_MUTEX(nlmsvc_mutex); static unsigned int nlmsvc_users; static pid_t nlmsvc_pid; int nlmsvc_grace_period; unsigned long nlmsvc_timeout; -static DECLARE_MUTEX_LOCKED(lockd_start); +static DECLARE_COMPLETION(lockd_start_done); static DECLARE_WAIT_QUEUE_HEAD(lockd_exit); /* @@ -86,46 +90,6 @@ static inline void clear_grace_period(void) { nlmsvc_grace_period = 0; } -int -nlmsvc_dispatch(struct svc_rqst *rqstp, u32 *statp) -{ - struct svc_procedure *procp; - kxdrproc_t xdr; - struct kvec *argv; - struct kvec *resv; - - dprintk("nlmsvc_dispatch: vers %d proc %d\n", - rqstp->rq_vers, rqstp->rq_proc); - - procp = rqstp->rq_procinfo; - argv = &rqstp->rq_arg.head[0]; - resv = &rqstp->rq_res.head[0]; - - /* Decode arguments */ - xdr = procp->pc_decode; - if (xdr && !xdr(rqstp, argv->iov_base, rqstp->rq_argp)) { - dprintk("nlmsvc_dispatch: failed to decode arguments!\n"); - *statp = rpc_garbage_args; - return 1; - } - *statp = procp->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); - if (*statp == nlm_lck_dropit) { - dprintk("nlmsvc_dispatch: dropping request\n"); - return 0; - } - - /* Encode reply */ - if (*statp == rpc_success && (xdr = procp->pc_encode) - && !xdr(rqstp, resv->iov_base+resv->iov_len, rqstp->rq_resp)) { - dprintk("nlmsvc_dispatch: failed to encode reply\n"); - *statp = rpc_system_err; - return 1; - } - - dprintk("nlmsvc_dispatch: statp %d\n", ntohl(*statp)); - - return 1; -} /* * This is the lockd kernel thread @@ -149,7 +113,7 @@ lockd(struct svc_rqst *rqstp) * Let our maker know we're running. */ nlmsvc_pid = current->pid; - up(&lockd_start); + complete(&lockd_start_done); daemonize("lockd"); @@ -215,6 +179,8 @@ lockd(struct svc_rqst *rqstp) } + flush_signals(current); + /* * Check whether there's a new lockd process before * shutting down the hosts and clearing the slot. @@ -228,7 +194,7 @@ lockd(struct svc_rqst *rqstp) printk(KERN_DEBUG "lockd: new process, skipping host shutdown\n"); wake_up(&lockd_exit); - + /* Exit the RPC thread */ svc_exit_thread(rqstp); @@ -250,7 +216,7 @@ lockd_up(void) struct svc_serv * serv; int error = 0; - down(&nlmsvc_sema); + mutex_lock(&nlmsvc_mutex); /* * Unconditionally increment the user count ... this is * the number of clients who _want_ a lockd process. @@ -298,7 +264,7 @@ lockd_up(void) "lockd_up: create thread failed, error=%d\n", error); goto destroy_and_out; } - down(&lockd_start); + wait_for_completion(&lockd_start_done); /* * Note: svc_serv structures have an initial use count of 1, @@ -307,9 +273,10 @@ lockd_up(void) destroy_and_out: svc_destroy(serv); out: - up(&nlmsvc_sema); + mutex_unlock(&nlmsvc_mutex); return error; } +EXPORT_SYMBOL(lockd_up); /* * Decrement the user count and bring down lockd if we're the last. @@ -318,10 +285,8 @@ void lockd_down(void) { static int warned; - wait_queue_t __wait; - int retries=0; - down(&nlmsvc_sema); + mutex_lock(&nlmsvc_mutex); if (nlmsvc_users) { if (--nlmsvc_users) goto out; @@ -336,36 +301,24 @@ lockd_down(void) warned = 0; kill_proc(nlmsvc_pid, SIGKILL, 1); - - init_waitqueue_entry(&__wait, current); - add_wait_queue(&lockd_exit, &__wait); - /* * Wait for the lockd process to exit, but since we're holding * the lockd semaphore, we can't wait around forever ... */ clear_thread_flag(TIF_SIGPENDING); - set_current_state(TASK_UNINTERRUPTIBLE); - while (nlmsvc_pid) { - - schedule_timeout(HZ); - if (retries++ < 3) - continue; - + wait_event_timeout(lockd_exit, nlmsvc_pid == 0, HZ); + if (nlmsvc_pid) { printk(KERN_WARNING "lockd_down: lockd failed to exit, clearing pid\n"); nlmsvc_pid = 0; } - set_current_state(TASK_RUNNING); - remove_wait_queue(&lockd_exit, &__wait); - spin_lock_irq(¤t->sighand->siglock); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - out: - up(&nlmsvc_sema); + mutex_unlock(&nlmsvc_mutex); } +EXPORT_SYMBOL(lockd_down); /* * Sysctl parameters (same as module parameters, different interface). @@ -379,7 +332,7 @@ static ctl_table nlm_sysctls[] = { .ctl_name = CTL_UNNUMBERED, .procname = "nlm_grace_period", .data = &nlm_grace_period, - .maxlen = sizeof(int), + .maxlen = sizeof(unsigned long), .mode = 0644, .proc_handler = &proc_doulongvec_minmax, .extra1 = (unsigned long *) &nlm_grace_period_min, @@ -389,7 +342,7 @@ static ctl_table nlm_sysctls[] = { .ctl_name = CTL_UNNUMBERED, .procname = "nlm_timeout", .data = &nlm_timeout, - .maxlen = sizeof(int), + .maxlen = sizeof(unsigned long), .mode = 0644, .proc_handler = &proc_doulongvec_minmax, .extra1 = (unsigned long *) &nlm_timeout_min, @@ -453,6 +406,38 @@ static int param_set_##name(const char *val, struct kernel_param *kp) \ return 0; \ } +static inline int is_callback(u32 proc) +{ + return proc == NLMPROC_GRANTED + || proc == NLMPROC_GRANTED_MSG + || proc == NLMPROC_TEST_RES + || proc == NLMPROC_LOCK_RES + || proc == NLMPROC_CANCEL_RES + || proc == NLMPROC_UNLOCK_RES + || proc == NLMPROC_NSM_NOTIFY; +} + + +static int lockd_authenticate(struct svc_rqst *rqstp) +{ + rqstp->rq_client = NULL; + switch (rqstp->rq_authop->flavour) { + case RPC_AUTH_NULL: + case RPC_AUTH_UNIX: + if (rqstp->rq_proc == 0) + return SVC_OK; + if (is_callback(rqstp->rq_proc)) { + /* Leave it to individual procedures to + * call nlmsvc_lookup_host(rqstp) + */ + return SVC_OK; + } + return svc_set_client(rqstp); + } + return SVC_DENIED; +} + + param_set_min_max(port, int, simple_strtol, 0, 65535) param_set_min_max(grace_period, unsigned long, simple_strtoul, nlm_grace_period_min, nlm_grace_period_max) @@ -499,14 +484,12 @@ static struct svc_version nlmsvc_version1 = { .vs_vers = 1, .vs_nproc = 17, .vs_proc = nlmsvc_procedures, - .vs_dispatch = nlmsvc_dispatch, .vs_xdrsize = NLMSVC_XDRSIZE, }; static struct svc_version nlmsvc_version3 = { .vs_vers = 3, .vs_nproc = 24, .vs_proc = nlmsvc_procedures, - .vs_dispatch = nlmsvc_dispatch, .vs_xdrsize = NLMSVC_XDRSIZE, }; #ifdef CONFIG_LOCKD_V4 @@ -514,7 +497,6 @@ static struct svc_version nlmsvc_version4 = { .vs_vers = 4, .vs_nproc = 24, .vs_proc = nlmsvc_procedures4, - .vs_dispatch = nlmsvc_dispatch, .vs_xdrsize = NLMSVC_XDRSIZE, }; #endif @@ -528,12 +510,13 @@ static struct svc_version * nlmsvc_version[] = { static struct svc_stat nlmsvc_stats; -#define NLM_NRVERS (sizeof(nlmsvc_version)/sizeof(nlmsvc_version[0])) -struct svc_program nlmsvc_program = { - .pg_prog = NLM_PROGRAM, /* program number */ - .pg_nvers = NLM_NRVERS, /* number of entries in nlmsvc_version */ - .pg_vers = nlmsvc_version, /* version table */ - .pg_name = "lockd", /* service name */ - .pg_class = "nfsd", /* share authentication with nfsd */ - .pg_stats = &nlmsvc_stats, /* stats table */ +#define NLM_NRVERS ARRAY_SIZE(nlmsvc_version) +static struct svc_program nlmsvc_program = { + .pg_prog = NLM_PROGRAM, /* program number */ + .pg_nvers = NLM_NRVERS, /* number of entries in nlmsvc_version */ + .pg_vers = nlmsvc_version, /* version table */ + .pg_name = "lockd", /* service name */ + .pg_class = "nfsd", /* share authentication with nfsd */ + .pg_stats = &nlmsvc_stats, /* stats table */ + .pg_authenticate = &lockd_authenticate /* export authentication */ };