diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2012-12-05 16:09:45 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-12-05 16:09:45 -0500 |
commit | 778229af95977a4aca8656143d457401c2bb8f96 (patch) | |
tree | 7b739fabd330d5ac59150d43325a9b719d5630ec /drivers/target | |
parent | 40ff2c3b3da35dd3a00ac6722056a59b4b3f2caf (diff) |
target/file: merge fd_do_readv() and fd_do_writev()
Those two functions are almost identical so merge them. Noticed this
while fixing the highmem in both cases.
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/target_core_file.c | 92 |
1 files changed, 32 insertions, 60 deletions
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 1fc5825b3912..b9c88497e8f0 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c | |||
@@ -216,8 +216,8 @@ static void fd_free_device(struct se_device *dev) | |||
216 | kfree(fd_dev); | 216 | kfree(fd_dev); |
217 | } | 217 | } |
218 | 218 | ||
219 | static int fd_do_readv(struct se_cmd *cmd, struct scatterlist *sgl, | 219 | static int fd_do_rw(struct se_cmd *cmd, struct scatterlist *sgl, |
220 | u32 sgl_nents) | 220 | u32 sgl_nents, int is_write) |
221 | { | 221 | { |
222 | struct se_device *se_dev = cmd->se_dev; | 222 | struct se_device *se_dev = cmd->se_dev; |
223 | struct fd_dev *dev = FD_DEV(se_dev); | 223 | struct fd_dev *dev = FD_DEV(se_dev); |
@@ -241,73 +241,45 @@ static int fd_do_readv(struct se_cmd *cmd, struct scatterlist *sgl, | |||
241 | 241 | ||
242 | old_fs = get_fs(); | 242 | old_fs = get_fs(); |
243 | set_fs(get_ds()); | 243 | set_fs(get_ds()); |
244 | ret = vfs_readv(fd, &iov[0], sgl_nents, &pos); | 244 | |
245 | if (is_write) | ||
246 | ret = vfs_writev(fd, &iov[0], sgl_nents, &pos); | ||
247 | else | ||
248 | ret = vfs_readv(fd, &iov[0], sgl_nents, &pos); | ||
249 | |||
245 | set_fs(old_fs); | 250 | set_fs(old_fs); |
246 | 251 | ||
247 | for_each_sg(sgl, sg, sgl_nents, i) | 252 | for_each_sg(sgl, sg, sgl_nents, i) |
248 | kunmap(sg_page(sg)); | 253 | kunmap(sg_page(sg)); |
254 | |||
249 | kfree(iov); | 255 | kfree(iov); |
250 | /* | 256 | |
251 | * Return zeros and GOOD status even if the READ did not return | 257 | if (is_write) { |
252 | * the expected virt_size for struct file w/o a backing struct | ||
253 | * block_device. | ||
254 | */ | ||
255 | if (S_ISBLK(fd->f_dentry->d_inode->i_mode)) { | ||
256 | if (ret < 0 || ret != cmd->data_length) { | 258 | if (ret < 0 || ret != cmd->data_length) { |
257 | pr_err("vfs_readv() returned %d," | 259 | pr_err("%s() write returned %d\n", __func__, ret); |
258 | " expecting %d for S_ISBLK\n", ret, | ||
259 | (int)cmd->data_length); | ||
260 | return (ret < 0 ? ret : -EINVAL); | 260 | return (ret < 0 ? ret : -EINVAL); |
261 | } | 261 | } |
262 | } else { | 262 | } else { |
263 | if (ret < 0) { | 263 | /* |
264 | pr_err("vfs_readv() returned %d for non" | 264 | * Return zeros and GOOD status even if the READ did not return |
265 | " S_ISBLK\n", ret); | 265 | * the expected virt_size for struct file w/o a backing struct |
266 | return ret; | 266 | * block_device. |
267 | */ | ||
268 | if (S_ISBLK(fd->f_dentry->d_inode->i_mode)) { | ||
269 | if (ret < 0 || ret != cmd->data_length) { | ||
270 | pr_err("%s() returned %d, expecting %u for " | ||
271 | "S_ISBLK\n", __func__, ret, | ||
272 | cmd->data_length); | ||
273 | return (ret < 0 ? ret : -EINVAL); | ||
274 | } | ||
275 | } else { | ||
276 | if (ret < 0) { | ||
277 | pr_err("%s() returned %d for non S_ISBLK\n", | ||
278 | __func__, ret); | ||
279 | return ret; | ||
280 | } | ||
267 | } | 281 | } |
268 | } | 282 | } |
269 | |||
270 | return 1; | ||
271 | } | ||
272 | |||
273 | static int fd_do_writev(struct se_cmd *cmd, struct scatterlist *sgl, | ||
274 | u32 sgl_nents) | ||
275 | { | ||
276 | struct se_device *se_dev = cmd->se_dev; | ||
277 | struct fd_dev *dev = FD_DEV(se_dev); | ||
278 | struct file *fd = dev->fd_file; | ||
279 | struct scatterlist *sg; | ||
280 | struct iovec *iov; | ||
281 | mm_segment_t old_fs; | ||
282 | loff_t pos = (cmd->t_task_lba * se_dev->dev_attrib.block_size); | ||
283 | int ret, i = 0; | ||
284 | |||
285 | iov = kzalloc(sizeof(struct iovec) * sgl_nents, GFP_KERNEL); | ||
286 | if (!iov) { | ||
287 | pr_err("Unable to allocate fd_do_writev iov[]\n"); | ||
288 | return -ENOMEM; | ||
289 | } | ||
290 | |||
291 | for_each_sg(sgl, sg, sgl_nents, i) { | ||
292 | iov[i].iov_len = sg->length; | ||
293 | iov[i].iov_base = kmap(sg_page(sg)) + sg->offset; | ||
294 | } | ||
295 | |||
296 | old_fs = get_fs(); | ||
297 | set_fs(get_ds()); | ||
298 | ret = vfs_writev(fd, &iov[0], sgl_nents, &pos); | ||
299 | set_fs(old_fs); | ||
300 | |||
301 | for_each_sg(sgl, sg, sgl_nents, i) | ||
302 | kunmap(sg_page(sg)); | ||
303 | |||
304 | kfree(iov); | ||
305 | |||
306 | if (ret < 0 || ret != cmd->data_length) { | ||
307 | pr_err("vfs_writev() returned %d\n", ret); | ||
308 | return (ret < 0 ? ret : -EINVAL); | ||
309 | } | ||
310 | |||
311 | return 1; | 283 | return 1; |
312 | } | 284 | } |
313 | 285 | ||
@@ -370,9 +342,9 @@ fd_execute_rw(struct se_cmd *cmd) | |||
370 | * physical memory addresses to struct iovec virtual memory. | 342 | * physical memory addresses to struct iovec virtual memory. |
371 | */ | 343 | */ |
372 | if (data_direction == DMA_FROM_DEVICE) { | 344 | if (data_direction == DMA_FROM_DEVICE) { |
373 | ret = fd_do_readv(cmd, sgl, sgl_nents); | 345 | ret = fd_do_rw(cmd, sgl, sgl_nents, 0); |
374 | } else { | 346 | } else { |
375 | ret = fd_do_writev(cmd, sgl, sgl_nents); | 347 | ret = fd_do_rw(cmd, sgl, sgl_nents, 1); |
376 | /* | 348 | /* |
377 | * Perform implict vfs_fsync_range() for fd_do_writev() ops | 349 | * Perform implict vfs_fsync_range() for fd_do_writev() ops |
378 | * for SCSI WRITEs with Forced Unit Access (FUA) set. | 350 | * for SCSI WRITEs with Forced Unit Access (FUA) set. |