diff options
-rw-r--r-- | fs/nfs/direct.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index cbfbd17eae85..85e4e4be401a 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
@@ -500,16 +500,17 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, const struct iovec *iov, | |||
500 | if (!count) | 500 | if (!count) |
501 | goto out; | 501 | goto out; |
502 | 502 | ||
503 | mutex_lock(&inode->i_mutex); | ||
503 | result = nfs_sync_mapping(mapping); | 504 | result = nfs_sync_mapping(mapping); |
504 | if (result) | 505 | if (result) |
505 | goto out; | 506 | goto out_unlock; |
506 | 507 | ||
507 | task_io_account_read(count); | 508 | task_io_account_read(count); |
508 | 509 | ||
509 | result = -ENOMEM; | 510 | result = -ENOMEM; |
510 | dreq = nfs_direct_req_alloc(); | 511 | dreq = nfs_direct_req_alloc(); |
511 | if (dreq == NULL) | 512 | if (dreq == NULL) |
512 | goto out; | 513 | goto out_unlock; |
513 | 514 | ||
514 | dreq->inode = inode; | 515 | dreq->inode = inode; |
515 | dreq->bytes_left = iov_length(iov, nr_segs); | 516 | dreq->bytes_left = iov_length(iov, nr_segs); |
@@ -525,13 +526,22 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, const struct iovec *iov, | |||
525 | 526 | ||
526 | NFS_I(inode)->read_io += iov_length(iov, nr_segs); | 527 | NFS_I(inode)->read_io += iov_length(iov, nr_segs); |
527 | result = nfs_direct_read_schedule_iovec(dreq, iov, nr_segs, pos, uio); | 528 | result = nfs_direct_read_schedule_iovec(dreq, iov, nr_segs, pos, uio); |
529 | |||
530 | mutex_unlock(&inode->i_mutex); | ||
531 | |||
528 | if (!result) { | 532 | if (!result) { |
529 | result = nfs_direct_wait(dreq); | 533 | result = nfs_direct_wait(dreq); |
530 | if (result > 0) | 534 | if (result > 0) |
531 | iocb->ki_pos = pos + result; | 535 | iocb->ki_pos = pos + result; |
532 | } | 536 | } |
537 | |||
538 | nfs_direct_req_release(dreq); | ||
539 | return result; | ||
540 | |||
533 | out_release: | 541 | out_release: |
534 | nfs_direct_req_release(dreq); | 542 | nfs_direct_req_release(dreq); |
543 | out_unlock: | ||
544 | mutex_unlock(&inode->i_mutex); | ||
535 | out: | 545 | out: |
536 | return result; | 546 | return result; |
537 | } | 547 | } |