markers: don't risk NULL deref in marker
[cascardo/linux.git] / fs / nfsd / nfssvc.c
index ff55950..9647b0f 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/slab.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
+#include <linux/freezer.h>
 #include <linux/fs_struct.h>
 
 #include <linux/sunrpc/types.h>
@@ -154,8 +155,8 @@ static int killsig; /* signal that was used to kill last nfsd */
 static void nfsd_last_thread(struct svc_serv *serv)
 {
        /* When last nfsd thread exits we need to do some clean-up */
-       struct svc_sock *svsk;
-       list_for_each_entry(svsk, &serv->sv_permsocks, sk_list)
+       struct svc_xprt *xprt;
+       list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list)
                lockd_down();
        nfsd_serv = NULL;
        nfsd_racache_shutdown();
@@ -235,7 +236,7 @@ static int nfsd_init_socks(int port)
 
        error = lockd_up(IPPROTO_UDP);
        if (error >= 0) {
-               error = svc_makesock(nfsd_serv, IPPROTO_UDP, port,
+               error = svc_create_xprt(nfsd_serv, "udp", port,
                                        SVC_SOCK_DEFAULTS);
                if (error < 0)
                        lockd_down();
@@ -246,7 +247,7 @@ static int nfsd_init_socks(int port)
 #ifdef CONFIG_NFSD_TCP
        error = lockd_up(IPPROTO_TCP);
        if (error >= 0) {
-               error = svc_makesock(nfsd_serv, IPPROTO_TCP, port,
+               error = svc_create_xprt(nfsd_serv, "tcp", port,
                                        SVC_SOCK_DEFAULTS);
                if (error < 0)
                        lockd_down();
@@ -348,9 +349,7 @@ nfsd_svc(unsigned short port, int nrservs)
        error = nfsd_racache_init(2*nrservs);
        if (error<0)
                goto out;
-       error = nfs4_state_start();
-       if (error<0)
-               goto out;
+       nfs4_state_start();
 
        nfsd_reset_versions();
 
@@ -432,6 +431,7 @@ nfsd(struct svc_rqst *rqstp)
         * dirty pages.
         */
        current->flags |= PF_LESS_THROTTLE;
+       set_freezable();
 
        /*
         * The main request loop
@@ -492,6 +492,15 @@ out:
        module_put_and_exit(0);
 }
 
+static __be32 map_new_errors(u32 vers, __be32 nfserr)
+{
+       if (nfserr == nfserr_jukebox && vers == 2)
+               return nfserr_dropit;
+       if (nfserr == nfserr_wrongsec && vers < 4)
+               return nfserr_acces;
+       return nfserr;
+}
+
 int
 nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
 {
@@ -534,10 +543,9 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
 
        /* Now call the procedure handler, and encode NFS status. */
        nfserr = proc->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp);
-       if (nfserr == nfserr_jukebox && rqstp->rq_vers == 2)
-               nfserr = nfserr_dropit;
+       nfserr = map_new_errors(rqstp->rq_vers, nfserr);
        if (nfserr == nfserr_dropit) {
-               dprintk("nfsd: Dropping request due to malloc failure!\n");
+               dprintk("nfsd: Dropping request; may be revisited later\n");
                nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
                return 0;
        }