Re: [PATCH Version 2 1/1] NFSv4.1 Fix umount when filelayout DS is also the MDS

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Jun 14, 2012, at 1:21 PM, Myklebust, Trond wrote:

> On Thu, 2012-06-14 at 12:12 -0400, andros@xxxxxxxxxx wrote:
> 
>> ---
>> fs/nfs/client.c            |   88 ++++++++++++++++++++++++++++++++++++++++++-
>> fs/nfs/internal.h          |    1 +
>> fs/nfs/nfs4filelayoutdev.c |   29 ++++++++++++--
>> include/linux/nfs_fs_sb.h  |    1 +
>> 4 files changed, 112 insertions(+), 7 deletions(-)
> 
> Hi Andy,
> 
> Is there any reason why the following wouldn't work instead? It is
> essentially the same idea.

Hi Trond

Works great - less filling - cool!

ACK

-->Andy

> 
> Cheers
>  Trond
> 8<-------------------------------------------------------
> From dbee3513f10c3324aa0683d415193a5d2af6a31e Mon Sep 17 00:00:00 2001
> From: Trond Myklebust <Trond.Myklebust@xxxxxxxxxx>
> Date: Thu, 14 Jun 2012 13:08:38 -0400
> Subject: [PATCH] NFSv4.1: Fix umount when filelayout DS is also the MDS
> 
> Currently there is a 'chicken and egg' issue when the DS is also the mounted
> MDS. The nfs_match_client() reference from nfs4_set_ds_client bumps the
> cl_count, the nfs_client is not freed at umount, and nfs4_deviceid_purge_client
> is not called to dereference the MDS usage of a deviceid which holds a
> reference to the DS nfs_client.  The result is the umount program returns,
> but the nfs_client is not freed, and the cl_session hearbeat continues.
> 
> The MDS (and all other nfs mounts) lose their last nfs_client reference in
> nfs_free_server when the last nfs_server (fsid) is umounted.
> The file layout DS lose their last nfs_client reference in destroy_ds
> when the last deviceid referencing the data server is put and destroy_ds is
> called. This is triggered by a call to nfs4_deviceid_purge_client which
> removes references to a pNFS deviceid used by an MDS mount.
> 
> The fix is to track how many filesystems are mounted from this server,
> and then to purge the device id cache once that count is zero.
> 
> Reported-by: Jorge Mora <Jorge.Mora@xxxxxxxxxx>
> Reported-by: Andy Adamson <andros@xxxxxxxxxx>
> Signed-off-by: Trond Myklebust <Trond.Myklebust@xxxxxxxxxx>
> ---
> fs/nfs/client.c           |   43 +++++++++++++++++++++++++++++++++++++------
> include/linux/nfs_fs_sb.h |    1 +
> 2 files changed, 38 insertions(+), 6 deletions(-)
> 
> diff --git a/fs/nfs/client.c b/fs/nfs/client.c
> index 17ba6b9..faa58d5 100644
> --- a/fs/nfs/client.c
> +++ b/fs/nfs/client.c
> @@ -207,16 +207,25 @@ error_0:
> static void nfs4_shutdown_session(struct nfs_client *clp)
> {
> 	if (nfs4_has_session(clp)) {
> -		nfs4_deviceid_purge_client(clp);
> 		nfs4_destroy_session(clp->cl_session);
> 		nfs4_destroy_clientid(clp);
> 	}
> 
> }
> +
> +static void nfs4_purge_dataservers(struct nfs_client *clp)
> +{
> +	if (nfs4_has_session(clp))
> +		nfs4_deviceid_purge_client(clp);
> +}
> #else /* CONFIG_NFS_V4_1 */
> static void nfs4_shutdown_session(struct nfs_client *clp)
> {
> }
> +
> +static void nfs4_purge_dataservers(struct nfs_client *clp)
> +{
> +}
> #endif /* CONFIG_NFS_V4_1 */
> 
> /*
> @@ -801,6 +810,29 @@ static int nfs_init_server_rpcclient(struct nfs_server *server,
> 	return 0;
> }
> 
> +static int
> +nfs_server_set_client(struct nfs_server *server, struct nfs_client *clp)
> +{
> +	/* Track the number of filesystems being mounted from this server */
> +	atomic_inc(&clp->cl_server_count);
> +	server->nfs_client = clp;
> +	return 0;
> +}
> +
> +static void
> +nfs_server_unset_client(struct nfs_server *server)
> +{
> +	struct nfs_client *clp = server->nfs_client;
> +
> +	/* Purge the list of pNFS data servers once the number of mounted
> +	 * filesystems falls to zero.
> +	 */
> +	if (atomic_dec_and_test(&clp->cl_server_count))
> +		nfs4_purge_dataservers(clp);
> +
> +	nfs_put_client(clp);
> +}
> +
> /**
>  * nfs_init_client - Initialise an NFS2 or NFS3 client
>  *
> @@ -887,7 +919,7 @@ static int nfs_init_server(struct nfs_server *server,
> 		return PTR_ERR(clp);
> 	}
> 
> -	server->nfs_client = clp;
> +	nfs_server_set_client(server, clp);
> 
> 	/* Initialise the client representation from the mount data */
> 	server->flags = data->flags;
> @@ -934,8 +966,7 @@ static int nfs_init_server(struct nfs_server *server,
> 	return 0;
> 
> error:
> -	server->nfs_client = NULL;
> -	nfs_put_client(clp);
> +	nfs_server_unset_client(server);
> 	dprintk("<-- nfs_init_server() = xerror %d\n", error);
> 	return error;
> }
> @@ -1149,7 +1180,7 @@ void nfs_free_server(struct nfs_server *server)
> 	if (!IS_ERR(server->client))
> 		rpc_shutdown_client(server->client);
> 
> -	nfs_put_client(server->nfs_client);
> +	nfs_server_unset_client(server);
> 
> 	ida_destroy(&server->lockowner_id);
> 	ida_destroy(&server->openowner_id);
> @@ -1469,7 +1500,7 @@ static int nfs4_set_client(struct nfs_server *server,
> 	 */
> 	set_bit(NFS_CS_CHECK_LEASE_TIME, &clp->cl_res_state);
> 
> -	server->nfs_client = clp;
> +	nfs_server_set_client(server, clp);
> 	dprintk("<-- nfs4_set_client() = 0 [new %p]\n", clp);
> 	return 0;
> error:
> diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
> index fbb78fb..2d51077 100644
> --- a/include/linux/nfs_fs_sb.h
> +++ b/include/linux/nfs_fs_sb.h
> @@ -25,6 +25,7 @@ struct nfs41_impl_id;
>  */
> struct nfs_client {
> 	atomic_t		cl_count;
> +	atomic_t		cl_server_count;
> 	int			cl_cons_state;	/* current construction state (-ve: init error) */
> #define NFS_CS_READY		0		/* ready to be used */
> #define NFS_CS_INITING		1		/* busy initialising */
> -- 
> 1.7.10.2
> 
> 
> -- 
> Trond Myklebust
> Linux NFS client maintainer
> 
> NetApp
> Trond.Myklebust@xxxxxxxxxx
> www.netapp.com
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux