mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-01-15 06:00:41 +00:00
NFSv4: Deal with atomic upgrades of an existing delegation
Ensure that we deal correctly with the case where the server sends us a newer instance of the same delegation. If the stateids match, but the sequence numbers differ, then treat the new delegation as if it were an atomic upgrade. Signed-off-by: Trond Myklebust <Trond.Myklebust@primarydata.com>
This commit is contained in:
parent
89f0ff386c
commit
cf6726e2ee
@ -301,6 +301,17 @@ nfs_inode_detach_delegation(struct inode *inode)
|
|||||||
return nfs_detach_delegation(nfsi, delegation, server);
|
return nfs_detach_delegation(nfsi, delegation, server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nfs_update_inplace_delegation(struct nfs_delegation *delegation,
|
||||||
|
const struct nfs_delegation *update)
|
||||||
|
{
|
||||||
|
if (nfs4_stateid_is_newer(&update->stateid, &delegation->stateid)) {
|
||||||
|
delegation->stateid.seqid = update->stateid.seqid;
|
||||||
|
smp_wmb();
|
||||||
|
delegation->type = update->type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nfs_inode_set_delegation - set up a delegation on an inode
|
* nfs_inode_set_delegation - set up a delegation on an inode
|
||||||
* @inode: inode to which delegation applies
|
* @inode: inode to which delegation applies
|
||||||
@ -334,9 +345,12 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
|
|||||||
old_delegation = rcu_dereference_protected(nfsi->delegation,
|
old_delegation = rcu_dereference_protected(nfsi->delegation,
|
||||||
lockdep_is_held(&clp->cl_lock));
|
lockdep_is_held(&clp->cl_lock));
|
||||||
if (old_delegation != NULL) {
|
if (old_delegation != NULL) {
|
||||||
if (nfs4_stateid_match(&delegation->stateid,
|
/* Is this an update of the existing delegation? */
|
||||||
&old_delegation->stateid) &&
|
if (nfs4_stateid_match_other(&old_delegation->stateid,
|
||||||
delegation->type == old_delegation->type) {
|
&delegation->stateid)) {
|
||||||
|
nfs_update_inplace_delegation(old_delegation,
|
||||||
|
delegation);
|
||||||
|
nfsi->delegation_state = old_delegation->type;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user