diff options
Diffstat (limited to 'drivers/target/target_core_file.c')
-rw-r--r-- | drivers/target/target_core_file.c | 117 |
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 | ||
247 | static inline struct fd_request *FILE_REQ(struct se_task *task) | 247 | static 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 | |||
253 | static struct se_task * | ||
254 | fd_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 | |||
267 | static 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 | ||
320 | static int fd_do_writev(struct se_task *task) | 300 | static 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 | /* | 383 | static 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 | */ | ||
400 | static 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 | ||
418 | static int fd_do_task(struct se_task *task) | 400 | static 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 | */ | ||
462 | static void fd_free_task(struct se_task *task) | ||
463 | { | ||
464 | struct fd_request *req = FILE_REQ(task); | ||
465 | |||
466 | kfree(req); | ||
467 | } | ||
468 | |||
469 | enum { | 438 | enum { |
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, |