aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2012-12-05 16:09:45 -0500
committerNicholas Bellinger <nab@linux-iscsi.org>2012-12-05 16:09:45 -0500
commit778229af95977a4aca8656143d457401c2bb8f96 (patch)
tree7b739fabd330d5ac59150d43325a9b719d5630ec /drivers/target
parent40ff2c3b3da35dd3a00ac6722056a59b4b3f2caf (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.c92
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
219static int fd_do_readv(struct se_cmd *cmd, struct scatterlist *sgl, 219static 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
273static 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.