mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 10:49:33 +00: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;
|
u32 minor_version;
|
||||||
unsigned init_caps;
|
unsigned init_caps;
|
||||||
|
|
||||||
|
int (*init_client)(struct nfs_client *);
|
||||||
|
void (*shutdown_client)(struct nfs_client *);
|
||||||
bool (*match_stateid)(const nfs4_stateid *,
|
bool (*match_stateid)(const nfs4_stateid *,
|
||||||
const nfs4_stateid *);
|
const nfs4_stateid *);
|
||||||
int (*find_root_sec)(struct nfs_server *, struct nfs_fh *,
|
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_fsinfo_bitmap[3];
|
||||||
extern const u32 nfs4_fs_locations_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 *);
|
void nfs4_free_client(struct nfs_client *);
|
||||||
|
|
||||||
struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *);
|
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
|
#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)) {
|
if (nfs4_has_session(clp)) {
|
||||||
nfs4_destroy_session(clp->cl_session);
|
nfs4_destroy_session(clp->cl_session);
|
||||||
|
@ -49,11 +49,15 @@ static void nfs4_shutdown_session(struct nfs_client *clp)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#else /* CONFIG_NFS_V4_1 */
|
#endif /* CONFIG_NFS_V4_1 */
|
||||||
static void nfs4_shutdown_session(struct nfs_client *clp)
|
|
||||||
|
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)
|
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))
|
if (__test_and_clear_bit(NFS_CS_RENEWD, &clp->cl_res_state))
|
||||||
nfs4_kill_renewd(clp);
|
nfs4_kill_renewd(clp);
|
||||||
nfs4_shutdown_session(clp);
|
clp->cl_mvops->shutdown_client(clp);
|
||||||
nfs4_destroy_callback(clp);
|
nfs4_destroy_callback(clp);
|
||||||
if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state))
|
if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state))
|
||||||
nfs_idmap_delete(clp);
|
nfs_idmap_delete(clp);
|
||||||
|
@ -144,34 +148,77 @@ static int nfs4_init_callback(struct nfs_client *clp)
|
||||||
return 0;
|
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
|
* Initialize the minor version specific parts of an NFS4 client record
|
||||||
*/
|
*/
|
||||||
static int nfs4_init_client_minor_version(struct nfs_client *clp)
|
static int nfs4_init_client_minor_version(struct nfs_client *clp)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_NFS_V4_1)
|
int ret;
|
||||||
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 */
|
|
||||||
|
|
||||||
|
ret = clp->cl_mvops->init_client(clp);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
return nfs4_init_callback(clp);
|
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_ATOMIC_OPEN
|
||||||
| NFS_CAP_CHANGE_ATTR
|
| NFS_CAP_CHANGE_ATTR
|
||||||
| NFS_CAP_POSIX_LOCK,
|
| NFS_CAP_POSIX_LOCK,
|
||||||
|
.init_client = nfs40_init_client,
|
||||||
|
.shutdown_client = nfs40_shutdown_client,
|
||||||
.match_stateid = nfs4_match_stateid,
|
.match_stateid = nfs4_match_stateid,
|
||||||
.find_root_sec = nfs4_find_root_sec,
|
.find_root_sec = nfs4_find_root_sec,
|
||||||
.free_lock_state = nfs4_release_lockowner,
|
.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_POSIX_LOCK
|
||||||
| NFS_CAP_STATEID_NFSV41
|
| NFS_CAP_STATEID_NFSV41
|
||||||
| NFS_CAP_ATOMIC_OPEN_V1,
|
| NFS_CAP_ATOMIC_OPEN_V1,
|
||||||
|
.init_client = nfs41_init_client,
|
||||||
|
.shutdown_client = nfs41_shutdown_client,
|
||||||
.match_stateid = nfs41_match_stateid,
|
.match_stateid = nfs41_match_stateid,
|
||||||
.find_root_sec = nfs41_find_root_sec,
|
.find_root_sec = nfs41_find_root_sec,
|
||||||
.free_lock_state = nfs41_free_lock_state,
|
.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_POSIX_LOCK
|
||||||
| NFS_CAP_STATEID_NFSV41
|
| NFS_CAP_STATEID_NFSV41
|
||||||
| NFS_CAP_ATOMIC_OPEN_V1,
|
| NFS_CAP_ATOMIC_OPEN_V1,
|
||||||
|
.init_client = nfs41_init_client,
|
||||||
|
.shutdown_client = nfs41_shutdown_client,
|
||||||
.match_stateid = nfs41_match_stateid,
|
.match_stateid = nfs41_match_stateid,
|
||||||
.find_root_sec = nfs41_find_root_sec,
|
.find_root_sec = nfs41_find_root_sec,
|
||||||
.free_lock_state = nfs41_free_lock_state,
|
.free_lock_state = nfs41_free_lock_state,
|
||||||
|
|
|
@ -78,6 +78,9 @@ struct nfs_client {
|
||||||
u32 cl_cb_ident; /* v4.0 callback identifier */
|
u32 cl_cb_ident; /* v4.0 callback identifier */
|
||||||
const struct nfs4_minor_version_ops *cl_mvops;
|
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 */
|
/* The sequence id to use for the next CREATE_SESSION */
|
||||||
u32 cl_seqid;
|
u32 cl_seqid;
|
||||||
/* The flags used for obtaining the clientid during EXCHANGE_ID */
|
/* The flags used for obtaining the clientid during EXCHANGE_ID */
|
||||||
|
|
Loading…
Reference in a new issue