aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZheng Liu <wenqing.lz@taobao.com>2012-07-09 16:29:29 -0400
committerTheodore Ts'o <tytso@mit.edu>2012-07-09 16:29:29 -0400
commitfbe104942d3ff44f6802e8e4a3fbf267c1fb9ac4 (patch)
tree1022097e97679f5fc13fdef5fd5893cdfdd35dcf
parent62a1391ddd6fbe82fc02154dc760bcc5cbc9ef68 (diff)
ext4: split ext4_file_write into buffered IO and direct IO
ext4_file_dio_write is defined in order to split buffered IO and direct IO in ext4. This patch just refactor some stuff in write path. CC: Tao Ma <tm@tao.ma> CC: Eric Sandeen <sandeen@redhat.com> CC: Robin Dong <hao.bigrat@gmail.com> Signed-off-by: Zheng Liu <wenqing.lz@taobao.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r--fs/ext4/file.c60
1 files changed, 38 insertions, 22 deletions
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 8c7642a00054..a10dc7742aec 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -90,34 +90,16 @@ ext4_unaligned_aio(struct inode *inode, const struct iovec *iov,
90} 90}
91 91
92static ssize_t 92static ssize_t
93ext4_file_write(struct kiocb *iocb, const struct iovec *iov, 93ext4_file_dio_write(struct kiocb *iocb, const struct iovec *iov,
94 unsigned long nr_segs, loff_t pos) 94 unsigned long nr_segs, loff_t pos)
95{ 95{
96 struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode; 96 struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
97 int unaligned_aio = 0; 97 int unaligned_aio = 0;
98 ssize_t ret; 98 ssize_t ret;
99 99
100 /* 100 if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) &&
101 * If we have encountered a bitmap-format file, the size limit 101 !is_sync_kiocb(iocb))
102 * is smaller than s_maxbytes, which is for extent-mapped files.
103 */
104
105 if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
106 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
107 size_t length = iov_length(iov, nr_segs);
108
109 if ((pos > sbi->s_bitmap_maxbytes ||
110 (pos == sbi->s_bitmap_maxbytes && length > 0)))
111 return -EFBIG;
112
113 if (pos + length > sbi->s_bitmap_maxbytes) {
114 nr_segs = iov_shorten((struct iovec *)iov, nr_segs,
115 sbi->s_bitmap_maxbytes - pos);
116 }
117 } else if (unlikely((iocb->ki_filp->f_flags & O_DIRECT) &&
118 !is_sync_kiocb(iocb))) {
119 unaligned_aio = ext4_unaligned_aio(inode, iov, nr_segs, pos); 102 unaligned_aio = ext4_unaligned_aio(inode, iov, nr_segs, pos);
120 }
121 103
122 /* Unaligned direct AIO must be serialized; see comment above */ 104 /* Unaligned direct AIO must be serialized; see comment above */
123 if (unaligned_aio) { 105 if (unaligned_aio) {
@@ -141,6 +123,40 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
141 return ret; 123 return ret;
142} 124}
143 125
126static ssize_t
127ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
128 unsigned long nr_segs, loff_t pos)
129{
130 struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
131 ssize_t ret;
132
133 /*
134 * If we have encountered a bitmap-format file, the size limit
135 * is smaller than s_maxbytes, which is for extent-mapped files.
136 */
137
138 if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
139 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
140 size_t length = iov_length(iov, nr_segs);
141
142 if ((pos > sbi->s_bitmap_maxbytes ||
143 (pos == sbi->s_bitmap_maxbytes && length > 0)))
144 return -EFBIG;
145
146 if (pos + length > sbi->s_bitmap_maxbytes) {
147 nr_segs = iov_shorten((struct iovec *)iov, nr_segs,
148 sbi->s_bitmap_maxbytes - pos);
149 }
150 }
151
152 if (unlikely(iocb->ki_filp->f_flags & O_DIRECT))
153 ret = ext4_file_dio_write(iocb, iov, nr_segs, pos);
154 else
155 ret = generic_file_aio_write(iocb, iov, nr_segs, pos);
156
157 return ret;
158}
159
144static const struct vm_operations_struct ext4_file_vm_ops = { 160static const struct vm_operations_struct ext4_file_vm_ops = {
145 .fault = filemap_fault, 161 .fault = filemap_fault,
146 .page_mkwrite = ext4_page_mkwrite, 162 .page_mkwrite = ext4_page_mkwrite,