a couple of mntget+dget -> path_get in nfs4proc
[deliverable/linux.git] / fs / nfs / nfs4proc.c
index 198d51d17c135e1b41564636511ff0119e0a7219..84d83be25a98b4d8456fdaeb321f086d313b0e3f 100644 (file)
@@ -249,19 +249,15 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
                        if (state == NULL)
                                break;
                        nfs4_state_mark_reclaim_nograce(clp, state);
-               case -NFS4ERR_STALE_CLIENTID:
+                       goto do_state_recovery;
                case -NFS4ERR_STALE_STATEID:
-               case -NFS4ERR_EXPIRED:
-                       nfs4_schedule_state_recovery(clp);
-                       ret = nfs4_wait_clnt_recover(clp);
-                       if (ret == 0)
-                               exception->retry = 1;
-#if !defined(CONFIG_NFS_V4_1)
-                       break;
-#else /* !defined(CONFIG_NFS_V4_1) */
-                       if (!nfs4_has_session(server->nfs_client))
+                       if (state == NULL)
                                break;
-                       /* FALLTHROUGH */
+                       nfs4_state_mark_reclaim_reboot(clp, state);
+               case -NFS4ERR_STALE_CLIENTID:
+               case -NFS4ERR_EXPIRED:
+                       goto do_state_recovery;
+#if defined(CONFIG_NFS_V4_1)
                case -NFS4ERR_BADSESSION:
                case -NFS4ERR_BADSLOT:
                case -NFS4ERR_BAD_HIGH_SLOT:
@@ -274,7 +270,7 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
                        nfs4_schedule_state_recovery(clp);
                        exception->retry = 1;
                        break;
-#endif /* !defined(CONFIG_NFS_V4_1) */
+#endif /* defined(CONFIG_NFS_V4_1) */
                case -NFS4ERR_FILE_OPEN:
                        if (exception->timeout > HZ) {
                                /* We have retried a decent amount, time to
@@ -293,6 +289,12 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
        }
        /* We failed to handle the error */
        return nfs4_map_errors(ret);
+do_state_recovery:
+       nfs4_schedule_state_recovery(clp);
+       ret = nfs4_wait_clnt_recover(clp);
+       if (ret == 0)
+               exception->retry = 1;
+       return ret;
 }
 
 
@@ -722,8 +724,8 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path,
        p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
        if (p->o_arg.seqid == NULL)
                goto err_free;
-       p->path.mnt = mntget(path->mnt);
-       p->path.dentry = dget(path->dentry);
+       path_get(path);
+       p->path = *path;
        p->dir = parent;
        p->owner = sp;
        atomic_inc(&sp->so_count);
@@ -1658,6 +1660,8 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, in
        status = PTR_ERR(state);
        if (IS_ERR(state))
                goto err_opendata_put;
+       if ((opendata->o_res.rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) != 0)
+               set_bit(NFS_STATE_POSIX_LOCKS, &state->flags);
        nfs4_opendata_put(opendata);
        nfs4_put_state_owner(sp);
        *res = state;
@@ -1940,8 +1944,8 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
        calldata->res.seqid = calldata->arg.seqid;
        calldata->res.server = server;
        calldata->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
-       calldata->path.mnt = mntget(path->mnt);
-       calldata->path.dentry = dget(path->dentry);
+       path_get(path);
+       calldata->path = *path;
 
        msg.rpc_argp = &calldata->arg,
        msg.rpc_resp = &calldata->res,
@@ -3422,15 +3426,14 @@ _nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
                        if (state == NULL)
                                break;
                        nfs4_state_mark_reclaim_nograce(clp, state);
-               case -NFS4ERR_STALE_CLIENTID:
+                       goto do_state_recovery;
                case -NFS4ERR_STALE_STATEID:
+                       if (state == NULL)
+                               break;
+                       nfs4_state_mark_reclaim_reboot(clp, state);
+               case -NFS4ERR_STALE_CLIENTID:
                case -NFS4ERR_EXPIRED:
-                       rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL);
-                       nfs4_schedule_state_recovery(clp);
-                       if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0)
-                               rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);
-                       task->tk_status = 0;
-                       return -EAGAIN;
+                       goto do_state_recovery;
 #if defined(CONFIG_NFS_V4_1)
                case -NFS4ERR_BADSESSION:
                case -NFS4ERR_BADSLOT:
@@ -3458,6 +3461,13 @@ _nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
        }
        task->tk_status = nfs4_map_errors(task->tk_status);
        return 0;
+do_state_recovery:
+       rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL);
+       nfs4_schedule_state_recovery(clp);
+       if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0)
+               rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);
+       task->tk_status = 0;
+       return -EAGAIN;
 }
 
 static int
@@ -4088,6 +4098,28 @@ static const struct rpc_call_ops nfs4_recover_lock_ops = {
        .rpc_release = nfs4_lock_release,
 };
 
+static void nfs4_handle_setlk_error(struct nfs_server *server, struct nfs4_lock_state *lsp, int new_lock_owner, int error)
+{
+       struct nfs_client *clp = server->nfs_client;
+       struct nfs4_state *state = lsp->ls_state;
+
+       switch (error) {
+       case -NFS4ERR_ADMIN_REVOKED:
+       case -NFS4ERR_BAD_STATEID:
+       case -NFS4ERR_EXPIRED:
+               if (new_lock_owner != 0 ||
+                  (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0)
+                       nfs4_state_mark_reclaim_nograce(clp, state);
+               lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED;
+               break;
+       case -NFS4ERR_STALE_STATEID:
+               if (new_lock_owner != 0 ||
+                   (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0)
+                       nfs4_state_mark_reclaim_reboot(clp, state);
+               lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED;
+       };
+}
+
 static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *fl, int recovery_type)
 {
        struct nfs4_lockdata *data;
@@ -4126,6 +4158,9 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
        ret = nfs4_wait_for_completion_rpc_task(task);
        if (ret == 0) {
                ret = data->rpc_status;
+               if (ret)
+                       nfs4_handle_setlk_error(data->server, data->lsp,
+                                       data->arg.new_lock_owner, ret);
        } else
                data->cancelled = 1;
        rpc_put_task(task);
@@ -4181,8 +4216,11 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock
 {
        struct nfs_inode *nfsi = NFS_I(state->inode);
        unsigned char fl_flags = request->fl_flags;
-       int status;
+       int status = -ENOLCK;
 
+       if ((fl_flags & FL_POSIX) &&
+                       !test_bit(NFS_STATE_POSIX_LOCKS, &state->flags))
+               goto out;
        /* Is this a delegated open? */
        status = nfs4_set_lock_state(state, request);
        if (status != 0)
This page took 0.072187 seconds and 5 git commands to generate.