Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit abf79bb3 authored by Chuck Lever's avatar Chuck Lever Committed by Trond Myklebust
Browse files

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: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent eb2a1cd3
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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 *);
+74 −27
Original line number Diff line number Diff line
@@ -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,14 +148,44 @@ static int nfs4_init_callback(struct nfs_client *clp)
	return 0;
}

/*
 * Initialize the minor version specific parts of an NFS4 client record
/**
 * 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.
 */
static int nfs4_init_client_minor_version(struct nfs_client *clp)
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)
	if (clp->cl_mvops->minor_version) {

/**
 * 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
@@ -162,6 +196,7 @@ static int nfs4_init_client_minor_version(struct nfs_client *clp)
		return -ENOMEM;

	clp->cl_session = session;

	/*
	 * The create session reply races with the server back
	 * channel probe. Mark the client NFS_CS_SESSION_INITING
@@ -169,9 +204,21 @@ static int nfs4_init_client_minor_version(struct nfs_client *clp)
	 * 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)
{
	int ret;

	ret = clp->cl_mvops->init_client(clp);
	if (ret)
		return ret;
	return nfs4_init_callback(clp);
}

+6 −0
Original line number Diff line number Diff line
@@ -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,
+3 −0
Original line number Diff line number Diff line
@@ -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 */