4 * Copyright (C) 2004-2006 Vladislav Bolkhovitin <vst@vlnb.net>
7 * SCSI disk (type 0) and CDROM (type 5) dev handler using files
8 * on file systems (FILEIO)
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation, version 2
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
21 #include <asm/uaccess.h>
22 #include <linux/file.h>
24 #include <linux/string.h>
25 #include <linux/types.h>
26 #include <linux/unistd.h>
27 #include <linux/smp_lock.h>
28 #include <linux/spinlock.h>
29 #include <linux/init.h>
30 #include <linux/uio.h>
31 #include <linux/proc_fs.h>
32 #include <linux/list.h>
33 #include <linux/ctype.h>
34 #include <linux/writeback.h>
35 #include <asm/atomic.h>
37 #define LOG_PREFIX "dev_fileio"
38 #include "scst_debug.h"
40 #include "scst_dev_handler.h"
42 #include "scst_debug.c"
44 /* 8 byte ASCII Vendor of the FILE IO target */
45 #define SCST_FIO_VENDOR "SCST_FIO"
46 /* 4 byte ASCII Product Revision Level of the FILE IO target - left aligned */
47 #define SCST_FIO_REV " 095"
49 #define READ_CAP_LEN 8
50 #define READ_CAP16_LEN 32
54 #define INQ_BUF_SZ 128
58 #define MSENSE_BUF_SZ 256
59 #define DBD 0x08 /* disable block descriptor */
60 #define WP 0x80 /* write protect */
61 #define DPOFUA 0x10 /* DPOFUA bit */
62 #define WCE 0x04 /* write cache enable */
64 #define PF 0x10 /* page format */
65 #define SP 0x01 /* save pages */
66 #define PS 0x80 /* parameter saveable */
69 #define DEF_DISK_BLOCKSIZE 512
70 #define DEF_DISK_BLOCKSIZE_SHIFT 9
71 #define DEF_CDROM_BLOCKSIZE 2048
72 #define DEF_CDROM_BLOCKSIZE_SHIFT 11
73 #define DEF_SECTORS_PER 63
74 #define LEN_MEM (32 * 1024)
75 #define DISK_FILEIO_NAME "disk_fileio"
76 #define CDROM_FILEIO_NAME "cdrom_fileio"
78 #define FILEIO_PROC_HELP "help"
80 #if defined(DEBUG) || defined(TRACING)
81 unsigned long trace_flag = SCST_DEFAULT_DEV_LOG_FLAGS;
84 struct scst_fileio_dev {
88 loff_t file_size; /* in bytes */
89 unsigned int rd_only_flag:1;
90 unsigned int wt_flag:1;
91 unsigned int nv_cache:1;
92 unsigned int o_direct_flag:1;
93 unsigned int media_changed:1;
94 unsigned int prevent_allow_medium_removal:1;
95 unsigned int nullio:1;
96 unsigned int cdrom_empty:1;
98 char name[16+1]; /* Name of virtual device,
99 must be <= SCSI Model + 1 */
100 char *file_name; /* File name */
101 struct list_head fileio_dev_list_entry;
102 struct list_head ftgt_list;
103 struct semaphore ftgt_list_mutex;
106 struct scst_fileio_tgt_dev {
107 spinlock_t fdev_lock;
108 enum scst_cmd_queue_type last_write_cmd_queue_type;
113 struct list_head fdev_cmd_list;
114 wait_queue_head_t fdev_waitQ;
115 struct scst_fileio_dev *virt_dev;
116 atomic_t threads_count;
117 struct semaphore shutdown_mutex;
118 struct list_head ftgt_list_entry;
121 static int fileio_attach(struct scst_device *dev);
122 static void fileio_detach(struct scst_device *dev);
123 static int fileio_attach_tgt(struct scst_tgt_dev *tgt_dev);
124 static void fileio_detach_tgt(struct scst_tgt_dev *tgt_dev);
125 static int disk_fileio_parse(struct scst_cmd *, const struct scst_info_cdb *info_cdb);
126 static int disk_fileio_exec(struct scst_cmd *cmd);
127 static int cdrom_fileio_parse(struct scst_cmd *, const struct scst_info_cdb *info_cdb);
128 static int cdrom_fileio_exec(struct scst_cmd *cmd);
129 static void fileio_exec_read(struct scst_cmd *cmd, loff_t loff);
130 static void fileio_exec_write(struct scst_cmd *cmd, loff_t loff);
131 static void fileio_exec_verify(struct scst_cmd *cmd, loff_t loff);
132 static int fileio_task_mgmt_fn(struct scst_mgmt_cmd *mcmd,
133 struct scst_tgt_dev *tgt_dev);
134 static void fileio_exec_read_capacity(struct scst_cmd *cmd);
135 static void fileio_exec_read_capacity16(struct scst_cmd *cmd);
136 static void fileio_exec_inquiry(struct scst_cmd *cmd);
137 static void fileio_exec_mode_sense(struct scst_cmd *cmd);
138 static void fileio_exec_mode_select(struct scst_cmd *cmd);
139 static void fileio_exec_read_toc(struct scst_cmd *cmd);
140 static void fileio_exec_prevent_allow_medium_removal(struct scst_cmd *cmd);
141 static int fileio_fsync(struct scst_fileio_tgt_dev *ftgt_dev,
142 loff_t loff, loff_t len, struct scst_cmd *cmd);
143 static int disk_fileio_proc(char *buffer, char **start, off_t offset,
144 int length, int *eof, struct scst_dev_type *dev_type, int inout);
145 static int cdrom_fileio_proc(char *buffer, char **start, off_t offset,
146 int length, int *eof, struct scst_dev_type *dev_type, int inout);
147 static int fileio_proc_help_read(char *buffer, char **start,off_t offset,
148 int length, int *eof, void *data);
150 #define DISK_TYPE_FILEIO { \
151 name: DISK_FILEIO_NAME, \
155 dev_done_atomic: 1, \
156 attach: fileio_attach, \
157 detach: fileio_detach, \
158 attach_tgt: fileio_attach_tgt, \
159 detach_tgt: fileio_detach_tgt, \
160 parse: disk_fileio_parse, \
161 exec: disk_fileio_exec, \
162 task_mgmt_fn: fileio_task_mgmt_fn, \
163 proc_info: disk_fileio_proc, \
166 #define CDROM_TYPE_FILEIO { \
167 name: CDROM_FILEIO_NAME, \
171 dev_done_atomic: 1, \
172 attach: fileio_attach, \
173 detach: fileio_detach, \
174 attach_tgt: fileio_attach_tgt, \
175 detach_tgt: fileio_detach_tgt, \
176 parse: cdrom_fileio_parse, \
177 exec: cdrom_fileio_exec, \
178 task_mgmt_fn: fileio_task_mgmt_fn, \
179 proc_info: cdrom_fileio_proc, \
182 DECLARE_MUTEX(scst_fileio_mutex);
183 static LIST_HEAD(disk_fileio_dev_list);
184 static LIST_HEAD(cdrom_fileio_dev_list);
186 static struct scst_dev_type disk_devtype_fileio = DISK_TYPE_FILEIO;
187 static struct scst_dev_type cdrom_devtype_fileio = CDROM_TYPE_FILEIO;
189 static char *disk_fileio_proc_help_string =
190 "echo \"open|close NAME [FILE_NAME [BLOCK_SIZE] [WRITE_THROUGH "
191 "READ_ONLY O_DIRECT NULLIO NV_CACHE]]\" >/proc/scsi_tgt/"
192 DISK_FILEIO_NAME "/" DISK_FILEIO_NAME "\n";
194 static char *cdrom_fileio_proc_help_string =
195 "echo \"open|change|close NAME [FILE_NAME]\" "
196 ">/proc/scsi_tgt/" CDROM_FILEIO_NAME "/" CDROM_FILEIO_NAME "\n";
198 #define FILEIO_THREAD_FLAGS CLONE_KERNEL
200 /**************************************************************
201 * Function: fileio_open
205 * Returns : fd, use IS_ERR(fd) to get error status
208 *************************************************************/
209 static struct file *fileio_open(const struct scst_fileio_dev *virt_dev)
216 if (virt_dev->rd_only_flag)
217 open_flags |= O_RDONLY;
219 open_flags |= O_RDWR;
220 if (virt_dev->o_direct_flag)
221 open_flags |= O_DIRECT;
222 if (virt_dev->wt_flag)
223 open_flags |= O_SYNC;
224 TRACE_DBG("Opening file %s, flags 0x%x", virt_dev->file_name, open_flags);
225 fd = filp_open(virt_dev->file_name, O_LARGEFILE | open_flags, 0600);
231 /**************************************************************
232 * Function: fileio_attach
236 * Returns : 1 if attached, error code otherwise
239 *************************************************************/
240 static int fileio_attach(struct scst_device *dev)
246 struct scst_fileio_dev *virt_dev = NULL, *vv;
247 struct list_head *fileio_dev_list;
251 TRACE_DBG("virt_id %d (%s)", dev->virt_id, dev->virt_name);
253 if (dev->virt_id == 0) {
254 PRINT_ERROR_PR("%s", "Not a virtual device");
259 fileio_dev_list = (dev->handler->type == TYPE_DISK) ?
260 &disk_fileio_dev_list :
261 &cdrom_fileio_dev_list;
264 * scst_fileio_mutex must be already taken before
265 * scst_register_virtual_device()
267 list_for_each_entry(vv, fileio_dev_list, fileio_dev_list_entry)
269 if (strcmp(vv->name, dev->virt_name) == 0) {
275 if (virt_dev == NULL) {
276 PRINT_ERROR_PR("Device %s not found", dev->virt_name);
281 if (dev->handler->type == TYPE_ROM)
282 virt_dev->rd_only_flag = 1;
284 if (!virt_dev->cdrom_empty) {
285 fd = fileio_open(virt_dev);
288 PRINT_ERROR_PR("filp_open(%s) returned an error %d",
289 virt_dev->file_name, res);
293 if ((fd->f_op == NULL) || (fd->f_op->readv == NULL) ||
294 (fd->f_op->writev == NULL))
296 PRINT_ERROR_PR("%s", "Wrong f_op or FS doesn't have "
297 "required capabilities");
305 if (fd->f_op->llseek) {
306 err = fd->f_op->llseek(fd, 0, 2/*SEEK_END*/);
308 err = default_llseek(fd, 0, 2/*SEEK_END*/);
313 PRINT_ERROR_PR("llseek %s returned an error %d",
314 virt_dev->file_name, res);
317 virt_dev->file_size = err;
318 TRACE_DBG("size of file: %Ld", (uint64_t)err);
320 filp_close(fd, NULL);
322 virt_dev->file_size = 0;
324 if (dev->handler->type == TYPE_DISK) {
325 virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift;
327 virt_dev->block_size = DEF_CDROM_BLOCKSIZE;
328 virt_dev->block_shift = DEF_CDROM_BLOCKSIZE_SHIFT;
329 virt_dev->nblocks = virt_dev->file_size >> DEF_CDROM_BLOCKSIZE_SHIFT;
332 if (!virt_dev->cdrom_empty) {
333 PRINT_INFO_PR("Attached SCSI target virtual %s %s "
334 "(file=\"%s\", fs=%LdMB, bs=%d, nblocks=%Ld, cyln=%Ld%s)",
335 (dev->handler->type == TYPE_DISK) ? "disk" : "cdrom",
336 virt_dev->name, virt_dev->file_name,
337 virt_dev->file_size >> 20, virt_dev->block_size,
338 virt_dev->nblocks, virt_dev->nblocks/64/32,
339 virt_dev->nblocks < 64*32 ? " !WARNING! cyln less than 1" : "");
341 PRINT_INFO_PR("Attached empty SCSI target virtual cdrom %s",
345 dev->dh_priv = virt_dev;
352 filp_close(fd, NULL);
356 /************************************************************
357 * Function: fileio_detach
363 * Description: Called to detach this device type driver
364 ************************************************************/
365 static void fileio_detach(struct scst_device *dev)
367 struct scst_fileio_dev *virt_dev =
368 (struct scst_fileio_dev *)dev->dh_priv;
372 TRACE_DBG("virt_id %d", dev->virt_id);
374 PRINT_INFO_PR("Detached SCSI target virtual device %s (\"%s\")",
375 virt_dev->name, virt_dev->file_name);
377 /* virt_dev will be freed by the caller */
384 static inline int fileio_sync_queue_type(enum scst_cmd_queue_type qt)
387 case SCST_CMD_QUEUE_ORDERED:
388 case SCST_CMD_QUEUE_HEAD_OF_QUEUE:
395 static inline int fileio_need_pre_sync(enum scst_cmd_queue_type cwqt,
396 enum scst_cmd_queue_type lwqt)
398 if (fileio_sync_queue_type(cwqt))
399 if (!fileio_sync_queue_type(lwqt))
404 static void fileio_do_job(struct scst_cmd *cmd)
408 int opcode = cmd->cdb[0];
410 struct scst_device *dev = cmd->dev;
411 struct scst_fileio_dev *virt_dev =
412 (struct scst_fileio_dev *)dev->dh_priv;
417 if (unlikely(test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))) {
418 TRACE_MGMT_DBG("Flag ABORTED set for "
419 "cmd %p (tag %d), skipping", cmd, cmd->tag);
428 lba_start = (((cmd->cdb[1] & 0x1f) << (BYTE * 2)) +
429 (cmd->cdb[2] << (BYTE * 1)) +
430 (cmd->cdb[3] << (BYTE * 0)));
431 data_len = cmd->bufflen;
439 case WRITE_VERIFY_12:
441 lba_start = be32_to_cpu(*(u32 *)&cmd->cdb[2]);
442 data_len = cmd->bufflen;
444 case SYNCHRONIZE_CACHE:
445 lba_start = be32_to_cpu(*(u32 *)&cmd->cdb[2]);
446 data_len = ((cmd->cdb[7] << (BYTE * 1)) +
447 (cmd->cdb[8] << (BYTE * 0))) << virt_dev->block_shift;
449 data_len = virt_dev->file_size -
450 ((loff_t)lba_start << virt_dev->block_shift);
454 case WRITE_VERIFY_16:
456 lba_start = be64_to_cpu(*(u64*)&cmd->cdb[2]);
457 data_len = cmd->bufflen;
464 loff = (loff_t)lba_start << virt_dev->block_shift;
465 TRACE_DBG("cmd %p, lba_start %Ld, loff %Ld, data_len %Ld", cmd,
466 lba_start, (uint64_t)loff, (uint64_t)data_len);
467 if (unlikely(loff < 0) || unlikely(data_len < 0) ||
468 unlikely((loff + data_len) > virt_dev->file_size)) {
469 PRINT_INFO_PR("Access beyond the end of the device "
470 "(%lld of %lld, len %Ld)", (uint64_t)loff,
471 (uint64_t)virt_dev->file_size, (uint64_t)data_len);
472 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
473 scst_sense_block_out_range_error));
481 fua = (cmd->cdb[1] & 0x8) && !virt_dev->wt_flag;
482 if (cmd->cdb[1] & 0x8) {
483 TRACE(TRACE_SCSI, "FUA(%d): loff=%Ld, "
484 "data_len=%Ld", fua, (uint64_t)loff,
495 fileio_exec_read(cmd, loff);
501 if (likely(!virt_dev->rd_only_flag)) {
503 struct scst_fileio_tgt_dev *ftgt_dev =
504 (struct scst_fileio_tgt_dev*)
505 cmd->tgt_dev->dh_priv;
506 enum scst_cmd_queue_type last_queue_type =
507 ftgt_dev->last_write_cmd_queue_type;
508 ftgt_dev->last_write_cmd_queue_type = cmd->queue_type;
509 if (fileio_need_pre_sync(cmd->queue_type, last_queue_type) &&
510 !virt_dev->wt_flag) {
511 TRACE(TRACE_SCSI/*|TRACE_SPECIAL*/, "ORDERED "
512 "WRITE(%d): loff=%Ld, data_len=%Ld",
513 cmd->queue_type, (uint64_t)loff,
516 if (fileio_fsync(ftgt_dev, 0, 0, cmd) != 0)
519 fileio_exec_write(cmd, loff);
520 /* O_SYNC flag is used for wt_flag devices */
522 fileio_fsync(ftgt_dev, loff, data_len, cmd);
524 TRACE_DBG("%s", "Attempt to write to read-only device");
525 scst_set_cmd_error(cmd,
526 SCST_LOAD_SENSE(scst_sense_data_protect));
530 case WRITE_VERIFY_12:
531 case WRITE_VERIFY_16:
532 if (likely(!virt_dev->rd_only_flag)) {
534 struct scst_fileio_tgt_dev *ftgt_dev =
535 (struct scst_fileio_tgt_dev*)
536 cmd->tgt_dev->dh_priv;
537 enum scst_cmd_queue_type last_queue_type =
538 ftgt_dev->last_write_cmd_queue_type;
539 ftgt_dev->last_write_cmd_queue_type = cmd->queue_type;
540 if (fileio_need_pre_sync(cmd->queue_type, last_queue_type) &&
541 !virt_dev->wt_flag) {
542 TRACE(TRACE_SCSI/*|TRACE_SPECIAL*/, "ORDERED "
543 "WRITE_VERIFY(%d): loff=%Ld, data_len=%Ld",
544 cmd->queue_type, (uint64_t)loff,
547 if (fileio_fsync(ftgt_dev, 0, 0, cmd) != 0)
550 fileio_exec_write(cmd, loff);
551 /* O_SYNC flag is used for wt_flag devices */
552 if (cmd->status == 0)
553 fileio_exec_verify(cmd, loff);
555 fileio_fsync(ftgt_dev, loff, data_len, cmd);
557 TRACE_DBG("%s", "Attempt to write to read-only device");
558 scst_set_cmd_error(cmd,
559 SCST_LOAD_SENSE(scst_sense_data_protect));
562 case SYNCHRONIZE_CACHE:
564 int immed = cmd->cdb[1] & 0x2;
565 struct scst_fileio_tgt_dev *ftgt_dev =
566 (struct scst_fileio_tgt_dev*)
567 cmd->tgt_dev->dh_priv;
568 TRACE(TRACE_SCSI, "SYNCHRONIZE_CACHE: "
569 "loff=%Ld, data_len=%Ld, immed=%d", (uint64_t)loff,
570 (uint64_t)data_len, immed);
574 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
575 /* cmd is dead here */
576 fileio_fsync(ftgt_dev, loff, data_len, NULL);
577 /* ToDo: fileio_fsync() error processing */
581 fileio_fsync(ftgt_dev, loff, data_len, cmd);
589 fileio_exec_verify(cmd, loff);
593 fileio_exec_mode_sense(cmd);
597 fileio_exec_mode_select(cmd);
599 case ALLOW_MEDIUM_REMOVAL:
600 fileio_exec_prevent_allow_medium_removal(cmd);
603 fileio_exec_read_toc(cmd);
612 TRACE_DBG("Invalid opcode %d", opcode);
613 scst_set_cmd_error(cmd,
614 SCST_LOAD_SENSE(scst_sense_invalid_opcode));
621 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
628 static inline int test_cmd_list(struct scst_fileio_tgt_dev *ftgt_dev)
630 int res = !list_empty(&ftgt_dev->fdev_cmd_list) ||
631 unlikely(ftgt_dev->shutdown);
635 static int fileio_cmd_thread(void *arg)
637 struct scst_fileio_tgt_dev *ftgt_dev = (struct scst_fileio_tgt_dev*)arg;
641 daemonize("scst_fileio");
643 set_user_nice(current, 10);
644 current->flags |= PF_NOFREEZE;
646 spin_lock_bh(&ftgt_dev->fdev_lock);
649 struct scst_cmd *cmd;
650 init_waitqueue_entry(&wait, current);
652 if (!test_cmd_list(ftgt_dev)) {
653 add_wait_queue_exclusive(&ftgt_dev->fdev_waitQ, &wait);
655 set_current_state(TASK_INTERRUPTIBLE);
656 if (test_cmd_list(ftgt_dev))
658 spin_unlock_bh(&ftgt_dev->fdev_lock);
660 spin_lock_bh(&ftgt_dev->fdev_lock);
662 set_current_state(TASK_RUNNING);
663 remove_wait_queue(&ftgt_dev->fdev_waitQ, &wait);
666 while (!list_empty(&ftgt_dev->fdev_cmd_list)) {
667 cmd = list_entry(ftgt_dev->fdev_cmd_list.next,
668 typeof(*cmd), fileio_cmd_list_entry);
669 cmd->fileio_in_list = 0;
670 list_del(&cmd->fileio_cmd_list_entry);
671 spin_unlock_bh(&ftgt_dev->fdev_lock);
673 spin_lock_bh(&ftgt_dev->fdev_lock);
674 if (unlikely(ftgt_dev->shutdown))
678 if (unlikely(ftgt_dev->shutdown))
681 spin_unlock_bh(&ftgt_dev->fdev_lock);
683 if (atomic_dec_and_test(&ftgt_dev->threads_count)) {
684 smp_mb__after_atomic_dec();
685 TRACE_DBG("%s", "Releasing shutdown_mutex");
686 up(&ftgt_dev->shutdown_mutex);
693 static int fileio_attach_tgt(struct scst_tgt_dev *tgt_dev)
695 struct scst_fileio_dev *virt_dev =
696 (struct scst_fileio_dev *)tgt_dev->acg_dev->dev->dh_priv;
697 struct scst_fileio_tgt_dev *ftgt_dev;
702 ftgt_dev = kzalloc(sizeof(*ftgt_dev), GFP_KERNEL);
703 TRACE_MEM("kzalloc(GFP_KERNEL) for ftgt_dev (%zd): %p",
704 sizeof(*ftgt_dev), ftgt_dev);
705 if (ftgt_dev == NULL) {
706 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of per-session "
707 "virtual device failed");
712 spin_lock_init(&ftgt_dev->fdev_lock);
713 INIT_LIST_HEAD(&ftgt_dev->fdev_cmd_list);
714 init_waitqueue_head(&ftgt_dev->fdev_waitQ);
715 atomic_set(&ftgt_dev->threads_count, 0);
716 init_MUTEX_LOCKED(&ftgt_dev->shutdown_mutex);
717 ftgt_dev->virt_dev = virt_dev;
719 if (!virt_dev->cdrom_empty) {
720 ftgt_dev->fd = fileio_open(virt_dev);
721 if (IS_ERR(ftgt_dev->fd)) {
722 res = PTR_ERR(ftgt_dev->fd);
723 PRINT_ERROR_PR("filp_open(%s) returned an error %d",
724 virt_dev->file_name, res);
731 * Only ONE thread must be run here, otherwise the commands could
732 * be executed out of order !!
734 res = kernel_thread(fileio_cmd_thread, ftgt_dev, FILEIO_THREAD_FLAGS);
736 PRINT_ERROR_PR("kernel_thread() failed: %d", res);
740 atomic_inc(&ftgt_dev->threads_count);
742 tgt_dev->dh_priv = ftgt_dev;
744 down(&virt_dev->ftgt_list_mutex);
745 list_add_tail(&ftgt_dev->ftgt_list_entry,
746 &virt_dev->ftgt_list);
747 up(&virt_dev->ftgt_list_mutex);
755 filp_close(ftgt_dev->fd, NULL);
758 TRACE_MEM("kfree ftgt_dev: %p", ftgt_dev);
763 static void fileio_detach_tgt(struct scst_tgt_dev *tgt_dev)
765 struct scst_fileio_tgt_dev *ftgt_dev =
766 (struct scst_fileio_tgt_dev *)tgt_dev->dh_priv;
767 struct scst_fileio_dev *virt_dev =
768 (struct scst_fileio_dev *)tgt_dev->acg_dev->dev->dh_priv;
772 down(&virt_dev->ftgt_list_mutex);
773 list_del(&ftgt_dev->ftgt_list_entry);
774 up(&virt_dev->ftgt_list_mutex);
776 ftgt_dev->shutdown = 1;
777 wake_up_all(&ftgt_dev->fdev_waitQ);
778 down(&ftgt_dev->shutdown_mutex);
781 filp_close(ftgt_dev->fd, NULL);
783 if (ftgt_dev->iv != NULL) {
784 TRACE_MEM("kfree ftgt_dev->iv: %p", ftgt_dev->iv);
788 TRACE_MEM("kfree ftgt_dev: %p", ftgt_dev);
791 tgt_dev->dh_priv = NULL;
796 /********************************************************************
797 * Function: disk_fileio_parse
801 * Returns : The state of the command
803 * Description: This does the parsing of the command
805 * Note: Not all states are allowed on return
806 ********************************************************************/
807 static int disk_fileio_parse(struct scst_cmd *cmd,
808 const struct scst_info_cdb *info_cdb)
810 int res = SCST_CMD_STATE_DEFAULT;
812 struct scst_fileio_dev *virt_dev =
813 (struct scst_fileio_dev *)cmd->dev->dh_priv;
818 * SCST sets good defaults for cmd->data_direction and cmd->bufflen
819 * based on info_cdb, therefore change them only if necessary
822 TRACE_DBG("op_name <%s> direct %d flags %d transfer_len %d",
824 info_cdb->direction, info_cdb->flags, info_cdb->transfer_len);
826 fixed = info_cdb->flags & SCST_TRANSFER_LEN_TYPE_FIXED;
827 switch (cmd->cdb[0]) {
829 cmd->bufflen = READ_CAP_LEN;
830 cmd->data_direction = SCST_DATA_READ;
832 case SERVICE_ACTION_IN:
833 if ((cmd->cdb[1] & 0x1f) == SAI_READ_CAPACITY_16) {
834 cmd->bufflen = READ_CAP16_LEN;
835 cmd->data_direction = SCST_DATA_READ;
842 if ((cmd->cdb[1] & BYTCHK) == 0) {
844 info_cdb->transfer_len << virt_dev->block_shift;
846 cmd->data_direction = SCST_DATA_NONE;
858 * No need for locks here, since *_detach() can not be
859 * called, when there are existing commands.
861 cmd->bufflen = info_cdb->transfer_len << virt_dev->block_shift;
864 TRACE_DBG("res %d, bufflen %zd, data_len %zd, direct %d",
865 res, cmd->bufflen, cmd->data_len, cmd->data_direction);
871 static inline void fileio_queue_cmd(struct scst_cmd *cmd)
873 struct scst_fileio_tgt_dev *ftgt_dev =
874 (struct scst_fileio_tgt_dev *)cmd->tgt_dev->dh_priv;
875 spin_lock_bh(&ftgt_dev->fdev_lock);
876 TRACE_DBG("Pushing cmd %p to IO thread", cmd);
877 list_add_tail(&cmd->fileio_cmd_list_entry,
878 &ftgt_dev->fdev_cmd_list);
879 cmd->fileio_in_list = 1;
880 spin_unlock_bh(&ftgt_dev->fdev_lock);
881 wake_up(&ftgt_dev->fdev_waitQ);
885 /********************************************************************
886 * Function: disk_fileio_exec
890 * Returns : always SCST_EXEC_COMPLETED, real status is in error condition
894 ********************************************************************/
895 static int disk_fileio_exec(struct scst_cmd *cmd)
898 int opcode = cmd->cdb[0];
903 cmd->masked_status = 0;
905 cmd->host_status = DID_OK;
906 cmd->driver_status = 0;
910 * Only commands that unsensible to the execution order could be
911 * performed here, in place. Other ones must be passed to the
917 fileio_exec_inquiry(cmd);
920 fileio_exec_read_capacity(cmd);
922 case SERVICE_ACTION_IN:
923 if ((cmd->cdb[1] & 0x1f) == SAI_READ_CAPACITY_16)
924 fileio_exec_read_capacity16(cmd);
929 case WRITE_VERIFY_12:
930 case WRITE_VERIFY_16:
936 /* could move READ ONLY check up to here (currenlty in do_job()) */
946 case SYNCHRONIZE_CACHE:
956 fileio_queue_cmd(cmd);
959 case TEST_UNIT_READY:
964 TRACE_DBG("Invalid opcode 0x%02x", opcode);
965 scst_set_cmd_error(cmd,
966 SCST_LOAD_SENSE(scst_sense_invalid_opcode));
971 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
975 return SCST_EXEC_COMPLETED;
978 /********************************************************************
979 * Function: cdrom_fileio_parse
983 * Returns : The state of the command
985 * Description: This does the parsing of the command
987 * Note: Not all states are allowed on return
988 ********************************************************************/
989 static int cdrom_fileio_parse(struct scst_cmd *cmd,
990 const struct scst_info_cdb *info_cdb)
992 int res = SCST_CMD_STATE_DEFAULT;
994 struct scst_fileio_dev *virt_dev =
995 (struct scst_fileio_dev *)cmd->dev->dh_priv;
1000 * SCST sets good defaults for cmd->data_direction and cmd->bufflen
1001 * based on info_cdb, therefore change them only if necessary
1004 TRACE_DBG("op_name <%s> direct %d flags %d transfer_len %d",
1006 info_cdb->direction, info_cdb->flags, info_cdb->transfer_len);
1008 fixed = info_cdb->flags & SCST_TRANSFER_LEN_TYPE_FIXED;
1009 switch (cmd->cdb[0]) {
1011 cmd->bufflen = READ_CAP_LEN;
1012 cmd->data_direction = SCST_DATA_READ;
1018 if ((cmd->cdb[1] & BYTCHK) == 0) {
1020 info_cdb->transfer_len << virt_dev->block_shift;
1022 cmd->data_direction = SCST_DATA_NONE;
1034 * No need for locks here, since *_detach() can not be
1035 * called, when there are existing commands.
1037 cmd->bufflen = info_cdb->transfer_len << virt_dev->block_shift;
1040 TRACE_DBG("res %d, bufflen %zd, data_len %zd, direct %d",
1041 res, cmd->bufflen, cmd->data_len, cmd->data_direction);
1043 TRACE_EXIT_HRES(res);
1047 /********************************************************************
1048 * Function: cdrom_fileio_exec
1055 ********************************************************************/
1056 static int cdrom_fileio_exec(struct scst_cmd *cmd)
1059 int opcode = cmd->cdb[0];
1060 struct scst_fileio_dev *virt_dev =
1061 (struct scst_fileio_dev *)cmd->dev->dh_priv;
1066 cmd->masked_status = 0;
1067 cmd->msg_status = 0;
1068 cmd->host_status = DID_OK;
1069 cmd->driver_status = 0;
1071 if (virt_dev->cdrom_empty && (opcode != INQUIRY)) {
1072 TRACE_DBG("%s", "CDROM empty");
1073 scst_set_cmd_error(cmd,
1074 SCST_LOAD_SENSE(scst_sense_not_ready));
1079 * No protection is necessary, because media_changed set only
1080 * in suspended state and exec() is serialized
1082 if (virt_dev->media_changed && (cmd->cdb[0] != INQUIRY) &&
1083 (cmd->cdb[0] != REQUEST_SENSE) && (cmd->cdb[0] != REPORT_LUNS)) {
1084 virt_dev->media_changed = 0;
1085 TRACE_DBG("%s", "Reporting media changed");
1086 scst_set_cmd_error(cmd,
1087 SCST_LOAD_SENSE(scst_sense_medium_changed_UA));
1093 * Only commands that unsensible to the execution order could be
1094 * performed here, in place. Other ones must be passed to the
1101 fileio_exec_inquiry(cmd);
1104 fileio_exec_read_capacity(cmd);
1107 case WRITE_VERIFY_12:
1108 case WRITE_VERIFY_16:
1113 case MODE_SELECT_10:
1131 case ALLOW_MEDIUM_REMOVAL:
1133 fileio_queue_cmd(cmd);
1136 case TEST_UNIT_READY:
1140 TRACE_DBG("Invalid opcode 0x%02x", opcode);
1141 scst_set_cmd_error(cmd,
1142 SCST_LOAD_SENSE(scst_sense_invalid_opcode));
1148 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
1152 return SCST_EXEC_COMPLETED;
1155 static void fileio_exec_inquiry(struct scst_cmd *cmd)
1157 int32_t length, len, i;
1160 struct scst_fileio_dev *virt_dev =
1161 (struct scst_fileio_dev *)cmd->dev->dh_priv;
1163 /* ToDo: Performance Boost:
1164 * 1. remove kzalloc, buf
1165 * 2. do all checks before touching *address
1167 * 4. write directly to *address
1172 buf = kzalloc(INQ_BUF_SZ,
1173 scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL);
1179 length = scst_get_buf_first(cmd, &address);
1180 TRACE_DBG("length %d", length);
1181 if (unlikely(length <= 0)) {
1182 PRINT_ERROR_PR("scst_get_buf_first() failed: %d", length);
1183 scst_set_cmd_error(cmd,
1184 SCST_LOAD_SENSE(scst_sense_hardw_error));
1189 * ToDo: write through/back flags as well as read only one.
1190 * Also task queue size should be set on some value.
1193 if (cmd->cdb[1] & CMDDT) {
1194 TRACE_DBG("%s", "INQUIRY: CMDDT is unsupported");
1195 scst_set_cmd_error(cmd,
1196 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1200 memset(buf, 0, sizeof(buf));
1201 buf[0] = cmd->dev->handler->type; /* type dev */
1202 if (buf[0] == TYPE_ROM)
1203 buf[1] = 0x80; /* removable */
1205 if (cmd->cdb[1] & EVPD) {
1209 for (dev_id_num = 0, i = 0; i < strlen(virt_dev->name); i++) {
1210 dev_id_num += virt_dev->name[i];
1212 len = scnprintf(dev_id_str, 6, "%d", dev_id_num);
1213 TRACE_DBG("num %d, str <%s>, len %d",
1214 dev_id_num,dev_id_str, len);
1215 if (0 == cmd->cdb[2]) { /* supported vital product data pages */
1217 buf[4] = 0x0; /* this page */
1218 buf[5] = 0x80; /* unit serial number */
1219 buf[6] = 0x83; /* device identification */
1220 } else if (0x80 == cmd->cdb[2]) { /* unit serial number */
1223 memcpy(&buf[4], dev_id_str, len);
1224 } else if (0x83 == cmd->cdb[2]) { /* device identification */
1228 /* Two identification descriptors: */
1229 /* T10 vendor identifier field format (faked) */
1230 buf[num + 0] = 0x2; /* ASCII */
1233 memcpy(&buf[num + 4], SCST_FIO_VENDOR, 8);
1234 memset(&buf[num + 12], ' ', 16);
1235 i = strlen(virt_dev->name);
1236 i = i < 16 ? i : 16;
1237 memcpy(&buf[num + 12], virt_dev->name, len);
1238 memcpy(&buf[num + 28], dev_id_str, len);
1239 buf[num + 3] = 8 + 16 + len;
1240 num += buf[num + 3] + 4;
1241 /* NAA IEEE registered identifier (faked) */
1242 buf[num] = 0x1; /* binary */
1246 buf[num + 4] = 0x51; /* ieee company id=0x123456 (faked) */
1247 buf[num + 5] = 0x23;
1248 buf[num + 6] = 0x45;
1249 buf[num + 7] = 0x60;
1250 buf[num + 8] = (dev_id_num >> 24);
1251 buf[num + 9] = (dev_id_num >> 16) & 0xff;
1252 buf[num + 10] = (dev_id_num >> 8) & 0xff;
1253 buf[num + 11] = dev_id_num & 0xff;
1255 buf[3] = num + 12 - 4;
1257 TRACE_DBG("INQUIRY: Unsupported EVPD page %x",
1259 scst_set_cmd_error(cmd,
1260 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1264 if (cmd->cdb[2] != 0) {
1265 TRACE_DBG("INQUIRY: Unsupported page %x", cmd->cdb[2]);
1266 scst_set_cmd_error(cmd,
1267 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1271 buf[2] = 4; /* Device complies to this standard - SPC-2 */
1272 buf[3] = 2; /* data in format specified in this standard */
1273 buf[4] = 31; /* n - 4 = 35 - 4 = 31 for full 36 byte data */
1274 buf[6] = 0; buf[7] = 2; /* BQue = 0, CMDQUE = 1 commands queuing supported */
1276 /* 8 byte ASCII Vendor Identification of the target - left aligned */
1277 memcpy(&buf[8], SCST_FIO_VENDOR, 8);
1279 /* 16 byte ASCII Product Identification of the target - left aligned */
1280 memset(&buf[16], ' ', 16);
1281 len = strlen(virt_dev->name);
1282 len = len < 16 ? len : 16;
1283 memcpy(&buf[16], virt_dev->name, len);
1285 /* 4 byte ASCII Product Revision Level of the target - left aligned */
1286 memcpy(&buf[32], SCST_FIO_REV, 4);
1289 memcpy(address, buf, length < INQ_BUF_SZ ? length : INQ_BUF_SZ);
1292 scst_put_buf(cmd, address);
1303 * <<Following mode pages info copied from ST318451LW with some corrections>>
1308 static int fileio_err_recov_pg(unsigned char *p, int pcontrol,
1309 struct scst_fileio_dev *virt_dev)
1310 { /* Read-Write Error Recovery page for mode_sense */
1311 const unsigned char err_recov_pg[] = {0x1, 0xa, 0xc0, 11, 240, 0, 0, 0,
1314 memcpy(p, err_recov_pg, sizeof(err_recov_pg));
1316 memset(p + 2, 0, sizeof(err_recov_pg) - 2);
1317 return sizeof(err_recov_pg);
1320 static int fileio_disconnect_pg(unsigned char *p, int pcontrol,
1321 struct scst_fileio_dev *virt_dev)
1322 { /* Disconnect-Reconnect page for mode_sense */
1323 const unsigned char disconnect_pg[] = {0x2, 0xe, 128, 128, 0, 10, 0, 0,
1324 0, 0, 0, 0, 0, 0, 0, 0};
1326 memcpy(p, disconnect_pg, sizeof(disconnect_pg));
1328 memset(p + 2, 0, sizeof(disconnect_pg) - 2);
1329 return sizeof(disconnect_pg);
1332 static int fileio_format_pg(unsigned char *p, int pcontrol,
1333 struct scst_fileio_dev *virt_dev)
1334 { /* Format device page for mode_sense */
1335 const unsigned char format_pg[] = {0x3, 0x16, 0, 0, 0, 0, 0, 0,
1336 0, 0, 0, 0, 0, 0, 0, 0,
1337 0, 0, 0, 0, 0x40, 0, 0, 0};
1339 memcpy(p, format_pg, sizeof(format_pg));
1340 p[10] = (DEF_SECTORS_PER >> 8) & 0xff;
1341 p[11] = DEF_SECTORS_PER & 0xff;
1342 p[12] = (virt_dev->block_size >> 8) & 0xff;
1343 p[13] = virt_dev->block_size & 0xff;
1345 memset(p + 2, 0, sizeof(format_pg) - 2);
1346 return sizeof(format_pg);
1349 static int fileio_caching_pg(unsigned char *p, int pcontrol,
1350 struct scst_fileio_dev *virt_dev)
1351 { /* Caching page for mode_sense */
1352 const unsigned char caching_pg[] = {0x8, 18, 0x10, 0, 0xff, 0xff, 0, 0,
1353 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0, 0, 0, 0, 0};
1355 memcpy(p, caching_pg, sizeof(caching_pg));
1356 p[2] |= !(virt_dev->wt_flag) ? WCE : 0;
1358 memset(p + 2, 0, sizeof(caching_pg) - 2);
1359 return sizeof(caching_pg);
1362 static int fileio_ctrl_m_pg(unsigned char *p, int pcontrol,
1363 struct scst_fileio_dev *virt_dev)
1364 { /* Control mode page for mode_sense */
1365 const unsigned char ctrl_m_pg[] = {0xa, 0xa, 0x22, 0, 0, 0x40, 0, 0,
1368 memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg));
1369 if (!virt_dev->wt_flag)
1370 p[3] |= 0x10; /* Enable unrestricted reordering */
1372 memset(p + 2, 0, sizeof(ctrl_m_pg) - 2);
1373 return sizeof(ctrl_m_pg);
1376 static int fileio_iec_m_pg(unsigned char *p, int pcontrol,
1377 struct scst_fileio_dev *virt_dev)
1378 { /* Informational Exceptions control mode page for mode_sense */
1379 const unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0,
1381 memcpy(p, iec_m_pg, sizeof(iec_m_pg));
1383 memset(p + 2, 0, sizeof(iec_m_pg) - 2);
1384 return sizeof(iec_m_pg);
1387 static void fileio_exec_mode_sense(struct scst_cmd *cmd)
1392 struct scst_fileio_dev *virt_dev;
1395 unsigned char dbd, type;
1396 int pcontrol, pcode, subpcode;
1397 unsigned char dev_spec;
1398 int msense_6, offset, len;
1403 buf = kzalloc(MSENSE_BUF_SZ,
1404 scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL);
1410 virt_dev = (struct scst_fileio_dev *)cmd->dev->dh_priv;
1411 blocksize = virt_dev->block_size;
1412 nblocks = virt_dev->nblocks;
1414 type = cmd->dev->handler->type; /* type dev */
1415 dbd = cmd->cdb[1] & DBD;
1416 pcontrol = (cmd->cdb[2] & 0xc0) >> 6;
1417 pcode = cmd->cdb[2] & 0x3f;
1418 subpcode = cmd->cdb[3];
1419 msense_6 = (MODE_SENSE == cmd->cdb[0]);
1420 dev_spec = (virt_dev->rd_only_flag ? WP : 0) | DPOFUA;
1422 length = scst_get_buf_first(cmd, &address);
1423 if (unlikely(length <= 0)) {
1424 PRINT_ERROR_PR("scst_get_buf_first() failed: %d", length);
1425 scst_set_cmd_error(cmd,
1426 SCST_LOAD_SENSE(scst_sense_hardw_error));
1430 memset(buf, 0, sizeof(buf));
1432 if (0x3 == pcontrol) {
1433 TRACE_DBG("%s", "MODE SENSE: Saving values not supported");
1434 scst_set_cmd_error(cmd,
1435 SCST_LOAD_SENSE(scst_sense_saving_params_unsup));
1449 if (0 != subpcode) { /* TODO: Control Extension page */
1450 TRACE_DBG("%s", "MODE SENSE: Only subpage 0 is supported");
1451 scst_set_cmd_error(cmd,
1452 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1457 /* Create block descriptor */
1458 buf[offset - 1] = 0x08; /* block descriptor length */
1459 if (nblocks >> 32) {
1460 buf[offset + 0] = 0xFF;
1461 buf[offset + 1] = 0xFF;
1462 buf[offset + 2] = 0xFF;
1463 buf[offset + 3] = 0xFF;
1465 buf[offset + 0] = (nblocks >> (BYTE * 3)) & 0xFF;/* num blks */
1466 buf[offset + 1] = (nblocks >> (BYTE * 2)) & 0xFF;
1467 buf[offset + 2] = (nblocks >> (BYTE * 1)) & 0xFF;
1468 buf[offset + 3] = (nblocks >> (BYTE * 0)) & 0xFF;
1470 buf[offset + 4] = 0; /* density code */
1471 buf[offset + 5] = (blocksize >> (BYTE * 2)) & 0xFF;/* blklen */
1472 buf[offset + 6] = (blocksize >> (BYTE * 1)) & 0xFF;
1473 buf[offset + 7] = (blocksize >> (BYTE * 0)) & 0xFF;
1475 offset += 8; /* increment offset */
1481 case 0x1: /* Read-Write error recovery page, direct access */
1482 len = fileio_err_recov_pg(bp, pcontrol, virt_dev);
1485 case 0x2: /* Disconnect-Reconnect page, all devices */
1486 len = fileio_disconnect_pg(bp, pcontrol, virt_dev);
1489 case 0x3: /* Format device page, direct access */
1490 len = fileio_format_pg(bp, pcontrol, virt_dev);
1493 case 0x8: /* Caching page, direct access */
1494 len = fileio_caching_pg(bp, pcontrol, virt_dev);
1497 case 0xa: /* Control Mode page, all devices */
1498 len = fileio_ctrl_m_pg(bp, pcontrol, virt_dev);
1501 case 0x1c: /* Informational Exceptions Mode page, all devices */
1502 len = fileio_iec_m_pg(bp, pcontrol, virt_dev);
1505 case 0x3f: /* Read all Mode pages */
1506 len = fileio_err_recov_pg(bp, pcontrol, virt_dev);
1507 len += fileio_disconnect_pg(bp + len, pcontrol, virt_dev);
1508 len += fileio_format_pg(bp + len, pcontrol, virt_dev);
1509 len += fileio_caching_pg(bp + len, pcontrol, virt_dev);
1510 len += fileio_ctrl_m_pg(bp + len, pcontrol, virt_dev);
1511 len += fileio_iec_m_pg(bp + len, pcontrol, virt_dev);
1515 TRACE_DBG("MODE SENSE: Unsupported page %x", pcode);
1516 scst_set_cmd_error(cmd,
1517 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1521 buf[0] = offset - 1;
1523 buf[0] = ((offset - 2) >> 8) & 0xff;
1524 buf[1] = (offset - 2) & 0xff;
1527 memcpy(address, buf, min(length, offset));
1530 scst_put_buf(cmd, address);
1540 static int fileio_set_wt(struct scst_fileio_dev *virt_dev, int wt)
1543 struct scst_fileio_tgt_dev *ftgt_dev;
1548 if (virt_dev->wt_flag == wt)
1551 virt_dev->wt_flag = wt;
1553 scst_suspend_activity();
1555 down(&virt_dev->ftgt_list_mutex);
1556 list_for_each_entry(ftgt_dev, &virt_dev->ftgt_list,
1559 fd = fileio_open(virt_dev);
1562 PRINT_ERROR_PR("filp_open(%s) returned an error %d, "
1563 "unable to change the cache mode",
1564 virt_dev->file_name, res);
1565 up(&virt_dev->ftgt_list_mutex);
1566 res = 0; /* ?? ToDo */
1570 filp_close(ftgt_dev->fd, NULL);
1573 up(&virt_dev->ftgt_list_mutex);
1576 scst_resume_activity();
1579 TRACE_EXIT_RES(res);
1583 static void fileio_exec_mode_select(struct scst_cmd *cmd)
1587 struct scst_fileio_dev *virt_dev;
1588 int mselect_6, offset;
1592 virt_dev = (struct scst_fileio_dev *)cmd->dev->dh_priv;
1593 mselect_6 = (MODE_SELECT == cmd->cdb[0]);
1595 length = scst_get_buf_first(cmd, &address);
1596 if (unlikely(length <= 0)) {
1597 PRINT_ERROR_PR("scst_get_buf_first() failed: %d", length);
1598 scst_set_cmd_error(cmd,
1599 SCST_LOAD_SENSE(scst_sense_hardw_error));
1603 if (!(cmd->cdb[1] & PF) || (cmd->cdb[1] & SP)) {
1604 PRINT_ERROR_PR("MODE SELECT: PF and/or SP are wrongly set "
1605 "(cdb[1]=%x)", cmd->cdb[1]);
1606 scst_set_cmd_error(cmd,
1607 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1617 if (address[offset - 1] == 8) {
1619 } else if (address[offset - 1] != 0) {
1620 PRINT_ERROR_PR("%s", "MODE SELECT: Wrong parameters list "
1622 scst_set_cmd_error(cmd,
1623 SCST_LOAD_SENSE(scst_sense_invalid_field_in_parm_list));
1627 while (length > offset + 2) {
1628 if (address[offset] & PS) {
1629 PRINT_ERROR_PR("%s", "MODE SELECT: Illegal PS bit");
1630 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1631 scst_sense_invalid_field_in_parm_list));
1634 if ((address[offset] & 0x3f) == 0x8) { /* Caching page */
1635 if (address[offset + 1] != 18) {
1636 PRINT_ERROR_PR("%s", "MODE SELECT: Invalid "
1637 "caching page request");
1638 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1639 scst_sense_invalid_field_in_parm_list));
1642 if (fileio_set_wt(virt_dev,
1643 (address[offset + 2] & WCE) ? 0 : 1) != 0) {
1644 scst_set_cmd_error(cmd,
1645 SCST_LOAD_SENSE(scst_sense_hardw_error));
1650 offset += address[offset + 1];
1654 scst_put_buf(cmd, address);
1661 static void fileio_exec_read_capacity(struct scst_cmd *cmd)
1665 struct scst_fileio_dev *virt_dev;
1668 uint8_t buffer[READ_CAP_LEN];
1672 virt_dev = (struct scst_fileio_dev *)cmd->dev->dh_priv;
1673 blocksize = virt_dev->block_size;
1674 nblocks = virt_dev->nblocks;
1676 /* last block on the virt_dev is (nblocks-1) */
1677 memset(buffer, 0, sizeof(buffer));
1678 if (nblocks >> 32) {
1684 buffer[0] = ((nblocks - 1) >> (BYTE * 3)) & 0xFF;
1685 buffer[1] = ((nblocks - 1) >> (BYTE * 2)) & 0xFF;
1686 buffer[2] = ((nblocks - 1) >> (BYTE * 1)) & 0xFF;
1687 buffer[3] = ((nblocks - 1) >> (BYTE * 0)) & 0xFF;
1689 buffer[4] = (blocksize >> (BYTE * 3)) & 0xFF;
1690 buffer[5] = (blocksize >> (BYTE * 2)) & 0xFF;
1691 buffer[6] = (blocksize >> (BYTE * 1)) & 0xFF;
1692 buffer[7] = (blocksize >> (BYTE * 0)) & 0xFF;
1694 length = scst_get_buf_first(cmd, &address);
1695 if (unlikely(length <= 0)) {
1696 PRINT_ERROR_PR("scst_get_buf_first() failed: %d", length);
1697 scst_set_cmd_error(cmd,
1698 SCST_LOAD_SENSE(scst_sense_hardw_error));
1702 memcpy(address, buffer, length < READ_CAP_LEN ? length : READ_CAP_LEN);
1704 scst_put_buf(cmd, address);
1711 static void fileio_exec_read_capacity16(struct scst_cmd *cmd)
1715 struct scst_fileio_dev *virt_dev;
1718 uint8_t buffer[READ_CAP16_LEN];
1723 virt_dev = (struct scst_fileio_dev *)cmd->dev->dh_priv;
1724 blocksize = virt_dev->block_size;
1725 nblocks = virt_dev->nblocks;
1727 memset(buffer, 0, sizeof(buffer));
1728 data64 = (uint64_t*)buffer;
1729 data64[0] = cpu_to_be64(nblocks - 1);
1730 buffer[8] = (blocksize >> (BYTE * 3)) & 0xFF;
1731 buffer[9] = (blocksize >> (BYTE * 2)) & 0xFF;
1732 buffer[10] = (blocksize >> (BYTE * 1)) & 0xFF;
1733 buffer[11] = (blocksize >> (BYTE * 0)) & 0xFF;
1735 length = scst_get_buf_first(cmd, &address);
1736 if (unlikely(length <= 0)) {
1737 PRINT_ERROR_PR("scst_get_buf_first() failed: %d", length);
1738 scst_set_cmd_error(cmd,
1739 SCST_LOAD_SENSE(scst_sense_hardw_error));
1743 memcpy(address, buffer, length < READ_CAP16_LEN ?
1744 length : READ_CAP16_LEN);
1746 scst_put_buf(cmd, address);
1753 static void fileio_exec_read_toc(struct scst_cmd *cmd)
1755 int32_t length, off = 0;
1757 struct scst_fileio_dev *virt_dev;
1759 uint8_t buffer[4+8+8] = { 0x00, 0x0a, 0x01, 0x01, 0x00, 0x14,
1760 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
1764 if (cmd->dev->handler->type != TYPE_ROM) {
1765 PRINT_ERROR_PR("%s", "READ TOC for non-CDROM device");
1766 scst_set_cmd_error(cmd,
1767 SCST_LOAD_SENSE(scst_sense_invalid_opcode));
1771 if (cmd->cdb[2] & 0x0e/*Format*/) {
1772 PRINT_ERROR_PR("%s", "READ TOC: invalid requested data format");
1773 scst_set_cmd_error(cmd,
1774 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1778 if ((cmd->cdb[6] != 0 && (cmd->cdb[2] & 0x01)) ||
1779 (cmd->cdb[6] > 1 && cmd->cdb[6] != 0xAA)) {
1780 PRINT_ERROR_PR("READ TOC: invalid requested track number %x",
1782 scst_set_cmd_error(cmd,
1783 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1787 length = scst_get_buf_first(cmd, &address);
1788 if (unlikely(length <= 0)) {
1789 PRINT_ERROR_PR("scst_get_buf_first() failed: %d", length);
1790 scst_set_cmd_error(cmd,
1791 SCST_LOAD_SENSE(scst_sense_hardw_error));
1795 virt_dev = (struct scst_fileio_dev *)cmd->dev->dh_priv;
1796 /* FIXME when you have > 8TB ROM device. */
1797 nblocks = (uint32_t)virt_dev->nblocks;
1800 memset(buffer, 0, sizeof(buffer));
1801 buffer[2] = 0x01; /* First Track/Session */
1802 buffer[3] = 0x01; /* Last Track/Session */
1804 if (cmd->cdb[6] <= 1)
1806 /* Fistr TOC Track Descriptor */
1807 buffer[off+1] = 0x14; /* ADDR 0x10 - Q Sub-channel encodes current position data
1808 CONTROL 0x04 - Data track, recoreded uninterrupted */
1809 buffer[off+2] = 0x01; /* Track Number */
1812 if (!(cmd->cdb[2] & 0x01))
1814 /* Lead-out area TOC Track Descriptor */
1815 buffer[off+1] = 0x14;
1816 buffer[off+2] = 0xAA; /* Track Number */
1817 buffer[off+4] = (nblocks >> (BYTE * 3)) & 0xFF; /* Track Start Address */
1818 buffer[off+5] = (nblocks >> (BYTE * 2)) & 0xFF;
1819 buffer[off+6] = (nblocks >> (BYTE * 1)) & 0xFF;
1820 buffer[off+7] = (nblocks >> (BYTE * 0)) & 0xFF;
1824 buffer[1] = off - 2; /* Data Length */
1826 memcpy(address, buffer, (length < off) ? length : off);
1828 scst_put_buf(cmd, address);
1835 static void fileio_exec_prevent_allow_medium_removal(struct scst_cmd *cmd)
1837 struct scst_fileio_dev *virt_dev =
1838 (struct scst_fileio_dev *)cmd->dev->dh_priv;
1840 TRACE_DBG("PERSIST/PREVENT 0x%02x", cmd->cdb[4]);
1843 * No protection here, because in cdrom_fileio_change() the
1844 * activity is suspended and exec() is serialized
1846 if (cmd->dev->handler->type == TYPE_ROM)
1847 virt_dev->prevent_allow_medium_removal =
1848 cmd->cdb[4] & 0x01 ? 1 : 0;
1850 PRINT_ERROR_PR("%s", "Prevent allow medium removal for "
1851 "non-CDROM device");
1852 scst_set_cmd_error(cmd,
1853 SCST_LOAD_SENSE(scst_sense_invalid_opcode));
1859 static int fileio_fsync(struct scst_fileio_tgt_dev *ftgt_dev,
1860 loff_t loff, loff_t len, struct scst_cmd *cmd)
1863 struct file *file = ftgt_dev->fd;
1864 struct inode *inode = file->f_dentry->d_inode;
1865 struct address_space *mapping = file->f_mapping;
1869 if (ftgt_dev->virt_dev->nv_cache)
1872 res = sync_page_range(inode, mapping, loff, len);
1873 if (unlikely(res != 0)) {
1874 PRINT_ERROR_PR("sync_page_range() failed (%d)", res);
1876 scst_set_cmd_error(cmd,
1877 SCST_LOAD_SENSE(scst_sense_write_error));
1881 /* ToDo: flush the device cache, if needed */
1884 TRACE_EXIT_RES(res);
1888 static struct iovec *fileio_alloc_iv(struct scst_cmd *cmd,
1889 struct scst_fileio_tgt_dev *ftgt_dev)
1893 iv_count = scst_get_buf_count(cmd);
1894 if (iv_count > ftgt_dev->iv_count) {
1895 if (ftgt_dev->iv != NULL) {
1896 TRACE_MEM("kfree ftgt_dev->iv: %p", ftgt_dev->iv);
1897 kfree(ftgt_dev->iv);
1899 ftgt_dev->iv = kmalloc(sizeof(*ftgt_dev->iv) * iv_count, GFP_KERNEL);
1900 TRACE_MEM("kmalloc(GFP_KERNEL) for iv (%zd): %p",
1901 sizeof(*ftgt_dev->iv) * iv_count, ftgt_dev->iv);
1902 if (ftgt_dev->iv == NULL) {
1903 PRINT_ERROR_PR("Unable to allocate iv (%d)", iv_count);
1907 ftgt_dev->iv_count = iv_count;
1911 return ftgt_dev->iv;
1914 static void fileio_exec_read(struct scst_cmd *cmd, loff_t loff)
1916 mm_segment_t old_fs;
1918 ssize_t length, full_len;
1920 struct scst_fileio_dev *virt_dev =
1921 (struct scst_fileio_dev *)cmd->dev->dh_priv;
1922 struct scst_fileio_tgt_dev *ftgt_dev =
1923 (struct scst_fileio_tgt_dev *)cmd->tgt_dev->dh_priv;
1924 struct file *fd = ftgt_dev->fd;
1930 iv = fileio_alloc_iv(cmd, ftgt_dev);
1937 length = scst_get_buf_first(cmd, &address);
1938 while (length > 0) {
1942 iv[i].iov_base = address;
1943 iv[i].iov_len = length;
1944 length = scst_get_buf_next(cmd, &address);
1946 if (unlikely(length < 0)) {
1947 PRINT_ERROR_PR("scst_get_buf_() failed: %zd", length);
1948 scst_set_cmd_error(cmd,
1949 SCST_LOAD_SENSE(scst_sense_hardw_error));
1957 if (fd->f_op->llseek) {
1958 err = fd->f_op->llseek(fd, loff, 0/*SEEK_SET*/);
1960 err = default_llseek(fd, loff, 0/*SEEK_SET*/);
1963 PRINT_ERROR_PR("lseek trouble %Ld != %Ld", (uint64_t)err,
1965 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
1970 TRACE_DBG("reading(iv_count %d, full_len %zd)", iv_count, full_len);
1971 if (virt_dev->nullio)
1974 err = fd->f_op->readv(fd, iv, iv_count, &fd->f_pos);
1975 if ((err < 0) || (err < full_len)) {
1976 PRINT_ERROR_PR("readv() returned %Ld from %zd", (uint64_t)err,
1981 scst_set_cmd_error(cmd,
1982 SCST_LOAD_SENSE(scst_sense_read_error));
1992 scst_put_buf(cmd, iv[i].iov_base);
1999 static void fileio_exec_write(struct scst_cmd *cmd, loff_t loff)
2001 mm_segment_t old_fs;
2003 ssize_t length, full_len;
2005 struct scst_fileio_dev *virt_dev =
2006 (struct scst_fileio_dev *)cmd->dev->dh_priv;
2007 struct scst_fileio_tgt_dev *ftgt_dev =
2008 (struct scst_fileio_tgt_dev *)cmd->tgt_dev->dh_priv;
2009 struct file *fd = ftgt_dev->fd;
2010 struct iovec *iv, *eiv;
2011 int iv_count, eiv_count;
2015 iv = fileio_alloc_iv(cmd, ftgt_dev);
2021 length = scst_get_buf_first(cmd, &address);
2022 while (length > 0) {
2024 iv[iv_count].iov_base = address;
2025 iv[iv_count].iov_len = length;
2027 length = scst_get_buf_next(cmd, &address);
2029 if (unlikely(length < 0)) {
2030 PRINT_ERROR_PR("scst_get_buf_() failed: %zd", length);
2031 scst_set_cmd_error(cmd,
2032 SCST_LOAD_SENSE(scst_sense_hardw_error));
2040 if (fd->f_op->llseek) {
2041 err = fd->f_op->llseek(fd, loff, 0 /*SEEK_SET */ );
2043 err = default_llseek(fd, loff, 0 /*SEEK_SET */ );
2046 PRINT_ERROR_PR("lseek trouble %Ld != %Ld", (uint64_t)err,
2048 scst_set_cmd_error(cmd,
2049 SCST_LOAD_SENSE(scst_sense_hardw_error));
2055 eiv_count = iv_count;
2057 TRACE_DBG("writing(eiv_count %d, full_len %zd)", eiv_count, full_len);
2059 if (virt_dev->nullio)
2062 err = fd->f_op->writev(fd, eiv, eiv_count, &fd->f_pos);
2064 PRINT_ERROR_PR("write() returned %Ld from %zd",
2065 (uint64_t)err, full_len);
2069 scst_set_cmd_error(cmd,
2070 SCST_LOAD_SENSE(scst_sense_write_error));
2073 } else if (err < full_len) {
2075 * Probably that's wrong, but sometimes write() returns
2076 * value less, than requested. Let's restart.
2078 int i, e = eiv_count;
2079 TRACE(TRACE_MINOR, "write() returned %d from %zd "
2080 "(iv_count=%d)", (int)err, full_len,
2083 PRINT_INFO_PR("Suspicious: write() returned 0 from "
2084 "%zd (iv_count=%d)", full_len, eiv_count);
2087 for(i = 0; i < e; i++) {
2088 if (eiv->iov_len < err) {
2089 err -= eiv->iov_len;
2094 (uint8_t*)eiv->iov_base + err;
2095 eiv->iov_len -= err;
2106 while (iv_count > 0) {
2107 scst_put_buf(cmd, iv[iv_count-1].iov_base);
2116 static void fileio_exec_verify(struct scst_cmd *cmd, loff_t loff)
2118 mm_segment_t old_fs;
2120 ssize_t length, len_mem = 0;
2121 uint8_t *address_sav, *address;
2123 struct scst_fileio_tgt_dev *ftgt_dev =
2124 (struct scst_fileio_tgt_dev *)cmd->tgt_dev->dh_priv;
2125 struct file *fd = ftgt_dev->fd;
2126 uint8_t *mem_verify = NULL;
2130 if (fileio_fsync(ftgt_dev, loff, cmd->bufflen, cmd) != 0)
2134 * Until the cache is cleared prior the verifying, there is not
2135 * much point in this code. ToDo.
2137 * Nevertherless, this code is valuable if the data have not read
2138 * from the file/disk yet.
2145 if (fd->f_op->llseek) {
2146 err = fd->f_op->llseek(fd, loff, 0/*SEEK_SET*/);
2148 err = default_llseek(fd, loff, 0/*SEEK_SET*/);
2151 PRINT_ERROR_PR("lseek trouble %Ld != %Ld", (uint64_t)err,
2153 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
2157 mem_verify = vmalloc(LEN_MEM);
2158 if (mem_verify == NULL) {
2159 PRINT_ERROR_PR("Unable to allocate memory %d for verify",
2161 scst_set_cmd_error(cmd,
2162 SCST_LOAD_SENSE(scst_sense_hardw_error));
2166 length = scst_get_buf_first(cmd, &address);
2167 address_sav = address;
2168 if (!length && cmd->data_len) {
2169 length = cmd->data_len;
2174 while (length > 0) {
2175 len_mem = length > LEN_MEM ? LEN_MEM : length;
2176 TRACE_DBG("Verify: length %zd - len_mem %zd", length, len_mem);
2178 err = fd->f_op->read(fd, (char*)mem_verify, len_mem, &fd->f_pos);
2179 if ((err < 0) || (err < len_mem)) {
2180 PRINT_ERROR_PR("verify() returned %Ld from %zd",
2181 (uint64_t)err, len_mem);
2185 scst_set_cmd_error(cmd,
2186 SCST_LOAD_SENSE(scst_sense_read_error));
2188 scst_put_buf(cmd, address_sav);
2191 if (compare && memcmp(address, mem_verify, len_mem) != 0)
2193 TRACE_DBG("Verify: error memcmp length %zd", length);
2194 scst_set_cmd_error(cmd,
2195 SCST_LOAD_SENSE(scst_sense_miscompare_error));
2196 scst_put_buf(cmd, address_sav);
2201 if (compare && length <= 0)
2203 scst_put_buf(cmd, address_sav);
2204 length = scst_get_buf_next(cmd, &address);
2205 address_sav = address;
2210 PRINT_ERROR_PR("scst_get_buf_() failed: %zd", length);
2211 scst_set_cmd_error(cmd,
2212 SCST_LOAD_SENSE(scst_sense_hardw_error));
2225 /* Might be called under lock and IRQ off */
2226 static int fileio_task_mgmt_fn(struct scst_mgmt_cmd *mcmd,
2227 struct scst_tgt_dev *tgt_dev)
2229 int res = SCST_DEV_TM_COMPLETED_SUCCESS;
2233 if (mcmd->fn == SCST_ABORT_TASK) {
2234 unsigned long flags;
2235 struct scst_cmd *cmd_to_abort = mcmd->cmd_to_abort;
2236 struct scst_fileio_tgt_dev *ftgt_dev =
2237 (struct scst_fileio_tgt_dev *)cmd_to_abort->tgt_dev->dh_priv;
2239 * Actually, _bh lock is enough here. But, since we
2240 * could be called with IRQ off, the in-kernel debug check
2241 * gives false alarm on using _bh lock. So, let's suppress it.
2243 spin_lock_irqsave(&ftgt_dev->fdev_lock, flags);
2244 if (cmd_to_abort->fileio_in_list) {
2245 TRACE(TRACE_MGMT, "Aborting cmd %p and moving it to "
2246 "the queue head", cmd_to_abort);
2247 list_del(&cmd_to_abort->fileio_cmd_list_entry);
2248 list_add(&cmd_to_abort->fileio_cmd_list_entry,
2249 &ftgt_dev->fdev_cmd_list);
2250 wake_up(&ftgt_dev->fdev_waitQ);
2252 spin_unlock_irqrestore(&ftgt_dev->fdev_lock, flags);
2255 TRACE_EXIT_RES(res);
2259 static inline struct scst_fileio_dev *fileio_alloc_dev(void)
2261 struct scst_fileio_dev *dev;
2262 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
2263 TRACE_MEM("kzalloc(GFP_KERNEL) for dev (%zd): %p", sizeof(*dev), dev);
2265 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of virtual "
2269 INIT_LIST_HEAD(&dev->ftgt_list);
2270 init_MUTEX(&dev->ftgt_list_mutex);
2275 static int fileio_proc_update_size(int size, int *len,
2276 off_t *begin, off_t *pos, off_t *offset)
2281 *pos = *begin + *len;
2282 if (*pos < *offset) {
2293 * Called when a file in the /proc/DISK_FILEIO_NAME/DISK_FILEIO_NAME is read
2296 static int disk_fileio_proc(char *buffer, char **start, off_t offset,
2297 int length, int *eof, struct scst_dev_type *dev_type, int inout)
2299 int res = 0, action;
2300 char *p, *name, *file_name;
2301 struct scst_fileio_dev *virt_dev, *vv;
2303 off_t begin = 0, pos = 0;
2307 /* VERY UGLY code. You can rewrite it if you want */
2309 if (down_interruptible(&scst_fileio_mutex) != 0) {
2314 if (inout == 0) { /* read */
2315 size = scnprintf(buffer, length, "%-17s %-12s %-15s %s\n",
2316 "Name", "Size(MB)", "Options", "File name");
2317 if (fileio_proc_update_size(size, &len, &begin, &pos, &offset)) {
2322 list_for_each_entry(virt_dev, &disk_fileio_dev_list,
2323 fileio_dev_list_entry)
2326 size = scnprintf(buffer + len, length - len,
2327 "%-17s %-13d", virt_dev->name,
2328 (uint32_t)(virt_dev->file_size >> 20));
2329 if (fileio_proc_update_size(size, &len, &begin, &pos,
2335 if (virt_dev->wt_flag) {
2336 size = scnprintf(buffer + len, length - len, "WT");
2338 if (fileio_proc_update_size(size, &len, &begin,
2344 if (virt_dev->nv_cache) {
2345 size = scnprintf(buffer + len, length - len,
2348 if (fileio_proc_update_size(size, &len, &begin,
2354 if (virt_dev->rd_only_flag) {
2355 size = scnprintf(buffer + len, length - len,
2358 if (fileio_proc_update_size(size, &len, &begin,
2364 if (virt_dev->o_direct_flag) {
2365 size = scnprintf(buffer + len, length - len,
2368 if (fileio_proc_update_size(size, &len, &begin,
2374 if (virt_dev->nullio) {
2375 size = scnprintf(buffer + len, length - len,
2376 c ? ",NIO" : "NIO");
2378 if (fileio_proc_update_size(size, &len, &begin,
2385 size = scnprintf(buffer + len, length - len, " ");
2386 if (fileio_proc_update_size(size, &len, &begin, &pos,
2393 size = scnprintf(buffer + len, length - len, "%s\n",
2394 virt_dev->file_name);
2395 if (fileio_proc_update_size(size, &len, &begin,
2401 *start = buffer + (offset - begin);
2402 len -= (offset - begin);
2409 uint32_t block_size = DEF_DISK_BLOCKSIZE;
2410 int block_shift = DEF_DISK_BLOCKSIZE_SHIFT;
2412 if (p[strlen(p) - 1] == '\n') {
2413 p[strlen(p) - 1] = '\0';
2415 if (!strncmp("close ", p, 6)) {
2418 } else if (!strncmp("open ", p, 5)) {
2422 PRINT_ERROR_PR("Unknown action \"%s\"", p);
2427 while (isspace(*p) && *p != '\0')
2430 while (!isspace(*p) && *p != '\0')
2433 if (*name == '\0') {
2434 PRINT_ERROR_PR("%s", "Name required");
2437 } else if (strlen(name) >= sizeof(virt_dev->name)) {
2438 PRINT_ERROR_PR("Name is too long (max %zd "
2439 "characters)", sizeof(virt_dev->name)-1);
2444 if (action) { /* open */
2446 list_for_each_entry(vv, &disk_fileio_dev_list,
2447 fileio_dev_list_entry)
2449 if (strcmp(vv->name, name) == 0) {
2455 PRINT_ERROR_PR("Virtual device with name "
2456 "%s already exist", name);
2461 while (isspace(*p) && *p != '\0')
2464 while (!isspace(*p) && *p != '\0')
2467 if (*file_name == '\0') {
2468 PRINT_ERROR_PR("%s", "File name required");
2471 } else if (*file_name != '/') {
2472 PRINT_ERROR_PR("File path \"%s\" is not "
2473 "absolute", file_name);
2478 virt_dev = fileio_alloc_dev();
2479 if (virt_dev == NULL) {
2480 TRACE(TRACE_OUT_OF_MEM, "%s",
2481 "Allocation of virt_dev failed");
2486 while (isspace(*p) && *p != '\0')
2492 block_size = simple_strtoul(p, &pp, 0);
2494 if ((*p != '\0') && !isspace(*p)) {
2495 PRINT_ERROR_PR("Parse error: \"%s\"", p);
2499 while (isspace(*p) && *p != '\0')
2510 if (block_shift < 9) {
2511 PRINT_ERROR_PR("Wrong block size %d",
2517 virt_dev->block_size = block_size;
2518 virt_dev->block_shift = block_shift;
2520 while (*p != '\0') {
2521 if (!strncmp("WRITE_THROUGH", p, 13)) {
2523 virt_dev->wt_flag = 1;
2524 TRACE_DBG("%s", "WRITE_THROUGH");
2525 } else if (!strncmp("NV_CACHE", p, 8)) {
2527 virt_dev->nv_cache = 1;
2528 TRACE_DBG("%s", "NON-VOLATILE CACHE");
2529 } else if (!strncmp("READ_ONLY", p, 9)) {
2531 virt_dev->rd_only_flag = 1;
2532 TRACE_DBG("%s", "READ_ONLY");
2533 } else if (!strncmp("O_DIRECT", p, 8)) {
2535 virt_dev->o_direct_flag = 1;
2536 TRACE_DBG("%s", "O_DIRECT");
2537 } else if (!strncmp("NULLIO", p, 6)) {
2539 virt_dev->nullio = 1;
2540 TRACE_DBG("%s", "NULLIO");
2542 PRINT_ERROR_PR("Unknown flag \"%s\"", p);
2546 while (isspace(*p) && *p != '\0')
2550 strcpy(virt_dev->name, name);
2552 len = strlen(file_name) + 1;
2553 virt_dev->file_name = kmalloc(len, GFP_KERNEL);
2554 TRACE_MEM("kmalloc(GFP_KERNEL) for file_name (%d): %p",
2555 len, virt_dev->file_name);
2556 if (virt_dev->file_name == NULL) {
2557 TRACE(TRACE_OUT_OF_MEM, "%s",
2558 "Allocation of file_name failed");
2562 strncpy(virt_dev->file_name, file_name, len);
2564 list_add_tail(&virt_dev->fileio_dev_list_entry,
2565 &disk_fileio_dev_list);
2568 scst_register_virtual_device(&disk_devtype_fileio,
2570 if (virt_dev->virt_id < 0) {
2571 res = virt_dev->virt_id;
2572 goto out_free_vpath;
2574 TRACE_DBG("Added virt_dev (name %s, file name %s, "
2575 "id %d, block size %d) to "
2576 "disk_fileio_dev_list", virt_dev->name,
2577 virt_dev->file_name, virt_dev->virt_id,
2578 virt_dev->block_size);
2579 } else { /* close */
2581 list_for_each_entry(vv, &disk_fileio_dev_list,
2582 fileio_dev_list_entry)
2584 if (strcmp(vv->name, name) == 0) {
2589 if (virt_dev == NULL) {
2590 PRINT_ERROR_PR("Device %s not found", name);
2594 scst_unregister_virtual_device(virt_dev->virt_id);
2595 PRINT_INFO_PR("Virtual device %s unregistered",
2597 TRACE_DBG("virt_id %d unregister", virt_dev->virt_id);
2599 list_del(&virt_dev->fileio_dev_list_entry);
2601 TRACE_MEM("kfree for file_name: %p", virt_dev->file_name);
2602 kfree(virt_dev->file_name);
2603 TRACE_MEM("kfree for virt_dev: %p", virt_dev);
2610 up(&scst_fileio_mutex);
2613 TRACE_EXIT_RES(res);
2617 list_del(&virt_dev->fileio_dev_list_entry);
2619 TRACE_MEM("kfree for file_name: %p", virt_dev->file_name);
2620 kfree(virt_dev->file_name);
2623 TRACE_MEM("kfree for virt_dev: %p", virt_dev);
2628 /* scst_fileio_mutex supposed to be held */
2629 static int cdrom_fileio_open(char *p, char *name)
2631 struct scst_fileio_dev *virt_dev, *vv;
2638 list_for_each_entry(vv, &cdrom_fileio_dev_list,
2639 fileio_dev_list_entry)
2641 if (strcmp(vv->name, name) == 0) {
2647 PRINT_ERROR_PR("Virtual device with name "
2648 "%s already exist", name);
2653 while (isspace(*p) && *p != '\0')
2656 while (!isspace(*p) && *p != '\0')
2659 if (*file_name == '\0') {
2661 TRACE_DBG("%s", "No media");
2662 } else if (*file_name != '/') {
2663 PRINT_ERROR_PR("File path \"%s\" is not "
2664 "absolute", file_name);
2670 virt_dev = fileio_alloc_dev();
2671 if (virt_dev == NULL) {
2672 TRACE(TRACE_OUT_OF_MEM, "%s",
2673 "Allocation of virt_dev failed");
2677 virt_dev->cdrom_empty = cdrom_empty;
2679 strcpy(virt_dev->name, name);
2681 if (!virt_dev->cdrom_empty) {
2682 len = strlen(file_name) + 1;
2683 virt_dev->file_name = kmalloc(len, GFP_KERNEL);
2684 TRACE_MEM("kmalloc(GFP_KERNEL) for file_name (%d): %p",
2685 len, virt_dev->file_name);
2686 if (virt_dev->file_name == NULL) {
2687 TRACE(TRACE_OUT_OF_MEM, "%s",
2688 "Allocation of file_name failed");
2692 strncpy(virt_dev->file_name, file_name, len);
2695 list_add_tail(&virt_dev->fileio_dev_list_entry,
2696 &cdrom_fileio_dev_list);
2699 scst_register_virtual_device(&cdrom_devtype_fileio,
2701 if (virt_dev->virt_id < 0) {
2702 res = virt_dev->virt_id;
2703 goto out_free_vpath;
2705 TRACE_DBG("Added virt_dev (name %s file_name %s id %d) "
2706 "to cdrom_fileio_dev_list", virt_dev->name,
2707 virt_dev->file_name, virt_dev->virt_id);
2713 list_del(&virt_dev->fileio_dev_list_entry);
2715 TRACE_MEM("kfree for file_name: %p", virt_dev->file_name);
2716 kfree(virt_dev->file_name);
2719 TRACE_MEM("kfree for virt_dev: %p", virt_dev);
2724 /* scst_fileio_mutex supposed to be held */
2725 static int cdrom_fileio_close(char *name)
2727 struct scst_fileio_dev *virt_dev, *vv;
2731 list_for_each_entry(vv, &cdrom_fileio_dev_list,
2732 fileio_dev_list_entry)
2734 if (strcmp(vv->name, name) == 0) {
2739 if (virt_dev == NULL) {
2740 PRINT_ERROR_PR("Virtual device with name "
2741 "%s not found", name);
2745 scst_unregister_virtual_device(virt_dev->virt_id);
2746 PRINT_INFO_PR("Virtual device %s unregistered",
2748 TRACE_DBG("virt_id %d unregister", virt_dev->virt_id);
2750 list_del(&virt_dev->fileio_dev_list_entry);
2752 if (virt_dev->file_name) {
2753 TRACE_MEM("kfree for file_name: %p", virt_dev->file_name);
2754 kfree(virt_dev->file_name);
2756 TRACE_MEM("kfree for virt_dev: %p", virt_dev);
2763 /* scst_fileio_mutex supposed to be held */
2764 static int cdrom_fileio_change(char *p, char *name)
2767 struct scst_fileio_tgt_dev *ftgt_dev;
2769 mm_segment_t old_fs;
2770 struct scst_fileio_dev *virt_dev, *vv;
2771 char *file_name, *fn, *old_fn;
2776 list_for_each_entry(vv, &cdrom_fileio_dev_list,
2777 fileio_dev_list_entry)
2779 if (strcmp(vv->name, name) == 0) {
2784 if (virt_dev == NULL) {
2785 PRINT_ERROR_PR("Virtual device with name "
2786 "%s not found", name);
2791 while (isspace(*p) && *p != '\0')
2794 while (!isspace(*p) && *p != '\0')
2797 if (*file_name == '\0') {
2798 virt_dev->cdrom_empty = 1;
2799 TRACE_DBG("%s", "No media");
2800 } else if (*file_name != '/') {
2801 PRINT_ERROR_PR("File path \"%s\" is not "
2802 "absolute", file_name);
2806 virt_dev->cdrom_empty = 0;
2808 old_fn = virt_dev->file_name;
2810 if (!virt_dev->cdrom_empty) {
2811 len = strlen(file_name) + 1;
2812 fn = kmalloc(len, GFP_KERNEL);
2813 TRACE_MEM("kmalloc(GFP_KERNEL) for file_name (%d): %p",
2816 TRACE(TRACE_OUT_OF_MEM, "%s",
2817 "Allocation of file_name failed");
2822 strncpy(fn, file_name, len);
2823 virt_dev->file_name = fn;
2825 fd = fileio_open(virt_dev);
2828 PRINT_ERROR_PR("filp_open(%s) returned an error %d",
2829 virt_dev->file_name, res);
2832 if ((fd->f_op == NULL) || (fd->f_op->readv == NULL)) {
2833 PRINT_ERROR_PR("%s", "Wrong f_op or FS doesn't "
2834 "have required capabilities");
2836 filp_close(fd, NULL);
2843 if (fd->f_op->llseek) {
2844 err = fd->f_op->llseek(fd, 0, 2/*SEEK_END*/);
2846 err = default_llseek(fd, 0, 2/*SEEK_END*/);
2849 filp_close(fd, NULL);
2852 PRINT_ERROR_PR("llseek %s returned an error %d",
2853 virt_dev->file_name, res);
2860 virt_dev->file_name = fn;
2863 scst_suspend_activity();
2865 if (virt_dev->prevent_allow_medium_removal) {
2866 PRINT_ERROR_PR("Prevent medium removal for "
2867 "virtual device with name %s", name);
2869 goto out_free_resume;
2872 virt_dev->file_size = err;
2873 virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift;
2874 if (!virt_dev->cdrom_empty)
2875 virt_dev->media_changed = 1;
2877 down(&virt_dev->ftgt_list_mutex);
2878 list_for_each_entry(ftgt_dev, &virt_dev->ftgt_list,
2881 if (!virt_dev->cdrom_empty) {
2882 fd = fileio_open(virt_dev);
2885 PRINT_ERROR_PR("filp_open(%s) returned an error %d, "
2886 "closing the device", virt_dev->file_name, res);
2887 up(&virt_dev->ftgt_list_mutex);
2888 goto out_err_resume;
2893 filp_close(ftgt_dev->fd, NULL);
2896 up(&virt_dev->ftgt_list_mutex);
2898 if (!virt_dev->cdrom_empty) {
2899 PRINT_INFO_PR("Changed SCSI target virtual cdrom %s "
2900 "(file=\"%s\", fs=%LdMB, bs=%d, nblocks=%Ld, cyln=%Ld%s)",
2901 virt_dev->name, virt_dev->file_name,
2902 virt_dev->file_size >> 20, virt_dev->block_size,
2903 virt_dev->nblocks, virt_dev->nblocks/64/32,
2904 virt_dev->nblocks < 64*32 ? " !WARNING! cyln less "
2907 PRINT_INFO_PR("Removed media from SCSI target virtual cdrom %s",
2912 TRACE_MEM("kfree for old_fn: %p", old_fn);
2917 scst_resume_activity();
2923 virt_dev->file_name = old_fn;
2924 TRACE_MEM("kfree for fn: %p", fn);
2929 virt_dev->file_name = old_fn;
2930 TRACE_MEM("kfree for fn: %p", fn);
2935 virt_dev->file_name = old_fn;
2936 TRACE_MEM("kfree for fn: %p", fn);
2938 scst_resume_activity();
2939 cdrom_fileio_close(name);
2944 * Called when a file in the /proc/CDROM_FILEIO_NAME/CDROM_FILEIO_NAME is read
2947 static int cdrom_fileio_proc(char *buffer, char **start, off_t offset,
2948 int length, int *eof, struct scst_dev_type *dev_type, int inout)
2950 int res = 0, action;
2952 struct scst_fileio_dev *virt_dev;
2954 off_t begin = 0, pos = 0;
2958 if (down_interruptible(&scst_fileio_mutex) != 0) {
2963 if (inout == 0) { /* read */
2964 size = scnprintf(buffer, length, "%-17s %-9s %s\n",
2965 "Name", "Size(MB)", "File name");
2966 if (fileio_proc_update_size(size, &len, &begin, &pos,
2972 list_for_each_entry(virt_dev, &cdrom_fileio_dev_list,
2973 fileio_dev_list_entry)
2975 size = scnprintf(buffer + len, length - len,
2976 "%-17s %-9d %s\n", virt_dev->name,
2977 (uint32_t)(virt_dev->file_size >> 20),
2978 virt_dev->file_name);
2979 if (fileio_proc_update_size(size, &len, &begin,
2985 *start = buffer + (offset - begin);
2986 len -= (offset - begin);
2993 if (p[strlen(p) - 1] == '\n') {
2994 p[strlen(p) - 1] = '\0';
2996 if (!strncmp("close ", p, 6)) {
2999 } else if (!strncmp("change ", p, 5)) {
3002 } else if (!strncmp("open ", p, 5)) {
3006 PRINT_ERROR_PR("Unknown action \"%s\"", p);
3011 while (isspace(*p) && *p != '\0')
3014 while (!isspace(*p) && *p != '\0')
3017 if (*name == '\0') {
3018 PRINT_ERROR_PR("%s", "Name required");
3021 } else if (strlen(name) >= sizeof(virt_dev->name)) {
3022 PRINT_ERROR_PR("Name is too long (max %zd "
3023 "characters)", sizeof(virt_dev->name)-1);
3028 if (action == 2) { /* open */
3029 res = cdrom_fileio_open(p, name);
3032 } else if (action == 1) { /* change */
3033 res = cdrom_fileio_change(p, name);
3036 } else { /* close */
3037 res = cdrom_fileio_close(name);
3045 up(&scst_fileio_mutex);
3048 TRACE_EXIT_RES(res);
3053 static int fileio_proc_help_build(struct scst_dev_type *dev_type)
3056 struct proc_dir_entry *p, *root;
3060 root = scst_proc_get_dev_type_root(dev_type);
3062 p = create_proc_read_entry(FILEIO_PROC_HELP,
3063 S_IFREG | S_IRUGO, root,
3064 fileio_proc_help_read,
3065 (dev_type->type == TYPE_DISK) ?
3066 disk_fileio_proc_help_string :
3067 cdrom_fileio_proc_help_string);
3069 PRINT_ERROR_PR("Not enough memory to register dev "
3070 "handler %s entry %s in /proc",
3071 dev_type->name, FILEIO_PROC_HELP);
3078 TRACE_EXIT_RES(res);
3082 static void fileio_proc_help_destroy(struct scst_dev_type *dev_type)
3084 struct proc_dir_entry *root;
3088 root = scst_proc_get_dev_type_root(dev_type);
3090 remove_proc_entry(FILEIO_PROC_HELP, root);
3095 static int fileio_proc_help_read(char *buffer, char **start, off_t offset,
3096 int length, int *eof, void *data)
3099 char *s = (char*)data;
3103 if (offset < strlen(s))
3104 res = scnprintf(buffer, length, "%s", &s[offset]);
3106 TRACE_EXIT_RES(res);
3110 static int __init init_scst_fileio(struct scst_dev_type *devtype)
3116 devtype->module = THIS_MODULE;
3118 res = scst_register_virtual_dev_driver(devtype);
3122 res = scst_dev_handler_build_std_proc(devtype);
3126 res = fileio_proc_help_build(devtype);
3128 goto out_destroy_proc;
3132 TRACE_EXIT_RES(res);
3136 scst_dev_handler_destroy_std_proc(devtype);
3139 scst_unregister_virtual_dev_driver(devtype);
3143 static void __exit exit_scst_fileio(struct scst_dev_type *devtype,
3144 struct list_head *fileio_dev_list)
3148 down(&scst_fileio_mutex);
3150 struct scst_fileio_dev *virt_dev;
3152 if (list_empty(fileio_dev_list))
3155 virt_dev = list_entry(fileio_dev_list->next, typeof(*virt_dev),
3156 fileio_dev_list_entry);
3158 scst_unregister_virtual_device(virt_dev->virt_id);
3160 list_del(&virt_dev->fileio_dev_list_entry);
3162 PRINT_INFO_PR("Virtual device %s unregistered", virt_dev->name);
3163 TRACE_DBG("virt_id %d", virt_dev->virt_id);
3164 TRACE_MEM("kfree for file_name: %p", virt_dev->file_name);
3165 kfree(virt_dev->file_name);
3166 TRACE_MEM("kfree for virt_dev: %p", virt_dev);
3169 up(&scst_fileio_mutex);
3171 fileio_proc_help_destroy(devtype);
3172 scst_dev_handler_destroy_std_proc(devtype);
3174 scst_unregister_virtual_dev_driver(devtype);
3180 static int __init init_scst_fileio_driver(void)
3183 res = init_scst_fileio(&disk_devtype_fileio);
3187 res = init_scst_fileio(&cdrom_devtype_fileio);
3195 exit_scst_fileio(&disk_devtype_fileio, &disk_fileio_dev_list);
3199 static void __exit exit_scst_fileio_driver(void)
3201 exit_scst_fileio(&disk_devtype_fileio, &disk_fileio_dev_list);
3202 exit_scst_fileio(&cdrom_devtype_fileio, &cdrom_fileio_dev_list);
3205 * Wait for one sec. to allow the thread(s) actually exit,
3206 * otherwise we can get Oops. Any better way?
3209 unsigned long t = jiffies;
3210 TRACE_DBG("%s", "Waiting 1 sec...");
3211 while ((jiffies - t) < HZ)
3216 module_init(init_scst_fileio_driver);
3217 module_exit(exit_scst_fileio_driver);
3219 MODULE_LICENSE("GPL");