aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target/target_core_file.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/target/target_core_file.c')
-rw-r--r--drivers/target/target_core_file.c117
1 files changed, 42 insertions, 75 deletions
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c
index a984964ab70a..bbcedcfc068a 100644
--- a/drivers/target/target_core_file.c
+++ b/drivers/target/target_core_file.c
@@ -244,53 +244,33 @@ static void fd_free_device(void *p)
244 kfree(fd_dev); 244 kfree(fd_dev);
245} 245}
246 246
247static inline struct fd_request *FILE_REQ(struct se_task *task) 247static int fd_do_readv(struct se_cmd *cmd, struct scatterlist *sgl,
248 u32 sgl_nents)
248{ 249{
249 return container_of(task, struct fd_request, fd_task); 250 struct se_device *se_dev = cmd->se_dev;
250}
251
252
253static struct se_task *
254fd_alloc_task(unsigned char *cdb)
255{
256 struct fd_request *fd_req;
257
258 fd_req = kzalloc(sizeof(struct fd_request), GFP_KERNEL);
259 if (!fd_req) {
260 pr_err("Unable to allocate struct fd_request\n");
261 return NULL;
262 }
263
264 return &fd_req->fd_task;
265}
266
267static int fd_do_readv(struct se_task *task)
268{
269 struct fd_request *req = FILE_REQ(task);
270 struct se_device *se_dev = req->fd_task.task_se_cmd->se_dev;
271 struct fd_dev *dev = se_dev->dev_ptr; 251 struct fd_dev *dev = se_dev->dev_ptr;
272 struct file *fd = dev->fd_file; 252 struct file *fd = dev->fd_file;
273 struct scatterlist *sg = task->task_sg; 253 struct scatterlist *sg;
274 struct iovec *iov; 254 struct iovec *iov;
275 mm_segment_t old_fs; 255 mm_segment_t old_fs;
276 loff_t pos = (task->task_se_cmd->t_task_lba * 256 loff_t pos = (cmd->t_task_lba *
277 se_dev->se_sub_dev->se_dev_attrib.block_size); 257 se_dev->se_sub_dev->se_dev_attrib.block_size);
278 int ret = 0, i; 258 int ret = 0, i;
279 259
280 iov = kzalloc(sizeof(struct iovec) * task->task_sg_nents, GFP_KERNEL); 260 iov = kzalloc(sizeof(struct iovec) * sgl_nents, GFP_KERNEL);
281 if (!iov) { 261 if (!iov) {
282 pr_err("Unable to allocate fd_do_readv iov[]\n"); 262 pr_err("Unable to allocate fd_do_readv iov[]\n");
283 return -ENOMEM; 263 return -ENOMEM;
284 } 264 }
285 265
286 for_each_sg(task->task_sg, sg, task->task_sg_nents, i) { 266 for_each_sg(sgl, sg, sgl_nents, i) {
287 iov[i].iov_len = sg->length; 267 iov[i].iov_len = sg->length;
288 iov[i].iov_base = sg_virt(sg); 268 iov[i].iov_base = sg_virt(sg);
289 } 269 }
290 270
291 old_fs = get_fs(); 271 old_fs = get_fs();
292 set_fs(get_ds()); 272 set_fs(get_ds());
293 ret = vfs_readv(fd, &iov[0], task->task_sg_nents, &pos); 273 ret = vfs_readv(fd, &iov[0], sgl_nents, &pos);
294 set_fs(old_fs); 274 set_fs(old_fs);
295 275
296 kfree(iov); 276 kfree(iov);
@@ -300,10 +280,10 @@ static int fd_do_readv(struct se_task *task)
300 * block_device. 280 * block_device.
301 */ 281 */
302 if (S_ISBLK(fd->f_dentry->d_inode->i_mode)) { 282 if (S_ISBLK(fd->f_dentry->d_inode->i_mode)) {
303 if (ret < 0 || ret != task->task_se_cmd->data_length) { 283 if (ret < 0 || ret != cmd->data_length) {
304 pr_err("vfs_readv() returned %d," 284 pr_err("vfs_readv() returned %d,"
305 " expecting %d for S_ISBLK\n", ret, 285 " expecting %d for S_ISBLK\n", ret,
306 (int)task->task_se_cmd->data_length); 286 (int)cmd->data_length);
307 return (ret < 0 ? ret : -EINVAL); 287 return (ret < 0 ? ret : -EINVAL);
308 } 288 }
309 } else { 289 } else {
@@ -317,38 +297,38 @@ static int fd_do_readv(struct se_task *task)
317 return 1; 297 return 1;
318} 298}
319 299
320static int fd_do_writev(struct se_task *task) 300static int fd_do_writev(struct se_cmd *cmd, struct scatterlist *sgl,
301 u32 sgl_nents)
321{ 302{
322 struct fd_request *req = FILE_REQ(task); 303 struct se_device *se_dev = cmd->se_dev;
323 struct se_device *se_dev = req->fd_task.task_se_cmd->se_dev;
324 struct fd_dev *dev = se_dev->dev_ptr; 304 struct fd_dev *dev = se_dev->dev_ptr;
325 struct file *fd = dev->fd_file; 305 struct file *fd = dev->fd_file;
326 struct scatterlist *sg = task->task_sg; 306 struct scatterlist *sg;
327 struct iovec *iov; 307 struct iovec *iov;
328 mm_segment_t old_fs; 308 mm_segment_t old_fs;
329 loff_t pos = (task->task_se_cmd->t_task_lba * 309 loff_t pos = (cmd->t_task_lba *
330 se_dev->se_sub_dev->se_dev_attrib.block_size); 310 se_dev->se_sub_dev->se_dev_attrib.block_size);
331 int ret, i = 0; 311 int ret, i = 0;
332 312
333 iov = kzalloc(sizeof(struct iovec) * task->task_sg_nents, GFP_KERNEL); 313 iov = kzalloc(sizeof(struct iovec) * sgl_nents, GFP_KERNEL);
334 if (!iov) { 314 if (!iov) {
335 pr_err("Unable to allocate fd_do_writev iov[]\n"); 315 pr_err("Unable to allocate fd_do_writev iov[]\n");
336 return -ENOMEM; 316 return -ENOMEM;
337 } 317 }
338 318
339 for_each_sg(task->task_sg, sg, task->task_sg_nents, i) { 319 for_each_sg(sgl, sg, sgl_nents, i) {
340 iov[i].iov_len = sg->length; 320 iov[i].iov_len = sg->length;
341 iov[i].iov_base = sg_virt(sg); 321 iov[i].iov_base = sg_virt(sg);
342 } 322 }
343 323
344 old_fs = get_fs(); 324 old_fs = get_fs();
345 set_fs(get_ds()); 325 set_fs(get_ds());
346 ret = vfs_writev(fd, &iov[0], task->task_sg_nents, &pos); 326 ret = vfs_writev(fd, &iov[0], sgl_nents, &pos);
347 set_fs(old_fs); 327 set_fs(old_fs);
348 328
349 kfree(iov); 329 kfree(iov);
350 330
351 if (ret < 0 || ret != task->task_se_cmd->data_length) { 331 if (ret < 0 || ret != cmd->data_length) {
352 pr_err("vfs_writev() returned %d\n", ret); 332 pr_err("vfs_writev() returned %d\n", ret);
353 return (ret < 0 ? ret : -EINVAL); 333 return (ret < 0 ? ret : -EINVAL);
354 } 334 }
@@ -369,7 +349,7 @@ static void fd_emulate_sync_cache(struct se_cmd *cmd)
369 * for this SYNCHRONIZE_CACHE op 349 * for this SYNCHRONIZE_CACHE op
370 */ 350 */
371 if (immed) 351 if (immed)
372 transport_complete_sync_cache(cmd, 1); 352 target_complete_cmd(cmd, SAM_STAT_GOOD);
373 353
374 /* 354 /*
375 * Determine if we will be flushing the entire device. 355 * Determine if we will be flushing the entire device.
@@ -389,35 +369,37 @@ static void fd_emulate_sync_cache(struct se_cmd *cmd)
389 if (ret != 0) 369 if (ret != 0)
390 pr_err("FILEIO: vfs_fsync_range() failed: %d\n", ret); 370 pr_err("FILEIO: vfs_fsync_range() failed: %d\n", ret);
391 371
392 if (!immed) 372 if (immed)
393 transport_complete_sync_cache(cmd, ret == 0); 373 return;
374
375 if (ret) {
376 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
377 target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION);
378 } else {
379 target_complete_cmd(cmd, SAM_STAT_GOOD);
380 }
394} 381}
395 382
396/* 383static void fd_emulate_write_fua(struct se_cmd *cmd)
397 * WRITE Force Unit Access (FUA) emulation on a per struct se_task
398 * LBA range basis..
399 */
400static void fd_emulate_write_fua(struct se_cmd *cmd, struct se_task *task)
401{ 384{
402 struct se_device *dev = cmd->se_dev; 385 struct se_device *dev = cmd->se_dev;
403 struct fd_dev *fd_dev = dev->dev_ptr; 386 struct fd_dev *fd_dev = dev->dev_ptr;
404 loff_t start = task->task_se_cmd->t_task_lba * 387 loff_t start = cmd->t_task_lba *
405 dev->se_sub_dev->se_dev_attrib.block_size; 388 dev->se_sub_dev->se_dev_attrib.block_size;
406 loff_t end = start + task->task_se_cmd->data_length; 389 loff_t end = start + cmd->data_length;
407 int ret; 390 int ret;
408 391
409 pr_debug("FILEIO: FUA WRITE LBA: %llu, bytes: %u\n", 392 pr_debug("FILEIO: FUA WRITE LBA: %llu, bytes: %u\n",
410 task->task_se_cmd->t_task_lba, 393 cmd->t_task_lba, cmd->data_length);
411 task->task_se_cmd->data_length);
412 394
413 ret = vfs_fsync_range(fd_dev->fd_file, start, end, 1); 395 ret = vfs_fsync_range(fd_dev->fd_file, start, end, 1);
414 if (ret != 0) 396 if (ret != 0)
415 pr_err("FILEIO: vfs_fsync_range() failed: %d\n", ret); 397 pr_err("FILEIO: vfs_fsync_range() failed: %d\n", ret);
416} 398}
417 399
418static int fd_do_task(struct se_task *task) 400static int fd_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl,
401 u32 sgl_nents, enum dma_data_direction data_direction)
419{ 402{
420 struct se_cmd *cmd = task->task_se_cmd;
421 struct se_device *dev = cmd->se_dev; 403 struct se_device *dev = cmd->se_dev;
422 int ret = 0; 404 int ret = 0;
423 405
@@ -425,10 +407,10 @@ static int fd_do_task(struct se_task *task)
425 * Call vectorized fileio functions to map struct scatterlist 407 * Call vectorized fileio functions to map struct scatterlist
426 * physical memory addresses to struct iovec virtual memory. 408 * physical memory addresses to struct iovec virtual memory.
427 */ 409 */
428 if (task->task_data_direction == DMA_FROM_DEVICE) { 410 if (data_direction == DMA_FROM_DEVICE) {
429 ret = fd_do_readv(task); 411 ret = fd_do_readv(cmd, sgl, sgl_nents);
430 } else { 412 } else {
431 ret = fd_do_writev(task); 413 ret = fd_do_writev(cmd, sgl, sgl_nents);
432 414
433 if (ret > 0 && 415 if (ret > 0 &&
434 dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0 && 416 dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0 &&
@@ -439,7 +421,7 @@ static int fd_do_task(struct se_task *task)
439 * and return some sense data to let the initiator 421 * and return some sense data to let the initiator
440 * know the FUA WRITE cache sync failed..? 422 * know the FUA WRITE cache sync failed..?
441 */ 423 */
442 fd_emulate_write_fua(cmd, task); 424 fd_emulate_write_fua(cmd);
443 } 425 }
444 426
445 } 427 }
@@ -448,24 +430,11 @@ static int fd_do_task(struct se_task *task)
448 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 430 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
449 return ret; 431 return ret;
450 } 432 }
451 if (ret) { 433 if (ret)
452 task->task_scsi_status = GOOD; 434 target_complete_cmd(cmd, SAM_STAT_GOOD);
453 transport_complete_task(task, 1);
454 }
455 return 0; 435 return 0;
456} 436}
457 437
458/* fd_free_task(): (Part of se_subsystem_api_t template)
459 *
460 *
461 */
462static void fd_free_task(struct se_task *task)
463{
464 struct fd_request *req = FILE_REQ(task);
465
466 kfree(req);
467}
468
469enum { 438enum {
470 Opt_fd_dev_name, Opt_fd_dev_size, Opt_fd_buffered_io, Opt_err 439 Opt_fd_dev_name, Opt_fd_dev_size, Opt_fd_buffered_io, Opt_err
471}; 440};
@@ -618,10 +587,8 @@ static struct se_subsystem_api fileio_template = {
618 .allocate_virtdevice = fd_allocate_virtdevice, 587 .allocate_virtdevice = fd_allocate_virtdevice,
619 .create_virtdevice = fd_create_virtdevice, 588 .create_virtdevice = fd_create_virtdevice,
620 .free_device = fd_free_device, 589 .free_device = fd_free_device,
621 .alloc_task = fd_alloc_task, 590 .execute_cmd = fd_execute_cmd,
622 .do_task = fd_do_task,
623 .do_sync_cache = fd_emulate_sync_cache, 591 .do_sync_cache = fd_emulate_sync_cache,
624 .free_task = fd_free_task,
625 .check_configfs_dev_params = fd_check_configfs_dev_params, 592 .check_configfs_dev_params = fd_check_configfs_dev_params,
626 .set_configfs_dev_params = fd_set_configfs_dev_params, 593 .set_configfs_dev_params = fd_set_configfs_dev_params,
627 .show_configfs_dev_params = fd_show_configfs_dev_params, 594 .show_configfs_dev_params = fd_show_configfs_dev_params,