aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2013-11-14 11:50:29 -0500
committerTrond Myklebust <trond.myklebust@primarydata.com>2014-01-13 17:29:48 -0500
commit2a009ec98cce440c0992fc9a2353e96cdb0b048b (patch)
treee2cb12a379834aa6283b1a5b01b52ab542e2885c /fs/nfs
parent9811cd57f4c6b5b60ec104de68a88303717e3106 (diff)
nfs: defer inode_dio_done call until size update is done
We need to have the I/O fully finished before telling the truncate code that we are done. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/direct.c32
1 files changed, 15 insertions, 17 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index ce52a9774ec1..75ed2a90b0f2 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -226,21 +226,27 @@ static void nfs_direct_complete(struct nfs_direct_req *dreq, bool write)
226{ 226{
227 struct inode *inode = dreq->inode; 227 struct inode *inode = dreq->inode;
228 228
229 if (dreq->iocb) { 229 if (dreq->iocb && write) {
230 loff_t pos = dreq->iocb->ki_pos + dreq->count; 230 loff_t pos = dreq->iocb->ki_pos + dreq->count;
231
232 spin_lock(&inode->i_lock);
233 if (i_size_read(inode) < pos)
234 i_size_write(inode, pos);
235 spin_unlock(&inode->i_lock);
236 }
237
238 if (write) {
239 nfs_zap_mapping(inode, inode->i_mapping);
240 inode_dio_done(inode);
241 }
242
243 if (dreq->iocb) {
231 long res = (long) dreq->error; 244 long res = (long) dreq->error;
232 if (!res) 245 if (!res)
233 res = (long) dreq->count; 246 res = (long) dreq->count;
234
235 if (write) {
236 spin_lock(&inode->i_lock);
237 if (i_size_read(inode) < pos)
238 i_size_write(inode, pos);
239 spin_unlock(&inode->i_lock);
240 }
241
242 aio_complete(dreq->iocb, res, 0); 247 aio_complete(dreq->iocb, res, 0);
243 } 248 }
249
244 complete_all(&dreq->completion); 250 complete_all(&dreq->completion);
245 251
246 nfs_direct_req_release(dreq); 252 nfs_direct_req_release(dreq);
@@ -483,12 +489,6 @@ out:
483 return result; 489 return result;
484} 490}
485 491
486static void nfs_inode_dio_write_done(struct inode *inode)
487{
488 nfs_zap_mapping(inode, inode->i_mapping);
489 inode_dio_done(inode);
490}
491
492#if IS_ENABLED(CONFIG_NFS_V3) || IS_ENABLED(CONFIG_NFS_V4) 492#if IS_ENABLED(CONFIG_NFS_V3) || IS_ENABLED(CONFIG_NFS_V4)
493static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) 493static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
494{ 494{
@@ -604,7 +604,6 @@ static void nfs_direct_write_schedule_work(struct work_struct *work)
604 nfs_direct_write_reschedule(dreq); 604 nfs_direct_write_reschedule(dreq);
605 break; 605 break;
606 default: 606 default:
607 nfs_inode_dio_write_done(dreq->inode);
608 nfs_direct_complete(dreq, true); 607 nfs_direct_complete(dreq, true);
609 } 608 }
610} 609}
@@ -621,7 +620,6 @@ static void nfs_direct_write_schedule_work(struct work_struct *work)
621 620
622static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode *inode) 621static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode *inode)
623{ 622{
624 nfs_inode_dio_write_done(inode);
625 nfs_direct_complete(dreq, true); 623 nfs_direct_complete(dreq, true);
626} 624}
627#endif 625#endif