aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/file.c')
-rw-r--r--fs/nfs/file.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index f5fdd39e037a..8d965bddb87e 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -24,9 +24,9 @@
24#include <linux/nfs_fs.h> 24#include <linux/nfs_fs.h>
25#include <linux/nfs_mount.h> 25#include <linux/nfs_mount.h>
26#include <linux/mm.h> 26#include <linux/mm.h>
27#include <linux/slab.h>
28#include <linux/pagemap.h> 27#include <linux/pagemap.h>
29#include <linux/aio.h> 28#include <linux/aio.h>
29#include <linux/gfp.h>
30 30
31#include <asm/uaccess.h> 31#include <asm/uaccess.h>
32#include <asm/system.h> 32#include <asm/system.h>
@@ -123,11 +123,11 @@ nfs_file_open(struct inode *inode, struct file *filp)
123 filp->f_path.dentry->d_parent->d_name.name, 123 filp->f_path.dentry->d_parent->d_name.name,
124 filp->f_path.dentry->d_name.name); 124 filp->f_path.dentry->d_name.name);
125 125
126 nfs_inc_stats(inode, NFSIOS_VFSOPEN);
126 res = nfs_check_flags(filp->f_flags); 127 res = nfs_check_flags(filp->f_flags);
127 if (res) 128 if (res)
128 return res; 129 return res;
129 130
130 nfs_inc_stats(inode, NFSIOS_VFSOPEN);
131 res = nfs_open(inode, filp); 131 res = nfs_open(inode, filp);
132 return res; 132 return res;
133} 133}
@@ -237,9 +237,9 @@ nfs_file_flush(struct file *file, fl_owner_t id)
237 dentry->d_parent->d_name.name, 237 dentry->d_parent->d_name.name,
238 dentry->d_name.name); 238 dentry->d_name.name);
239 239
240 nfs_inc_stats(inode, NFSIOS_VFSFLUSH);
240 if ((file->f_mode & FMODE_WRITE) == 0) 241 if ((file->f_mode & FMODE_WRITE) == 0)
241 return 0; 242 return 0;
242 nfs_inc_stats(inode, NFSIOS_VFSFLUSH);
243 243
244 /* Flush writes to the server and return any errors */ 244 /* Flush writes to the server and return any errors */
245 return nfs_do_fsync(ctx, inode); 245 return nfs_do_fsync(ctx, inode);
@@ -262,9 +262,11 @@ nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
262 (unsigned long) count, (unsigned long) pos); 262 (unsigned long) count, (unsigned long) pos);
263 263
264 result = nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping); 264 result = nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping);
265 nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, count); 265 if (!result) {
266 if (!result)
267 result = generic_file_aio_read(iocb, iov, nr_segs, pos); 266 result = generic_file_aio_read(iocb, iov, nr_segs, pos);
267 if (result > 0)
268 nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, result);
269 }
268 return result; 270 return result;
269} 271}
270 272
@@ -282,8 +284,11 @@ nfs_file_splice_read(struct file *filp, loff_t *ppos,
282 (unsigned long) count, (unsigned long long) *ppos); 284 (unsigned long) count, (unsigned long long) *ppos);
283 285
284 res = nfs_revalidate_mapping(inode, filp->f_mapping); 286 res = nfs_revalidate_mapping(inode, filp->f_mapping);
285 if (!res) 287 if (!res) {
286 res = generic_file_splice_read(filp, ppos, pipe, count, flags); 288 res = generic_file_splice_read(filp, ppos, pipe, count, flags);
289 if (res > 0)
290 nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, res);
291 }
287 return res; 292 return res;
288} 293}
289 294
@@ -486,6 +491,9 @@ static int nfs_release_page(struct page *page, gfp_t gfp)
486{ 491{
487 dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page); 492 dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page);
488 493
494 /* Only do I/O if gfp is a superset of GFP_KERNEL */
495 if ((gfp & GFP_KERNEL) == GFP_KERNEL)
496 nfs_wb_page(page->mapping->host, page);
489 /* If PagePrivate() is set, then the page is not freeable */ 497 /* If PagePrivate() is set, then the page is not freeable */
490 if (PagePrivate(page)) 498 if (PagePrivate(page))
491 return 0; 499 return 0;
@@ -581,7 +589,7 @@ static int nfs_need_sync_write(struct file *filp, struct inode *inode)
581{ 589{
582 struct nfs_open_context *ctx; 590 struct nfs_open_context *ctx;
583 591
584 if (IS_SYNC(inode) || (filp->f_flags & O_SYNC)) 592 if (IS_SYNC(inode) || (filp->f_flags & O_DSYNC))
585 return 1; 593 return 1;
586 ctx = nfs_file_open_context(filp); 594 ctx = nfs_file_open_context(filp);
587 if (test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags)) 595 if (test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags))
@@ -594,6 +602,7 @@ static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
594{ 602{
595 struct dentry * dentry = iocb->ki_filp->f_path.dentry; 603 struct dentry * dentry = iocb->ki_filp->f_path.dentry;
596 struct inode * inode = dentry->d_inode; 604 struct inode * inode = dentry->d_inode;
605 unsigned long written = 0;
597 ssize_t result; 606 ssize_t result;
598 size_t count = iov_length(iov, nr_segs); 607 size_t count = iov_length(iov, nr_segs);
599 608
@@ -620,14 +629,18 @@ static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
620 if (!count) 629 if (!count)
621 goto out; 630 goto out;
622 631
623 nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count);
624 result = generic_file_aio_write(iocb, iov, nr_segs, pos); 632 result = generic_file_aio_write(iocb, iov, nr_segs, pos);
625 /* Return error values for O_SYNC and IS_SYNC() */ 633 if (result > 0)
634 written = result;
635
636 /* Return error values for O_DSYNC and IS_SYNC() */
626 if (result >= 0 && nfs_need_sync_write(iocb->ki_filp, inode)) { 637 if (result >= 0 && nfs_need_sync_write(iocb->ki_filp, inode)) {
627 int err = nfs_do_fsync(nfs_file_open_context(iocb->ki_filp), inode); 638 int err = nfs_do_fsync(nfs_file_open_context(iocb->ki_filp), inode);
628 if (err < 0) 639 if (err < 0)
629 result = err; 640 result = err;
630 } 641 }
642 if (result > 0)
643 nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, written);
631out: 644out:
632 return result; 645 return result;
633 646
@@ -642,6 +655,7 @@ static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
642{ 655{
643 struct dentry *dentry = filp->f_path.dentry; 656 struct dentry *dentry = filp->f_path.dentry;
644 struct inode *inode = dentry->d_inode; 657 struct inode *inode = dentry->d_inode;
658 unsigned long written = 0;
645 ssize_t ret; 659 ssize_t ret;
646 660
647 dprintk("NFS splice_write(%s/%s, %lu@%llu)\n", 661 dprintk("NFS splice_write(%s/%s, %lu@%llu)\n",
@@ -652,14 +666,17 @@ static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
652 * The combination of splice and an O_APPEND destination is disallowed. 666 * The combination of splice and an O_APPEND destination is disallowed.
653 */ 667 */
654 668
655 nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count);
656
657 ret = generic_file_splice_write(pipe, filp, ppos, count, flags); 669 ret = generic_file_splice_write(pipe, filp, ppos, count, flags);
670 if (ret > 0)
671 written = ret;
672
658 if (ret >= 0 && nfs_need_sync_write(filp, inode)) { 673 if (ret >= 0 && nfs_need_sync_write(filp, inode)) {
659 int err = nfs_do_fsync(nfs_file_open_context(filp), inode); 674 int err = nfs_do_fsync(nfs_file_open_context(filp), inode);
660 if (err < 0) 675 if (err < 0)
661 ret = err; 676 ret = err;
662 } 677 }
678 if (ret > 0)
679 nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, written);
663 return ret; 680 return ret;
664} 681}
665 682