From patchwork Mon Jan 21 20:45:51 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Greear X-Patchwork-Id: 2014021 Return-Path: X-Original-To: patchwork-linux-nfs@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id BB8B03FDD2 for ; Mon, 21 Jan 2013 20:47:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753973Ab3AUUrP (ORCPT ); Mon, 21 Jan 2013 15:47:15 -0500 Received: from mail.candelatech.com ([208.74.158.172]:39879 "EHLO ns3.lanforge.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752250Ab3AUUrO (ORCPT ); Mon, 21 Jan 2013 15:47:14 -0500 Received: from fs3.candelatech.com (firewall.candelatech.com [70.89.124.249]) by ns3.lanforge.com (8.14.2/8.14.2) with ESMTP id r0LKkDwu022791 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 21 Jan 2013 12:46:14 -0800 From: greearb@candelatech.com To: linux-nfs@vger.kernel.org Cc: Ben Greear Subject: [RFC 05/13] nfs: Pay attention to srcaddr in v4.1 callback logic. Date: Mon, 21 Jan 2013 12:45:51 -0800 Message-Id: <1358801159-18829-6-git-send-email-greearb@candelatech.com> X-Mailer: git-send-email 1.7.3.4 In-Reply-To: <1358801159-18829-1-git-send-email-greearb@candelatech.com> References: <1358801159-18829-1-git-send-email-greearb@candelatech.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Ben Greear Signed-off-by: Ben Greear --- fs/nfs/callback_proc.c | 3 ++- fs/nfs/internal.h | 6 ++++-- fs/nfs/nfs4client.c | 24 +++++++++++++++++++++++- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 36b2e7a..24a3457 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -451,7 +451,8 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, int i; __be32 status = htonl(NFS4ERR_BADSESSION); - clp = nfs4_find_client_sessionid(cps->net, args->csa_addr, &args->csa_sessionid); + clp = nfs4_find_client_sessionid(cps->net, args->csa_daddr, args->csa_addr, + &args->csa_sessionid); if (clp == NULL) goto out; diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 80504e1..11c5ac7 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -190,8 +190,10 @@ extern void nfs_put_client(struct nfs_client *); extern void nfs_free_client(struct nfs_client *); extern struct nfs_client *nfs4_find_client_ident(struct net *, int); extern struct nfs_client * -nfs4_find_client_sessionid(struct net *, const struct sockaddr *, - struct nfs4_sessionid *); +nfs4_find_client_sessionid(struct net *, + const struct sockaddr *srcaddr, + const struct sockaddr *addr, + struct nfs4_sessionid *); extern struct nfs_server *nfs_create_server(struct nfs_mount_info *, struct nfs_subversion *); extern struct nfs_server *nfs4_create_server( diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index 1f55131..7c4dc21 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -543,11 +543,13 @@ static bool nfs4_cb_match_client(const struct sockaddr *addr, * Returns NULL if no such client */ struct nfs_client * -nfs4_find_client_sessionid(struct net *net, const struct sockaddr *addr, +nfs4_find_client_sessionid(struct net *net, const struct sockaddr *srcaddr, + const struct sockaddr *addr, struct nfs4_sessionid *sid) { struct nfs_client *clp; struct nfs_net *nn = net_generic(net, nfs_net_id); + struct nfs_client *ok_fit = NULL; spin_lock(&nn->nfs_client_lock); list_for_each_entry(clp, &nn->nfs_client_list, cl_share_link) { @@ -562,10 +564,30 @@ nfs4_find_client_sessionid(struct net *net, const struct sockaddr *addr, sid->data, NFS4_MAX_SESSIONID_LEN) != 0) continue; + if (srcaddr) { + const struct sockaddr *sa; + sa = (const struct sockaddr *)&clp->cl_addr; + if (!nfs_sockaddr_match_ipaddr(srcaddr, sa)) { + /* If clp doesn't bind to srcaddr, then + * it is a potential match if we don't find + * a better one. + */ + if (sa->sa_family == AF_UNSPEC && !ok_fit) + ok_fit = clp; + continue; + } + } +found_one: atomic_inc(&clp->cl_count); spin_unlock(&nn->nfs_client_lock); return clp; } + + if (ok_fit) { + clp = ok_fit; + goto found_one; + } + spin_unlock(&nn->nfs_client_lock); return NULL; }