nfsd: fix spurious EACCESS in reconnect_path()
[safe/jmp/linux-2.6] / fs / nfsd / nfs4callback.c
index 6eb5cd2..0b3ffa9 100644 (file)
@@ -104,7 +104,7 @@ xdr_writemem(__be32 *p, const void *ptr, int nbytes)
 } while (0)
 #define RESERVE_SPACE(nbytes)   do {                            \
        p = xdr_reserve_space(xdr, nbytes);                     \
-       if (!p) dprintk("NFSD: RESERVE_SPACE(%d) failed in function %s\n", (int) (nbytes), __FUNCTION__); \
+       if (!p) dprintk("NFSD: RESERVE_SPACE(%d) failed in function %s\n", (int) (nbytes), __func__); \
        BUG_ON(!p);                                             \
 } while (0)
 
@@ -134,7 +134,7 @@ xdr_error:                                      \
        p = xdr_inline_decode(xdr, nbytes); \
        if (!p) { \
                dprintk("NFSD: %s: reply buffer overflowed in line %d.\n", \
-                       __FUNCTION__, __LINE__); \
+                       __func__, __LINE__); \
                return -EIO; \
        } \
 } while (0)
@@ -344,6 +344,21 @@ static struct rpc_version *        nfs_cb_version[] = {
        &nfs_cb_version4,
 };
 
+static struct rpc_program cb_program;
+
+static struct rpc_stat cb_stats = {
+               .program        = &cb_program
+};
+
+#define NFS4_CALLBACK 0x40000000
+static struct rpc_program cb_program = {
+               .name           = "nfs4_cb",
+               .number         = NFS4_CALLBACK,
+               .nrvers         = ARRAY_SIZE(nfs_cb_version),
+               .version        = nfs_cb_version,
+               .stats          = &cb_stats,
+};
+
 /* Reference counting, callback cleanup, etc., all look racy as heck.
  * And why is cb_set an atomic? */
 
@@ -358,13 +373,12 @@ static int do_probe_callback(void *data)
                .to_maxval      = (NFSD_LEASE_TIME/2) * HZ,
                .to_exponential = 1,
        };
-       struct rpc_program *    program = &cb->cb_program;
        struct rpc_create_args args = {
                .protocol       = IPPROTO_TCP,
                .address        = (struct sockaddr *)&addr,
                .addrsize       = sizeof(addr),
                .timeout        = &timeparms,
-               .program        = program,
+               .program        = &cb_program,
                .version        = nfs_cb_version[1]->number,
                .authflavor     = RPC_AUTH_UNIX, /* XXX: need AUTH_GSS... */
                .flags          = (RPC_CLNT_CREATE_NOPING),
@@ -382,16 +396,8 @@ static int do_probe_callback(void *data)
        addr.sin_port = htons(cb->cb_port);
        addr.sin_addr.s_addr = htonl(cb->cb_addr);
 
-       /* Initialize rpc_program */
-       program->name = "nfs4_cb";
-       program->number = cb->cb_prog;
-       program->nrvers = ARRAY_SIZE(nfs_cb_version);
-       program->version = nfs_cb_version;
-       program->stats = &cb->cb_stat;
-
        /* Initialize rpc_stat */
-       memset(program->stats, 0, sizeof(cb->cb_stat));
-       program->stats->program = program;
+       memset(args.program->stats, 0, sizeof(struct rpc_stat));
 
        /* Create RPC client */
        client = rpc_create(&args);
@@ -457,9 +463,6 @@ nfsd4_cb_recall(struct nfs4_delegation *dp)
        int retries = 1;
        int status = 0;
 
-       if ((!atomic_read(&clp->cl_callback.cb_set)) || !clnt)
-               return;
-
        cbr->cbr_trunc = 0; /* XXX need to implement truncate optimization */
        cbr->cbr_dp = dp;
 
@@ -468,6 +471,7 @@ nfsd4_cb_recall(struct nfs4_delegation *dp)
                switch (status) {
                        case -EIO:
                                /* Network partition? */
+                               atomic_set(&clp->cl_callback.cb_set, 0);
                        case -EBADHANDLE:
                        case -NFS4ERR_BAD_STATEID:
                                /* Race: client probably got cb_recall
@@ -480,11 +484,10 @@ nfsd4_cb_recall(struct nfs4_delegation *dp)
                status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFT);
        }
 out_put_cred:
-       if (status == -EIO)
-               atomic_set(&clp->cl_callback.cb_set, 0);
-       /* Success or failure, now we're either waiting for lease expiration
-        * or deleg_return. */
-       dprintk("NFSD: nfs4_cb_recall: dp %p dl_flock %p dl_count %d\n",dp, dp->dl_flock, atomic_read(&dp->dl_count));
+       /*
+        * Success or failure, now we're either waiting for lease expiration
+        * or deleg_return.
+        */
        put_nfs4_client(clp);
        nfs4_put_delegation(dp);
        return;