diff options
author | Theodore Ts'o <tytso@mit.edu> | 2014-04-21 14:26:57 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2014-04-21 14:26:57 -0400 |
commit | 8ad2850f44831919f63f0e58d7203e65d5b3914c (patch) | |
tree | 4d827818c9b5e206f41a8c15d141e54cf08a0020 /fs/ext4 | |
parent | 7608e61044e7636a2ca04ff33fa1ff9697d1df88 (diff) |
ext4: move ext4_file_dio_write() into ext4_file_write()
This commit doesn't actually change anything; it just moves code
around in preparation for some code simplification work.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Reviewed-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/file.c | 138 |
1 files changed, 64 insertions, 74 deletions
diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 79b77a51a322..20f1c03b6077 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c | |||
@@ -92,82 +92,15 @@ ext4_unaligned_aio(struct inode *inode, const struct iovec *iov, | |||
92 | } | 92 | } |
93 | 93 | ||
94 | static ssize_t | 94 | static ssize_t |
95 | ext4_file_dio_write(struct kiocb *iocb, const struct iovec *iov, | 95 | ext4_file_write(struct kiocb *iocb, const struct iovec *iov, |
96 | unsigned long nr_segs, loff_t pos) | 96 | unsigned long nr_segs, loff_t pos) |
97 | { | 97 | { |
98 | struct file *file = iocb->ki_filp; | 98 | struct file *file = iocb->ki_filp; |
99 | struct inode *inode = file->f_mapping->host; | 99 | struct inode *inode = file_inode(iocb->ki_filp); |
100 | struct blk_plug plug; | 100 | struct blk_plug plug; |
101 | int unaligned_aio = 0; | 101 | int unaligned_aio = 0; |
102 | ssize_t ret; | ||
103 | int overwrite = 0; | 102 | int overwrite = 0; |
104 | size_t length = iov_length(iov, nr_segs); | 103 | size_t length = iov_length(iov, nr_segs); |
105 | |||
106 | if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) && | ||
107 | !is_sync_kiocb(iocb)) | ||
108 | unaligned_aio = ext4_unaligned_aio(inode, iov, nr_segs, pos); | ||
109 | |||
110 | /* Unaligned direct AIO must be serialized; see comment above */ | ||
111 | if (unaligned_aio) { | ||
112 | mutex_lock(ext4_aio_mutex(inode)); | ||
113 | ext4_unwritten_wait(inode); | ||
114 | } | ||
115 | |||
116 | mutex_lock(&inode->i_mutex); | ||
117 | blk_start_plug(&plug); | ||
118 | |||
119 | iocb->private = &overwrite; | ||
120 | |||
121 | /* check whether we do a DIO overwrite or not */ | ||
122 | if (ext4_should_dioread_nolock(inode) && !unaligned_aio && | ||
123 | !file->f_mapping->nrpages && pos + length <= i_size_read(inode)) { | ||
124 | struct ext4_map_blocks map; | ||
125 | unsigned int blkbits = inode->i_blkbits; | ||
126 | int err, len; | ||
127 | |||
128 | map.m_lblk = pos >> blkbits; | ||
129 | map.m_len = (EXT4_BLOCK_ALIGN(pos + length, blkbits) >> blkbits) | ||
130 | - map.m_lblk; | ||
131 | len = map.m_len; | ||
132 | |||
133 | err = ext4_map_blocks(NULL, inode, &map, 0); | ||
134 | /* | ||
135 | * 'err==len' means that all of blocks has been preallocated no | ||
136 | * matter they are initialized or not. For excluding | ||
137 | * unwritten extents, we need to check m_flags. There are | ||
138 | * two conditions that indicate for initialized extents. | ||
139 | * 1) If we hit extent cache, EXT4_MAP_MAPPED flag is returned; | ||
140 | * 2) If we do a real lookup, non-flags are returned. | ||
141 | * So we should check these two conditions. | ||
142 | */ | ||
143 | if (err == len && (map.m_flags & EXT4_MAP_MAPPED)) | ||
144 | overwrite = 1; | ||
145 | } | ||
146 | |||
147 | ret = __generic_file_aio_write(iocb, iov, nr_segs); | ||
148 | mutex_unlock(&inode->i_mutex); | ||
149 | |||
150 | if (ret > 0) { | ||
151 | ssize_t err; | ||
152 | |||
153 | err = generic_write_sync(file, iocb->ki_pos - ret, ret); | ||
154 | if (err < 0) | ||
155 | ret = err; | ||
156 | } | ||
157 | blk_finish_plug(&plug); | ||
158 | |||
159 | if (unaligned_aio) | ||
160 | mutex_unlock(ext4_aio_mutex(inode)); | ||
161 | |||
162 | return ret; | ||
163 | } | ||
164 | |||
165 | static ssize_t | ||
166 | ext4_file_write(struct kiocb *iocb, const struct iovec *iov, | ||
167 | unsigned long nr_segs, loff_t pos) | ||
168 | { | ||
169 | struct file *file = iocb->ki_filp; | ||
170 | struct inode *inode = file_inode(iocb->ki_filp); | ||
171 | ssize_t ret; | 104 | ssize_t ret; |
172 | 105 | ||
173 | BUG_ON(iocb->ki_pos != pos); | 106 | BUG_ON(iocb->ki_pos != pos); |
@@ -179,7 +112,6 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov, | |||
179 | 112 | ||
180 | if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) { | 113 | if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) { |
181 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); | 114 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); |
182 | size_t length = iov_length(iov, nr_segs); | ||
183 | 115 | ||
184 | if ((pos > sbi->s_bitmap_maxbytes || | 116 | if ((pos > sbi->s_bitmap_maxbytes || |
185 | (pos == sbi->s_bitmap_maxbytes && length > 0))) | 117 | (pos == sbi->s_bitmap_maxbytes && length > 0))) |
@@ -191,9 +123,67 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov, | |||
191 | } | 123 | } |
192 | } | 124 | } |
193 | 125 | ||
194 | if (unlikely(iocb->ki_filp->f_flags & O_DIRECT)) | 126 | if (unlikely(iocb->ki_filp->f_flags & O_DIRECT)) { |
195 | ret = ext4_file_dio_write(iocb, iov, nr_segs, pos); | 127 | if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) && |
196 | else { | 128 | !is_sync_kiocb(iocb)) |
129 | unaligned_aio = ext4_unaligned_aio(inode, iov, | ||
130 | nr_segs, pos); | ||
131 | |||
132 | /* Unaligned direct AIO must be serialized; see comment above */ | ||
133 | if (unaligned_aio) { | ||
134 | mutex_lock(ext4_aio_mutex(inode)); | ||
135 | ext4_unwritten_wait(inode); | ||
136 | } | ||
137 | |||
138 | mutex_lock(&inode->i_mutex); | ||
139 | blk_start_plug(&plug); | ||
140 | |||
141 | iocb->private = &overwrite; | ||
142 | |||
143 | /* check whether we do a DIO overwrite or not */ | ||
144 | if (ext4_should_dioread_nolock(inode) && !unaligned_aio && | ||
145 | !file->f_mapping->nrpages && pos + length <= i_size_read(inode)) { | ||
146 | struct ext4_map_blocks map; | ||
147 | unsigned int blkbits = inode->i_blkbits; | ||
148 | int err, len; | ||
149 | |||
150 | map.m_lblk = pos >> blkbits; | ||
151 | map.m_len = (EXT4_BLOCK_ALIGN(pos + length, blkbits) >> blkbits) | ||
152 | - map.m_lblk; | ||
153 | len = map.m_len; | ||
154 | |||
155 | err = ext4_map_blocks(NULL, inode, &map, 0); | ||
156 | /* | ||
157 | * 'err==len' means that all of blocks has | ||
158 | * been preallocated no matter they are | ||
159 | * initialized or not. For excluding | ||
160 | * unwritten extents, we need to check | ||
161 | * m_flags. There are two conditions that | ||
162 | * indicate for initialized extents. 1) If we | ||
163 | * hit extent cache, EXT4_MAP_MAPPED flag is | ||
164 | * returned; 2) If we do a real lookup, | ||
165 | * non-flags are returned. So we should check | ||
166 | * these two conditions. | ||
167 | */ | ||
168 | if (err == len && (map.m_flags & EXT4_MAP_MAPPED)) | ||
169 | overwrite = 1; | ||
170 | } | ||
171 | |||
172 | ret = __generic_file_aio_write(iocb, iov, nr_segs); | ||
173 | mutex_unlock(&inode->i_mutex); | ||
174 | |||
175 | if (ret > 0) { | ||
176 | ssize_t err; | ||
177 | |||
178 | err = generic_write_sync(file, iocb->ki_pos - ret, ret); | ||
179 | if (err < 0) | ||
180 | ret = err; | ||
181 | } | ||
182 | blk_finish_plug(&plug); | ||
183 | |||
184 | if (unaligned_aio) | ||
185 | mutex_unlock(ext4_aio_mutex(inode)); | ||
186 | } else { | ||
197 | mutex_lock(&inode->i_mutex); | 187 | mutex_lock(&inode->i_mutex); |
198 | ret = __generic_file_aio_write(iocb, iov, nr_segs); | 188 | ret = __generic_file_aio_write(iocb, iov, nr_segs); |
199 | mutex_unlock(&inode->i_mutex); | 189 | mutex_unlock(&inode->i_mutex); |