direct.c (d3514abcf5b896a3a66d8b7c960a0018a52ebc2c) direct.c (9bce008bae8b57bc7b007bcc2071d1247a527120)
1/*
2 * linux/fs/nfs/direct.c
3 *
4 * Copyright (C) 2003 by Chuck Lever <cel@netapp.com>
5 *
6 * High-performance uncached I/O for the Linux NFS client
7 *
8 * There are important applications whose performance or correctness

--- 440 unchanged lines hidden (view full) ---

449 result = nfs_direct_wait(dreq);
450 NFS_I(inode)->read_io += result;
451out_release:
452 nfs_direct_req_release(dreq);
453out:
454 return result;
455}
456
1/*
2 * linux/fs/nfs/direct.c
3 *
4 * Copyright (C) 2003 by Chuck Lever <cel@netapp.com>
5 *
6 * High-performance uncached I/O for the Linux NFS client
7 *
8 * There are important applications whose performance or correctness

--- 440 unchanged lines hidden (view full) ---

449 result = nfs_direct_wait(dreq);
450 NFS_I(inode)->read_io += result;
451out_release:
452 nfs_direct_req_release(dreq);
453out:
454 return result;
455}
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
463#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
464static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
465{
466 struct nfs_pageio_descriptor desc;
467 struct nfs_page *req, *tmp;
468 LIST_HEAD(reqs);
469 struct nfs_commit_info cinfo;
470 LIST_HEAD(failed);

--- 94 unchanged lines hidden (view full) ---

565 switch (flags) {
566 case NFS_ODIRECT_DO_COMMIT:
567 nfs_direct_commit_schedule(dreq);
568 break;
569 case NFS_ODIRECT_RESCHED_WRITES:
570 nfs_direct_write_reschedule(dreq);
571 break;
572 default:
457#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
458static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
459{
460 struct nfs_pageio_descriptor desc;
461 struct nfs_page *req, *tmp;
462 LIST_HEAD(reqs);
463 struct nfs_commit_info cinfo;
464 LIST_HEAD(failed);

--- 94 unchanged lines hidden (view full) ---

559 switch (flags) {
560 case NFS_ODIRECT_DO_COMMIT:
561 nfs_direct_commit_schedule(dreq);
562 break;
563 case NFS_ODIRECT_RESCHED_WRITES:
564 nfs_direct_write_reschedule(dreq);
565 break;
566 default:
573 nfs_inode_dio_write_done(dreq->inode);
567 nfs_zap_mapping(dreq->inode, dreq->inode->i_mapping);
574 nfs_direct_complete(dreq);
575 }
576}
577
578static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode *inode)
579{
580 schedule_work(&dreq->work); /* Calls nfs_direct_write_schedule_work */
581}
582
583#else
584static void nfs_direct_write_schedule_work(struct work_struct *work)
585{
586}
587
588static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode *inode)
589{
568 nfs_direct_complete(dreq);
569 }
570}
571
572static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode *inode)
573{
574 schedule_work(&dreq->work); /* Calls nfs_direct_write_schedule_work */
575}
576
577#else
578static void nfs_direct_write_schedule_work(struct work_struct *work)
579{
580}
581
582static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode *inode)
583{
590 nfs_inode_dio_write_done(inode);
584 nfs_zap_mapping(inode, inode->i_mapping);
591 nfs_direct_complete(dreq);
592}
593#endif
594
595/*
596 * NB: Return the value of the first error return code. Subsequent
597 * errors after the first one are ignored.
598 */

--- 112 unchanged lines hidden (view full) ---

711 dreq->count += hdr->good_bytes;
712 if (test_bit(NFS_IOHDR_NEED_RESCHED, &hdr->flags)) {
713 dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
714 bit = NFS_IOHDR_NEED_RESCHED;
715 } else if (test_bit(NFS_IOHDR_NEED_COMMIT, &hdr->flags)) {
716 if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES)
717 bit = NFS_IOHDR_NEED_RESCHED;
718 else if (dreq->flags == 0) {
585 nfs_direct_complete(dreq);
586}
587#endif
588
589/*
590 * NB: Return the value of the first error return code. Subsequent
591 * errors after the first one are ignored.
592 */

--- 112 unchanged lines hidden (view full) ---

705 dreq->count += hdr->good_bytes;
706 if (test_bit(NFS_IOHDR_NEED_RESCHED, &hdr->flags)) {
707 dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
708 bit = NFS_IOHDR_NEED_RESCHED;
709 } else if (test_bit(NFS_IOHDR_NEED_COMMIT, &hdr->flags)) {
710 if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES)
711 bit = NFS_IOHDR_NEED_RESCHED;
712 else if (dreq->flags == 0) {
719 memcpy(&dreq->verf, &req->wb_verf,
713 memcpy(&dreq->verf, hdr->verf,
720 sizeof(dreq->verf));
721 bit = NFS_IOHDR_NEED_COMMIT;
722 dreq->flags = NFS_ODIRECT_DO_COMMIT;
723 } else if (dreq->flags == NFS_ODIRECT_DO_COMMIT) {
714 sizeof(dreq->verf));
715 bit = NFS_IOHDR_NEED_COMMIT;
716 dreq->flags = NFS_ODIRECT_DO_COMMIT;
717 } else if (dreq->flags == NFS_ODIRECT_DO_COMMIT) {
724 if (memcmp(&dreq->verf, &req->wb_verf, sizeof(dreq->verf))) {
718 if (memcmp(&dreq->verf, hdr->verf, sizeof(dreq->verf))) {
725 dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
726 bit = NFS_IOHDR_NEED_RESCHED;
727 } else
728 bit = NFS_IOHDR_NEED_COMMIT;
729 }
730 }
731 }
732 spin_unlock(&dreq->lock);

--- 34 unchanged lines hidden (view full) ---

767};
768
769static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
770 const struct iovec *iov,
771 unsigned long nr_segs,
772 loff_t pos)
773{
774 struct nfs_pageio_descriptor desc;
719 dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
720 bit = NFS_IOHDR_NEED_RESCHED;
721 } else
722 bit = NFS_IOHDR_NEED_COMMIT;
723 }
724 }
725 }
726 spin_unlock(&dreq->lock);

--- 34 unchanged lines hidden (view full) ---

761};
762
763static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
764 const struct iovec *iov,
765 unsigned long nr_segs,
766 loff_t pos)
767{
768 struct nfs_pageio_descriptor desc;
775 struct inode *inode = dreq->inode;
776 ssize_t result = 0;
777 size_t requested_bytes = 0;
778 unsigned long seg;
779
769 ssize_t result = 0;
770 size_t requested_bytes = 0;
771 unsigned long seg;
772
780 nfs_pageio_init_write(&desc, inode, FLUSH_COND_STABLE,
773 nfs_pageio_init_write(&desc, dreq->inode, FLUSH_COND_STABLE,
781 &nfs_direct_write_completion_ops);
782 desc.pg_dreq = dreq;
783 get_dreq(dreq);
774 &nfs_direct_write_completion_ops);
775 desc.pg_dreq = dreq;
776 get_dreq(dreq);
784 atomic_inc(&inode->i_dio_count);
785
786 for (seg = 0; seg < nr_segs; seg++) {
787 const struct iovec *vec = &iov[seg];
788 result = nfs_direct_write_schedule_segment(&desc, vec, pos);
789 if (result < 0)
790 break;
791 requested_bytes += result;
792 if ((size_t)result < vec->iov_len)
793 break;
794 pos += vec->iov_len;
795 }
796 nfs_pageio_complete(&desc);
797 NFS_I(dreq->inode)->write_io += desc.pg_bytes_written;
798
799 /*
800 * If no bytes were started, return the error, and let the
801 * generic layer handle the completion.
802 */
803 if (requested_bytes == 0) {
777
778 for (seg = 0; seg < nr_segs; seg++) {
779 const struct iovec *vec = &iov[seg];
780 result = nfs_direct_write_schedule_segment(&desc, vec, pos);
781 if (result < 0)
782 break;
783 requested_bytes += result;
784 if ((size_t)result < vec->iov_len)
785 break;
786 pos += vec->iov_len;
787 }
788 nfs_pageio_complete(&desc);
789 NFS_I(dreq->inode)->write_io += desc.pg_bytes_written;
790
791 /*
792 * If no bytes were started, return the error, and let the
793 * generic layer handle the completion.
794 */
795 if (requested_bytes == 0) {
804 inode_dio_done(inode);
805 nfs_direct_req_release(dreq);
806 return result < 0 ? result : -EIO;
807 }
808
809 if (put_dreq(dreq))
810 nfs_direct_write_complete(dreq, dreq->inode);
811 return 0;
812}

--- 179 unchanged lines hidden ---
796 nfs_direct_req_release(dreq);
797 return result < 0 ? result : -EIO;
798 }
799
800 if (put_dreq(dreq))
801 nfs_direct_write_complete(dreq, dreq->inode);
802 return 0;
803}

--- 179 unchanged lines hidden ---