Return-Path: linux-nfs-owner@vger.kernel.org Received: from mail-ig0-f174.google.com ([209.85.213.174]:52846 "EHLO mail-ig0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751165AbaLSUje (ORCPT ); Fri, 19 Dec 2014 15:39:34 -0500 Received: by mail-ig0-f174.google.com with SMTP id hn15so1283073igb.7 for ; Fri, 19 Dec 2014 12:39:33 -0800 (PST) MIME-Version: 1.0 In-Reply-To: References: <1419015154-91037-1-git-send-email-trond.myklebust@primarydata.com> Date: Fri, 19 Dec 2014 15:39:33 -0500 Message-ID: Subject: Re: [PATCH v2 1/2] NFSv4: Deal with atomic upgrades of an existing delegation From: Olga Kornievskaia To: Trond Myklebust Cc: linux-nfs Content-Type: text/plain; charset=UTF-8 Sender: linux-nfs-owner@vger.kernel.org List-ID: On Fri, Dec 19, 2014 at 3:31 PM, Trond Myklebust wrote: > On Fri, Dec 19, 2014 at 1:52 PM, Trond Myklebust > 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 >> --- >> 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