diff options
author | Chuck Lever <cel@netapp.com> | 2006-03-20 13:44:14 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-03-20 13:44:14 -0500 |
commit | 91d5b47023b608227d605d1e916b29dd0215bff7 (patch) | |
tree | 31dbb285639ea68db3abc0c4129988f02d50f11a /fs/nfs/write.c | |
parent | d9ef5a8c26aab09762afce43df64736720b4860e (diff) |
NFS: add I/O performance counters
Invoke the byte and event counter macros where we want to count bytes and
events.
Clean-up: fix a possible NULL dereference in nfs_lock, and simplify
nfs_file_open.
Test-plan:
fsx and iozone on UP and SMP systems, with and without pre-emption. Watch
for memory overwrite bugs, and performance loss (significantly more CPU
required per op).
Signed-off-by: Chuck Lever <cel@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r-- | fs/nfs/write.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 92ecf24455c3..e7c8361cf201 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -63,6 +63,7 @@ | |||
63 | #include <linux/smp_lock.h> | 63 | #include <linux/smp_lock.h> |
64 | 64 | ||
65 | #include "delegation.h" | 65 | #include "delegation.h" |
66 | #include "iostat.h" | ||
66 | 67 | ||
67 | #define NFSDBG_FACILITY NFSDBG_PAGECACHE | 68 | #define NFSDBG_FACILITY NFSDBG_PAGECACHE |
68 | 69 | ||
@@ -134,6 +135,7 @@ static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int c | |||
134 | end = ((loff_t)page->index << PAGE_CACHE_SHIFT) + ((loff_t)offset+count); | 135 | end = ((loff_t)page->index << PAGE_CACHE_SHIFT) + ((loff_t)offset+count); |
135 | if (i_size >= end) | 136 | if (i_size >= end) |
136 | return; | 137 | return; |
138 | nfs_inc_stats(inode, NFSIOS_EXTENDWRITE); | ||
137 | i_size_write(inode, end); | 139 | i_size_write(inode, end); |
138 | } | 140 | } |
139 | 141 | ||
@@ -223,6 +225,7 @@ static int nfs_writepage_sync(struct nfs_open_context *ctx, struct inode *inode, | |||
223 | wdata->args.pgbase += result; | 225 | wdata->args.pgbase += result; |
224 | written += result; | 226 | written += result; |
225 | count -= result; | 227 | count -= result; |
228 | nfs_add_stats(inode, NFSIOS_SERVERWRITTENBYTES, result); | ||
226 | } while (count); | 229 | } while (count); |
227 | /* Update file length */ | 230 | /* Update file length */ |
228 | nfs_grow_file(page, offset, written); | 231 | nfs_grow_file(page, offset, written); |
@@ -279,6 +282,9 @@ int nfs_writepage(struct page *page, struct writeback_control *wbc) | |||
279 | int priority = wb_priority(wbc); | 282 | int priority = wb_priority(wbc); |
280 | int err; | 283 | int err; |
281 | 284 | ||
285 | nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE); | ||
286 | nfs_add_stats(inode, NFSIOS_WRITEPAGES, 1); | ||
287 | |||
282 | /* | 288 | /* |
283 | * Note: We need to ensure that we have a reference to the inode | 289 | * Note: We need to ensure that we have a reference to the inode |
284 | * if we are to do asynchronous writes. If not, waiting | 290 | * if we are to do asynchronous writes. If not, waiting |
@@ -343,6 +349,8 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc) | |||
343 | struct inode *inode = mapping->host; | 349 | struct inode *inode = mapping->host; |
344 | int err; | 350 | int err; |
345 | 351 | ||
352 | nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGES); | ||
353 | |||
346 | err = generic_writepages(mapping, wbc); | 354 | err = generic_writepages(mapping, wbc); |
347 | if (err) | 355 | if (err) |
348 | return err; | 356 | return err; |
@@ -354,6 +362,7 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc) | |||
354 | err = nfs_flush_inode(inode, 0, 0, wb_priority(wbc)); | 362 | err = nfs_flush_inode(inode, 0, 0, wb_priority(wbc)); |
355 | if (err < 0) | 363 | if (err < 0) |
356 | goto out; | 364 | goto out; |
365 | nfs_add_stats(inode, NFSIOS_WRITEPAGES, err); | ||
357 | wbc->nr_to_write -= err; | 366 | wbc->nr_to_write -= err; |
358 | if (!wbc->nonblocking && wbc->sync_mode == WB_SYNC_ALL) { | 367 | if (!wbc->nonblocking && wbc->sync_mode == WB_SYNC_ALL) { |
359 | err = nfs_wait_on_requests(inode, 0, 0); | 368 | err = nfs_wait_on_requests(inode, 0, 0); |
@@ -596,6 +605,9 @@ static int nfs_wait_on_write_congestion(struct address_space *mapping, int intr) | |||
596 | 605 | ||
597 | if (!bdi_write_congested(bdi)) | 606 | if (!bdi_write_congested(bdi)) |
598 | return 0; | 607 | return 0; |
608 | |||
609 | nfs_inc_stats(mapping->host, NFSIOS_CONGESTIONWAIT); | ||
610 | |||
599 | if (intr) { | 611 | if (intr) { |
600 | struct rpc_clnt *clnt = NFS_CLIENT(mapping->host); | 612 | struct rpc_clnt *clnt = NFS_CLIENT(mapping->host); |
601 | sigset_t oldset; | 613 | sigset_t oldset; |
@@ -749,6 +761,8 @@ int nfs_updatepage(struct file *file, struct page *page, | |||
749 | struct nfs_page *req; | 761 | struct nfs_page *req; |
750 | int status = 0; | 762 | int status = 0; |
751 | 763 | ||
764 | nfs_inc_stats(inode, NFSIOS_VFSUPDATEPAGE); | ||
765 | |||
752 | dprintk("NFS: nfs_updatepage(%s/%s %d@%Ld)\n", | 766 | dprintk("NFS: nfs_updatepage(%s/%s %d@%Ld)\n", |
753 | file->f_dentry->d_parent->d_name.name, | 767 | file->f_dentry->d_parent->d_name.name, |
754 | file->f_dentry->d_name.name, count, | 768 | file->f_dentry->d_name.name, count, |
@@ -1152,6 +1166,8 @@ void nfs_writeback_done(struct rpc_task *task, void *calldata) | |||
1152 | dprintk("NFS: %4d nfs_writeback_done (status %d)\n", | 1166 | dprintk("NFS: %4d nfs_writeback_done (status %d)\n", |
1153 | task->tk_pid, task->tk_status); | 1167 | task->tk_pid, task->tk_status); |
1154 | 1168 | ||
1169 | nfs_add_stats(data->inode, NFSIOS_SERVERWRITTENBYTES, resp->count); | ||
1170 | |||
1155 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | 1171 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) |
1156 | if (resp->verf->committed < argp->stable && task->tk_status >= 0) { | 1172 | if (resp->verf->committed < argp->stable && task->tk_status >= 0) { |
1157 | /* We tried a write call, but the server did not | 1173 | /* We tried a write call, but the server did not |
@@ -1177,6 +1193,8 @@ void nfs_writeback_done(struct rpc_task *task, void *calldata) | |||
1177 | if (task->tk_status >= 0 && resp->count < argp->count) { | 1193 | if (task->tk_status >= 0 && resp->count < argp->count) { |
1178 | static unsigned long complain; | 1194 | static unsigned long complain; |
1179 | 1195 | ||
1196 | nfs_inc_stats(data->inode, NFSIOS_SHORTWRITE); | ||
1197 | |||
1180 | /* Has the server at least made some progress? */ | 1198 | /* Has the server at least made some progress? */ |
1181 | if (resp->count != 0) { | 1199 | if (resp->count != 0) { |
1182 | /* Was this an NFSv2 write or an NFSv3 stable write? */ | 1200 | /* Was this an NFSv2 write or an NFSv3 stable write? */ |