Message ID | 1419015154-91037-1-git-send-email-trond.myklebust@primarydata.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Aha, yes yes yes, that would make sense how it is still returned if seq ids are different. I'll have this tested asap. On Fri, Dec 19, 2014 at 1:52 PM, Trond Myklebust <trond.myklebust@primarydata.com> wrote: > 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> > --- > fs/nfs/delegation.c | 21 ++++++++++++++++++--- > 1 file changed, 18 insertions(+), 3 deletions(-) > > diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c > index 7f3f60641344..02b5b2a6d557 100644 > --- a/fs/nfs/delegation.c > +++ b/fs/nfs/delegation.c > @@ -301,6 +301,19 @@ nfs_inode_detach_delegation(struct inode *inode) > return nfs_detach_delegation(nfsi, delegation, server); > } > > +static void > +nfs_update_inplace_delegation(struct nfs_inode *nfsi, > + struct nfs_delegation *delegation, > + struct nfs_delegation *update) > +{ > + if (nfs4_stateid_is_newer(&update->stateid, &delegation->stateid)) > + return; > + delegation->stateid.seqid = update->stateid.seqid; > + smp_wmb(); > + delegation->type = update->type; > + nfsi->delegation_state = update->type; > +} > + > /** > * nfs_inode_set_delegation - set up a delegation on an inode > * @inode: inode to which delegation applies > @@ -334,9 +347,11 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct > old_delegation = rcu_dereference_protected(nfsi->delegation, > lockdep_is_held(&clp->cl_lock)); > if (old_delegation != NULL) { > - if (nfs4_stateid_match(&delegation->stateid, > - &old_delegation->stateid) && > - delegation->type == old_delegation->type) { > + /* Is this an update of the existing delegation? */ > + if (nfs4_stateid_match_other(&old_delegation->stateid, > + &delegation->stateid)) { > + nfs_update_inplace_delegation(nfsi, old_delegation, > + delegation); > goto out; > } > /* > -- > 2.1.0 > -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Fri, Dec 19, 2014 at 1:52 PM, Trond Myklebust <trond.myklebust@primarydata.com> wrote: > 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> > --- > fs/nfs/delegation.c | 21 ++++++++++++++++++--- > 1 file changed, 18 insertions(+), 3 deletions(-) > > diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c > index 7f3f60641344..02b5b2a6d557 100644 > --- a/fs/nfs/delegation.c > +++ b/fs/nfs/delegation.c > @@ -301,6 +301,19 @@ nfs_inode_detach_delegation(struct inode *inode) > return nfs_detach_delegation(nfsi, delegation, server); > } > > +static void > +nfs_update_inplace_delegation(struct nfs_inode *nfsi, > + struct nfs_delegation *delegation, > + struct nfs_delegation *update) > +{ > + if (nfs4_stateid_is_newer(&update->stateid, &delegation->stateid)) ...and the above comparison should be reversed. > + return; > + delegation->stateid.seqid = update->stateid.seqid; > + smp_wmb(); > + delegation->type = update->type; > + nfsi->delegation_state = update->type; > +} > + > /** > * nfs_inode_set_delegation - set up a delegation on an inode > * @inode: inode to which delegation applies > @@ -334,9 +347,11 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct > old_delegation = rcu_dereference_protected(nfsi->delegation, > lockdep_is_held(&clp->cl_lock)); > if (old_delegation != NULL) { > - if (nfs4_stateid_match(&delegation->stateid, > - &old_delegation->stateid) && > - delegation->type == old_delegation->type) { > + /* Is this an update of the existing delegation? */ > + if (nfs4_stateid_match_other(&old_delegation->stateid, > + &delegation->stateid)) { > + nfs_update_inplace_delegation(nfsi, old_delegation, > + delegation); > goto out; > } > /* > -- > 2.1.0 >
On Fri, Dec 19, 2014 at 3:31 PM, Trond Myklebust <trond.myklebust@primarydata.com> wrote: > On Fri, Dec 19, 2014 at 1:52 PM, Trond Myklebust > <trond.myklebust@primarydata.com> wrote: >> 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> >> --- >> fs/nfs/delegation.c | 21 ++++++++++++++++++--- >> 1 file changed, 18 insertions(+), 3 deletions(-) >> >> diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c >> index 7f3f60641344..02b5b2a6d557 100644 >> --- a/fs/nfs/delegation.c >> +++ b/fs/nfs/delegation.c >> @@ -301,6 +301,19 @@ nfs_inode_detach_delegation(struct inode *inode) >> return nfs_detach_delegation(nfsi, delegation, server); >> } >> >> +static void >> +nfs_update_inplace_delegation(struct nfs_inode *nfsi, >> + struct nfs_delegation *delegation, >> + struct nfs_delegation *update) >> +{ >> + if (nfs4_stateid_is_newer(&update->stateid, &delegation->stateid)) > > ...and the above comparison should be reversed. do you mean: if(!nfs4_stateid_is_newer()) but if we received a delegation stateid with sequence number lower than what we have, shouldn't that be some kind of an error? > >> + return; >> + delegation->stateid.seqid = update->stateid.seqid; >> + smp_wmb(); >> + delegation->type = update->type; >> + nfsi->delegation_state = update->type; >> +} >> + >> /** >> * nfs_inode_set_delegation - set up a delegation on an inode >> * @inode: inode to which delegation applies >> @@ -334,9 +347,11 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct >> old_delegation = rcu_dereference_protected(nfsi->delegation, >> lockdep_is_held(&clp->cl_lock)); >> if (old_delegation != NULL) { >> - if (nfs4_stateid_match(&delegation->stateid, >> - &old_delegation->stateid) && >> - delegation->type == old_delegation->type) { >> + /* Is this an update of the existing delegation? */ >> + if (nfs4_stateid_match_other(&old_delegation->stateid, >> + &delegation->stateid)) { >> + nfs_update_inplace_delegation(nfsi, old_delegation, >> + delegation); >> goto out; >> } >> /* >> -- >> 2.1.0 >> > > > > -- > Trond Myklebust > > Linux NFS client maintainer, PrimaryData > > trond.myklebust@primarydata.com -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Fri, Dec 19, 2014 at 3:39 PM, Olga Kornievskaia <aglo@umich.edu> wrote: > On Fri, Dec 19, 2014 at 3:31 PM, Trond Myklebust > <trond.myklebust@primarydata.com> wrote: >> On Fri, Dec 19, 2014 at 1:52 PM, Trond Myklebust >> <trond.myklebust@primarydata.com> wrote: >>> 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> >>> --- >>> fs/nfs/delegation.c | 21 ++++++++++++++++++--- >>> 1 file changed, 18 insertions(+), 3 deletions(-) >>> >>> diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c >>> index 7f3f60641344..02b5b2a6d557 100644 >>> --- a/fs/nfs/delegation.c >>> +++ b/fs/nfs/delegation.c >>> @@ -301,6 +301,19 @@ nfs_inode_detach_delegation(struct inode *inode) >>> return nfs_detach_delegation(nfsi, delegation, server); >>> } >>> >>> +static void >>> +nfs_update_inplace_delegation(struct nfs_inode *nfsi, >>> + struct nfs_delegation *delegation, >>> + struct nfs_delegation *update) >>> +{ >>> + if (nfs4_stateid_is_newer(&update->stateid, &delegation->stateid)) >> >> ...and the above comparison should be reversed. > > do you mean: if(!nfs4_stateid_is_newer()) > > but if we received a delegation stateid with sequence number lower > than what we have, shouldn't that be some kind of an error? See the v3 patch. Yes, it would be a bug if the server sent us something with a lower number, so we ignore that and don't update the delegation. Ditto if it sends us something with the same sequence number.
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 7f3f60641344..02b5b2a6d557 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -301,6 +301,19 @@ nfs_inode_detach_delegation(struct inode *inode) return nfs_detach_delegation(nfsi, delegation, server); } +static void +nfs_update_inplace_delegation(struct nfs_inode *nfsi, + struct nfs_delegation *delegation, + struct nfs_delegation *update) +{ + if (nfs4_stateid_is_newer(&update->stateid, &delegation->stateid)) + return; + delegation->stateid.seqid = update->stateid.seqid; + smp_wmb(); + delegation->type = update->type; + nfsi->delegation_state = update->type; +} + /** * nfs_inode_set_delegation - set up a delegation on an inode * @inode: inode to which delegation applies @@ -334,9 +347,11 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct old_delegation = rcu_dereference_protected(nfsi->delegation, lockdep_is_held(&clp->cl_lock)); if (old_delegation != NULL) { - if (nfs4_stateid_match(&delegation->stateid, - &old_delegation->stateid) && - delegation->type == old_delegation->type) { + /* Is this an update of the existing delegation? */ + if (nfs4_stateid_match_other(&old_delegation->stateid, + &delegation->stateid)) { + nfs_update_inplace_delegation(nfsi, old_delegation, + delegation); goto out; } /*
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> --- fs/nfs/delegation.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-)