Revert to Fedora kernel-2.6.17-1.2187_FC5 patched with vs2.0.2.1; there are too many...
[linux-2.6.git] / fs / lockd / svc.c
index 815a3b5..fdb9412 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/slab.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
+#include <linux/mutex.h>
 
 #include <linux/sunrpc/types.h>
 #include <linux/sunrpc/stats.h>
 #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(&current->sighand->siglock);
        recalc_sigpending();
        spin_unlock_irq(&current->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 */
 };