Merge branch 'linux-ssc-for-5.5'

This commit is contained in:
Trond Myklebust
2019-11-05 14:53:29 -05:00
13 changed files with 604 additions and 47 deletions

View File

@@ -1557,16 +1557,32 @@ static void nfs42_complete_copies(struct nfs4_state_owner *sp, struct nfs4_state
{
struct nfs4_copy_state *copy;
if (!test_bit(NFS_CLNT_DST_SSC_COPY_STATE, &state->flags))
if (!test_bit(NFS_CLNT_DST_SSC_COPY_STATE, &state->flags) &&
!test_bit(NFS_CLNT_SRC_SSC_COPY_STATE, &state->flags))
return;
spin_lock(&sp->so_server->nfs_client->cl_lock);
list_for_each_entry(copy, &sp->so_server->ss_copies, copies) {
if (!nfs4_stateid_match_other(&state->stateid, &copy->parent_state->stateid))
continue;
if ((test_bit(NFS_CLNT_DST_SSC_COPY_STATE, &state->flags) &&
!nfs4_stateid_match_other(&state->stateid,
&copy->parent_dst_state->stateid)))
continue;
copy->flags = 1;
complete(&copy->completion);
break;
if (test_and_clear_bit(NFS_CLNT_DST_SSC_COPY_STATE,
&state->flags)) {
clear_bit(NFS_CLNT_SRC_SSC_COPY_STATE, &state->flags);
complete(&copy->completion);
}
}
list_for_each_entry(copy, &sp->so_server->ss_copies, src_copies) {
if ((test_bit(NFS_CLNT_SRC_SSC_COPY_STATE, &state->flags) &&
!nfs4_stateid_match_other(&state->stateid,
&copy->parent_src_state->stateid)))
continue;
copy->flags = 1;
if (test_and_clear_bit(NFS_CLNT_DST_SSC_COPY_STATE,
&state->flags))
complete(&copy->completion);
}
spin_unlock(&sp->so_server->nfs_client->cl_lock);
}
@@ -1610,6 +1626,9 @@ static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp, const struct nfs
struct nfs4_state *state;
unsigned int loop = 0;
int status = 0;
#ifdef CONFIG_NFS_V4_2
bool found_ssc_copy_state = false;
#endif /* CONFIG_NFS_V4_2 */
/* Note: we rely on the sp->so_states list being ordered
* so that we always reclaim open(O_RDWR) and/or open(O_WRITE)
@@ -1629,6 +1648,13 @@ restart:
continue;
if (state->state == 0)
continue;
#ifdef CONFIG_NFS_V4_2
if (test_bit(NFS_SRV_SSC_COPY_STATE, &state->flags)) {
nfs4_state_mark_recovery_failed(state, -EIO);
found_ssc_copy_state = true;
continue;
}
#endif /* CONFIG_NFS_V4_2 */
refcount_inc(&state->count);
spin_unlock(&sp->so_lock);
status = __nfs4_reclaim_open_state(sp, state, ops);
@@ -1683,6 +1709,10 @@ restart:
}
raw_write_seqcount_end(&sp->so_reclaim_seqcount);
spin_unlock(&sp->so_lock);
#ifdef CONFIG_NFS_V4_2
if (found_ssc_copy_state)
return -EIO;
#endif /* CONFIG_NFS_V4_2 */
return 0;
out_err:
nfs4_put_open_state(state);