From patchwork Thu Jun 26 19:11:56 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 4430281 Return-Path: X-Original-To: patchwork-linux-nfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id ED42E9F2C8 for ; Thu, 26 Jun 2014 19:14:14 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C6BAF2028D for ; Thu, 26 Jun 2014 19:14:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D116F2024D for ; Thu, 26 Jun 2014 19:14:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751432AbaFZTOJ (ORCPT ); Thu, 26 Jun 2014 15:14:09 -0400 Received: from mail-qa0-f44.google.com ([209.85.216.44]:64903 "EHLO mail-qa0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751470AbaFZTOI (ORCPT ); Thu, 26 Jun 2014 15:14:08 -0400 Received: by mail-qa0-f44.google.com with SMTP id hw13so3195639qab.3 for ; Thu, 26 Jun 2014 12:14:08 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=M/R6Ob+lZUq2w+jMFbh7KLV07G3GwMJBiOrc43zgC2s=; b=W9sORm/+KCRBxM3WYxXKi4lLwGxWXqlNXA1mnekTYR508ESlluSY5zCuY09M94rKuk +sFLc7ehg9z4oR4Zlcu/fB7363CBRtKOI/l54ywzhBBxnBngLKg4gh48a7mEcz5RHRES vU/e2qoUjAMXmnnXMR0tDI13XF/LV9uqnfhhdjCTXkCoWy7aQbOpGzNuTrPxxe5qCeGJ ul6oJdQEo9uKtxBLx8JgOuAIy3qBGVa4Vlqo4VWcNfpsNGghzdOUfwPJndZxhVZ0Cpgm PfM0g8eoqXav5Tbx1BKBB3AQCvNhQY6raZ15THfyFQYGaN0KjHSHZO0OQw51+feTD5LL zqbw== X-Gm-Message-State: ALoCoQkJLiz3iQD/cgxWnL1hC/kKo84q7Rw4dSO8W7StPM/Pz3pI5VZ1jGwXY/oWsURMP2fj2qsa X-Received: by 10.229.234.3 with SMTP id ka3mr16955317qcb.16.1403810048392; Thu, 26 Jun 2014 12:14:08 -0700 (PDT) Received: from tlielax.poochiereds.net ([2001:470:8:d63:3a60:77ff:fe93:a95d]) by mx.google.com with ESMTPSA id 88sm4763039qgh.5.2014.06.26.12.14.07 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 26 Jun 2014 12:14:07 -0700 (PDT) From: Jeff Layton To: bfields@fieldses.org Cc: linux-nfs@vger.kernel.org Subject: [PATCH v2 016/117] nfsd: Allow lockowners to hold several stateids Date: Thu, 26 Jun 2014 15:11:56 -0400 Message-Id: <1403810017-16062-17-git-send-email-jlayton@primarydata.com> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1403810017-16062-1-git-send-email-jlayton@primarydata.com> References: <1403810017-16062-1-git-send-email-jlayton@primarydata.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP A lockowner can have more than one lock stateid. For instance, if a process has more than one file open and has locks on both, then the same lockowner has more than one stateid associated with it. Change it so that this reality is better reflected by the objects that nfsd uses. Reviewed-by: Christoph Hellwig Signed-off-by: Trond Myklebust Signed-off-by: Jeff Layton --- fs/nfsd/nfs4state.c | 55 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 2d7887a752db..5b903761ba73 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -3913,12 +3913,7 @@ nfsd4_free_lock_stateid(struct nfs4_ol_stateid *stp) if (check_for_locks(stp->st_file, lo)) return nfserr_locks_held; - /* - * Currently there's a 1-1 lock stateid<->lockowner - * correspondance, and we have to delete the lockowner when we - * delete the lock stateid: - */ - release_lockowner(lo); + release_lockowner_if_empty(lo); return nfs_ok; } @@ -4442,6 +4437,19 @@ alloc_init_lock_stateid(struct nfs4_lockowner *lo, struct nfs4_file *fp, struct return stp; } +static struct nfs4_ol_stateid * +find_lock_stateid(struct nfs4_lockowner *lo, struct nfs4_file *fp) +{ + struct nfs4_ol_stateid *lst; + + list_for_each_entry(lst, &lo->lo_owner.so_stateids, st_perstateowner) { + if (lst->st_file == fp) + return lst; + } + return NULL; +} + + static int check_lock_length(u64 offset, u64 length) { @@ -4471,25 +4479,28 @@ static __be32 lookup_or_create_lock_state(struct nfsd4_compound_state *cstate, s lo = find_lockowner_str(fi->fi_inode, &cl->cl_clientid, &lock->v.new.owner, nn); - if (lo) { - if (!cstate->minorversion) + if (!lo) { + strhashval = ownerstr_hashval(cl->cl_clientid.cl_id, + &lock->v.new.owner); + lo = alloc_init_lock_stateowner(strhashval, cl, ost, lock); + if (lo == NULL) + return nfserr_jukebox; + } else { + /* with an existing lockowner, seqids must be the same */ + if (!cstate->minorversion && + lock->lk_new_lock_seqid != lo->lo_owner.so_seqid) return nfserr_bad_seqid; - /* XXX: a lockowner always has exactly one stateid: */ - *lst = list_first_entry(&lo->lo_owner.so_stateids, - struct nfs4_ol_stateid, st_perstateowner); - return nfs_ok; } - strhashval = ownerstr_hashval(cl->cl_clientid.cl_id, - &lock->v.new.owner); - lo = alloc_init_lock_stateowner(strhashval, cl, ost, lock); - if (lo == NULL) - return nfserr_jukebox; - *lst = alloc_init_lock_stateid(lo, fi, ost); + + *lst = find_lock_stateid(lo, fi); if (*lst == NULL) { - release_lockowner(lo); - return nfserr_jukebox; + *lst = alloc_init_lock_stateid(lo, fi, ost); + if (*lst == NULL) { + release_lockowner_if_empty(lo); + return nfserr_jukebox; + } + *new = true; } - *new = true; return nfs_ok; } @@ -4646,7 +4657,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, } out: if (status && new_state) - release_lockowner(lock_sop); + release_lockowner_if_empty(lock_sop); nfsd4_bump_seqid(cstate, status); if (!cstate->replay_owner) nfs4_unlock_state();