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 --- |