NFSv4: Don't try to recover NFSv4 locks when they are lost.
[linux-block.git] / fs / nfs / nfs4proc.c
index 0122919a311aa8306324bda95290d2af0ffb9714..1eb694e0f305b98a0e612dbf21db9a1fff3f1295 100644 (file)
@@ -4028,15 +4028,19 @@ static void nfs4_proc_read_setup(struct nfs_read_data *data, struct rpc_message
        nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 0);
 }
 
-static void nfs4_proc_read_rpc_prepare(struct rpc_task *task, struct nfs_read_data *data)
+static int nfs4_proc_read_rpc_prepare(struct rpc_task *task, struct nfs_read_data *data)
 {
        if (nfs4_setup_sequence(NFS_SERVER(data->header->inode),
                        &data->args.seq_args,
                        &data->res.seq_res,
                        task))
-               return;
-       nfs4_set_rw_stateid(&data->args.stateid, data->args.context,
-                       data->args.lock_context, FMODE_READ);
+               return 0;
+       if (nfs4_set_rw_stateid(&data->args.stateid, data->args.context,
+                               data->args.lock_context, FMODE_READ) == -EIO)
+               return -EIO;
+       if (unlikely(test_bit(NFS_CONTEXT_BAD, &data->args.context->flags)))
+               return -EIO;
+       return 0;
 }
 
 static int nfs4_write_done_cb(struct rpc_task *task, struct nfs_write_data *data)
@@ -4112,15 +4116,19 @@ static void nfs4_proc_write_setup(struct nfs_write_data *data, struct rpc_messag
        nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1);
 }
 
-static void nfs4_proc_write_rpc_prepare(struct rpc_task *task, struct nfs_write_data *data)
+static int nfs4_proc_write_rpc_prepare(struct rpc_task *task, struct nfs_write_data *data)
 {
        if (nfs4_setup_sequence(NFS_SERVER(data->header->inode),
                        &data->args.seq_args,
                        &data->res.seq_res,
                        task))
-               return;
-       nfs4_set_rw_stateid(&data->args.stateid, data->args.context,
-                       data->args.lock_context, FMODE_WRITE);
+               return 0;
+       if (nfs4_set_rw_stateid(&data->args.stateid, data->args.context,
+                               data->args.lock_context, FMODE_WRITE) == -EIO)
+               return -EIO;
+       if (unlikely(test_bit(NFS_CONTEXT_BAD, &data->args.context->flags)))
+               return -EIO;
+       return 0;
 }
 
 static void nfs4_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data)
@@ -5515,6 +5523,12 @@ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request
        return err;
 }
 
+bool recover_locks = true;
+module_param(recover_locks, bool, 0644);
+MODULE_PARM_DESC(recover_locks,
+                "If the server reports that a lock might be lost, "
+                "try to recovery it risking corruption.");
+
 static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
 {
        struct nfs_server *server = NFS_SERVER(state->inode);
@@ -5526,6 +5540,10 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request
        err = nfs4_set_lock_state(state, request);
        if (err != 0)
                return err;
+       if (!recover_locks) {
+               set_bit(NFS_LOCK_LOST, &request->fl_u.nfs4_fl.owner->ls_flags);
+               return 0;
+       }
        do {
                if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0)
                        return 0;