linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / fs / lockd / svc.c
index b499701..71a30b4 100644 (file)
@@ -38,7 +38,7 @@
 #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;
 EXPORT_SYMBOL(nlmsvc_ops);
@@ -178,6 +178,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.
@@ -191,7 +193,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);
 
@@ -282,8 +284,6 @@ void
 lockd_down(void)
 {
        static int warned;
-       wait_queue_t __wait;
-       int retries=0;
 
        down(&nlmsvc_sema);
        if (nlmsvc_users) {
@@ -300,33 +300,20 @@ 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;
-
+       interruptible_sleep_on_timeout(&lockd_exit, 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(&current->sighand->siglock);
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
-
 out:
        up(&nlmsvc_sema);
 }
@@ -344,7 +331,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,
@@ -354,7 +341,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,
@@ -418,6 +405,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)
@@ -491,11 +510,12 @@ 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 */
+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 */
 };