summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <cel@netapp.com>2006-03-20 13:44:14 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-03-20 13:44:14 -0500
commit006ea73e5fa82915d0ac7a3f15ee7c688433236d (patch)
tree0f522982fe3d01a74f1ad9f5f713cbd10a6b09bd
parent91d5b47023b608227d605d1e916b29dd0215bff7 (diff)
NFS: add hooks to account for NFSERR_JUKEBOX errors
Make an inode or an nfs_server struct available in the logic that handles JUKEBOX/DELAY type errors so the NFS client can account for them. This patch is split out from the main nfs iostat patch to highlight minor architectural changes required to support this statistic. Test plan: None. Signed-off-by: Chuck Lever <cel@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/iostat.h19
-rw-r--r--fs/nfs/nfs3proc.c13
-rw-r--r--fs/nfs/nfs4proc.c5
3 files changed, 27 insertions, 10 deletions
diff --git a/fs/nfs/iostat.h b/fs/nfs/iostat.h
index dc080e50ec5..7a749515331 100644
--- a/fs/nfs/iostat.h
+++ b/fs/nfs/iostat.h
@@ -103,6 +103,7 @@ enum nfs_stat_eventcounters {
NFSIOS_SILLYRENAME,
NFSIOS_SHORTREAD,
NFSIOS_SHORTWRITE,
+ NFSIOS_DELAY,
__NFSIOS_COUNTSMAX,
};
@@ -116,28 +117,38 @@ struct nfs_iostats {
unsigned long events[__NFSIOS_COUNTSMAX];
} ____cacheline_aligned;
-static inline void nfs_inc_stats(struct inode *inode, enum nfs_stat_eventcounters stat)
+static inline void nfs_inc_server_stats(struct nfs_server *server, enum nfs_stat_eventcounters stat)
{
struct nfs_iostats *iostats;
int cpu;
cpu = get_cpu();
- iostats = per_cpu_ptr(NFS_SERVER(inode)->io_stats, cpu);
+ iostats = per_cpu_ptr(server->io_stats, cpu);
iostats->events[stat] ++;
put_cpu_no_resched();
}
-static inline void nfs_add_stats(struct inode *inode, enum nfs_stat_bytecounters stat, unsigned long addend)
+static inline void nfs_inc_stats(struct inode *inode, enum nfs_stat_eventcounters stat)
+{
+ nfs_inc_server_stats(NFS_SERVER(inode), stat);
+}
+
+static inline void nfs_add_server_stats(struct nfs_server *server, enum nfs_stat_bytecounters stat, unsigned long addend)
{
struct nfs_iostats *iostats;
int cpu;
cpu = get_cpu();
- iostats = per_cpu_ptr(NFS_SERVER(inode)->io_stats, cpu);
+ iostats = per_cpu_ptr(server->io_stats, cpu);
iostats->bytes[stat] += addend;
put_cpu_no_resched();
}
+static inline void nfs_add_stats(struct inode *inode, enum nfs_stat_bytecounters stat, unsigned long addend)
+{
+ nfs_add_server_stats(NFS_SERVER(inode), stat, addend);
+}
+
static inline struct nfs_iostats *nfs_alloc_iostats(void)
{
return alloc_percpu(struct nfs_iostats);
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index ed67567f055..7204ba5b2bf 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -19,6 +19,8 @@
#include <linux/smp_lock.h>
#include <linux/nfs_mount.h>
+#include "iostat.h"
+
#define NFSDBG_FACILITY NFSDBG_PROC
extern struct rpc_procinfo nfs3_procedures[];
@@ -58,10 +60,11 @@ nfs3_rpc_call_wrapper(struct rpc_clnt *clnt, u32 proc, void *argp, void *resp, i
nfs3_rpc_wrapper(clnt, msg, flags)
static int
-nfs3_async_handle_jukebox(struct rpc_task *task)
+nfs3_async_handle_jukebox(struct rpc_task *task, struct inode *inode)
{
if (task->tk_status != -EJUKEBOX)
return 0;
+ nfs_inc_stats(inode, NFSIOS_DELAY);
task->tk_status = 0;
rpc_restart_call(task);
rpc_delay(task, NFS_JUKEBOX_RETRY_TIME);
@@ -447,7 +450,7 @@ nfs3_proc_unlink_done(struct dentry *dir, struct rpc_task *task)
struct rpc_message *msg = &task->tk_msg;
struct nfs_fattr *dir_attr;
- if (nfs3_async_handle_jukebox(task))
+ if (nfs3_async_handle_jukebox(task, dir->d_inode))
return 1;
if (msg->rpc_argp) {
dir_attr = (struct nfs_fattr*)msg->rpc_resp;
@@ -748,7 +751,7 @@ static void nfs3_read_done(struct rpc_task *task, void *calldata)
{
struct nfs_read_data *data = calldata;
- if (nfs3_async_handle_jukebox(task))
+ if (nfs3_async_handle_jukebox(task, data->inode))
return;
/* Call back common NFS readpage processing */
if (task->tk_status >= 0)
@@ -786,7 +789,7 @@ static void nfs3_write_done(struct rpc_task *task, void *calldata)
{
struct nfs_write_data *data = calldata;
- if (nfs3_async_handle_jukebox(task))
+ if (nfs3_async_handle_jukebox(task, data->inode))
return;
if (task->tk_status >= 0)
nfs_post_op_update_inode(data->inode, data->res.fattr);
@@ -833,7 +836,7 @@ static void nfs3_commit_done(struct rpc_task *task, void *calldata)
{
struct nfs_write_data *data = calldata;
- if (nfs3_async_handle_jukebox(task))
+ if (nfs3_async_handle_jukebox(task, data->inode))
return;
if (task->tk_status >= 0)
nfs_post_op_update_inode(data->inode, data->res.fattr);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 77a565eba56..f1ff4fa6cce 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -51,6 +51,7 @@
#include "nfs4_fs.h"
#include "delegation.h"
+#include "iostat.h"
#define NFSDBG_FACILITY NFSDBG_PROC
@@ -2755,8 +2756,10 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server)
rpc_wake_up_task(task);
task->tk_status = 0;
return -EAGAIN;
- case -NFS4ERR_GRACE:
case -NFS4ERR_DELAY:
+ nfs_inc_server_stats((struct nfs_server *) server,
+ NFSIOS_DELAY);
+ case -NFS4ERR_GRACE:
rpc_delay(task, NFS4_POLL_RETRY_MAX);
task->tk_status = 0;
return -EAGAIN;