From patchwork Wed Jul 11 20:31:25 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 1185391 Return-Path: X-Original-To: patchwork-linux-nfs@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 53384DF25A for ; Wed, 11 Jul 2012 20:31:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933194Ab2GKUb2 (ORCPT ); Wed, 11 Jul 2012 16:31:28 -0400 Received: from mail-gh0-f174.google.com ([209.85.160.174]:56583 "EHLO mail-gh0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932350Ab2GKUb1 (ORCPT ); Wed, 11 Jul 2012 16:31:27 -0400 Received: by mail-gh0-f174.google.com with SMTP id r11so1692583ghr.19 for ; Wed, 11 Jul 2012 13:31:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:subject:to:cc:date:message-id:in-reply-to:references :user-agent:mime-version:content-type:content-transfer-encoding; bh=K1amG6HkKHvJxe2ddLFRt7U69neoGgBQdDjP8FgSr5Q=; b=SJEzKzzvjmn/5ZfLrBGd/WbMFk7LTmsNV2Urj2odFF7VJ4nceSaR4jf2VQelNgs8tf ykFh+BubVN23Sq37Nta3lXOiiFJYWj0fNm8deR8X5+423hjKLE8Il7n81aY3YYkUFtBi w1x6K6o7HTX+5Wo6/VQ86f3X5gGU0G0g/hx9xMpy2zOClMKvmVz8fc2zd6EqiXFecZsH nHTdBnFslwkut09tsgEufZzisGuZwJosDwKe52g6oACb09vE4//mLt+z8mzBoBK5ODnn tkfZN+ZUV6CNHtcjUo8FvJmFQXG00shDz9mv0P+jAEC4W+uUF3SP1kL7wTL0D8ByqGT/ T+Jg== Received: by 10.43.48.8 with SMTP id uu8mr26545940icb.31.1342038687098; Wed, 11 Jul 2012 13:31:27 -0700 (PDT) Received: from degas.1015granger.net (adsl-99-26-161-222.dsl.sfldmi.sbcglobal.net. [99.26.161.222]) by mx.google.com with ESMTPS id k6sm15136309igz.9.2012.07.11.13.31.26 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 11 Jul 2012 13:31:26 -0700 (PDT) From: Chuck Lever Subject: [PATCH 12/15] NFS: Use the same nfs_client_id4 for every server To: trond.myklebust@netapp.com Cc: linux-nfs@vger.kernel.org Date: Wed, 11 Jul 2012 16:31:25 -0400 Message-ID: <20120711203125.3767.93859.stgit@degas.1015granger.net> In-Reply-To: <20120711201718.3767.66867.stgit@degas.1015granger.net> References: <20120711201718.3767.66867.stgit@degas.1015granger.net> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org Currently, when identifying itself to NFS servers, the Linux NFS client uses a unique nfs_client_id4.id string for each server IP address it talks with. For example, when client A talks to server X, the client identifies itself using a string like "AX". The requirements for these strings are specified in detail by RFC 3530 (and bis). This form of client identification presents a problem for Transparent State Migration. When client A's state on server X is migrated to server Y, it continues to be associated with string "AX." But, according to the rules of client string construction above, client A will present string "AY" when communicating with server Y. Server Y thus has no way to know that client A should be associated with the state migrated from server X. "AX" is all but abandoned, interfering with establishing fresh state for client A on server Y. To support transparent state migration, then, NFSv4.0 clients must instead use the same nfs_client_id4.id string to identify themselves to every NFS server; something like "A". Now a client identifies itself as "A" to server X. When a file system on server X transitions to server Y, and client A identifies itself as "A" to server Y, Y will know immediately that the state associated with "A," whether it is native or migrated, is owned by the client, and can merge both into a single lease. As a pre-requisite to adding support for NFSv4 migration to the Linux NFS client, this patch changes the way Linux identifies itself to NFS servers via the SETCLIENTID (NFSv4 minor version 0) and EXCHANGE_ID (NFSv4 minor version 1) operations. In addition to removing the server's IP address from nfs_client_id4, the Linux NFS client will also no longer use its own source IP address as part of the nfs_client_id4 string. On multi-homed clients, the value of this address depends on the address family and network routing used to contact the server, thus it can be different for each server. Signed-off-by: Chuck Lever --- fs/nfs/nfs4proc.c | 51 +++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 39 insertions(+), 12 deletions(-) -- 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 diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 75bff3f..b09b849 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -4024,6 +4024,32 @@ static void nfs4_init_boot_verifier(const struct nfs_client *clp, memcpy(bootverf->data, verf, sizeof(bootverf->data)); } +static unsigned int +nfs4_init_nonuniform_client_string(const struct nfs_client *clp, + char *buf, size_t len) +{ + unsigned int result; + + rcu_read_lock(); + result = scnprintf(buf, len, "Linux NFSv4.0 %s/%s %s", + clp->cl_ipaddr, + rpc_peeraddr2str(clp->cl_rpcclient, + RPC_DISPLAY_ADDR), + rpc_peeraddr2str(clp->cl_rpcclient, + RPC_DISPLAY_PROTO)); + rcu_read_unlock(); + return result; +} + +static unsigned int +nfs4_init_uniform_client_string(const struct nfs_client *clp, + char *buf, size_t len) +{ + return scnprintf(buf, len, "Linux NFSv%u.%u %s", + clp->rpc_ops->version, clp->cl_minorversion, + clp->cl_rpcclient->cl_nodename); +} + /** * nfs4_proc_setclientid - Negotiate client ID * @clp: state data structure @@ -4054,15 +4080,18 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, /* nfs_client_id4 */ nfs4_init_boot_verifier(clp, &sc_verifier); - rcu_read_lock(); - setclientid.sc_name_len = scnprintf(setclientid.sc_name, - sizeof(setclientid.sc_name), "%s/%s %s", - clp->cl_ipaddr, - rpc_peeraddr2str(clp->cl_rpcclient, - RPC_DISPLAY_ADDR), - rpc_peeraddr2str(clp->cl_rpcclient, - RPC_DISPLAY_PROTO)); + if (test_bit(NFS_CS_MIGRATION, &clp->cl_flags)) + setclientid.sc_name_len = + nfs4_init_uniform_client_string(clp, + setclientid.sc_name, + sizeof(setclientid.sc_name)); + else + setclientid.sc_name_len = + nfs4_init_nonuniform_client_string(clp, + setclientid.sc_name, + sizeof(setclientid.sc_name)); /* cb_client4 */ + rcu_read_lock(); setclientid.sc_netid_len = scnprintf(setclientid.sc_netid, sizeof(setclientid.sc_netid), rpc_peeraddr2str(clp->cl_rpcclient, @@ -5284,10 +5313,8 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred) }; nfs4_init_boot_verifier(clp, &verifier); - args.id_len = scnprintf(args.id, sizeof(args.id), - "%s/%s", - clp->cl_ipaddr, - clp->cl_rpcclient->cl_nodename); + args.id_len = nfs4_init_uniform_client_string(clp, args.id, + sizeof(args.id)); dprintk("NFS call exchange_id auth=%s, '%.*s'\n", clp->cl_rpcclient->cl_auth->au_ops->au_name, args.id_len, args.id);