diff options
author | Zheng Liu <wenqing.lz@taobao.com> | 2012-07-09 16:29:29 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2012-07-09 16:29:29 -0400 |
commit | fbe104942d3ff44f6802e8e4a3fbf267c1fb9ac4 (patch) | |
tree | 1022097e97679f5fc13fdef5fd5893cdfdd35dcf | |
parent | 62a1391ddd6fbe82fc02154dc760bcc5cbc9ef68 (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.c | 60 |
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 | ||
92 | static ssize_t | 92 | static ssize_t |
93 | ext4_file_write(struct kiocb *iocb, const struct iovec *iov, | 93 | ext4_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 | ||
126 | static ssize_t | ||
127 | ext4_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 | |||
144 | static const struct vm_operations_struct ext4_file_vm_ops = { | 160 | static 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, |