aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/direct.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2012-05-31 12:22:33 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-31 14:41:36 -0400
commit1d59d61f606547f0712aa6971f91f71154071c99 (patch)
treecb2fd4b9ce3e3ee9440d566d43ea350221edfc8e /fs/nfs/direct.c
parent2d117403b30cd7301af60d7d54b279a9f566d10d (diff)
NFS: Ensure that setattr and getattr wait for O_DIRECT write completion
Use the same mechanism as the block devices are using, but move the helper functions from fs/direct-io.c into fs/inode.c to remove the dependency on CONFIG_BLOCK. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> Cc: Christoph Hellwig <hch@infradead.org> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Fred Isaman <iisaman@netapp.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/nfs/direct.c')
-rw-r--r--fs/nfs/direct.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 23d170bc44f4..ad2775d3e219 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -454,6 +454,12 @@ out:
454 return result; 454 return result;
455} 455}
456 456
457static void nfs_inode_dio_write_done(struct inode *inode)
458{
459 nfs_zap_mapping(inode, inode->i_mapping);
460 inode_dio_done(inode);
461}
462
457#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) 463#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
458static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) 464static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
459{ 465{
@@ -564,7 +570,7 @@ static void nfs_direct_write_schedule_work(struct work_struct *work)
564 nfs_direct_write_reschedule(dreq); 570 nfs_direct_write_reschedule(dreq);
565 break; 571 break;
566 default: 572 default:
567 nfs_zap_mapping(dreq->inode, dreq->inode->i_mapping); 573 nfs_inode_dio_write_done(dreq->inode);
568 nfs_direct_complete(dreq); 574 nfs_direct_complete(dreq);
569 } 575 }
570} 576}
@@ -581,7 +587,7 @@ static void nfs_direct_write_schedule_work(struct work_struct *work)
581 587
582static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode *inode) 588static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode *inode)
583{ 589{
584 nfs_zap_mapping(inode, inode->i_mapping); 590 nfs_inode_dio_write_done(inode);
585 nfs_direct_complete(dreq); 591 nfs_direct_complete(dreq);
586} 592}
587#endif 593#endif
@@ -766,14 +772,16 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
766 loff_t pos) 772 loff_t pos)
767{ 773{
768 struct nfs_pageio_descriptor desc; 774 struct nfs_pageio_descriptor desc;
775 struct inode *inode = dreq->inode;
769 ssize_t result = 0; 776 ssize_t result = 0;
770 size_t requested_bytes = 0; 777 size_t requested_bytes = 0;
771 unsigned long seg; 778 unsigned long seg;
772 779
773 nfs_pageio_init_write(&desc, dreq->inode, FLUSH_COND_STABLE, 780 nfs_pageio_init_write(&desc, inode, FLUSH_COND_STABLE,
774 &nfs_direct_write_completion_ops); 781 &nfs_direct_write_completion_ops);
775 desc.pg_dreq = dreq; 782 desc.pg_dreq = dreq;
776 get_dreq(dreq); 783 get_dreq(dreq);
784 atomic_inc(&inode->i_dio_count);
777 785
778 for (seg = 0; seg < nr_segs; seg++) { 786 for (seg = 0; seg < nr_segs; seg++) {
779 const struct iovec *vec = &iov[seg]; 787 const struct iovec *vec = &iov[seg];
@@ -793,6 +801,7 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
793 * generic layer handle the completion. 801 * generic layer handle the completion.
794 */ 802 */
795 if (requested_bytes == 0) { 803 if (requested_bytes == 0) {
804 inode_dio_done(inode);
796 nfs_direct_req_release(dreq); 805 nfs_direct_req_release(dreq);
797 return result < 0 ? result : -EIO; 806 return result < 0 ? result : -EIO;
798 } 807 }