direct.c (d0b9875d65c1abcc9d405d648660dfb919353959) direct.c (a9ab5e840669b19aca2974e2c771a77df2876434)
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

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

934 unsigned long nr_segs, loff_t pos, bool uio)
935{
936 ssize_t result = -EINVAL;
937 struct file *file = iocb->ki_filp;
938 struct address_space *mapping = file->f_mapping;
939 struct inode *inode = mapping->host;
940 struct nfs_direct_req *dreq;
941 struct nfs_lock_context *l_ctx;
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

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

934 unsigned long nr_segs, loff_t pos, bool uio)
935{
936 ssize_t result = -EINVAL;
937 struct file *file = iocb->ki_filp;
938 struct address_space *mapping = file->f_mapping;
939 struct inode *inode = mapping->host;
940 struct nfs_direct_req *dreq;
941 struct nfs_lock_context *l_ctx;
942 loff_t end;
942 size_t count;
943
944 count = iov_length(iov, nr_segs);
943 size_t count;
944
945 count = iov_length(iov, nr_segs);
946 end = (pos + count - 1) >> PAGE_CACHE_SHIFT;
947
945 nfs_add_stats(mapping->host, NFSIOS_DIRECTWRITTENBYTES, count);
946
947 dfprintk(FILE, "NFS: direct write(%pD2, %zd@%Ld)\n",
948 file, count, (long long) pos);
949
950 result = generic_write_checks(file, &pos, &count, 0);
951 if (result)
952 goto out;
953
954 result = -EINVAL;
955 if ((ssize_t) count < 0)
956 goto out;
957 result = 0;
958 if (!count)
959 goto out;
960
948 nfs_add_stats(mapping->host, NFSIOS_DIRECTWRITTENBYTES, count);
949
950 dfprintk(FILE, "NFS: direct write(%pD2, %zd@%Ld)\n",
951 file, count, (long long) pos);
952
953 result = generic_write_checks(file, &pos, &count, 0);
954 if (result)
955 goto out;
956
957 result = -EINVAL;
958 if ((ssize_t) count < 0)
959 goto out;
960 result = 0;
961 if (!count)
962 goto out;
963
964 mutex_lock(&inode->i_mutex);
965
961 result = nfs_sync_mapping(mapping);
962 if (result)
966 result = nfs_sync_mapping(mapping);
967 if (result)
963 goto out;
968 goto out_unlock;
964
969
970 if (mapping->nrpages) {
971 result = invalidate_inode_pages2_range(mapping,
972 pos >> PAGE_CACHE_SHIFT, end);
973 if (result)
974 goto out_unlock;
975 }
976
965 task_io_account_write(count);
966
967 result = -ENOMEM;
968 dreq = nfs_direct_req_alloc();
969 if (!dreq)
977 task_io_account_write(count);
978
979 result = -ENOMEM;
980 dreq = nfs_direct_req_alloc();
981 if (!dreq)
970 goto out;
982 goto out_unlock;
971
972 dreq->inode = inode;
973 dreq->bytes_left = count;
974 dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
975 l_ctx = nfs_get_lock_context(dreq->ctx);
976 if (IS_ERR(l_ctx)) {
977 result = PTR_ERR(l_ctx);
978 goto out_release;
979 }
980 dreq->l_ctx = l_ctx;
981 if (!is_sync_kiocb(iocb))
982 dreq->iocb = iocb;
983
984 result = nfs_direct_write_schedule_iovec(dreq, iov, nr_segs, pos, uio);
983
984 dreq->inode = inode;
985 dreq->bytes_left = count;
986 dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
987 l_ctx = nfs_get_lock_context(dreq->ctx);
988 if (IS_ERR(l_ctx)) {
989 result = PTR_ERR(l_ctx);
990 goto out_release;
991 }
992 dreq->l_ctx = l_ctx;
993 if (!is_sync_kiocb(iocb))
994 dreq->iocb = iocb;
995
996 result = nfs_direct_write_schedule_iovec(dreq, iov, nr_segs, pos, uio);
997
998 if (mapping->nrpages) {
999 invalidate_inode_pages2_range(mapping,
1000 pos >> PAGE_CACHE_SHIFT, end);
1001 }
1002
1003 mutex_unlock(&inode->i_mutex);
1004
985 if (!result) {
986 result = nfs_direct_wait(dreq);
987 if (result > 0) {
988 struct inode *inode = mapping->host;
989
990 iocb->ki_pos = pos + result;
991 spin_lock(&inode->i_lock);
992 if (i_size_read(inode) < iocb->ki_pos)
993 i_size_write(inode, iocb->ki_pos);
994 spin_unlock(&inode->i_lock);
995 }
996 }
1005 if (!result) {
1006 result = nfs_direct_wait(dreq);
1007 if (result > 0) {
1008 struct inode *inode = mapping->host;
1009
1010 iocb->ki_pos = pos + result;
1011 spin_lock(&inode->i_lock);
1012 if (i_size_read(inode) < iocb->ki_pos)
1013 i_size_write(inode, iocb->ki_pos);
1014 spin_unlock(&inode->i_lock);
1015 }
1016 }
1017 nfs_direct_req_release(dreq);
1018 return result;
1019
997out_release:
998 nfs_direct_req_release(dreq);
1020out_release:
1021 nfs_direct_req_release(dreq);
1022out_unlock:
1023 mutex_unlock(&inode->i_mutex);
999out:
1000 return result;
1001}
1002
1003/**
1004 * nfs_init_directcache - create a slab cache for nfs_direct_req structures
1005 *
1006 */

--- 21 unchanged lines hidden ---
1024out:
1025 return result;
1026}
1027
1028/**
1029 * nfs_init_directcache - create a slab cache for nfs_direct_req structures
1030 *
1031 */

--- 21 unchanged lines hidden ---