mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	NFS: Add a slot table to struct nfs_client for NFSv4.0 transport blocking
Anchor an nfs4_slot_table in the nfs_client for use with NFSv4.0 transport blocking. It is initialized only for NFSv4.0 nfs_client's. Introduce appropriate minor version ops to handle nfs_client initialization and shutdown requirements that differ for each minor version. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
		
							parent
							
								
									eb2a1cd3c9
								
							
						
					
					
						commit
						abf79bb341
					
				
					 4 changed files with 89 additions and 27 deletions
				
			
		| 
						 | 
				
			
			@ -38,6 +38,8 @@ struct nfs4_minor_version_ops {
 | 
			
		|||
	u32	minor_version;
 | 
			
		||||
	unsigned init_caps;
 | 
			
		||||
 | 
			
		||||
	int	(*init_client)(struct nfs_client *);
 | 
			
		||||
	void	(*shutdown_client)(struct nfs_client *);
 | 
			
		||||
	bool	(*match_stateid)(const nfs4_stateid *,
 | 
			
		||||
			const nfs4_stateid *);
 | 
			
		||||
	int	(*find_root_sec)(struct nfs_server *, struct nfs_fh *,
 | 
			
		||||
| 
						 | 
				
			
			@ -292,6 +294,10 @@ extern const u32 nfs4_pathconf_bitmap[3];
 | 
			
		|||
extern const u32 nfs4_fsinfo_bitmap[3];
 | 
			
		||||
extern const u32 nfs4_fs_locations_bitmap[3];
 | 
			
		||||
 | 
			
		||||
void nfs40_shutdown_client(struct nfs_client *);
 | 
			
		||||
void nfs41_shutdown_client(struct nfs_client *);
 | 
			
		||||
int nfs40_init_client(struct nfs_client *);
 | 
			
		||||
int nfs41_init_client(struct nfs_client *);
 | 
			
		||||
void nfs4_free_client(struct nfs_client *);
 | 
			
		||||
 | 
			
		||||
struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,7 +41,7 @@ static int nfs_get_cb_ident_idr(struct nfs_client *clp, int minorversion)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_NFS_V4_1
 | 
			
		||||
static void nfs4_shutdown_session(struct nfs_client *clp)
 | 
			
		||||
void nfs41_shutdown_client(struct nfs_client *clp)
 | 
			
		||||
{
 | 
			
		||||
	if (nfs4_has_session(clp)) {
 | 
			
		||||
		nfs4_destroy_session(clp->cl_session);
 | 
			
		||||
| 
						 | 
				
			
			@ -49,11 +49,15 @@ static void nfs4_shutdown_session(struct nfs_client *clp)
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
#else /* CONFIG_NFS_V4_1 */
 | 
			
		||||
static void nfs4_shutdown_session(struct nfs_client *clp)
 | 
			
		||||
#endif	/* CONFIG_NFS_V4_1 */
 | 
			
		||||
 | 
			
		||||
void nfs40_shutdown_client(struct nfs_client *clp)
 | 
			
		||||
{
 | 
			
		||||
	if (clp->cl_slot_tbl) {
 | 
			
		||||
		nfs4_release_slot_table(clp->cl_slot_tbl);
 | 
			
		||||
		kfree(clp->cl_slot_tbl);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
#endif /* CONFIG_NFS_V4_1 */
 | 
			
		||||
 | 
			
		||||
struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -97,7 +101,7 @@ static void nfs4_shutdown_client(struct nfs_client *clp)
 | 
			
		|||
{
 | 
			
		||||
	if (__test_and_clear_bit(NFS_CS_RENEWD, &clp->cl_res_state))
 | 
			
		||||
		nfs4_kill_renewd(clp);
 | 
			
		||||
	nfs4_shutdown_session(clp);
 | 
			
		||||
	clp->cl_mvops->shutdown_client(clp);
 | 
			
		||||
	nfs4_destroy_callback(clp);
 | 
			
		||||
	if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state))
 | 
			
		||||
		nfs_idmap_delete(clp);
 | 
			
		||||
| 
						 | 
				
			
			@ -144,34 +148,77 @@ static int nfs4_init_callback(struct nfs_client *clp)
 | 
			
		|||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nfs40_init_client - nfs_client initialization tasks for NFSv4.0
 | 
			
		||||
 * @clp - nfs_client to initialize
 | 
			
		||||
 *
 | 
			
		||||
 * Returns zero on success, or a negative errno if some error occurred.
 | 
			
		||||
 */
 | 
			
		||||
int nfs40_init_client(struct nfs_client *clp)
 | 
			
		||||
{
 | 
			
		||||
	struct nfs4_slot_table *tbl;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	tbl = kzalloc(sizeof(*tbl), GFP_NOFS);
 | 
			
		||||
	if (tbl == NULL)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
	ret = nfs4_setup_slot_table(tbl, NFS4_MAX_SLOT_TABLE,
 | 
			
		||||
					"NFSv4.0 transport Slot table");
 | 
			
		||||
	if (ret) {
 | 
			
		||||
		kfree(tbl);
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	clp->cl_slot_tbl = tbl;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(CONFIG_NFS_V4_1)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nfs41_init_client - nfs_client initialization tasks for NFSv4.1+
 | 
			
		||||
 * @clp - nfs_client to initialize
 | 
			
		||||
 *
 | 
			
		||||
 * Returns zero on success, or a negative errno if some error occurred.
 | 
			
		||||
 */
 | 
			
		||||
int nfs41_init_client(struct nfs_client *clp)
 | 
			
		||||
{
 | 
			
		||||
	struct nfs4_session *session = NULL;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Create the session and mark it expired.
 | 
			
		||||
	 * When a SEQUENCE operation encounters the expired session
 | 
			
		||||
	 * it will do session recovery to initialize it.
 | 
			
		||||
	 */
 | 
			
		||||
	session = nfs4_alloc_session(clp);
 | 
			
		||||
	if (!session)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
	clp->cl_session = session;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * The create session reply races with the server back
 | 
			
		||||
	 * channel probe. Mark the client NFS_CS_SESSION_INITING
 | 
			
		||||
	 * so that the client back channel can find the
 | 
			
		||||
	 * nfs_client struct
 | 
			
		||||
	 */
 | 
			
		||||
	nfs_mark_client_ready(clp, NFS_CS_SESSION_INITING);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif	/* CONFIG_NFS_V4_1 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Initialize the minor version specific parts of an NFS4 client record
 | 
			
		||||
 */
 | 
			
		||||
static int nfs4_init_client_minor_version(struct nfs_client *clp)
 | 
			
		||||
{
 | 
			
		||||
#if defined(CONFIG_NFS_V4_1)
 | 
			
		||||
	if (clp->cl_mvops->minor_version) {
 | 
			
		||||
		struct nfs4_session *session = NULL;
 | 
			
		||||
		/*
 | 
			
		||||
		 * Create the session and mark it expired.
 | 
			
		||||
		 * When a SEQUENCE operation encounters the expired session
 | 
			
		||||
		 * it will do session recovery to initialize it.
 | 
			
		||||
		 */
 | 
			
		||||
		session = nfs4_alloc_session(clp);
 | 
			
		||||
		if (!session)
 | 
			
		||||
			return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
		clp->cl_session = session;
 | 
			
		||||
		/*
 | 
			
		||||
		 * The create session reply races with the server back
 | 
			
		||||
		 * channel probe. Mark the client NFS_CS_SESSION_INITING
 | 
			
		||||
		 * so that the client back channel can find the
 | 
			
		||||
		 * nfs_client struct
 | 
			
		||||
		 */
 | 
			
		||||
		nfs_mark_client_ready(clp, NFS_CS_SESSION_INITING);
 | 
			
		||||
	}
 | 
			
		||||
#endif /* CONFIG_NFS_V4_1 */
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	ret = clp->cl_mvops->init_client(clp);
 | 
			
		||||
	if (ret)
 | 
			
		||||
		return ret;
 | 
			
		||||
	return nfs4_init_callback(clp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7533,6 +7533,8 @@ static const struct nfs4_minor_version_ops nfs_v4_0_minor_ops = {
 | 
			
		|||
		| NFS_CAP_ATOMIC_OPEN
 | 
			
		||||
		| NFS_CAP_CHANGE_ATTR
 | 
			
		||||
		| NFS_CAP_POSIX_LOCK,
 | 
			
		||||
	.init_client = nfs40_init_client,
 | 
			
		||||
	.shutdown_client = nfs40_shutdown_client,
 | 
			
		||||
	.match_stateid = nfs4_match_stateid,
 | 
			
		||||
	.find_root_sec = nfs4_find_root_sec,
 | 
			
		||||
	.free_lock_state = nfs4_release_lockowner,
 | 
			
		||||
| 
						 | 
				
			
			@ -7551,6 +7553,8 @@ static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = {
 | 
			
		|||
		| NFS_CAP_POSIX_LOCK
 | 
			
		||||
		| NFS_CAP_STATEID_NFSV41
 | 
			
		||||
		| NFS_CAP_ATOMIC_OPEN_V1,
 | 
			
		||||
	.init_client = nfs41_init_client,
 | 
			
		||||
	.shutdown_client = nfs41_shutdown_client,
 | 
			
		||||
	.match_stateid = nfs41_match_stateid,
 | 
			
		||||
	.find_root_sec = nfs41_find_root_sec,
 | 
			
		||||
	.free_lock_state = nfs41_free_lock_state,
 | 
			
		||||
| 
						 | 
				
			
			@ -7570,6 +7574,8 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = {
 | 
			
		|||
		| NFS_CAP_POSIX_LOCK
 | 
			
		||||
		| NFS_CAP_STATEID_NFSV41
 | 
			
		||||
		| NFS_CAP_ATOMIC_OPEN_V1,
 | 
			
		||||
	.init_client = nfs41_init_client,
 | 
			
		||||
	.shutdown_client = nfs41_shutdown_client,
 | 
			
		||||
	.match_stateid = nfs41_match_stateid,
 | 
			
		||||
	.find_root_sec = nfs41_find_root_sec,
 | 
			
		||||
	.free_lock_state = nfs41_free_lock_state,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -78,6 +78,9 @@ struct nfs_client {
 | 
			
		|||
	u32			cl_cb_ident;	/* v4.0 callback identifier */
 | 
			
		||||
	const struct nfs4_minor_version_ops *cl_mvops;
 | 
			
		||||
 | 
			
		||||
	/* NFSv4.0 transport blocking */
 | 
			
		||||
	struct nfs4_slot_table	*cl_slot_tbl;
 | 
			
		||||
 | 
			
		||||
	/* The sequence id to use for the next CREATE_SESSION */
 | 
			
		||||
	u32			cl_seqid;
 | 
			
		||||
	/* The flags used for obtaining the clientid during EXCHANGE_ID */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue