提交 91d5b470 编写于 作者: C Chuck Lever 提交者: Trond Myklebust

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: NChuck Lever <cel@netapp.com>
Signed-off-by: NTrond Myklebust <Trond.Myklebust@netapp.com>
上级 d9ef5a8c
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "nfs4_fs.h" #include "nfs4_fs.h"
#include "delegation.h" #include "delegation.h"
#include "iostat.h"
#define NFS_PARANOIA 1 #define NFS_PARANOIA 1
/* #define NFS_DEBUG_VERBOSE 1 */ /* #define NFS_DEBUG_VERBOSE 1 */
...@@ -507,6 +508,8 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -507,6 +508,8 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
struct nfs_fattr fattr; struct nfs_fattr fattr;
long res; long res;
nfs_inc_stats(inode, NFSIOS_VFSGETDENTS);
lock_kernel(); lock_kernel();
res = nfs_revalidate_inode(NFS_SERVER(inode), inode); res = nfs_revalidate_inode(NFS_SERVER(inode), inode);
...@@ -713,6 +716,7 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd) ...@@ -713,6 +716,7 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
parent = dget_parent(dentry); parent = dget_parent(dentry);
lock_kernel(); lock_kernel();
dir = parent->d_inode; dir = parent->d_inode;
nfs_inc_stats(dir, NFSIOS_DENTRYREVALIDATE);
inode = dentry->d_inode; inode = dentry->d_inode;
if (!inode) { if (!inode) {
...@@ -844,6 +848,7 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru ...@@ -844,6 +848,7 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
dfprintk(VFS, "NFS: lookup(%s/%s)\n", dfprintk(VFS, "NFS: lookup(%s/%s)\n",
dentry->d_parent->d_name.name, dentry->d_name.name); dentry->d_parent->d_name.name, dentry->d_name.name);
nfs_inc_stats(dir, NFSIOS_VFSLOOKUP);
res = ERR_PTR(-ENAMETOOLONG); res = ERR_PTR(-ENAMETOOLONG);
if (dentry->d_name.len > NFS_SERVER(dir)->namelen) if (dentry->d_name.len > NFS_SERVER(dir)->namelen)
...@@ -1241,6 +1246,7 @@ static int nfs_sillyrename(struct inode *dir, struct dentry *dentry) ...@@ -1241,6 +1246,7 @@ static int nfs_sillyrename(struct inode *dir, struct dentry *dentry)
dfprintk(VFS, "NFS: silly-rename(%s/%s, ct=%d)\n", dfprintk(VFS, "NFS: silly-rename(%s/%s, ct=%d)\n",
dentry->d_parent->d_name.name, dentry->d_name.name, dentry->d_parent->d_name.name, dentry->d_name.name,
atomic_read(&dentry->d_count)); atomic_read(&dentry->d_count));
nfs_inc_stats(dir, NFSIOS_SILLYRENAME);
#ifdef NFS_PARANOIA #ifdef NFS_PARANOIA
if (!dentry->d_inode) if (!dentry->d_inode)
...@@ -1640,6 +1646,8 @@ int nfs_permission(struct inode *inode, int mask, struct nameidata *nd) ...@@ -1640,6 +1646,8 @@ int nfs_permission(struct inode *inode, int mask, struct nameidata *nd)
struct rpc_cred *cred; struct rpc_cred *cred;
int res = 0; int res = 0;
nfs_inc_stats(inode, NFSIOS_VFSACCESS);
if (mask == 0) if (mask == 0)
goto out; goto out;
/* Is this sys_access() ? */ /* Is this sys_access() ? */
......
...@@ -54,6 +54,8 @@ ...@@ -54,6 +54,8 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/atomic.h> #include <asm/atomic.h>
#include "iostat.h"
#define NFSDBG_FACILITY NFSDBG_VFS #define NFSDBG_FACILITY NFSDBG_VFS
#define MAX_DIRECTIO_SIZE (4096UL << PAGE_SHIFT) #define MAX_DIRECTIO_SIZE (4096UL << PAGE_SHIFT)
...@@ -67,6 +69,7 @@ struct nfs_direct_req { ...@@ -67,6 +69,7 @@ struct nfs_direct_req {
struct kref kref; /* release manager */ struct kref kref; /* release manager */
struct list_head list; /* nfs_read_data structs */ struct list_head list; /* nfs_read_data structs */
wait_queue_head_t wait; /* wait for i/o completion */ wait_queue_head_t wait; /* wait for i/o completion */
struct inode * inode; /* target file of I/O */
struct page ** pages; /* pages in our buffer */ struct page ** pages; /* pages in our buffer */
unsigned int npages; /* count of pages */ unsigned int npages; /* count of pages */
atomic_t complete, /* i/os we're waiting for */ atomic_t complete, /* i/os we're waiting for */
...@@ -357,7 +360,9 @@ static ssize_t nfs_direct_read_seg(struct inode *inode, ...@@ -357,7 +360,9 @@ static ssize_t nfs_direct_read_seg(struct inode *inode,
dreq->pages = pages; dreq->pages = pages;
dreq->npages = nr_pages; dreq->npages = nr_pages;
dreq->inode = inode;
nfs_add_stats(inode, NFSIOS_DIRECTREADBYTES, count);
rpc_clnt_sigmask(clnt, &oldset); rpc_clnt_sigmask(clnt, &oldset);
nfs_direct_read_schedule(dreq, inode, ctx, user_addr, count, nfs_direct_read_schedule(dreq, inode, ctx, user_addr, count,
file_offset); file_offset);
...@@ -572,6 +577,7 @@ static ssize_t nfs_direct_write(struct inode *inode, ...@@ -572,6 +577,7 @@ static ssize_t nfs_direct_write(struct inode *inode,
return page_count; return page_count;
} }
nfs_add_stats(inode, NFSIOS_DIRECTWRITTENBYTES, size);
result = nfs_direct_write_seg(inode, ctx, user_addr, size, result = nfs_direct_write_seg(inode, ctx, user_addr, size,
file_offset, pages, page_count); file_offset, pages, page_count);
nfs_free_user_pages(pages, page_count, 0); nfs_free_user_pages(pages, page_count, 0);
...@@ -581,6 +587,7 @@ static ssize_t nfs_direct_write(struct inode *inode, ...@@ -581,6 +587,7 @@ static ssize_t nfs_direct_write(struct inode *inode,
break; break;
return result; return result;
} }
nfs_add_stats(inode, NFSIOS_SERVERWRITTENBYTES, result);
tot_bytes += result; tot_bytes += result;
file_offset += result; file_offset += result;
if (result < size) if (result < size)
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <asm/system.h> #include <asm/system.h>
#include "delegation.h" #include "delegation.h"
#include "iostat.h"
#define NFSDBG_FACILITY NFSDBG_FILE #define NFSDBG_FACILITY NFSDBG_FILE
...@@ -102,18 +103,15 @@ static int nfs_check_flags(int flags) ...@@ -102,18 +103,15 @@ static int nfs_check_flags(int flags)
static int static int
nfs_file_open(struct inode *inode, struct file *filp) nfs_file_open(struct inode *inode, struct file *filp)
{ {
struct nfs_server *server = NFS_SERVER(inode);
int (*open)(struct inode *, struct file *);
int res; int res;
res = nfs_check_flags(filp->f_flags); res = nfs_check_flags(filp->f_flags);
if (res) if (res)
return res; return res;
nfs_inc_stats(inode, NFSIOS_VFSOPEN);
lock_kernel(); lock_kernel();
/* Do NFSv4 open() call */ res = NFS_SERVER(inode)->rpc_ops->file_open(inode, filp);
if ((open = server->rpc_ops->file_open) != NULL)
res = open(inode, filp);
unlock_kernel(); unlock_kernel();
return res; return res;
} }
...@@ -124,6 +122,7 @@ nfs_file_release(struct inode *inode, struct file *filp) ...@@ -124,6 +122,7 @@ nfs_file_release(struct inode *inode, struct file *filp)
/* Ensure that dirty pages are flushed out with the right creds */ /* Ensure that dirty pages are flushed out with the right creds */
if (filp->f_mode & FMODE_WRITE) if (filp->f_mode & FMODE_WRITE)
filemap_fdatawrite(filp->f_mapping); filemap_fdatawrite(filp->f_mapping);
nfs_inc_stats(inode, NFSIOS_VFSRELEASE);
return NFS_PROTO(inode)->file_release(inode, filp); return NFS_PROTO(inode)->file_release(inode, filp);
} }
...@@ -199,6 +198,7 @@ nfs_file_flush(struct file *file) ...@@ -199,6 +198,7 @@ nfs_file_flush(struct file *file)
if ((file->f_mode & FMODE_WRITE) == 0) if ((file->f_mode & FMODE_WRITE) == 0)
return 0; return 0;
nfs_inc_stats(inode, NFSIOS_VFSFLUSH);
lock_kernel(); lock_kernel();
/* Ensure that data+attribute caches are up to date after close() */ /* Ensure that data+attribute caches are up to date after close() */
status = nfs_wb_all(inode); status = nfs_wb_all(inode);
...@@ -229,6 +229,7 @@ nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos) ...@@ -229,6 +229,7 @@ nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos)
(unsigned long) count, (unsigned long) pos); (unsigned long) count, (unsigned long) pos);
result = nfs_revalidate_file(inode, iocb->ki_filp); result = nfs_revalidate_file(inode, iocb->ki_filp);
nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, count);
if (!result) if (!result)
result = generic_file_aio_read(iocb, buf, count, pos); result = generic_file_aio_read(iocb, buf, count, pos);
return result; return result;
...@@ -282,6 +283,7 @@ nfs_fsync(struct file *file, struct dentry *dentry, int datasync) ...@@ -282,6 +283,7 @@ nfs_fsync(struct file *file, struct dentry *dentry, int datasync)
dfprintk(VFS, "nfs: fsync(%s/%ld)\n", inode->i_sb->s_id, inode->i_ino); dfprintk(VFS, "nfs: fsync(%s/%ld)\n", inode->i_sb->s_id, inode->i_ino);
nfs_inc_stats(inode, NFSIOS_VFSFSYNC);
lock_kernel(); lock_kernel();
status = nfs_wb_all(inode); status = nfs_wb_all(inode);
if (!status) { if (!status) {
...@@ -378,6 +380,7 @@ nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t ...@@ -378,6 +380,7 @@ nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t
if (!count) if (!count)
goto out; goto out;
nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count);
result = generic_file_aio_write(iocb, buf, count, pos); result = generic_file_aio_write(iocb, buf, count, pos);
out: out:
return result; return result;
...@@ -517,9 +520,7 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl) ...@@ -517,9 +520,7 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
inode->i_sb->s_id, inode->i_ino, inode->i_sb->s_id, inode->i_ino,
fl->fl_type, fl->fl_flags, fl->fl_type, fl->fl_flags,
(long long)fl->fl_start, (long long)fl->fl_end); (long long)fl->fl_start, (long long)fl->fl_end);
nfs_inc_stats(inode, NFSIOS_VFSLOCK);
if (!inode)
return -EINVAL;
/* No mandatory locks over NFS */ /* No mandatory locks over NFS */
if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID && if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID &&
...@@ -544,9 +545,6 @@ static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl) ...@@ -544,9 +545,6 @@ static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
inode->i_sb->s_id, inode->i_ino, inode->i_sb->s_id, inode->i_ino,
fl->fl_type, fl->fl_flags); fl->fl_type, fl->fl_flags);
if (!inode)
return -EINVAL;
/* /*
* No BSD flocks over NFS allowed. * No BSD flocks over NFS allowed.
* Note: we could try to fake a POSIX lock request here by * Note: we could try to fake a POSIX lock request here by
......
...@@ -753,6 +753,8 @@ static void nfs_zap_caches_locked(struct inode *inode) ...@@ -753,6 +753,8 @@ static void nfs_zap_caches_locked(struct inode *inode)
struct nfs_inode *nfsi = NFS_I(inode); struct nfs_inode *nfsi = NFS_I(inode);
int mode = inode->i_mode; int mode = inode->i_mode;
nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE);
NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode); NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode);
NFS_ATTRTIMEO_UPDATE(inode) = jiffies; NFS_ATTRTIMEO_UPDATE(inode) = jiffies;
...@@ -940,6 +942,8 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) ...@@ -940,6 +942,8 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
struct nfs_fattr fattr; struct nfs_fattr fattr;
int error; int error;
nfs_inc_stats(inode, NFSIOS_VFSSETATTR);
if (attr->ia_valid & ATTR_SIZE) { if (attr->ia_valid & ATTR_SIZE) {
if (!S_ISREG(inode->i_mode) || attr->ia_size == i_size_read(inode)) if (!S_ISREG(inode->i_mode) || attr->ia_size == i_size_read(inode))
attr->ia_valid &= ~ATTR_SIZE; attr->ia_valid &= ~ATTR_SIZE;
...@@ -993,6 +997,7 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr) ...@@ -993,6 +997,7 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr)
spin_unlock(&inode->i_lock); spin_unlock(&inode->i_lock);
} }
if ((attr->ia_valid & ATTR_SIZE) != 0) { if ((attr->ia_valid & ATTR_SIZE) != 0) {
nfs_inc_stats(inode, NFSIOS_SETATTRTRUNC);
inode->i_size = attr->ia_size; inode->i_size = attr->ia_size;
vmtruncate(inode, attr->ia_size); vmtruncate(inode, attr->ia_size);
} }
...@@ -1278,6 +1283,7 @@ int nfs_attribute_timeout(struct inode *inode) ...@@ -1278,6 +1283,7 @@ int nfs_attribute_timeout(struct inode *inode)
*/ */
int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
{ {
nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE);
if (!(NFS_I(inode)->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA)) if (!(NFS_I(inode)->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA))
&& !nfs_attribute_timeout(inode)) && !nfs_attribute_timeout(inode))
return NFS_STALE(inode) ? -ESTALE : 0; return NFS_STALE(inode) ? -ESTALE : 0;
...@@ -1294,6 +1300,7 @@ void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) ...@@ -1294,6 +1300,7 @@ void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
struct nfs_inode *nfsi = NFS_I(inode); struct nfs_inode *nfsi = NFS_I(inode);
if (nfsi->cache_validity & NFS_INO_INVALID_DATA) { if (nfsi->cache_validity & NFS_INO_INVALID_DATA) {
nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE);
if (S_ISREG(inode->i_mode)) if (S_ISREG(inode->i_mode))
nfs_sync_mapping(mapping); nfs_sync_mapping(mapping);
invalidate_inode_pages2(mapping); invalidate_inode_pages2(mapping);
...@@ -1615,6 +1622,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) ...@@ -1615,6 +1622,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
/* Update attrtimeo value if we're out of the unstable period */ /* Update attrtimeo value if we're out of the unstable period */
if (invalid & NFS_INO_INVALID_ATTR) { if (invalid & NFS_INO_INVALID_ATTR) {
nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE);
nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);
nfsi->attrtimeo_timestamp = jiffies; nfsi->attrtimeo_timestamp = jiffies;
} else if (time_after(jiffies, nfsi->attrtimeo_timestamp+nfsi->attrtimeo)) { } else if (time_after(jiffies, nfsi->attrtimeo_timestamp+nfsi->attrtimeo)) {
......
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
#include <asm/system.h> #include <asm/system.h>
#include "iostat.h"
#define NFSDBG_FACILITY NFSDBG_PAGECACHE #define NFSDBG_FACILITY NFSDBG_PAGECACHE
static int nfs_pagein_one(struct list_head *, struct inode *); static int nfs_pagein_one(struct list_head *, struct inode *);
...@@ -133,6 +135,8 @@ static int nfs_readpage_sync(struct nfs_open_context *ctx, struct inode *inode, ...@@ -133,6 +135,8 @@ static int nfs_readpage_sync(struct nfs_open_context *ctx, struct inode *inode,
} }
count -= result; count -= result;
rdata->args.pgbase += result; rdata->args.pgbase += result;
nfs_add_stats(inode, NFSIOS_SERVERREADBYTES, result);
/* Note: result == 0 should only happen if we're caching /* Note: result == 0 should only happen if we're caching
* a write that extends the file and punches a hole. * a write that extends the file and punches a hole.
*/ */
...@@ -458,8 +462,11 @@ void nfs_readpage_result(struct rpc_task *task, void *calldata) ...@@ -458,8 +462,11 @@ void nfs_readpage_result(struct rpc_task *task, void *calldata)
dprintk("NFS: %4d nfs_readpage_result, (status %d)\n", dprintk("NFS: %4d nfs_readpage_result, (status %d)\n",
task->tk_pid, status); task->tk_pid, status);
nfs_add_stats(data->inode, NFSIOS_SERVERREADBYTES, resp->count);
/* Is this a short read? */ /* Is this a short read? */
if (task->tk_status >= 0 && resp->count < argp->count && !resp->eof) { if (task->tk_status >= 0 && resp->count < argp->count && !resp->eof) {
nfs_inc_stats(data->inode, NFSIOS_SHORTREAD);
/* Has the server at least made some progress? */ /* Has the server at least made some progress? */
if (resp->count != 0) { if (resp->count != 0) {
/* Yes, so retry the read at the end of the data */ /* Yes, so retry the read at the end of the data */
...@@ -491,6 +498,9 @@ int nfs_readpage(struct file *file, struct page *page) ...@@ -491,6 +498,9 @@ int nfs_readpage(struct file *file, struct page *page)
dprintk("NFS: nfs_readpage (%p %ld@%lu)\n", dprintk("NFS: nfs_readpage (%p %ld@%lu)\n",
page, PAGE_CACHE_SIZE, page->index); page, PAGE_CACHE_SIZE, page->index);
nfs_inc_stats(inode, NFSIOS_VFSREADPAGE);
nfs_add_stats(inode, NFSIOS_READPAGES, 1);
/* /*
* Try to flush any pending writes to the file.. * Try to flush any pending writes to the file..
* *
...@@ -570,6 +580,7 @@ int nfs_readpages(struct file *filp, struct address_space *mapping, ...@@ -570,6 +580,7 @@ int nfs_readpages(struct file *filp, struct address_space *mapping,
inode->i_sb->s_id, inode->i_sb->s_id,
(long long)NFS_FILEID(inode), (long long)NFS_FILEID(inode),
nr_pages); nr_pages);
nfs_inc_stats(inode, NFSIOS_VFSREADPAGES);
if (filp == NULL) { if (filp == NULL) {
desc.ctx = nfs_find_open_context(inode, NULL, FMODE_READ); desc.ctx = nfs_find_open_context(inode, NULL, FMODE_READ);
...@@ -582,6 +593,7 @@ int nfs_readpages(struct file *filp, struct address_space *mapping, ...@@ -582,6 +593,7 @@ int nfs_readpages(struct file *filp, struct address_space *mapping,
if (!list_empty(&head)) { if (!list_empty(&head)) {
int err = nfs_pagein_list(&head, server->rpages); int err = nfs_pagein_list(&head, server->rpages);
if (!ret) if (!ret)
nfs_add_stats(inode, NFSIOS_READPAGES, err);
ret = err; ret = err;
} }
put_nfs_open_context(desc.ctx); put_nfs_open_context(desc.ctx);
......
...@@ -63,6 +63,7 @@ ...@@ -63,6 +63,7 @@
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include "delegation.h" #include "delegation.h"
#include "iostat.h"
#define NFSDBG_FACILITY NFSDBG_PAGECACHE #define NFSDBG_FACILITY NFSDBG_PAGECACHE
...@@ -134,6 +135,7 @@ static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int c ...@@ -134,6 +135,7 @@ static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int c
end = ((loff_t)page->index << PAGE_CACHE_SHIFT) + ((loff_t)offset+count); end = ((loff_t)page->index << PAGE_CACHE_SHIFT) + ((loff_t)offset+count);
if (i_size >= end) if (i_size >= end)
return; return;
nfs_inc_stats(inode, NFSIOS_EXTENDWRITE);
i_size_write(inode, end); i_size_write(inode, end);
} }
...@@ -223,6 +225,7 @@ static int nfs_writepage_sync(struct nfs_open_context *ctx, struct inode *inode, ...@@ -223,6 +225,7 @@ static int nfs_writepage_sync(struct nfs_open_context *ctx, struct inode *inode,
wdata->args.pgbase += result; wdata->args.pgbase += result;
written += result; written += result;
count -= result; count -= result;
nfs_add_stats(inode, NFSIOS_SERVERWRITTENBYTES, result);
} while (count); } while (count);
/* Update file length */ /* Update file length */
nfs_grow_file(page, offset, written); nfs_grow_file(page, offset, written);
...@@ -279,6 +282,9 @@ int nfs_writepage(struct page *page, struct writeback_control *wbc) ...@@ -279,6 +282,9 @@ int nfs_writepage(struct page *page, struct writeback_control *wbc)
int priority = wb_priority(wbc); int priority = wb_priority(wbc);
int err; int err;
nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE);
nfs_add_stats(inode, NFSIOS_WRITEPAGES, 1);
/* /*
* Note: We need to ensure that we have a reference to the inode * Note: We need to ensure that we have a reference to the inode
* if we are to do asynchronous writes. If not, waiting * 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,6 +349,8 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
struct inode *inode = mapping->host; struct inode *inode = mapping->host;
int err; int err;
nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGES);
err = generic_writepages(mapping, wbc); err = generic_writepages(mapping, wbc);
if (err) if (err)
return err; return err;
...@@ -354,6 +362,7 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc) ...@@ -354,6 +362,7 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
err = nfs_flush_inode(inode, 0, 0, wb_priority(wbc)); err = nfs_flush_inode(inode, 0, 0, wb_priority(wbc));
if (err < 0) if (err < 0)
goto out; goto out;
nfs_add_stats(inode, NFSIOS_WRITEPAGES, err);
wbc->nr_to_write -= err; wbc->nr_to_write -= err;
if (!wbc->nonblocking && wbc->sync_mode == WB_SYNC_ALL) { if (!wbc->nonblocking && wbc->sync_mode == WB_SYNC_ALL) {
err = nfs_wait_on_requests(inode, 0, 0); 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,6 +605,9 @@ static int nfs_wait_on_write_congestion(struct address_space *mapping, int intr)
if (!bdi_write_congested(bdi)) if (!bdi_write_congested(bdi))
return 0; return 0;
nfs_inc_stats(mapping->host, NFSIOS_CONGESTIONWAIT);
if (intr) { if (intr) {
struct rpc_clnt *clnt = NFS_CLIENT(mapping->host); struct rpc_clnt *clnt = NFS_CLIENT(mapping->host);
sigset_t oldset; sigset_t oldset;
...@@ -749,6 +761,8 @@ int nfs_updatepage(struct file *file, struct page *page, ...@@ -749,6 +761,8 @@ int nfs_updatepage(struct file *file, struct page *page,
struct nfs_page *req; struct nfs_page *req;
int status = 0; int status = 0;
nfs_inc_stats(inode, NFSIOS_VFSUPDATEPAGE);
dprintk("NFS: nfs_updatepage(%s/%s %d@%Ld)\n", dprintk("NFS: nfs_updatepage(%s/%s %d@%Ld)\n",
file->f_dentry->d_parent->d_name.name, file->f_dentry->d_parent->d_name.name,
file->f_dentry->d_name.name, count, file->f_dentry->d_name.name, count,
...@@ -1152,6 +1166,8 @@ void nfs_writeback_done(struct rpc_task *task, void *calldata) ...@@ -1152,6 +1166,8 @@ void nfs_writeback_done(struct rpc_task *task, void *calldata)
dprintk("NFS: %4d nfs_writeback_done (status %d)\n", dprintk("NFS: %4d nfs_writeback_done (status %d)\n",
task->tk_pid, task->tk_status); task->tk_pid, task->tk_status);
nfs_add_stats(data->inode, NFSIOS_SERVERWRITTENBYTES, resp->count);
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
if (resp->verf->committed < argp->stable && task->tk_status >= 0) { if (resp->verf->committed < argp->stable && task->tk_status >= 0) {
/* We tried a write call, but the server did not /* 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,6 +1193,8 @@ void nfs_writeback_done(struct rpc_task *task, void *calldata)
if (task->tk_status >= 0 && resp->count < argp->count) { if (task->tk_status >= 0 && resp->count < argp->count) {
static unsigned long complain; static unsigned long complain;
nfs_inc_stats(data->inode, NFSIOS_SHORTWRITE);
/* Has the server at least made some progress? */ /* Has the server at least made some progress? */
if (resp->count != 0) { if (resp->count != 0) {
/* Was this an NFSv2 write or an NFSv3 stable write? */ /* Was this an NFSv2 write or an NFSv3 stable write? */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册