2017-01-11 18:55:07

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH 00/11] Create a single nfs4_setup_sequence() function

From: Anna Schumaker <[email protected]>

I noticed that NFS v4.0 and v4.1 have different setup_sequence() functions
that are very, very similar. I think we should try to share as much code
as possible whenever possible, so these patches merge together both versions
of this function using the presence of a session to decide if we need to do
a little extra work in some cases.

I broke this change into several logical steps that (hopefully) make it easier
to follow what I did.

Questions? Comments? Thoughts?
Anna


Anna Schumaker (11):
NFS: Move nfs4_get_session() into nfs4_session.h
NFS: Change nfs4_get_session() to take an nfs_client structure
NFS: Change nfs4_setup_sequence() to take an nfs_client structure
NFS: Use nfs4_setup_sequence() everywhere
NFS: Create a single nfs4_setup_sequence() function
NFS: Move slot-already-allocated check into nfs_setup_sequence()
NFS: Lock the slot table from a single place during setup sequence
NFS: Handle setup sequence task rescheduling in a single place
NFS: Check if the slot table is draining from nfs4_setup_sequence()
NFS: Merge the remaining setup_sequence functions
NFS: Make trace_nfs4_setup_sequence() available to NFS v4.0

fs/nfs/filelayout/filelayout.c | 6 +-
fs/nfs/flexfilelayout/flexfilelayout.c | 40 ++----
fs/nfs/nfs42proc.c | 6 +-
fs/nfs/nfs4_fs.h | 15 +-
fs/nfs/nfs4proc.c | 244 +++++++++++----------------------
fs/nfs/nfs4session.h | 7 +
fs/nfs/nfs4trace.h | 64 ++++-----
7 files changed, 139 insertions(+), 243 deletions(-)

--
2.11.0



2017-01-11 18:55:07

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH 01/11] NFS: Move nfs4_get_session() into nfs4_session.h

From: Anna Schumaker <[email protected]>

This puts session related functions together in the same space. I only
keep one version of this function, since this variable will always be
NULL when using NFS v4.0.

Signed-off-by: Anna Schumaker <[email protected]>
---
fs/nfs/nfs42proc.c | 1 +
fs/nfs/nfs4_fs.h | 10 ----------
fs/nfs/nfs4session.h | 5 +++++
3 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c
index d12ff9385f49..b752d85ad8c6 100644
--- a/fs/nfs/nfs42proc.c
+++ b/fs/nfs/nfs42proc.c
@@ -12,6 +12,7 @@
#include "nfs42.h"
#include "iostat.h"
#include "pnfs.h"
+#include "nfs4session.h"
#include "internal.h"

#define NFSDBG_FACILITY NFSDBG_PROC
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 665165833660..04ffea093d56 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -273,11 +273,6 @@ extern int nfs4_set_rw_stateid(nfs4_stateid *stateid,
fmode_t fmode);

#if defined(CONFIG_NFS_V4_1)
-static inline struct nfs4_session *nfs4_get_session(const struct nfs_server *server)
-{
- return server->nfs_client->cl_session;
-}
-
extern int nfs41_setup_sequence(struct nfs4_session *session,
struct nfs4_sequence_args *args, struct nfs4_sequence_res *res,
struct rpc_task *task);
@@ -357,11 +352,6 @@ nfs4_state_protect_write(struct nfs_client *clp, struct rpc_clnt **clntp,
hdr->args.stable = NFS_FILE_SYNC;
}
#else /* CONFIG_NFS_v4_1 */
-static inline struct nfs4_session *nfs4_get_session(const struct nfs_server *server)
-{
- return NULL;
-}
-
static inline bool
is_ds_only_client(struct nfs_client *clp)
{
diff --git a/fs/nfs/nfs4session.h b/fs/nfs/nfs4session.h
index dae385500005..22cb55015b2b 100644
--- a/fs/nfs/nfs4session.h
+++ b/fs/nfs/nfs4session.h
@@ -103,6 +103,11 @@ static inline bool nfs4_test_locked_slot(const struct nfs4_slot_table *tbl,
return !!test_bit(slotid, tbl->used_slots);
}

+static inline struct nfs4_session *nfs4_get_session(const struct nfs_server *server)
+{
+ return server->nfs_client->cl_session;
+}
+
#if defined(CONFIG_NFS_V4_1)
extern void nfs41_set_target_slotid(struct nfs4_slot_table *tbl,
u32 target_highest_slotid);
--
2.11.0


2017-01-11 18:55:08

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH 02/11] NFS: Change nfs4_get_session() to take an nfs_client structure

From: Anna Schumaker <[email protected]>

pNFS only has access to the nfs_client structure, and not the
nfs_server, so we need to make this change so the function can be used
by pNFS as well.

Signed-off-by: Anna Schumaker <[email protected]>
---
fs/nfs/nfs42proc.c | 5 ++---
fs/nfs/nfs4proc.c | 10 +++++-----
fs/nfs/nfs4session.h | 4 ++--
3 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c
index b752d85ad8c6..b03010eebafd 100644
--- a/fs/nfs/nfs42proc.c
+++ b/fs/nfs/nfs42proc.c
@@ -332,9 +332,8 @@ nfs42_layoutstat_prepare(struct rpc_task *task, void *calldata)
}
nfs4_stateid_copy(&data->args.stateid, &lo->plh_stateid);
spin_unlock(&inode->i_lock);
- nfs41_setup_sequence(nfs4_get_session(server), &data->args.seq_args,
- &data->res.seq_res, task);
-
+ nfs41_setup_sequence(nfs4_get_session(server->nfs_client),
+ &data->args.seq_args, &data->res.seq_res, task);
}

static void
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 6dcbc5defb7a..d1fde35bfd7e 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -953,7 +953,7 @@ static int nfs4_setup_sequence(const struct nfs_server *server,
struct nfs4_sequence_res *res,
struct rpc_task *task)
{
- struct nfs4_session *session = nfs4_get_session(server);
+ struct nfs4_session *session = nfs4_get_session(server->nfs_client);
int ret = 0;

if (!session)
@@ -973,7 +973,7 @@ static int nfs4_setup_sequence(const struct nfs_server *server,
static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata)
{
struct nfs4_call_sync_data *data = calldata;
- struct nfs4_session *session = nfs4_get_session(data->seq_server);
+ struct nfs4_session *session = nfs4_get_session(data->seq_server->nfs_client);

dprintk("--> %s data->seq_server %p\n", __func__, data->seq_server);

@@ -8389,7 +8389,7 @@ nfs4_layoutget_prepare(struct rpc_task *task, void *calldata)
{
struct nfs4_layoutget *lgp = calldata;
struct nfs_server *server = NFS_SERVER(lgp->args.inode);
- struct nfs4_session *session = nfs4_get_session(server);
+ struct nfs4_session *session = nfs4_get_session(server->nfs_client);

dprintk("--> %s\n", __func__);
nfs41_setup_sequence(session, &lgp->args.seq_args,
@@ -8785,7 +8785,7 @@ static void nfs4_layoutcommit_prepare(struct rpc_task *task, void *calldata)
{
struct nfs4_layoutcommit_data *data = calldata;
struct nfs_server *server = NFS_SERVER(data->args.inode);
- struct nfs4_session *session = nfs4_get_session(server);
+ struct nfs4_session *session = nfs4_get_session(server->nfs_client);

nfs41_setup_sequence(session,
&data->args.seq_args,
@@ -9111,7 +9111,7 @@ struct nfs_free_stateid_data {
static void nfs41_free_stateid_prepare(struct rpc_task *task, void *calldata)
{
struct nfs_free_stateid_data *data = calldata;
- nfs41_setup_sequence(nfs4_get_session(data->server),
+ nfs41_setup_sequence(nfs4_get_session(data->server->nfs_client),
&data->args.seq_args,
&data->res.seq_res,
task);
diff --git a/fs/nfs/nfs4session.h b/fs/nfs/nfs4session.h
index 22cb55015b2b..f6378d95b1b5 100644
--- a/fs/nfs/nfs4session.h
+++ b/fs/nfs/nfs4session.h
@@ -103,9 +103,9 @@ static inline bool nfs4_test_locked_slot(const struct nfs4_slot_table *tbl,
return !!test_bit(slotid, tbl->used_slots);
}

-static inline struct nfs4_session *nfs4_get_session(const struct nfs_server *server)
+static inline struct nfs4_session *nfs4_get_session(const struct nfs_client *clp)
{
- return server->nfs_client->cl_session;
+ return clp->cl_session;
}

#if defined(CONFIG_NFS_V4_1)
--
2.11.0


2017-01-11 18:55:10

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH 03/11] NFS: Change nfs4_setup_sequence() to take an nfs_client structure

From: Anna Schumaker <[email protected]>

I want to have all callers use this function, rather than calling the
NFS v4.0 and v4.1 versions directly. This includes pNFS, which only has
access to the nfs_client structure in some places.

Signed-off-by: Anna Schumaker <[email protected]>
---
fs/nfs/nfs4proc.c | 31 +++++++++++++++----------------
1 file changed, 15 insertions(+), 16 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index d1fde35bfd7e..a2e5c6f39182 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -948,16 +948,16 @@ int nfs41_setup_sequence(struct nfs4_session *session,
}
EXPORT_SYMBOL_GPL(nfs41_setup_sequence);

-static int nfs4_setup_sequence(const struct nfs_server *server,
+static int nfs4_setup_sequence(const struct nfs_client *client,
struct nfs4_sequence_args *args,
struct nfs4_sequence_res *res,
struct rpc_task *task)
{
- struct nfs4_session *session = nfs4_get_session(server->nfs_client);
+ struct nfs4_session *session = nfs4_get_session(client);
int ret = 0;

if (!session)
- return nfs40_setup_sequence(server->nfs_client->cl_slot_tbl,
+ return nfs40_setup_sequence(client->cl_slot_tbl,
args, res, task);

dprintk("--> %s clp %p session %p sr_slot %u\n",
@@ -994,13 +994,12 @@ static const struct rpc_call_ops nfs41_call_sync_ops = {

#else /* !CONFIG_NFS_V4_1 */

-static int nfs4_setup_sequence(const struct nfs_server *server,
+static int nfs4_setup_sequence(const struct nfs_client *client,
struct nfs4_sequence_args *args,
struct nfs4_sequence_res *res,
struct rpc_task *task)
{
- return nfs40_setup_sequence(server->nfs_client->cl_slot_tbl,
- args, res, task);
+ return nfs40_setup_sequence(client->cl_slot_tbl, args, res, task);
}

static int nfs4_sequence_process(struct rpc_task *task, struct nfs4_sequence_res *res)
@@ -1026,7 +1025,7 @@ EXPORT_SYMBOL_GPL(nfs4_sequence_done);
static void nfs40_call_sync_prepare(struct rpc_task *task, void *calldata)
{
struct nfs4_call_sync_data *data = calldata;
- nfs4_setup_sequence(data->seq_server,
+ nfs4_setup_sequence(data->seq_server->nfs_client,
data->seq_args, data->seq_res, task);
}

@@ -2171,7 +2170,7 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
nfs_copy_fh(&data->o_res.fh, data->o_arg.fh);
}
data->timestamp = jiffies;
- if (nfs4_setup_sequence(data->o_arg.server,
+ if (nfs4_setup_sequence(data->o_arg.server->nfs_client,
&data->o_arg.seq_args,
&data->o_res.seq_res,
task) != 0)
@@ -3230,7 +3229,7 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
else if (calldata->arg.bitmask == NULL)
calldata->res.fattr = NULL;
calldata->timestamp = jiffies;
- if (nfs4_setup_sequence(NFS_SERVER(inode),
+ if (nfs4_setup_sequence(NFS_SERVER(inode)->nfs_client,
&calldata->arg.seq_args,
&calldata->res.seq_res,
task) != 0)
@@ -4109,7 +4108,7 @@ static void nfs4_proc_unlink_setup(struct rpc_message *msg, struct inode *dir)

static void nfs4_proc_unlink_rpc_prepare(struct rpc_task *task, struct nfs_unlinkdata *data)
{
- nfs4_setup_sequence(NFS_SB(data->dentry->d_sb),
+ nfs4_setup_sequence(NFS_SB(data->dentry->d_sb)->nfs_client,
&data->args.seq_args,
&data->res.seq_res,
task);
@@ -4142,7 +4141,7 @@ static void nfs4_proc_rename_setup(struct rpc_message *msg, struct inode *dir)

static void nfs4_proc_rename_rpc_prepare(struct rpc_task *task, struct nfs_renamedata *data)
{
- nfs4_setup_sequence(NFS_SERVER(data->old_dir),
+ nfs4_setup_sequence(NFS_SERVER(data->old_dir)->nfs_client,
&data->args.seq_args,
&data->res.seq_res,
task);
@@ -4713,7 +4712,7 @@ static void nfs4_proc_read_setup(struct nfs_pgio_header *hdr,
static int nfs4_proc_pgio_rpc_prepare(struct rpc_task *task,
struct nfs_pgio_header *hdr)
{
- if (nfs4_setup_sequence(NFS_SERVER(hdr->inode),
+ if (nfs4_setup_sequence(NFS_SERVER(hdr->inode)->nfs_client,
&hdr->args.seq_args,
&hdr->res.seq_res,
task))
@@ -4812,7 +4811,7 @@ static void nfs4_proc_write_setup(struct nfs_pgio_header *hdr,

static void nfs4_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data)
{
- nfs4_setup_sequence(NFS_SERVER(data->inode),
+ nfs4_setup_sequence(NFS_SERVER(data->inode)->nfs_client,
&data->args.seq_args,
&data->res.seq_res,
task);
@@ -5737,7 +5736,7 @@ static void nfs4_delegreturn_prepare(struct rpc_task *task, void *data)
if (!d_data->lr.roc && nfs4_wait_on_layoutreturn(d_data->inode, task))
return;

- nfs4_setup_sequence(d_data->res.server,
+ nfs4_setup_sequence(d_data->res.server->nfs_client,
&d_data->args.seq_args,
&d_data->res.seq_res,
task);
@@ -5979,7 +5978,7 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data)
goto out_no_action;
}
calldata->timestamp = jiffies;
- if (nfs4_setup_sequence(calldata->server,
+ if (nfs4_setup_sequence(calldata->server->nfs_client,
&calldata->arg.seq_args,
&calldata->res.seq_res,
task) != 0)
@@ -6165,7 +6164,7 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
goto out_release_open_seqid;
}
data->timestamp = jiffies;
- if (nfs4_setup_sequence(data->server,
+ if (nfs4_setup_sequence(data->server->nfs_client,
&data->arg.seq_args,
&data->res.seq_res,
task) == 0)
--
2.11.0


2017-01-11 18:55:10

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH 06/11] NFS: Move slot-already-allocated check into nfs_setup_sequence()

From: Anna Schumaker <[email protected]>

This puts the check in a single place, rather than needing to implement
it twice for v4.0 and v4.1.

Signed-off-by: Anna Schumaker <[email protected]>
---
fs/nfs/nfs4proc.c | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 132d73435b8f..856d0df8d653 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -630,10 +630,6 @@ static int nfs40_setup_sequence(struct nfs4_slot_table *tbl,
{
struct nfs4_slot *slot;

- /* slot already allocated? */
- if (res->sr_slot != NULL)
- goto out_start;
-
spin_lock(&tbl->slot_tbl_lock);
if (nfs4_slot_tbl_draining(tbl) && !args->sa_privileged)
goto out_sleep;
@@ -650,7 +646,6 @@ static int nfs40_setup_sequence(struct nfs4_slot_table *tbl,
args->sa_slot = slot;
res->sr_slot = slot;

-out_start:
rpc_call_start(task);
return 0;

@@ -891,10 +886,6 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
struct nfs4_slot_table *tbl;

dprintk("--> %s\n", __func__);
- /* slot already allocated? */
- if (res->sr_slot != NULL)
- goto out_success;
-
tbl = &session->fc_slot_table;

task->tk_timeout = 0;
@@ -932,7 +923,6 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
*/
res->sr_status = 1;
trace_nfs4_setup_sequence(session, args);
-out_success:
rpc_call_start(task);
return 0;
out_sleep:
@@ -997,12 +987,21 @@ int nfs4_setup_sequence(const struct nfs_client *client,
{
#if defined(CONFIG_NFS_V4_1)
struct nfs4_session *session = nfs4_get_session(client);
+#endif /* CONFIG_NFS_V4_1 */

+ /* slot already allocated? */
+ if (res->sr_slot != NULL)
+ goto out_start;
+
+#if defined(CONFIG_NFS_V4_1)
if (session)
return nfs41_setup_sequence(session, args, res, task);
#endif /* CONFIG_NFS_V4_1 */
return nfs40_setup_sequence(client->cl_slot_tbl, args, res, task);

+out_start:
+ rpc_call_start(task);
+ return 0;
}
EXPORT_SYMBOL_GPL(nfs4_setup_sequence);

--
2.11.0


2017-01-11 18:55:11

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH 07/11] NFS: Lock the slot table from a single place during setup sequence

From: Anna Schumaker <[email protected]>

Rather than implementing this twice for NFS v4.0 and v4.1

Signed-off-by: Anna Schumaker <[email protected]>
---
fs/nfs/nfs4proc.c | 25 ++++++++++++-------------
1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 856d0df8d653..0b409b84b9a2 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -630,7 +630,6 @@ static int nfs40_setup_sequence(struct nfs4_slot_table *tbl,
{
struct nfs4_slot *slot;

- spin_lock(&tbl->slot_tbl_lock);
if (nfs4_slot_tbl_draining(tbl) && !args->sa_privileged)
goto out_sleep;

@@ -640,13 +639,10 @@ static int nfs40_setup_sequence(struct nfs4_slot_table *tbl,
task->tk_timeout = HZ >> 2;
goto out_sleep;
}
- spin_unlock(&tbl->slot_tbl_lock);

slot->privileged = args->sa_privileged ? 1 : 0;
args->sa_slot = slot;
res->sr_slot = slot;
-
- rpc_call_start(task);
return 0;

out_sleep:
@@ -655,7 +651,6 @@ static int nfs40_setup_sequence(struct nfs4_slot_table *tbl,
NULL, RPC_PRIORITY_PRIVILEGED);
else
rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
- spin_unlock(&tbl->slot_tbl_lock);
return -EAGAIN;
}

@@ -890,7 +885,6 @@ static int nfs41_setup_sequence(struct nfs4_session *session,

task->tk_timeout = 0;

- spin_lock(&tbl->slot_tbl_lock);
if (test_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state) &&
!args->sa_privileged) {
/* The state manager will wait until the slot table is empty */
@@ -906,7 +900,6 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
dprintk("<-- %s: no free slots\n", __func__);
goto out_sleep;
}
- spin_unlock(&tbl->slot_tbl_lock);

slot->privileged = args->sa_privileged ? 1 : 0;
args->sa_slot = slot;
@@ -923,7 +916,6 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
*/
res->sr_status = 1;
trace_nfs4_setup_sequence(session, args);
- rpc_call_start(task);
return 0;
out_sleep:
/* Privileged tasks are queued with top priority */
@@ -932,7 +924,6 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
NULL, RPC_PRIORITY_PRIVILEGED);
else
rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
- spin_unlock(&tbl->slot_tbl_lock);
return -EAGAIN;
}

@@ -985,19 +976,27 @@ int nfs4_setup_sequence(const struct nfs_client *client,
struct nfs4_sequence_res *res,
struct rpc_task *task)
{
-#if defined(CONFIG_NFS_V4_1)
struct nfs4_session *session = nfs4_get_session(client);
-#endif /* CONFIG_NFS_V4_1 */
+ struct nfs4_slot_table *tbl = session ? &session->fc_slot_table :
+ client->cl_slot_tbl;
+ int ret;

/* slot already allocated? */
if (res->sr_slot != NULL)
goto out_start;

+ spin_lock(&tbl->slot_tbl_lock);
+
#if defined(CONFIG_NFS_V4_1)
if (session)
- return nfs41_setup_sequence(session, args, res, task);
+ ret = nfs41_setup_sequence(session, args, res, task);
+ else
#endif /* CONFIG_NFS_V4_1 */
- return nfs40_setup_sequence(client->cl_slot_tbl, args, res, task);
+ ret = nfs40_setup_sequence(client->cl_slot_tbl, args, res, task);
+
+ spin_unlock(&tbl->slot_tbl_lock);
+ if (ret < 0)
+ return ret;

out_start:
rpc_call_start(task);
--
2.11.0


2017-01-11 18:55:12

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH 04/11] NFS: Use nfs4_setup_sequence() everywhere

From: Anna Schumaker <[email protected]>

This does the right thing depending on if we have a session, rather than
needing to handle this manually in multiple places.

Signed-off-by: Anna Schumaker <[email protected]>
---
fs/nfs/filelayout/filelayout.c | 6 ++---
fs/nfs/flexfilelayout/flexfilelayout.c | 40 ++++++++++------------------------
fs/nfs/nfs42proc.c | 4 ++--
fs/nfs/nfs4_fs.h | 5 +----
fs/nfs/nfs4proc.c | 30 ++++++++++++-------------
5 files changed, 33 insertions(+), 52 deletions(-)

diff --git a/fs/nfs/filelayout/filelayout.c b/fs/nfs/filelayout/filelayout.c
index a3fc48ba4931..7aff350f15b1 100644
--- a/fs/nfs/filelayout/filelayout.c
+++ b/fs/nfs/filelayout/filelayout.c
@@ -305,7 +305,7 @@ static void filelayout_read_prepare(struct rpc_task *task, void *data)
}
hdr->pgio_done_cb = filelayout_read_done_cb;

- if (nfs41_setup_sequence(hdr->ds_clp->cl_session,
+ if (nfs4_setup_sequence(hdr->ds_clp,
&hdr->args.seq_args,
&hdr->res.seq_res,
task))
@@ -403,7 +403,7 @@ static void filelayout_write_prepare(struct rpc_task *task, void *data)
rpc_exit(task, 0);
return;
}
- if (nfs41_setup_sequence(hdr->ds_clp->cl_session,
+ if (nfs4_setup_sequence(hdr->ds_clp,
&hdr->args.seq_args,
&hdr->res.seq_res,
task))
@@ -438,7 +438,7 @@ static void filelayout_commit_prepare(struct rpc_task *task, void *data)
{
struct nfs_commit_data *wdata = data;

- nfs41_setup_sequence(wdata->ds_clp->cl_session,
+ nfs4_setup_sequence(wdata->ds_clp,
&wdata->args.seq_args,
&wdata->res.seq_res,
task);
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
index 0ca4af8cca5d..cc9064974104 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.c
+++ b/fs/nfs/flexfilelayout/flexfilelayout.c
@@ -1384,30 +1384,14 @@ static void ff_layout_read_prepare_v3(struct rpc_task *task, void *data)
rpc_call_start(task);
}

-static int ff_layout_setup_sequence(struct nfs_client *ds_clp,
- struct nfs4_sequence_args *args,
- struct nfs4_sequence_res *res,
- struct rpc_task *task)
-{
- if (ds_clp->cl_session)
- return nfs41_setup_sequence(ds_clp->cl_session,
- args,
- res,
- task);
- return nfs40_setup_sequence(ds_clp->cl_slot_tbl,
- args,
- res,
- task);
-}
-
static void ff_layout_read_prepare_v4(struct rpc_task *task, void *data)
{
struct nfs_pgio_header *hdr = data;

- if (ff_layout_setup_sequence(hdr->ds_clp,
- &hdr->args.seq_args,
- &hdr->res.seq_res,
- task))
+ if (nfs4_setup_sequence(hdr->ds_clp,
+ &hdr->args.seq_args,
+ &hdr->res.seq_res,
+ task))
return;

if (ff_layout_read_prepare_common(task, hdr))
@@ -1578,10 +1562,10 @@ static void ff_layout_write_prepare_v4(struct rpc_task *task, void *data)
{
struct nfs_pgio_header *hdr = data;

- if (ff_layout_setup_sequence(hdr->ds_clp,
- &hdr->args.seq_args,
- &hdr->res.seq_res,
- task))
+ if (nfs4_setup_sequence(hdr->ds_clp,
+ &hdr->args.seq_args,
+ &hdr->res.seq_res,
+ task))
return;

if (ff_layout_write_prepare_common(task, hdr))
@@ -1667,10 +1651,10 @@ static void ff_layout_commit_prepare_v4(struct rpc_task *task, void *data)
{
struct nfs_commit_data *wdata = data;

- if (ff_layout_setup_sequence(wdata->ds_clp,
- &wdata->args.seq_args,
- &wdata->res.seq_res,
- task))
+ if (nfs4_setup_sequence(wdata->ds_clp,
+ &wdata->args.seq_args,
+ &wdata->res.seq_res,
+ task))
return;
ff_layout_commit_prepare_common(task, data);
}
diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c
index b03010eebafd..98cf58341066 100644
--- a/fs/nfs/nfs42proc.c
+++ b/fs/nfs/nfs42proc.c
@@ -332,8 +332,8 @@ nfs42_layoutstat_prepare(struct rpc_task *task, void *calldata)
}
nfs4_stateid_copy(&data->args.stateid, &lo->plh_stateid);
spin_unlock(&inode->i_lock);
- nfs41_setup_sequence(nfs4_get_session(server->nfs_client),
- &data->args.seq_args, &data->res.seq_res, task);
+ nfs4_setup_sequence(server->nfs_client, &data->args.seq_args,
+ &data->res.seq_res, task);
}

static void
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 04ffea093d56..af285cc27ccf 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -273,9 +273,6 @@ extern int nfs4_set_rw_stateid(nfs4_stateid *stateid,
fmode_t fmode);

#if defined(CONFIG_NFS_V4_1)
-extern int nfs41_setup_sequence(struct nfs4_session *session,
- struct nfs4_sequence_args *args, struct nfs4_sequence_res *res,
- struct rpc_task *task);
extern int nfs41_sequence_done(struct rpc_task *, struct nfs4_sequence_res *);
extern int nfs4_proc_create_session(struct nfs_client *, struct rpc_cred *);
extern int nfs4_proc_destroy_session(struct nfs4_session *, struct rpc_cred *);
@@ -456,7 +453,7 @@ extern void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid);
extern void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid);
extern void nfs_release_seqid(struct nfs_seqid *seqid);
extern void nfs_free_seqid(struct nfs_seqid *seqid);
-extern int nfs40_setup_sequence(struct nfs4_slot_table *tbl,
+extern int nfs4_setup_sequence(const struct nfs_client *client,
struct nfs4_sequence_args *args,
struct nfs4_sequence_res *res,
struct rpc_task *task);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index a2e5c6f39182..3f7199a0b784 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -623,10 +623,10 @@ static void nfs4_set_sequence_privileged(struct nfs4_sequence_args *args)
args->sa_privileged = 1;
}

-int nfs40_setup_sequence(struct nfs4_slot_table *tbl,
- struct nfs4_sequence_args *args,
- struct nfs4_sequence_res *res,
- struct rpc_task *task)
+static int nfs40_setup_sequence(struct nfs4_slot_table *tbl,
+ struct nfs4_sequence_args *args,
+ struct nfs4_sequence_res *res,
+ struct rpc_task *task)
{
struct nfs4_slot *slot;

@@ -663,7 +663,6 @@ int nfs40_setup_sequence(struct nfs4_slot_table *tbl,
spin_unlock(&tbl->slot_tbl_lock);
return -EAGAIN;
}
-EXPORT_SYMBOL_GPL(nfs40_setup_sequence);

static void nfs40_sequence_free_slot(struct nfs4_sequence_res *res)
{
@@ -883,7 +882,7 @@ int nfs4_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res)
}
EXPORT_SYMBOL_GPL(nfs4_sequence_done);

-int nfs41_setup_sequence(struct nfs4_session *session,
+static int nfs41_setup_sequence(struct nfs4_session *session,
struct nfs4_sequence_args *args,
struct nfs4_sequence_res *res,
struct rpc_task *task)
@@ -946,12 +945,11 @@ int nfs41_setup_sequence(struct nfs4_session *session,
spin_unlock(&tbl->slot_tbl_lock);
return -EAGAIN;
}
-EXPORT_SYMBOL_GPL(nfs41_setup_sequence);

-static int nfs4_setup_sequence(const struct nfs_client *client,
- struct nfs4_sequence_args *args,
- struct nfs4_sequence_res *res,
- struct rpc_task *task)
+int nfs4_setup_sequence(const struct nfs_client *client,
+ struct nfs4_sequence_args *args,
+ struct nfs4_sequence_res *res,
+ struct rpc_task *task)
{
struct nfs4_session *session = nfs4_get_session(client);
int ret = 0;
@@ -969,6 +967,7 @@ static int nfs4_setup_sequence(const struct nfs_client *client,
dprintk("<-- %s status=%d\n", __func__, ret);
return ret;
}
+EXPORT_SYMBOL_GPL(nfs4_setup_sequence);

static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata)
{
@@ -994,13 +993,14 @@ static const struct rpc_call_ops nfs41_call_sync_ops = {

#else /* !CONFIG_NFS_V4_1 */

-static int nfs4_setup_sequence(const struct nfs_client *client,
- struct nfs4_sequence_args *args,
- struct nfs4_sequence_res *res,
- struct rpc_task *task)
+int nfs4_setup_sequence(const struct nfs_client *client,
+ struct nfs4_sequence_args *args,
+ struct nfs4_sequence_res *res,
+ struct rpc_task *task)
{
return nfs40_setup_sequence(client->cl_slot_tbl, args, res, task);
}
+EXPORT_SYMBOL_GPL(nfs4_setup_sequence);

static int nfs4_sequence_process(struct rpc_task *task, struct nfs4_sequence_res *res)
{
--
2.11.0


2017-01-11 18:55:12

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH 09/11] NFS: Check if the slot table is draining from nfs4_setup_sequence()

From: Anna Schumaker <[email protected]>

Signed-off-by: Anna Schumaker <[email protected]>
---
fs/nfs/nfs4proc.c | 23 +++++++++--------------
1 file changed, 9 insertions(+), 14 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 56e8c9e04f4a..aaa87f4eacf2 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -630,9 +630,6 @@ static int nfs40_setup_sequence(struct nfs4_slot_table *tbl,
{
struct nfs4_slot *slot;

- if (nfs4_slot_tbl_draining(tbl) && !args->sa_privileged)
- return -EAGAIN;
-
slot = nfs4_alloc_slot(tbl);
if (IS_ERR(slot)) {
if (slot == ERR_PTR(-ENOMEM))
@@ -875,15 +872,6 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
dprintk("--> %s\n", __func__);
tbl = &session->fc_slot_table;

- task->tk_timeout = 0;
-
- if (test_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state) &&
- !args->sa_privileged) {
- /* The state manager will wait until the slot table is empty */
- dprintk("%s session is draining\n", __func__);
- return -EAGAIN;
- }
-
slot = nfs4_alloc_slot(tbl);
if (IS_ERR(slot)) {
/* If out of memory, try again in 1/4 second */
@@ -961,15 +949,22 @@ int nfs4_setup_sequence(const struct nfs_client *client,
struct rpc_task *task)
{
struct nfs4_session *session = nfs4_get_session(client);
- struct nfs4_slot_table *tbl = session ? &session->fc_slot_table :
- client->cl_slot_tbl;
+ struct nfs4_slot_table *tbl = client->cl_slot_tbl;
int ret;

/* slot already allocated? */
if (res->sr_slot != NULL)
goto out_start;

+ if (session) {
+ tbl = &session->fc_slot_table;
+ task->tk_timeout = 0;
+ }
+
spin_lock(&tbl->slot_tbl_lock);
+ /* The state manager will wait until the slot table is empty */
+ if (nfs4_slot_tbl_draining(tbl) && !args->sa_privileged)
+ goto out_sleep;

#if defined(CONFIG_NFS_V4_1)
if (session)
--
2.11.0


2017-01-11 18:55:13

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH 10/11] NFS: Merge the remaining setup_sequence functions

From: Anna Schumaker <[email protected]>

This creates a single place for all the work to happen, using the
presence of a session to determine if extra values need to be set.

Signed-off-by: Anna Schumaker <[email protected]>
---
fs/nfs/nfs4proc.c | 87 +++++++++++++------------------------------------------
1 file changed, 20 insertions(+), 67 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index aaa87f4eacf2..31edcf07ac93 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -623,26 +623,6 @@ static void nfs4_set_sequence_privileged(struct nfs4_sequence_args *args)
args->sa_privileged = 1;
}

-static int nfs40_setup_sequence(struct nfs4_slot_table *tbl,
- struct nfs4_sequence_args *args,
- struct nfs4_sequence_res *res,
- struct rpc_task *task)
-{
- struct nfs4_slot *slot;
-
- slot = nfs4_alloc_slot(tbl);
- if (IS_ERR(slot)) {
- if (slot == ERR_PTR(-ENOMEM))
- task->tk_timeout = HZ >> 2;
- return -EAGAIN;
- }
-
- slot->privileged = args->sa_privileged ? 1 : 0;
- args->sa_slot = slot;
- res->sr_slot = slot;
- return 0;
-}
-
static void nfs40_sequence_free_slot(struct nfs4_sequence_res *res)
{
struct nfs4_slot *slot = res->sr_slot;
@@ -861,44 +841,6 @@ int nfs4_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res)
}
EXPORT_SYMBOL_GPL(nfs4_sequence_done);

-static int nfs41_setup_sequence(struct nfs4_session *session,
- struct nfs4_sequence_args *args,
- struct nfs4_sequence_res *res,
- struct rpc_task *task)
-{
- struct nfs4_slot *slot;
- struct nfs4_slot_table *tbl;
-
- dprintk("--> %s\n", __func__);
- tbl = &session->fc_slot_table;
-
- slot = nfs4_alloc_slot(tbl);
- if (IS_ERR(slot)) {
- /* If out of memory, try again in 1/4 second */
- if (slot == ERR_PTR(-ENOMEM))
- task->tk_timeout = HZ >> 2;
- dprintk("<-- %s: no free slots\n", __func__);
- return -EAGAIN;
- }
-
- slot->privileged = args->sa_privileged ? 1 : 0;
- args->sa_slot = slot;
-
- dprintk("<-- %s slotid=%u seqid=%u\n", __func__,
- slot->slot_nr, slot->seq_nr);
-
- res->sr_slot = slot;
- res->sr_timestamp = jiffies;
- res->sr_status_flags = 0;
- /*
- * sr_status is only set in decode_sequence, and so will remain
- * set to 1 if an rpc level failure occurs.
- */
- res->sr_status = 1;
- trace_nfs4_setup_sequence(session, args);
- return 0;
-}
-
static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata)
{
struct nfs4_call_sync_data *data = calldata;
@@ -950,7 +892,7 @@ int nfs4_setup_sequence(const struct nfs_client *client,
{
struct nfs4_session *session = nfs4_get_session(client);
struct nfs4_slot_table *tbl = client->cl_slot_tbl;
- int ret;
+ struct nfs4_slot *slot;

/* slot already allocated? */
if (res->sr_slot != NULL)
@@ -966,17 +908,28 @@ int nfs4_setup_sequence(const struct nfs_client *client,
if (nfs4_slot_tbl_draining(tbl) && !args->sa_privileged)
goto out_sleep;

-#if defined(CONFIG_NFS_V4_1)
- if (session)
- ret = nfs41_setup_sequence(session, args, res, task);
- else
-#endif /* CONFIG_NFS_V4_1 */
- ret = nfs40_setup_sequence(client->cl_slot_tbl, args, res, task);
-
- if (ret == -EAGAIN)
+ slot = nfs4_alloc_slot(tbl);
+ if (IS_ERR(slot)) {
+ /* Try again in 1/4 second */
+ if (slot == ERR_PTR(-ENOMEM))
+ task->tk_timeout = HZ >> 2;
goto out_sleep;
+ }
spin_unlock(&tbl->slot_tbl_lock);

+ slot->privileged = args->sa_privileged ? 1 : 0;
+ args->sa_slot = slot;
+
+ res->sr_slot = slot;
+ if (session) {
+ res->sr_timestamp = jiffies;
+ res->sr_status_flags = 0;
+ res->sr_status = 1;
+#ifdef CONFIG_NFS_V4_1
+ trace_nfs4_setup_sequence(session, args);
+#endif /* CONFIG_NFS_V4_1 */
+ }
+
out_start:
rpc_call_start(task);
return 0;
--
2.11.0


2017-01-11 18:55:11

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH 05/11] NFS: Create a single nfs4_setup_sequence() function

From: Anna Schumaker <[email protected]>

The inline ifdef lets us put everything in a single place, rather than
having two (very similar) versions of this function.

Signed-off-by: Anna Schumaker <[email protected]>
---
fs/nfs/nfs4proc.c | 76 +++++++++++++++++++++----------------------------------
1 file changed, 29 insertions(+), 47 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 3f7199a0b784..132d73435b8f 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -946,37 +946,14 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
return -EAGAIN;
}

-int nfs4_setup_sequence(const struct nfs_client *client,
- struct nfs4_sequence_args *args,
- struct nfs4_sequence_res *res,
- struct rpc_task *task)
-{
- struct nfs4_session *session = nfs4_get_session(client);
- int ret = 0;
-
- if (!session)
- return nfs40_setup_sequence(client->cl_slot_tbl,
- args, res, task);
-
- dprintk("--> %s clp %p session %p sr_slot %u\n",
- __func__, session->clp, session, res->sr_slot ?
- res->sr_slot->slot_nr : NFS4_NO_SLOT);
-
- ret = nfs41_setup_sequence(session, args, res, task);
-
- dprintk("<-- %s status=%d\n", __func__, ret);
- return ret;
-}
-EXPORT_SYMBOL_GPL(nfs4_setup_sequence);
-
static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata)
{
struct nfs4_call_sync_data *data = calldata;
- struct nfs4_session *session = nfs4_get_session(data->seq_server->nfs_client);

dprintk("--> %s data->seq_server %p\n", __func__, data->seq_server);

- nfs41_setup_sequence(session, data->seq_args, data->seq_res, task);
+ nfs4_setup_sequence(data->seq_server->nfs_client,
+ data->seq_args, data->seq_res, task);
}

static void nfs41_call_sync_done(struct rpc_task *task, void *calldata)
@@ -993,15 +970,6 @@ static const struct rpc_call_ops nfs41_call_sync_ops = {

#else /* !CONFIG_NFS_V4_1 */

-int nfs4_setup_sequence(const struct nfs_client *client,
- struct nfs4_sequence_args *args,
- struct nfs4_sequence_res *res,
- struct rpc_task *task)
-{
- return nfs40_setup_sequence(client->cl_slot_tbl, args, res, task);
-}
-EXPORT_SYMBOL_GPL(nfs4_setup_sequence);
-
static int nfs4_sequence_process(struct rpc_task *task, struct nfs4_sequence_res *res)
{
return nfs40_sequence_done(task, res);
@@ -1022,6 +990,22 @@ EXPORT_SYMBOL_GPL(nfs4_sequence_done);

#endif /* !CONFIG_NFS_V4_1 */

+int nfs4_setup_sequence(const struct nfs_client *client,
+ struct nfs4_sequence_args *args,
+ struct nfs4_sequence_res *res,
+ struct rpc_task *task)
+{
+#if defined(CONFIG_NFS_V4_1)
+ struct nfs4_session *session = nfs4_get_session(client);
+
+ if (session)
+ return nfs41_setup_sequence(session, args, res, task);
+#endif /* CONFIG_NFS_V4_1 */
+ return nfs40_setup_sequence(client->cl_slot_tbl, args, res, task);
+
+}
+EXPORT_SYMBOL_GPL(nfs4_setup_sequence);
+
static void nfs40_call_sync_prepare(struct rpc_task *task, void *calldata)
{
struct nfs4_call_sync_data *data = calldata;
@@ -2046,8 +2030,8 @@ static void nfs4_open_confirm_prepare(struct rpc_task *task, void *calldata)
{
struct nfs4_opendata *data = calldata;

- nfs40_setup_sequence(data->o_arg.server->nfs_client->cl_slot_tbl,
- &data->c_arg.seq_args, &data->c_res.seq_res, task);
+ nfs4_setup_sequence(data->o_arg.server->nfs_client,
+ &data->c_arg.seq_args, &data->c_res.seq_res, task);
}

static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata)
@@ -6631,8 +6615,8 @@ static void nfs4_release_lockowner_prepare(struct rpc_task *task, void *calldata
{
struct nfs_release_lockowner_data *data = calldata;
struct nfs_server *server = data->server;
- nfs40_setup_sequence(server->nfs_client->cl_slot_tbl,
- &data->args.seq_args, &data->res.seq_res, task);
+ nfs4_setup_sequence(server->nfs_client, &data->args.seq_args,
+ &data->res.seq_res, task);
data->args.lock_owner.clientid = server->nfs_client->cl_clientid;
data->timestamp = jiffies;
}
@@ -7822,7 +7806,7 @@ static void nfs4_get_lease_time_prepare(struct rpc_task *task,
dprintk("--> %s\n", __func__);
/* just setup sequence, do not trigger session recovery
since we're invoked within one */
- nfs41_setup_sequence(data->clp->cl_session,
+ nfs4_setup_sequence(data->clp,
&data->args->la_seq_args,
&data->res->lr_seq_res,
task);
@@ -8193,7 +8177,7 @@ static void nfs41_sequence_prepare(struct rpc_task *task, void *data)
args = task->tk_msg.rpc_argp;
res = task->tk_msg.rpc_resp;

- nfs41_setup_sequence(clp->cl_session, args, res, task);
+ nfs4_setup_sequence(clp, args, res, task);
}

static const struct rpc_call_ops nfs41_sequence_ops = {
@@ -8281,7 +8265,7 @@ static void nfs4_reclaim_complete_prepare(struct rpc_task *task, void *data)
{
struct nfs4_reclaim_complete_data *calldata = data;

- nfs41_setup_sequence(calldata->clp->cl_session,
+ nfs4_setup_sequence(calldata->clp,
&calldata->arg.seq_args,
&calldata->res.seq_res,
task);
@@ -8388,10 +8372,9 @@ nfs4_layoutget_prepare(struct rpc_task *task, void *calldata)
{
struct nfs4_layoutget *lgp = calldata;
struct nfs_server *server = NFS_SERVER(lgp->args.inode);
- struct nfs4_session *session = nfs4_get_session(server->nfs_client);

dprintk("--> %s\n", __func__);
- nfs41_setup_sequence(session, &lgp->args.seq_args,
+ nfs4_setup_sequence(server->nfs_client, &lgp->args.seq_args,
&lgp->res.seq_res, task);
dprintk("<-- %s\n", __func__);
}
@@ -8634,7 +8617,7 @@ nfs4_layoutreturn_prepare(struct rpc_task *task, void *calldata)
struct nfs4_layoutreturn *lrp = calldata;

dprintk("--> %s\n", __func__);
- nfs41_setup_sequence(lrp->clp->cl_session,
+ nfs4_setup_sequence(lrp->clp,
&lrp->args.seq_args,
&lrp->res.seq_res,
task);
@@ -8784,9 +8767,8 @@ static void nfs4_layoutcommit_prepare(struct rpc_task *task, void *calldata)
{
struct nfs4_layoutcommit_data *data = calldata;
struct nfs_server *server = NFS_SERVER(data->args.inode);
- struct nfs4_session *session = nfs4_get_session(server->nfs_client);

- nfs41_setup_sequence(session,
+ nfs4_setup_sequence(server->nfs_client,
&data->args.seq_args,
&data->res.seq_res,
task);
@@ -9110,7 +9092,7 @@ struct nfs_free_stateid_data {
static void nfs41_free_stateid_prepare(struct rpc_task *task, void *calldata)
{
struct nfs_free_stateid_data *data = calldata;
- nfs41_setup_sequence(nfs4_get_session(data->server->nfs_client),
+ nfs4_setup_sequence(data->server->nfs_client,
&data->args.seq_args,
&data->res.seq_res,
task);
--
2.11.0


2017-01-11 18:55:25

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH 08/11] NFS: Handle setup sequence task rescheduling in a single place

From: Anna Schumaker <[email protected]>

Signed-off-by: Anna Schumaker <[email protected]>
---
fs/nfs/nfs4proc.c | 37 +++++++++++++++----------------------
1 file changed, 15 insertions(+), 22 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 0b409b84b9a2..56e8c9e04f4a 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -631,27 +631,19 @@ static int nfs40_setup_sequence(struct nfs4_slot_table *tbl,
struct nfs4_slot *slot;

if (nfs4_slot_tbl_draining(tbl) && !args->sa_privileged)
- goto out_sleep;
+ return -EAGAIN;

slot = nfs4_alloc_slot(tbl);
if (IS_ERR(slot)) {
if (slot == ERR_PTR(-ENOMEM))
task->tk_timeout = HZ >> 2;
- goto out_sleep;
+ return -EAGAIN;
}

slot->privileged = args->sa_privileged ? 1 : 0;
args->sa_slot = slot;
res->sr_slot = slot;
return 0;
-
-out_sleep:
- if (args->sa_privileged)
- rpc_sleep_on_priority(&tbl->slot_tbl_waitq, task,
- NULL, RPC_PRIORITY_PRIVILEGED);
- else
- rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
- return -EAGAIN;
}

static void nfs40_sequence_free_slot(struct nfs4_sequence_res *res)
@@ -889,7 +881,7 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
!args->sa_privileged) {
/* The state manager will wait until the slot table is empty */
dprintk("%s session is draining\n", __func__);
- goto out_sleep;
+ return -EAGAIN;
}

slot = nfs4_alloc_slot(tbl);
@@ -898,7 +890,7 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
if (slot == ERR_PTR(-ENOMEM))
task->tk_timeout = HZ >> 2;
dprintk("<-- %s: no free slots\n", __func__);
- goto out_sleep;
+ return -EAGAIN;
}

slot->privileged = args->sa_privileged ? 1 : 0;
@@ -917,14 +909,6 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
res->sr_status = 1;
trace_nfs4_setup_sequence(session, args);
return 0;
-out_sleep:
- /* Privileged tasks are queued with top priority */
- if (args->sa_privileged)
- rpc_sleep_on_priority(&tbl->slot_tbl_waitq, task,
- NULL, RPC_PRIORITY_PRIVILEGED);
- else
- rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
- return -EAGAIN;
}

static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata)
@@ -994,13 +978,22 @@ int nfs4_setup_sequence(const struct nfs_client *client,
#endif /* CONFIG_NFS_V4_1 */
ret = nfs40_setup_sequence(client->cl_slot_tbl, args, res, task);

+ if (ret == -EAGAIN)
+ goto out_sleep;
spin_unlock(&tbl->slot_tbl_lock);
- if (ret < 0)
- return ret;

out_start:
rpc_call_start(task);
return 0;
+
+out_sleep:
+ if (args->sa_privileged)
+ rpc_sleep_on_priority(&tbl->slot_tbl_waitq, task,
+ NULL, RPC_PRIORITY_PRIVILEGED);
+ else
+ rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
+ spin_unlock(&tbl->slot_tbl_lock);
+ return -EAGAIN;
}
EXPORT_SYMBOL_GPL(nfs4_setup_sequence);

--
2.11.0


2017-01-11 18:55:27

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH 11/11] NFS: Make trace_nfs4_setup_sequence() available to NFS v4.0

From: Anna Schumaker <[email protected]>

This tracepoint displays information about the slot that was chosen for
the RPC, in addition to session information. This could be useful
information for debugging, and we can set the session id hash to 0 to
indicate that there is no session.

Signed-off-by: Anna Schumaker <[email protected]>
---
fs/nfs/nfs4proc.c | 4 +---
fs/nfs/nfs4session.h | 2 ++
fs/nfs/nfs4trace.h | 64 ++++++++++++++++++++++++++--------------------------
3 files changed, 35 insertions(+), 35 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 31edcf07ac93..94fdf26f9bf4 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -925,11 +925,9 @@ int nfs4_setup_sequence(const struct nfs_client *client,
res->sr_timestamp = jiffies;
res->sr_status_flags = 0;
res->sr_status = 1;
-#ifdef CONFIG_NFS_V4_1
- trace_nfs4_setup_sequence(session, args);
-#endif /* CONFIG_NFS_V4_1 */
}

+ trace_nfs4_setup_sequence(session, args);
out_start:
rpc_call_start(task);
return 0;
diff --git a/fs/nfs/nfs4session.h b/fs/nfs/nfs4session.h
index f6378d95b1b5..dfae4880eacb 100644
--- a/fs/nfs/nfs4session.h
+++ b/fs/nfs/nfs4session.h
@@ -175,6 +175,8 @@ static inline int nfs4_has_persistent_session(const struct nfs_client *clp)
return 0;
}

+#define nfs_session_id_hash(session) (0)
+
#endif /* defined(CONFIG_NFS_V4_1) */
#endif /* IS_ENABLED(CONFIG_NFS_V4) */
#endif /* __LINUX_FS_NFS_NFS4SESSION_H */
diff --git a/fs/nfs/nfs4trace.h b/fs/nfs/nfs4trace.h
index cfb8f7ce5cf6..845d0eadefc9 100644
--- a/fs/nfs/nfs4trace.h
+++ b/fs/nfs/nfs4trace.h
@@ -241,38 +241,6 @@ DEFINE_NFS4_CLIENTID_EVENT(nfs4_bind_conn_to_session);
DEFINE_NFS4_CLIENTID_EVENT(nfs4_sequence);
DEFINE_NFS4_CLIENTID_EVENT(nfs4_reclaim_complete);

-TRACE_EVENT(nfs4_setup_sequence,
- TP_PROTO(
- const struct nfs4_session *session,
- const struct nfs4_sequence_args *args
- ),
- TP_ARGS(session, args),
-
- TP_STRUCT__entry(
- __field(unsigned int, session)
- __field(unsigned int, slot_nr)
- __field(unsigned int, seq_nr)
- __field(unsigned int, highest_used_slotid)
- ),
-
- TP_fast_assign(
- const struct nfs4_slot *sa_slot = args->sa_slot;
- __entry->session = nfs_session_id_hash(&session->sess_id);
- __entry->slot_nr = sa_slot->slot_nr;
- __entry->seq_nr = sa_slot->seq_nr;
- __entry->highest_used_slotid =
- sa_slot->table->highest_used_slotid;
- ),
- TP_printk(
- "session=0x%08x slot_nr=%u seq_nr=%u "
- "highest_used_slotid=%u",
- __entry->session,
- __entry->slot_nr,
- __entry->seq_nr,
- __entry->highest_used_slotid
- )
-);
-
#define show_nfs4_sequence_status_flags(status) \
__print_flags((unsigned long)status, "|", \
{ SEQ4_STATUS_CB_PATH_DOWN, "CB_PATH_DOWN" }, \
@@ -382,6 +350,38 @@ TRACE_EVENT(nfs4_cb_sequence,
);
#endif /* CONFIG_NFS_V4_1 */

+TRACE_EVENT(nfs4_setup_sequence,
+ TP_PROTO(
+ const struct nfs4_session *session,
+ const struct nfs4_sequence_args *args
+ ),
+ TP_ARGS(session, args),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, session)
+ __field(unsigned int, slot_nr)
+ __field(unsigned int, seq_nr)
+ __field(unsigned int, highest_used_slotid)
+ ),
+
+ TP_fast_assign(
+ const struct nfs4_slot *sa_slot = args->sa_slot;
+ __entry->session = session ? nfs_session_id_hash(&session->sess_id) : 0;
+ __entry->slot_nr = sa_slot->slot_nr;
+ __entry->seq_nr = sa_slot->seq_nr;
+ __entry->highest_used_slotid =
+ sa_slot->table->highest_used_slotid;
+ ),
+ TP_printk(
+ "session=0x%08x slot_nr=%u seq_nr=%u "
+ "highest_used_slotid=%u",
+ __entry->session,
+ __entry->slot_nr,
+ __entry->seq_nr,
+ __entry->highest_used_slotid
+ )
+);
+
DECLARE_EVENT_CLASS(nfs4_open_event,
TP_PROTO(
const struct nfs_open_context *ctx,
--
2.11.0


2017-01-11 18:57:16

by Chuck Lever III

[permalink] [raw]
Subject: Re: [PATCH 00/11] Create a single nfs4_setup_sequence() function


> On Jan 11, 2017, at 1:54 PM, [email protected] wrote:
>
> From: Anna Schumaker <[email protected]>
>
> I noticed that NFS v4.0 and v4.1 have different setup_sequence() functions
> that are very, very similar. I think we should try to share as much code
> as possible whenever possible, so these patches merge together both versions
> of this function using the presence of a session to decide if we need to do
> a little extra work in some cases.

NFSv4.0 has a slot table these days to handle plugging the mount
point during a migration. Hopefully that logic isn't fooled by
your "has a session" test.


> I broke this change into several logical steps that (hopefully) make it easier
> to follow what I did.
>
> Questions? Comments? Thoughts?
> Anna
>
>
> Anna Schumaker (11):
> NFS: Move nfs4_get_session() into nfs4_session.h
> NFS: Change nfs4_get_session() to take an nfs_client structure
> NFS: Change nfs4_setup_sequence() to take an nfs_client structure
> NFS: Use nfs4_setup_sequence() everywhere
> NFS: Create a single nfs4_setup_sequence() function
> NFS: Move slot-already-allocated check into nfs_setup_sequence()
> NFS: Lock the slot table from a single place during setup sequence
> NFS: Handle setup sequence task rescheduling in a single place
> NFS: Check if the slot table is draining from nfs4_setup_sequence()
> NFS: Merge the remaining setup_sequence functions
> NFS: Make trace_nfs4_setup_sequence() available to NFS v4.0
>
> fs/nfs/filelayout/filelayout.c | 6 +-
> fs/nfs/flexfilelayout/flexfilelayout.c | 40 ++----
> fs/nfs/nfs42proc.c | 6 +-
> fs/nfs/nfs4_fs.h | 15 +-
> fs/nfs/nfs4proc.c | 244 +++++++++++----------------------
> fs/nfs/nfs4session.h | 7 +
> fs/nfs/nfs4trace.h | 64 ++++-----
> 7 files changed, 139 insertions(+), 243 deletions(-)
>
> --
> 2.11.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html

--
Chuck Lever




2017-01-11 19:13:27

by Anna Schumaker

[permalink] [raw]
Subject: Re: [PATCH 00/11] Create a single nfs4_setup_sequence() function



On 01/11/2017 01:57 PM, Chuck Lever wrote:
>
>> On Jan 11, 2017, at 1:54 PM, [email protected] wrote:
>>
>> From: Anna Schumaker <[email protected]>
>>
>> I noticed that NFS v4.0 and v4.1 have different setup_sequence() functions
>> that are very, very similar. I think we should try to share as much code
>> as possible whenever possible, so these patches merge together both versions
>> of this function using the presence of a session to decide if we need to do
>> a little extra work in some cases.
>
> NFSv4.0 has a slot table these days to handle plugging the mount
> point during a migration. Hopefully that logic isn't fooled by
> your "has a session" test.

It shouldn't be. The "has session" test was already there to select between the two functions I merged, so I'd expect everything to keep working.

Anna

>
>
>> I broke this change into several logical steps that (hopefully) make it easier
>> to follow what I did.
>>
>> Questions? Comments? Thoughts?
>> Anna
>>
>>
>> Anna Schumaker (11):
>> NFS: Move nfs4_get_session() into nfs4_session.h
>> NFS: Change nfs4_get_session() to take an nfs_client structure
>> NFS: Change nfs4_setup_sequence() to take an nfs_client structure
>> NFS: Use nfs4_setup_sequence() everywhere
>> NFS: Create a single nfs4_setup_sequence() function
>> NFS: Move slot-already-allocated check into nfs_setup_sequence()
>> NFS: Lock the slot table from a single place during setup sequence
>> NFS: Handle setup sequence task rescheduling in a single place
>> NFS: Check if the slot table is draining from nfs4_setup_sequence()
>> NFS: Merge the remaining setup_sequence functions
>> NFS: Make trace_nfs4_setup_sequence() available to NFS v4.0
>>
>> fs/nfs/filelayout/filelayout.c | 6 +-
>> fs/nfs/flexfilelayout/flexfilelayout.c | 40 ++----
>> fs/nfs/nfs42proc.c | 6 +-
>> fs/nfs/nfs4_fs.h | 15 +-
>> fs/nfs/nfs4proc.c | 244 +++++++++++----------------------
>> fs/nfs/nfs4session.h | 7 +
>> fs/nfs/nfs4trace.h | 64 ++++-----
>> 7 files changed, 139 insertions(+), 243 deletions(-)
>>
>> --
>> 2.11.0
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
>> the body of a message to [email protected]
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
> --
> Chuck Lever
>
>
>