NFSv4: Check the return value of update_open_stateid()
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Mon, 29 Jul 2019 17:25:00 +0000 (18:25 +0100)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Mon, 5 Aug 2019 02:35:40 +0000 (22:35 -0400)
Ensure that we always check the return value of update_open_stateid()
so that we can retry if the update of local state failed. This fixes
infinite looping on state recovery.

Fixes: e23008ec81ef3 ("NFSv4 reduce attribute requests for open reclaim")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Cc: stable@vger.kernel.org # v3.7+
fs/nfs/nfs4proc.c

index c9e14ce..3e0b93f 100644 (file)
@@ -1915,8 +1915,9 @@ _nfs4_opendata_reclaim_to_nfs4_state(struct nfs4_opendata *data)
        if (data->o_res.delegation_type != 0)
                nfs4_opendata_check_deleg(data, state);
 update:
-       update_open_stateid(state, &data->o_res.stateid, NULL,
-                           data->o_arg.fmode);
+       if (!update_open_stateid(state, &data->o_res.stateid,
+                               NULL, data->o_arg.fmode))
+               return ERR_PTR(-EAGAIN);
        refcount_inc(&state->count);
 
        return state;
@@ -1981,8 +1982,11 @@ _nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data)
 
        if (data->o_res.delegation_type != 0)
                nfs4_opendata_check_deleg(data, state);
-       update_open_stateid(state, &data->o_res.stateid, NULL,
-                       data->o_arg.fmode);
+       if (!update_open_stateid(state, &data->o_res.stateid,
+                               NULL, data->o_arg.fmode)) {
+               nfs4_put_open_state(state);
+               state = ERR_PTR(-EAGAIN);
+       }
 out:
        nfs_release_seqid(data->o_arg.seqid);
        return state;