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 if (ftgt_dev == NULL) {
704 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of per-session "
705 "virtual device failed");
710 spin_lock_init(&ftgt_dev->fdev_lock);
711 INIT_LIST_HEAD(&ftgt_dev->fdev_cmd_list);
712 init_waitqueue_head(&ftgt_dev->fdev_waitQ);
713 atomic_set(&ftgt_dev->threads_count, 0);
714 init_MUTEX_LOCKED(&ftgt_dev->shutdown_mutex);
715 ftgt_dev->virt_dev = virt_dev;
717 if (!virt_dev->cdrom_empty) {
718 ftgt_dev->fd = fileio_open(virt_dev);
719 if (IS_ERR(ftgt_dev->fd)) {
720 res = PTR_ERR(ftgt_dev->fd);
721 PRINT_ERROR_PR("filp_open(%s) returned an error %d",
722 virt_dev->file_name, res);
729 * Only ONE thread must be run here, otherwise the commands could
730 * be executed out of order !!
732 res = kernel_thread(fileio_cmd_thread, ftgt_dev, FILEIO_THREAD_FLAGS);
734 PRINT_ERROR_PR("kernel_thread() failed: %d", res);
738 atomic_inc(&ftgt_dev->threads_count);
740 tgt_dev->dh_priv = ftgt_dev;
742 down(&virt_dev->ftgt_list_mutex);
743 list_add_tail(&ftgt_dev->ftgt_list_entry,
744 &virt_dev->ftgt_list);
745 up(&virt_dev->ftgt_list_mutex);
753 filp_close(ftgt_dev->fd, NULL);
760 static void fileio_detach_tgt(struct scst_tgt_dev *tgt_dev)
762 struct scst_fileio_tgt_dev *ftgt_dev =
763 (struct scst_fileio_tgt_dev *)tgt_dev->dh_priv;
764 struct scst_fileio_dev *virt_dev =
765 (struct scst_fileio_dev *)tgt_dev->acg_dev->dev->dh_priv;
769 down(&virt_dev->ftgt_list_mutex);
770 list_del(&ftgt_dev->ftgt_list_entry);
771 up(&virt_dev->ftgt_list_mutex);
773 ftgt_dev->shutdown = 1;
774 wake_up_all(&ftgt_dev->fdev_waitQ);
775 down(&ftgt_dev->shutdown_mutex);
778 filp_close(ftgt_dev->fd, NULL);
780 if (ftgt_dev->iv != NULL)
785 tgt_dev->dh_priv = NULL;
790 /********************************************************************
791 * Function: disk_fileio_parse
795 * Returns : The state of the command
797 * Description: This does the parsing of the command
799 * Note: Not all states are allowed on return
800 ********************************************************************/
801 static int disk_fileio_parse(struct scst_cmd *cmd,
802 const struct scst_info_cdb *info_cdb)
804 int res = SCST_CMD_STATE_DEFAULT;
806 struct scst_fileio_dev *virt_dev =
807 (struct scst_fileio_dev *)cmd->dev->dh_priv;
812 * SCST sets good defaults for cmd->data_direction and cmd->bufflen
813 * based on info_cdb, therefore change them only if necessary
816 TRACE_DBG("op_name <%s> direct %d flags %d transfer_len %d",
818 info_cdb->direction, info_cdb->flags, info_cdb->transfer_len);
820 fixed = info_cdb->flags & SCST_TRANSFER_LEN_TYPE_FIXED;
821 switch (cmd->cdb[0]) {
823 cmd->bufflen = READ_CAP_LEN;
824 cmd->data_direction = SCST_DATA_READ;
826 case SERVICE_ACTION_IN:
827 if ((cmd->cdb[1] & 0x1f) == SAI_READ_CAPACITY_16) {
828 cmd->bufflen = READ_CAP16_LEN;
829 cmd->data_direction = SCST_DATA_READ;
836 if ((cmd->cdb[1] & BYTCHK) == 0) {
838 info_cdb->transfer_len << virt_dev->block_shift;
840 cmd->data_direction = SCST_DATA_NONE;
852 * No need for locks here, since *_detach() can not be
853 * called, when there are existing commands.
855 cmd->bufflen = info_cdb->transfer_len << virt_dev->block_shift;
858 TRACE_DBG("res %d, bufflen %zd, data_len %zd, direct %d",
859 res, cmd->bufflen, cmd->data_len, cmd->data_direction);
865 static inline void fileio_queue_cmd(struct scst_cmd *cmd)
867 struct scst_fileio_tgt_dev *ftgt_dev =
868 (struct scst_fileio_tgt_dev *)cmd->tgt_dev->dh_priv;
869 spin_lock_bh(&ftgt_dev->fdev_lock);
870 TRACE_DBG("Pushing cmd %p to IO thread", cmd);
871 list_add_tail(&cmd->fileio_cmd_list_entry,
872 &ftgt_dev->fdev_cmd_list);
873 cmd->fileio_in_list = 1;
874 spin_unlock_bh(&ftgt_dev->fdev_lock);
875 wake_up(&ftgt_dev->fdev_waitQ);
879 /********************************************************************
880 * Function: disk_fileio_exec
884 * Returns : always SCST_EXEC_COMPLETED, real status is in error condition
888 ********************************************************************/
889 static int disk_fileio_exec(struct scst_cmd *cmd)
892 int opcode = cmd->cdb[0];
897 cmd->masked_status = 0;
899 cmd->host_status = DID_OK;
900 cmd->driver_status = 0;
904 * Only commands that unsensible to the execution order could be
905 * performed here, in place. Other ones must be passed to the
911 fileio_exec_inquiry(cmd);
914 fileio_exec_read_capacity(cmd);
916 case SERVICE_ACTION_IN:
917 if ((cmd->cdb[1] & 0x1f) == SAI_READ_CAPACITY_16)
918 fileio_exec_read_capacity16(cmd);
923 case WRITE_VERIFY_12:
924 case WRITE_VERIFY_16:
930 /* could move READ ONLY check up to here (currenlty in do_job()) */
940 case SYNCHRONIZE_CACHE:
950 fileio_queue_cmd(cmd);
953 case TEST_UNIT_READY:
958 TRACE_DBG("Invalid opcode 0x%02x", opcode);
959 scst_set_cmd_error(cmd,
960 SCST_LOAD_SENSE(scst_sense_invalid_opcode));
965 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
969 return SCST_EXEC_COMPLETED;
972 /********************************************************************
973 * Function: cdrom_fileio_parse
977 * Returns : The state of the command
979 * Description: This does the parsing of the command
981 * Note: Not all states are allowed on return
982 ********************************************************************/
983 static int cdrom_fileio_parse(struct scst_cmd *cmd,
984 const struct scst_info_cdb *info_cdb)
986 int res = SCST_CMD_STATE_DEFAULT;
988 struct scst_fileio_dev *virt_dev =
989 (struct scst_fileio_dev *)cmd->dev->dh_priv;
994 * SCST sets good defaults for cmd->data_direction and cmd->bufflen
995 * based on info_cdb, therefore change them only if necessary
998 TRACE_DBG("op_name <%s> direct %d flags %d transfer_len %d",
1000 info_cdb->direction, info_cdb->flags, info_cdb->transfer_len);
1002 fixed = info_cdb->flags & SCST_TRANSFER_LEN_TYPE_FIXED;
1003 switch (cmd->cdb[0]) {
1005 cmd->bufflen = READ_CAP_LEN;
1006 cmd->data_direction = SCST_DATA_READ;
1012 if ((cmd->cdb[1] & BYTCHK) == 0) {
1014 info_cdb->transfer_len << virt_dev->block_shift;
1016 cmd->data_direction = SCST_DATA_NONE;
1028 * No need for locks here, since *_detach() can not be
1029 * called, when there are existing commands.
1031 cmd->bufflen = info_cdb->transfer_len << virt_dev->block_shift;
1034 TRACE_DBG("res %d, bufflen %zd, data_len %zd, direct %d",
1035 res, cmd->bufflen, cmd->data_len, cmd->data_direction);
1037 TRACE_EXIT_HRES(res);
1041 /********************************************************************
1042 * Function: cdrom_fileio_exec
1049 ********************************************************************/
1050 static int cdrom_fileio_exec(struct scst_cmd *cmd)
1053 int opcode = cmd->cdb[0];
1054 struct scst_fileio_dev *virt_dev =
1055 (struct scst_fileio_dev *)cmd->dev->dh_priv;
1060 cmd->masked_status = 0;
1061 cmd->msg_status = 0;
1062 cmd->host_status = DID_OK;
1063 cmd->driver_status = 0;
1065 if (virt_dev->cdrom_empty && (opcode != INQUIRY)) {
1066 TRACE_DBG("%s", "CDROM empty");
1067 scst_set_cmd_error(cmd,
1068 SCST_LOAD_SENSE(scst_sense_not_ready));
1073 * No protection is necessary, because media_changed set only
1074 * in suspended state and exec() is serialized
1076 if (virt_dev->media_changed && (cmd->cdb[0] != INQUIRY) &&
1077 (cmd->cdb[0] != REQUEST_SENSE) && (cmd->cdb[0] != REPORT_LUNS)) {
1078 virt_dev->media_changed = 0;
1079 TRACE_DBG("%s", "Reporting media changed");
1080 scst_set_cmd_error(cmd,
1081 SCST_LOAD_SENSE(scst_sense_medium_changed_UA));
1087 * Only commands that unsensible to the execution order could be
1088 * performed here, in place. Other ones must be passed to the
1095 fileio_exec_inquiry(cmd);
1098 fileio_exec_read_capacity(cmd);
1101 case WRITE_VERIFY_12:
1102 case WRITE_VERIFY_16:
1107 case MODE_SELECT_10:
1125 case ALLOW_MEDIUM_REMOVAL:
1127 fileio_queue_cmd(cmd);
1130 case TEST_UNIT_READY:
1134 TRACE_DBG("Invalid opcode 0x%02x", opcode);
1135 scst_set_cmd_error(cmd,
1136 SCST_LOAD_SENSE(scst_sense_invalid_opcode));
1142 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
1146 return SCST_EXEC_COMPLETED;
1149 static void fileio_exec_inquiry(struct scst_cmd *cmd)
1151 int32_t length, len, i;
1154 struct scst_fileio_dev *virt_dev =
1155 (struct scst_fileio_dev *)cmd->dev->dh_priv;
1157 /* ToDo: Performance Boost:
1158 * 1. remove kzalloc, buf
1159 * 2. do all checks before touching *address
1161 * 4. write directly to *address
1166 buf = kzalloc(INQ_BUF_SZ,
1167 scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL);
1173 length = scst_get_buf_first(cmd, &address);
1174 TRACE_DBG("length %d", length);
1175 if (unlikely(length <= 0)) {
1176 PRINT_ERROR_PR("scst_get_buf_first() failed: %d", length);
1177 scst_set_cmd_error(cmd,
1178 SCST_LOAD_SENSE(scst_sense_hardw_error));
1183 * ToDo: write through/back flags as well as read only one.
1184 * Also task queue size should be set on some value.
1187 if (cmd->cdb[1] & CMDDT) {
1188 TRACE_DBG("%s", "INQUIRY: CMDDT is unsupported");
1189 scst_set_cmd_error(cmd,
1190 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1194 memset(buf, 0, sizeof(buf));
1195 buf[0] = cmd->dev->handler->type; /* type dev */
1196 if (buf[0] == TYPE_ROM)
1197 buf[1] = 0x80; /* removable */
1199 if (cmd->cdb[1] & EVPD) {
1203 for (dev_id_num = 0, i = 0; i < strlen(virt_dev->name); i++) {
1204 dev_id_num += virt_dev->name[i];
1206 len = scnprintf(dev_id_str, 6, "%d", dev_id_num);
1207 TRACE_DBG("num %d, str <%s>, len %d",
1208 dev_id_num,dev_id_str, len);
1209 if (0 == cmd->cdb[2]) { /* supported vital product data pages */
1211 buf[4] = 0x0; /* this page */
1212 buf[5] = 0x80; /* unit serial number */
1213 buf[6] = 0x83; /* device identification */
1214 } else if (0x80 == cmd->cdb[2]) { /* unit serial number */
1217 memcpy(&buf[4], dev_id_str, len);
1218 } else if (0x83 == cmd->cdb[2]) { /* device identification */
1222 /* Two identification descriptors: */
1223 /* T10 vendor identifier field format (faked) */
1224 buf[num + 0] = 0x2; /* ASCII */
1227 memcpy(&buf[num + 4], SCST_FIO_VENDOR, 8);
1228 memset(&buf[num + 12], ' ', 16);
1229 i = strlen(virt_dev->name);
1230 i = i < 16 ? i : 16;
1231 memcpy(&buf[num + 12], virt_dev->name, len);
1232 memcpy(&buf[num + 28], dev_id_str, len);
1233 buf[num + 3] = 8 + 16 + len;
1234 num += buf[num + 3] + 4;
1235 /* NAA IEEE registered identifier (faked) */
1236 buf[num] = 0x1; /* binary */
1240 buf[num + 4] = 0x51; /* ieee company id=0x123456 (faked) */
1241 buf[num + 5] = 0x23;
1242 buf[num + 6] = 0x45;
1243 buf[num + 7] = 0x60;
1244 buf[num + 8] = (dev_id_num >> 24);
1245 buf[num + 9] = (dev_id_num >> 16) & 0xff;
1246 buf[num + 10] = (dev_id_num >> 8) & 0xff;
1247 buf[num + 11] = dev_id_num & 0xff;
1249 buf[3] = num + 12 - 4;
1251 TRACE_DBG("INQUIRY: Unsupported EVPD page %x",
1253 scst_set_cmd_error(cmd,
1254 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1258 if (cmd->cdb[2] != 0) {
1259 TRACE_DBG("INQUIRY: Unsupported page %x", cmd->cdb[2]);
1260 scst_set_cmd_error(cmd,
1261 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1265 buf[2] = 4; /* Device complies to this standard - SPC-2 */
1266 buf[3] = 2; /* data in format specified in this standard */
1267 buf[4] = 31; /* n - 4 = 35 - 4 = 31 for full 36 byte data */
1268 buf[6] = 0; buf[7] = 2; /* BQue = 0, CMDQUE = 1 commands queuing supported */
1270 /* 8 byte ASCII Vendor Identification of the target - left aligned */
1271 memcpy(&buf[8], SCST_FIO_VENDOR, 8);
1273 /* 16 byte ASCII Product Identification of the target - left aligned */
1274 memset(&buf[16], ' ', 16);
1275 len = strlen(virt_dev->name);
1276 len = len < 16 ? len : 16;
1277 memcpy(&buf[16], virt_dev->name, len);
1279 /* 4 byte ASCII Product Revision Level of the target - left aligned */
1280 memcpy(&buf[32], SCST_FIO_REV, 4);
1283 memcpy(address, buf, length < INQ_BUF_SZ ? length : INQ_BUF_SZ);
1286 scst_put_buf(cmd, address);
1297 * <<Following mode pages info copied from ST318451LW with some corrections>>
1302 static int fileio_err_recov_pg(unsigned char *p, int pcontrol,
1303 struct scst_fileio_dev *virt_dev)
1304 { /* Read-Write Error Recovery page for mode_sense */
1305 const unsigned char err_recov_pg[] = {0x1, 0xa, 0xc0, 11, 240, 0, 0, 0,
1308 memcpy(p, err_recov_pg, sizeof(err_recov_pg));
1310 memset(p + 2, 0, sizeof(err_recov_pg) - 2);
1311 return sizeof(err_recov_pg);
1314 static int fileio_disconnect_pg(unsigned char *p, int pcontrol,
1315 struct scst_fileio_dev *virt_dev)
1316 { /* Disconnect-Reconnect page for mode_sense */
1317 const unsigned char disconnect_pg[] = {0x2, 0xe, 128, 128, 0, 10, 0, 0,
1318 0, 0, 0, 0, 0, 0, 0, 0};
1320 memcpy(p, disconnect_pg, sizeof(disconnect_pg));
1322 memset(p + 2, 0, sizeof(disconnect_pg) - 2);
1323 return sizeof(disconnect_pg);
1326 static int fileio_format_pg(unsigned char *p, int pcontrol,
1327 struct scst_fileio_dev *virt_dev)
1328 { /* Format device page for mode_sense */
1329 const unsigned char format_pg[] = {0x3, 0x16, 0, 0, 0, 0, 0, 0,
1330 0, 0, 0, 0, 0, 0, 0, 0,
1331 0, 0, 0, 0, 0x40, 0, 0, 0};
1333 memcpy(p, format_pg, sizeof(format_pg));
1334 p[10] = (DEF_SECTORS_PER >> 8) & 0xff;
1335 p[11] = DEF_SECTORS_PER & 0xff;
1336 p[12] = (virt_dev->block_size >> 8) & 0xff;
1337 p[13] = virt_dev->block_size & 0xff;
1339 memset(p + 2, 0, sizeof(format_pg) - 2);
1340 return sizeof(format_pg);
1343 static int fileio_caching_pg(unsigned char *p, int pcontrol,
1344 struct scst_fileio_dev *virt_dev)
1345 { /* Caching page for mode_sense */
1346 const unsigned char caching_pg[] = {0x8, 18, 0x10, 0, 0xff, 0xff, 0, 0,
1347 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0, 0, 0, 0, 0};
1349 memcpy(p, caching_pg, sizeof(caching_pg));
1350 p[2] |= !(virt_dev->wt_flag) ? WCE : 0;
1352 memset(p + 2, 0, sizeof(caching_pg) - 2);
1353 return sizeof(caching_pg);
1356 static int fileio_ctrl_m_pg(unsigned char *p, int pcontrol,
1357 struct scst_fileio_dev *virt_dev)
1358 { /* Control mode page for mode_sense */
1359 const unsigned char ctrl_m_pg[] = {0xa, 0xa, 0x22, 0, 0, 0x40, 0, 0,
1362 memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg));
1363 if (!virt_dev->wt_flag)
1364 p[3] |= 0x10; /* Enable unrestricted reordering */
1366 memset(p + 2, 0, sizeof(ctrl_m_pg) - 2);
1367 return sizeof(ctrl_m_pg);
1370 static int fileio_iec_m_pg(unsigned char *p, int pcontrol,
1371 struct scst_fileio_dev *virt_dev)
1372 { /* Informational Exceptions control mode page for mode_sense */
1373 const unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0,
1375 memcpy(p, iec_m_pg, sizeof(iec_m_pg));
1377 memset(p + 2, 0, sizeof(iec_m_pg) - 2);
1378 return sizeof(iec_m_pg);
1381 static void fileio_exec_mode_sense(struct scst_cmd *cmd)
1386 struct scst_fileio_dev *virt_dev;
1389 unsigned char dbd, type;
1390 int pcontrol, pcode, subpcode;
1391 unsigned char dev_spec;
1392 int msense_6, offset, len;
1397 buf = kzalloc(MSENSE_BUF_SZ,
1398 scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL);
1404 virt_dev = (struct scst_fileio_dev *)cmd->dev->dh_priv;
1405 blocksize = virt_dev->block_size;
1406 nblocks = virt_dev->nblocks;
1408 type = cmd->dev->handler->type; /* type dev */
1409 dbd = cmd->cdb[1] & DBD;
1410 pcontrol = (cmd->cdb[2] & 0xc0) >> 6;
1411 pcode = cmd->cdb[2] & 0x3f;
1412 subpcode = cmd->cdb[3];
1413 msense_6 = (MODE_SENSE == cmd->cdb[0]);
1414 dev_spec = (virt_dev->rd_only_flag ? WP : 0) | DPOFUA;
1416 length = scst_get_buf_first(cmd, &address);
1417 if (unlikely(length <= 0)) {
1418 PRINT_ERROR_PR("scst_get_buf_first() failed: %d", length);
1419 scst_set_cmd_error(cmd,
1420 SCST_LOAD_SENSE(scst_sense_hardw_error));
1424 memset(buf, 0, sizeof(buf));
1426 if (0x3 == pcontrol) {
1427 TRACE_DBG("%s", "MODE SENSE: Saving values not supported");
1428 scst_set_cmd_error(cmd,
1429 SCST_LOAD_SENSE(scst_sense_saving_params_unsup));
1443 if (0 != subpcode) { /* TODO: Control Extension page */
1444 TRACE_DBG("%s", "MODE SENSE: Only subpage 0 is supported");
1445 scst_set_cmd_error(cmd,
1446 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1451 /* Create block descriptor */
1452 buf[offset - 1] = 0x08; /* block descriptor length */
1453 if (nblocks >> 32) {
1454 buf[offset + 0] = 0xFF;
1455 buf[offset + 1] = 0xFF;
1456 buf[offset + 2] = 0xFF;
1457 buf[offset + 3] = 0xFF;
1459 buf[offset + 0] = (nblocks >> (BYTE * 3)) & 0xFF;/* num blks */
1460 buf[offset + 1] = (nblocks >> (BYTE * 2)) & 0xFF;
1461 buf[offset + 2] = (nblocks >> (BYTE * 1)) & 0xFF;
1462 buf[offset + 3] = (nblocks >> (BYTE * 0)) & 0xFF;
1464 buf[offset + 4] = 0; /* density code */
1465 buf[offset + 5] = (blocksize >> (BYTE * 2)) & 0xFF;/* blklen */
1466 buf[offset + 6] = (blocksize >> (BYTE * 1)) & 0xFF;
1467 buf[offset + 7] = (blocksize >> (BYTE * 0)) & 0xFF;
1469 offset += 8; /* increment offset */
1475 case 0x1: /* Read-Write error recovery page, direct access */
1476 len = fileio_err_recov_pg(bp, pcontrol, virt_dev);
1479 case 0x2: /* Disconnect-Reconnect page, all devices */
1480 len = fileio_disconnect_pg(bp, pcontrol, virt_dev);
1483 case 0x3: /* Format device page, direct access */
1484 len = fileio_format_pg(bp, pcontrol, virt_dev);
1487 case 0x8: /* Caching page, direct access */
1488 len = fileio_caching_pg(bp, pcontrol, virt_dev);
1491 case 0xa: /* Control Mode page, all devices */
1492 len = fileio_ctrl_m_pg(bp, pcontrol, virt_dev);
1495 case 0x1c: /* Informational Exceptions Mode page, all devices */
1496 len = fileio_iec_m_pg(bp, pcontrol, virt_dev);
1499 case 0x3f: /* Read all Mode pages */
1500 len = fileio_err_recov_pg(bp, pcontrol, virt_dev);
1501 len += fileio_disconnect_pg(bp + len, pcontrol, virt_dev);
1502 len += fileio_format_pg(bp + len, pcontrol, virt_dev);
1503 len += fileio_caching_pg(bp + len, pcontrol, virt_dev);
1504 len += fileio_ctrl_m_pg(bp + len, pcontrol, virt_dev);
1505 len += fileio_iec_m_pg(bp + len, pcontrol, virt_dev);
1509 TRACE_DBG("MODE SENSE: Unsupported page %x", pcode);
1510 scst_set_cmd_error(cmd,
1511 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1515 buf[0] = offset - 1;
1517 buf[0] = ((offset - 2) >> 8) & 0xff;
1518 buf[1] = (offset - 2) & 0xff;
1521 memcpy(address, buf, min(length, offset));
1524 scst_put_buf(cmd, address);
1534 static int fileio_set_wt(struct scst_fileio_dev *virt_dev, int wt)
1537 struct scst_fileio_tgt_dev *ftgt_dev;
1542 if (virt_dev->wt_flag == wt)
1545 virt_dev->wt_flag = wt;
1547 scst_suspend_activity();
1549 down(&virt_dev->ftgt_list_mutex);
1550 list_for_each_entry(ftgt_dev, &virt_dev->ftgt_list,
1553 fd = fileio_open(virt_dev);
1556 PRINT_ERROR_PR("filp_open(%s) returned an error %d, "
1557 "unable to change the cache mode",
1558 virt_dev->file_name, res);
1559 up(&virt_dev->ftgt_list_mutex);
1560 res = 0; /* ?? ToDo */
1564 filp_close(ftgt_dev->fd, NULL);
1567 up(&virt_dev->ftgt_list_mutex);
1570 scst_resume_activity();
1573 TRACE_EXIT_RES(res);
1577 static void fileio_exec_mode_select(struct scst_cmd *cmd)
1581 struct scst_fileio_dev *virt_dev;
1582 int mselect_6, offset;
1586 virt_dev = (struct scst_fileio_dev *)cmd->dev->dh_priv;
1587 mselect_6 = (MODE_SELECT == cmd->cdb[0]);
1589 length = scst_get_buf_first(cmd, &address);
1590 if (unlikely(length <= 0)) {
1591 PRINT_ERROR_PR("scst_get_buf_first() failed: %d", length);
1592 scst_set_cmd_error(cmd,
1593 SCST_LOAD_SENSE(scst_sense_hardw_error));
1597 if (!(cmd->cdb[1] & PF) || (cmd->cdb[1] & SP)) {
1598 PRINT_ERROR_PR("MODE SELECT: PF and/or SP are wrongly set "
1599 "(cdb[1]=%x)", cmd->cdb[1]);
1600 scst_set_cmd_error(cmd,
1601 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1611 if (address[offset - 1] == 8) {
1613 } else if (address[offset - 1] != 0) {
1614 PRINT_ERROR_PR("%s", "MODE SELECT: Wrong parameters list "
1616 scst_set_cmd_error(cmd,
1617 SCST_LOAD_SENSE(scst_sense_invalid_field_in_parm_list));
1621 while (length > offset + 2) {
1622 if (address[offset] & PS) {
1623 PRINT_ERROR_PR("%s", "MODE SELECT: Illegal PS bit");
1624 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1625 scst_sense_invalid_field_in_parm_list));
1628 if ((address[offset] & 0x3f) == 0x8) { /* Caching page */
1629 if (address[offset + 1] != 18) {
1630 PRINT_ERROR_PR("%s", "MODE SELECT: Invalid "
1631 "caching page request");
1632 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1633 scst_sense_invalid_field_in_parm_list));
1636 if (fileio_set_wt(virt_dev,
1637 (address[offset + 2] & WCE) ? 0 : 1) != 0) {
1638 scst_set_cmd_error(cmd,
1639 SCST_LOAD_SENSE(scst_sense_hardw_error));
1644 offset += address[offset + 1];
1648 scst_put_buf(cmd, address);
1655 static void fileio_exec_read_capacity(struct scst_cmd *cmd)
1659 struct scst_fileio_dev *virt_dev;
1662 uint8_t buffer[READ_CAP_LEN];
1666 virt_dev = (struct scst_fileio_dev *)cmd->dev->dh_priv;
1667 blocksize = virt_dev->block_size;
1668 nblocks = virt_dev->nblocks;
1670 /* last block on the virt_dev is (nblocks-1) */
1671 memset(buffer, 0, sizeof(buffer));
1672 if (nblocks >> 32) {
1678 buffer[0] = ((nblocks - 1) >> (BYTE * 3)) & 0xFF;
1679 buffer[1] = ((nblocks - 1) >> (BYTE * 2)) & 0xFF;
1680 buffer[2] = ((nblocks - 1) >> (BYTE * 1)) & 0xFF;
1681 buffer[3] = ((nblocks - 1) >> (BYTE * 0)) & 0xFF;
1683 buffer[4] = (blocksize >> (BYTE * 3)) & 0xFF;
1684 buffer[5] = (blocksize >> (BYTE * 2)) & 0xFF;
1685 buffer[6] = (blocksize >> (BYTE * 1)) & 0xFF;
1686 buffer[7] = (blocksize >> (BYTE * 0)) & 0xFF;
1688 length = scst_get_buf_first(cmd, &address);
1689 if (unlikely(length <= 0)) {
1690 PRINT_ERROR_PR("scst_get_buf_first() failed: %d", length);
1691 scst_set_cmd_error(cmd,
1692 SCST_LOAD_SENSE(scst_sense_hardw_error));
1696 memcpy(address, buffer, length < READ_CAP_LEN ? length : READ_CAP_LEN);
1698 scst_put_buf(cmd, address);
1705 static void fileio_exec_read_capacity16(struct scst_cmd *cmd)
1709 struct scst_fileio_dev *virt_dev;
1712 uint8_t buffer[READ_CAP16_LEN];
1717 virt_dev = (struct scst_fileio_dev *)cmd->dev->dh_priv;
1718 blocksize = virt_dev->block_size;
1719 nblocks = virt_dev->nblocks;
1721 memset(buffer, 0, sizeof(buffer));
1722 data64 = (uint64_t*)buffer;
1723 data64[0] = cpu_to_be64(nblocks - 1);
1724 buffer[8] = (blocksize >> (BYTE * 3)) & 0xFF;
1725 buffer[9] = (blocksize >> (BYTE * 2)) & 0xFF;
1726 buffer[10] = (blocksize >> (BYTE * 1)) & 0xFF;
1727 buffer[11] = (blocksize >> (BYTE * 0)) & 0xFF;
1729 length = scst_get_buf_first(cmd, &address);
1730 if (unlikely(length <= 0)) {
1731 PRINT_ERROR_PR("scst_get_buf_first() failed: %d", length);
1732 scst_set_cmd_error(cmd,
1733 SCST_LOAD_SENSE(scst_sense_hardw_error));
1737 memcpy(address, buffer, length < READ_CAP16_LEN ?
1738 length : READ_CAP16_LEN);
1740 scst_put_buf(cmd, address);
1747 static void fileio_exec_read_toc(struct scst_cmd *cmd)
1749 int32_t length, off = 0;
1751 struct scst_fileio_dev *virt_dev;
1753 uint8_t buffer[4+8+8] = { 0x00, 0x0a, 0x01, 0x01, 0x00, 0x14,
1754 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
1758 if (cmd->dev->handler->type != TYPE_ROM) {
1759 PRINT_ERROR_PR("%s", "READ TOC for non-CDROM device");
1760 scst_set_cmd_error(cmd,
1761 SCST_LOAD_SENSE(scst_sense_invalid_opcode));
1765 if (cmd->cdb[2] & 0x0e/*Format*/) {
1766 PRINT_ERROR_PR("%s", "READ TOC: invalid requested data format");
1767 scst_set_cmd_error(cmd,
1768 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1772 if ((cmd->cdb[6] != 0 && (cmd->cdb[2] & 0x01)) ||
1773 (cmd->cdb[6] > 1 && cmd->cdb[6] != 0xAA)) {
1774 PRINT_ERROR_PR("READ TOC: invalid requested track number %x",
1776 scst_set_cmd_error(cmd,
1777 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1781 length = scst_get_buf_first(cmd, &address);
1782 if (unlikely(length <= 0)) {
1783 PRINT_ERROR_PR("scst_get_buf_first() failed: %d", length);
1784 scst_set_cmd_error(cmd,
1785 SCST_LOAD_SENSE(scst_sense_hardw_error));
1789 virt_dev = (struct scst_fileio_dev *)cmd->dev->dh_priv;
1790 /* FIXME when you have > 8TB ROM device. */
1791 nblocks = (uint32_t)virt_dev->nblocks;
1794 memset(buffer, 0, sizeof(buffer));
1795 buffer[2] = 0x01; /* First Track/Session */
1796 buffer[3] = 0x01; /* Last Track/Session */
1798 if (cmd->cdb[6] <= 1)
1800 /* Fistr TOC Track Descriptor */
1801 buffer[off+1] = 0x14; /* ADDR 0x10 - Q Sub-channel encodes current position data
1802 CONTROL 0x04 - Data track, recoreded uninterrupted */
1803 buffer[off+2] = 0x01; /* Track Number */
1806 if (!(cmd->cdb[2] & 0x01))
1808 /* Lead-out area TOC Track Descriptor */
1809 buffer[off+1] = 0x14;
1810 buffer[off+2] = 0xAA; /* Track Number */
1811 buffer[off+4] = (nblocks >> (BYTE * 3)) & 0xFF; /* Track Start Address */
1812 buffer[off+5] = (nblocks >> (BYTE * 2)) & 0xFF;
1813 buffer[off+6] = (nblocks >> (BYTE * 1)) & 0xFF;
1814 buffer[off+7] = (nblocks >> (BYTE * 0)) & 0xFF;
1818 buffer[1] = off - 2; /* Data Length */
1820 memcpy(address, buffer, (length < off) ? length : off);
1822 scst_put_buf(cmd, address);
1829 static void fileio_exec_prevent_allow_medium_removal(struct scst_cmd *cmd)
1831 struct scst_fileio_dev *virt_dev =
1832 (struct scst_fileio_dev *)cmd->dev->dh_priv;
1834 TRACE_DBG("PERSIST/PREVENT 0x%02x", cmd->cdb[4]);
1837 * No protection here, because in cdrom_fileio_change() the
1838 * activity is suspended and exec() is serialized
1840 if (cmd->dev->handler->type == TYPE_ROM)
1841 virt_dev->prevent_allow_medium_removal =
1842 cmd->cdb[4] & 0x01 ? 1 : 0;
1844 PRINT_ERROR_PR("%s", "Prevent allow medium removal for "
1845 "non-CDROM device");
1846 scst_set_cmd_error(cmd,
1847 SCST_LOAD_SENSE(scst_sense_invalid_opcode));
1853 static int fileio_fsync(struct scst_fileio_tgt_dev *ftgt_dev,
1854 loff_t loff, loff_t len, struct scst_cmd *cmd)
1857 struct file *file = ftgt_dev->fd;
1858 struct inode *inode = file->f_dentry->d_inode;
1859 struct address_space *mapping = file->f_mapping;
1863 if (ftgt_dev->virt_dev->nv_cache)
1866 res = sync_page_range(inode, mapping, loff, len);
1867 if (unlikely(res != 0)) {
1868 PRINT_ERROR_PR("sync_page_range() failed (%d)", res);
1870 scst_set_cmd_error(cmd,
1871 SCST_LOAD_SENSE(scst_sense_write_error));
1875 /* ToDo: flush the device cache, if needed */
1878 TRACE_EXIT_RES(res);
1882 static struct iovec *fileio_alloc_iv(struct scst_cmd *cmd,
1883 struct scst_fileio_tgt_dev *ftgt_dev)
1887 iv_count = scst_get_buf_count(cmd);
1888 if (iv_count > ftgt_dev->iv_count) {
1889 if (ftgt_dev->iv != NULL)
1890 kfree(ftgt_dev->iv);
1891 ftgt_dev->iv = kmalloc(sizeof(*ftgt_dev->iv) * iv_count, GFP_KERNEL);
1892 if (ftgt_dev->iv == NULL) {
1893 PRINT_ERROR_PR("Unable to allocate iv (%d)", iv_count);
1897 ftgt_dev->iv_count = iv_count;
1901 return ftgt_dev->iv;
1904 static void fileio_exec_read(struct scst_cmd *cmd, loff_t loff)
1906 mm_segment_t old_fs;
1908 ssize_t length, full_len;
1910 struct scst_fileio_dev *virt_dev =
1911 (struct scst_fileio_dev *)cmd->dev->dh_priv;
1912 struct scst_fileio_tgt_dev *ftgt_dev =
1913 (struct scst_fileio_tgt_dev *)cmd->tgt_dev->dh_priv;
1914 struct file *fd = ftgt_dev->fd;
1920 iv = fileio_alloc_iv(cmd, ftgt_dev);
1927 length = scst_get_buf_first(cmd, &address);
1928 while (length > 0) {
1932 iv[i].iov_base = address;
1933 iv[i].iov_len = length;
1934 length = scst_get_buf_next(cmd, &address);
1936 if (unlikely(length < 0)) {
1937 PRINT_ERROR_PR("scst_get_buf_() failed: %zd", length);
1938 scst_set_cmd_error(cmd,
1939 SCST_LOAD_SENSE(scst_sense_hardw_error));
1947 if (fd->f_op->llseek) {
1948 err = fd->f_op->llseek(fd, loff, 0/*SEEK_SET*/);
1950 err = default_llseek(fd, loff, 0/*SEEK_SET*/);
1953 PRINT_ERROR_PR("lseek trouble %Ld != %Ld", (uint64_t)err,
1955 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
1960 TRACE_DBG("reading(iv_count %d, full_len %zd)", iv_count, full_len);
1961 if (virt_dev->nullio)
1964 err = fd->f_op->readv(fd, iv, iv_count, &fd->f_pos);
1965 if ((err < 0) || (err < full_len)) {
1966 PRINT_ERROR_PR("readv() returned %Ld from %zd", (uint64_t)err,
1971 scst_set_cmd_error(cmd,
1972 SCST_LOAD_SENSE(scst_sense_read_error));
1982 scst_put_buf(cmd, iv[i].iov_base);
1989 static void fileio_exec_write(struct scst_cmd *cmd, loff_t loff)
1991 mm_segment_t old_fs;
1993 ssize_t length, full_len;
1995 struct scst_fileio_dev *virt_dev =
1996 (struct scst_fileio_dev *)cmd->dev->dh_priv;
1997 struct scst_fileio_tgt_dev *ftgt_dev =
1998 (struct scst_fileio_tgt_dev *)cmd->tgt_dev->dh_priv;
1999 struct file *fd = ftgt_dev->fd;
2000 struct iovec *iv, *eiv;
2001 int iv_count, eiv_count;
2005 iv = fileio_alloc_iv(cmd, ftgt_dev);
2011 length = scst_get_buf_first(cmd, &address);
2012 while (length > 0) {
2014 iv[iv_count].iov_base = address;
2015 iv[iv_count].iov_len = length;
2017 length = scst_get_buf_next(cmd, &address);
2019 if (unlikely(length < 0)) {
2020 PRINT_ERROR_PR("scst_get_buf_() failed: %zd", length);
2021 scst_set_cmd_error(cmd,
2022 SCST_LOAD_SENSE(scst_sense_hardw_error));
2030 if (fd->f_op->llseek) {
2031 err = fd->f_op->llseek(fd, loff, 0 /*SEEK_SET */ );
2033 err = default_llseek(fd, loff, 0 /*SEEK_SET */ );
2036 PRINT_ERROR_PR("lseek trouble %Ld != %Ld", (uint64_t)err,
2038 scst_set_cmd_error(cmd,
2039 SCST_LOAD_SENSE(scst_sense_hardw_error));
2045 eiv_count = iv_count;
2047 TRACE_DBG("writing(eiv_count %d, full_len %zd)", eiv_count, full_len);
2049 if (virt_dev->nullio)
2052 err = fd->f_op->writev(fd, eiv, eiv_count, &fd->f_pos);
2054 PRINT_ERROR_PR("write() returned %Ld from %zd",
2055 (uint64_t)err, full_len);
2059 scst_set_cmd_error(cmd,
2060 SCST_LOAD_SENSE(scst_sense_write_error));
2063 } else if (err < full_len) {
2065 * Probably that's wrong, but sometimes write() returns
2066 * value less, than requested. Let's restart.
2068 int i, e = eiv_count;
2069 TRACE(TRACE_MINOR, "write() returned %d from %zd "
2070 "(iv_count=%d)", (int)err, full_len,
2073 PRINT_INFO_PR("Suspicious: write() returned 0 from "
2074 "%zd (iv_count=%d)", full_len, eiv_count);
2077 for(i = 0; i < e; i++) {
2078 if (eiv->iov_len < err) {
2079 err -= eiv->iov_len;
2084 (uint8_t*)eiv->iov_base + err;
2085 eiv->iov_len -= err;
2096 while (iv_count > 0) {
2097 scst_put_buf(cmd, iv[iv_count-1].iov_base);
2106 static void fileio_exec_verify(struct scst_cmd *cmd, loff_t loff)
2108 mm_segment_t old_fs;
2110 ssize_t length, len_mem = 0;
2111 uint8_t *address_sav, *address;
2113 struct scst_fileio_tgt_dev *ftgt_dev =
2114 (struct scst_fileio_tgt_dev *)cmd->tgt_dev->dh_priv;
2115 struct file *fd = ftgt_dev->fd;
2116 uint8_t *mem_verify = NULL;
2120 if (fileio_fsync(ftgt_dev, loff, cmd->bufflen, cmd) != 0)
2124 * Until the cache is cleared prior the verifying, there is not
2125 * much point in this code. ToDo.
2127 * Nevertherless, this code is valuable if the data have not read
2128 * from the file/disk yet.
2135 if (fd->f_op->llseek) {
2136 err = fd->f_op->llseek(fd, loff, 0/*SEEK_SET*/);
2138 err = default_llseek(fd, loff, 0/*SEEK_SET*/);
2141 PRINT_ERROR_PR("lseek trouble %Ld != %Ld", (uint64_t)err,
2143 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
2147 mem_verify = vmalloc(LEN_MEM);
2148 if (mem_verify == NULL) {
2149 PRINT_ERROR_PR("Unable to allocate memory %d for verify",
2151 scst_set_cmd_error(cmd,
2152 SCST_LOAD_SENSE(scst_sense_hardw_error));
2156 length = scst_get_buf_first(cmd, &address);
2157 address_sav = address;
2158 if (!length && cmd->data_len) {
2159 length = cmd->data_len;
2164 while (length > 0) {
2165 len_mem = length > LEN_MEM ? LEN_MEM : length;
2166 TRACE_DBG("Verify: length %zd - len_mem %zd", length, len_mem);
2168 err = fd->f_op->read(fd, (char*)mem_verify, len_mem, &fd->f_pos);
2169 if ((err < 0) || (err < len_mem)) {
2170 PRINT_ERROR_PR("verify() returned %Ld from %zd",
2171 (uint64_t)err, len_mem);
2175 scst_set_cmd_error(cmd,
2176 SCST_LOAD_SENSE(scst_sense_read_error));
2178 scst_put_buf(cmd, address_sav);
2181 if (compare && memcmp(address, mem_verify, len_mem) != 0)
2183 TRACE_DBG("Verify: error memcmp length %zd", length);
2184 scst_set_cmd_error(cmd,
2185 SCST_LOAD_SENSE(scst_sense_miscompare_error));
2186 scst_put_buf(cmd, address_sav);
2191 if (compare && length <= 0)
2193 scst_put_buf(cmd, address_sav);
2194 length = scst_get_buf_next(cmd, &address);
2195 address_sav = address;
2200 PRINT_ERROR_PR("scst_get_buf_() failed: %zd", length);
2201 scst_set_cmd_error(cmd,
2202 SCST_LOAD_SENSE(scst_sense_hardw_error));
2215 /* Might be called under lock and IRQ off */
2216 static int fileio_task_mgmt_fn(struct scst_mgmt_cmd *mcmd,
2217 struct scst_tgt_dev *tgt_dev)
2219 int res = SCST_DEV_TM_COMPLETED_SUCCESS;
2223 if (mcmd->fn == SCST_ABORT_TASK) {
2224 unsigned long flags;
2225 struct scst_cmd *cmd_to_abort = mcmd->cmd_to_abort;
2226 struct scst_fileio_tgt_dev *ftgt_dev =
2227 (struct scst_fileio_tgt_dev *)cmd_to_abort->tgt_dev->dh_priv;
2229 * Actually, _bh lock is enough here. But, since we
2230 * could be called with IRQ off, the in-kernel debug check
2231 * gives false alarm on using _bh lock. So, let's suppress it.
2233 spin_lock_irqsave(&ftgt_dev->fdev_lock, flags);
2234 if (cmd_to_abort->fileio_in_list) {
2235 TRACE(TRACE_MGMT, "Aborting cmd %p and moving it to "
2236 "the queue head", cmd_to_abort);
2237 list_del(&cmd_to_abort->fileio_cmd_list_entry);
2238 list_add(&cmd_to_abort->fileio_cmd_list_entry,
2239 &ftgt_dev->fdev_cmd_list);
2240 wake_up(&ftgt_dev->fdev_waitQ);
2242 spin_unlock_irqrestore(&ftgt_dev->fdev_lock, flags);
2245 TRACE_EXIT_RES(res);
2249 static inline struct scst_fileio_dev *fileio_alloc_dev(void)
2251 struct scst_fileio_dev *dev;
2252 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
2254 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of virtual "
2258 INIT_LIST_HEAD(&dev->ftgt_list);
2259 init_MUTEX(&dev->ftgt_list_mutex);
2264 static int fileio_proc_update_size(int size, int *len,
2265 off_t *begin, off_t *pos, off_t *offset)
2270 *pos = *begin + *len;
2271 if (*pos < *offset) {
2282 * Called when a file in the /proc/DISK_FILEIO_NAME/DISK_FILEIO_NAME is read
2285 static int disk_fileio_proc(char *buffer, char **start, off_t offset,
2286 int length, int *eof, struct scst_dev_type *dev_type, int inout)
2288 int res = 0, action;
2289 char *p, *name, *file_name;
2290 struct scst_fileio_dev *virt_dev, *vv;
2292 off_t begin = 0, pos = 0;
2296 /* VERY UGLY code. You can rewrite it if you want */
2298 if (down_interruptible(&scst_fileio_mutex) != 0) {
2303 if (inout == 0) { /* read */
2304 size = scnprintf(buffer, length, "%-17s %-12s %-15s %s\n",
2305 "Name", "Size(MB)", "Options", "File name");
2306 if (fileio_proc_update_size(size, &len, &begin, &pos, &offset)) {
2311 list_for_each_entry(virt_dev, &disk_fileio_dev_list,
2312 fileio_dev_list_entry)
2315 size = scnprintf(buffer + len, length - len,
2316 "%-17s %-13d", virt_dev->name,
2317 (uint32_t)(virt_dev->file_size >> 20));
2318 if (fileio_proc_update_size(size, &len, &begin, &pos,
2324 if (virt_dev->wt_flag) {
2325 size = scnprintf(buffer + len, length - len, "WT");
2327 if (fileio_proc_update_size(size, &len, &begin,
2333 if (virt_dev->nv_cache) {
2334 size = scnprintf(buffer + len, length - len,
2337 if (fileio_proc_update_size(size, &len, &begin,
2343 if (virt_dev->rd_only_flag) {
2344 size = scnprintf(buffer + len, length - len,
2347 if (fileio_proc_update_size(size, &len, &begin,
2353 if (virt_dev->o_direct_flag) {
2354 size = scnprintf(buffer + len, length - len,
2357 if (fileio_proc_update_size(size, &len, &begin,
2363 if (virt_dev->nullio) {
2364 size = scnprintf(buffer + len, length - len,
2365 c ? ",NIO" : "NIO");
2367 if (fileio_proc_update_size(size, &len, &begin,
2374 size = scnprintf(buffer + len, length - len, " ");
2375 if (fileio_proc_update_size(size, &len, &begin, &pos,
2382 size = scnprintf(buffer + len, length - len, "%s\n",
2383 virt_dev->file_name);
2384 if (fileio_proc_update_size(size, &len, &begin,
2390 *start = buffer + (offset - begin);
2391 len -= (offset - begin);
2398 uint32_t block_size = DEF_DISK_BLOCKSIZE;
2399 int block_shift = DEF_DISK_BLOCKSIZE_SHIFT;
2401 if (p[strlen(p) - 1] == '\n') {
2402 p[strlen(p) - 1] = '\0';
2404 if (!strncmp("close ", p, 6)) {
2407 } else if (!strncmp("open ", p, 5)) {
2411 PRINT_ERROR_PR("Unknown action \"%s\"", p);
2416 while (isspace(*p) && *p != '\0')
2419 while (!isspace(*p) && *p != '\0')
2422 if (*name == '\0') {
2423 PRINT_ERROR_PR("%s", "Name required");
2426 } else if (strlen(name) >= sizeof(virt_dev->name)) {
2427 PRINT_ERROR_PR("Name is too long (max %zd "
2428 "characters)", sizeof(virt_dev->name)-1);
2433 if (action) { /* open */
2435 list_for_each_entry(vv, &disk_fileio_dev_list,
2436 fileio_dev_list_entry)
2438 if (strcmp(vv->name, name) == 0) {
2444 PRINT_ERROR_PR("Virtual device with name "
2445 "%s already exist", name);
2450 while (isspace(*p) && *p != '\0')
2453 while (!isspace(*p) && *p != '\0')
2456 if (*file_name == '\0') {
2457 PRINT_ERROR_PR("%s", "File name required");
2460 } else if (*file_name != '/') {
2461 PRINT_ERROR_PR("File path \"%s\" is not "
2462 "absolute", file_name);
2467 virt_dev = fileio_alloc_dev();
2468 if (virt_dev == NULL) {
2469 TRACE(TRACE_OUT_OF_MEM, "%s",
2470 "Allocation of virt_dev failed");
2475 while (isspace(*p) && *p != '\0')
2481 block_size = simple_strtoul(p, &pp, 0);
2483 if ((*p != '\0') && !isspace(*p)) {
2484 PRINT_ERROR_PR("Parse error: \"%s\"", p);
2488 while (isspace(*p) && *p != '\0')
2499 if (block_shift < 9) {
2500 PRINT_ERROR_PR("Wrong block size %d",
2506 virt_dev->block_size = block_size;
2507 virt_dev->block_shift = block_shift;
2509 while (*p != '\0') {
2510 if (!strncmp("WRITE_THROUGH", p, 13)) {
2512 virt_dev->wt_flag = 1;
2513 TRACE_DBG("%s", "WRITE_THROUGH");
2514 } else if (!strncmp("NV_CACHE", p, 8)) {
2516 virt_dev->nv_cache = 1;
2517 TRACE_DBG("%s", "NON-VOLATILE CACHE");
2518 } else if (!strncmp("READ_ONLY", p, 9)) {
2520 virt_dev->rd_only_flag = 1;
2521 TRACE_DBG("%s", "READ_ONLY");
2522 } else if (!strncmp("O_DIRECT", p, 8)) {
2524 virt_dev->o_direct_flag = 1;
2525 TRACE_DBG("%s", "O_DIRECT");
2526 } else if (!strncmp("NULLIO", p, 6)) {
2528 virt_dev->nullio = 1;
2529 TRACE_DBG("%s", "NULLIO");
2531 PRINT_ERROR_PR("Unknown flag \"%s\"", p);
2535 while (isspace(*p) && *p != '\0')
2539 strcpy(virt_dev->name, name);
2541 len = strlen(file_name) + 1;
2542 virt_dev->file_name = kmalloc(len, GFP_KERNEL);
2543 if (virt_dev->file_name == NULL) {
2544 TRACE(TRACE_OUT_OF_MEM, "%s",
2545 "Allocation of file_name failed");
2549 strncpy(virt_dev->file_name, file_name, len);
2551 list_add_tail(&virt_dev->fileio_dev_list_entry,
2552 &disk_fileio_dev_list);
2555 scst_register_virtual_device(&disk_devtype_fileio,
2557 if (virt_dev->virt_id < 0) {
2558 res = virt_dev->virt_id;
2559 goto out_free_vpath;
2561 TRACE_DBG("Added virt_dev (name %s, file name %s, "
2562 "id %d, block size %d) to "
2563 "disk_fileio_dev_list", virt_dev->name,
2564 virt_dev->file_name, virt_dev->virt_id,
2565 virt_dev->block_size);
2566 } else { /* close */
2568 list_for_each_entry(vv, &disk_fileio_dev_list,
2569 fileio_dev_list_entry)
2571 if (strcmp(vv->name, name) == 0) {
2576 if (virt_dev == NULL) {
2577 PRINT_ERROR_PR("Device %s not found", name);
2581 scst_unregister_virtual_device(virt_dev->virt_id);
2582 PRINT_INFO_PR("Virtual device %s unregistered",
2584 TRACE_DBG("virt_id %d unregister", virt_dev->virt_id);
2586 list_del(&virt_dev->fileio_dev_list_entry);
2588 kfree(virt_dev->file_name);
2595 up(&scst_fileio_mutex);
2598 TRACE_EXIT_RES(res);
2602 list_del(&virt_dev->fileio_dev_list_entry);
2603 kfree(virt_dev->file_name);
2610 /* scst_fileio_mutex supposed to be held */
2611 static int cdrom_fileio_open(char *p, char *name)
2613 struct scst_fileio_dev *virt_dev, *vv;
2620 list_for_each_entry(vv, &cdrom_fileio_dev_list,
2621 fileio_dev_list_entry)
2623 if (strcmp(vv->name, name) == 0) {
2629 PRINT_ERROR_PR("Virtual device with name "
2630 "%s already exist", name);
2635 while (isspace(*p) && *p != '\0')
2638 while (!isspace(*p) && *p != '\0')
2641 if (*file_name == '\0') {
2643 TRACE_DBG("%s", "No media");
2644 } else if (*file_name != '/') {
2645 PRINT_ERROR_PR("File path \"%s\" is not "
2646 "absolute", file_name);
2652 virt_dev = fileio_alloc_dev();
2653 if (virt_dev == NULL) {
2654 TRACE(TRACE_OUT_OF_MEM, "%s",
2655 "Allocation of virt_dev failed");
2659 virt_dev->cdrom_empty = cdrom_empty;
2661 strcpy(virt_dev->name, name);
2663 if (!virt_dev->cdrom_empty) {
2664 len = strlen(file_name) + 1;
2665 virt_dev->file_name = kmalloc(len, GFP_KERNEL);
2666 if (virt_dev->file_name == NULL) {
2667 TRACE(TRACE_OUT_OF_MEM, "%s",
2668 "Allocation of file_name failed");
2672 strncpy(virt_dev->file_name, file_name, len);
2675 list_add_tail(&virt_dev->fileio_dev_list_entry,
2676 &cdrom_fileio_dev_list);
2679 scst_register_virtual_device(&cdrom_devtype_fileio,
2681 if (virt_dev->virt_id < 0) {
2682 res = virt_dev->virt_id;
2683 goto out_free_vpath;
2685 TRACE_DBG("Added virt_dev (name %s file_name %s id %d) "
2686 "to cdrom_fileio_dev_list", virt_dev->name,
2687 virt_dev->file_name, virt_dev->virt_id);
2693 list_del(&virt_dev->fileio_dev_list_entry);
2694 kfree(virt_dev->file_name);
2701 /* scst_fileio_mutex supposed to be held */
2702 static int cdrom_fileio_close(char *name)
2704 struct scst_fileio_dev *virt_dev, *vv;
2708 list_for_each_entry(vv, &cdrom_fileio_dev_list,
2709 fileio_dev_list_entry)
2711 if (strcmp(vv->name, name) == 0) {
2716 if (virt_dev == NULL) {
2717 PRINT_ERROR_PR("Virtual device with name "
2718 "%s not found", name);
2722 scst_unregister_virtual_device(virt_dev->virt_id);
2723 PRINT_INFO_PR("Virtual device %s unregistered",
2725 TRACE_DBG("virt_id %d unregister", virt_dev->virt_id);
2727 list_del(&virt_dev->fileio_dev_list_entry);
2729 if (virt_dev->file_name)
2730 kfree(virt_dev->file_name);
2737 /* scst_fileio_mutex supposed to be held */
2738 static int cdrom_fileio_change(char *p, char *name)
2741 struct scst_fileio_tgt_dev *ftgt_dev;
2743 mm_segment_t old_fs;
2744 struct scst_fileio_dev *virt_dev, *vv;
2745 char *file_name, *fn, *old_fn;
2750 list_for_each_entry(vv, &cdrom_fileio_dev_list,
2751 fileio_dev_list_entry)
2753 if (strcmp(vv->name, name) == 0) {
2758 if (virt_dev == NULL) {
2759 PRINT_ERROR_PR("Virtual device with name "
2760 "%s not found", name);
2765 while (isspace(*p) && *p != '\0')
2768 while (!isspace(*p) && *p != '\0')
2771 if (*file_name == '\0') {
2772 virt_dev->cdrom_empty = 1;
2773 TRACE_DBG("%s", "No media");
2774 } else if (*file_name != '/') {
2775 PRINT_ERROR_PR("File path \"%s\" is not "
2776 "absolute", file_name);
2780 virt_dev->cdrom_empty = 0;
2782 old_fn = virt_dev->file_name;
2784 if (!virt_dev->cdrom_empty) {
2785 len = strlen(file_name) + 1;
2786 fn = kmalloc(len, GFP_KERNEL);
2788 TRACE(TRACE_OUT_OF_MEM, "%s",
2789 "Allocation of file_name failed");
2794 strncpy(fn, file_name, len);
2795 virt_dev->file_name = fn;
2797 fd = fileio_open(virt_dev);
2800 PRINT_ERROR_PR("filp_open(%s) returned an error %d",
2801 virt_dev->file_name, res);
2804 if ((fd->f_op == NULL) || (fd->f_op->readv == NULL)) {
2805 PRINT_ERROR_PR("%s", "Wrong f_op or FS doesn't "
2806 "have required capabilities");
2808 filp_close(fd, NULL);
2815 if (fd->f_op->llseek) {
2816 err = fd->f_op->llseek(fd, 0, 2/*SEEK_END*/);
2818 err = default_llseek(fd, 0, 2/*SEEK_END*/);
2821 filp_close(fd, NULL);
2824 PRINT_ERROR_PR("llseek %s returned an error %d",
2825 virt_dev->file_name, res);
2832 virt_dev->file_name = fn;
2835 scst_suspend_activity();
2837 if (virt_dev->prevent_allow_medium_removal) {
2838 PRINT_ERROR_PR("Prevent medium removal for "
2839 "virtual device with name %s", name);
2841 goto out_free_resume;
2844 virt_dev->file_size = err;
2845 virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift;
2846 if (!virt_dev->cdrom_empty)
2847 virt_dev->media_changed = 1;
2849 down(&virt_dev->ftgt_list_mutex);
2850 list_for_each_entry(ftgt_dev, &virt_dev->ftgt_list,
2853 if (!virt_dev->cdrom_empty) {
2854 fd = fileio_open(virt_dev);
2857 PRINT_ERROR_PR("filp_open(%s) returned an error %d, "
2858 "closing the device", virt_dev->file_name, res);
2859 up(&virt_dev->ftgt_list_mutex);
2860 goto out_err_resume;
2865 filp_close(ftgt_dev->fd, NULL);
2868 up(&virt_dev->ftgt_list_mutex);
2870 if (!virt_dev->cdrom_empty) {
2871 PRINT_INFO_PR("Changed SCSI target virtual cdrom %s "
2872 "(file=\"%s\", fs=%LdMB, bs=%d, nblocks=%Ld, cyln=%Ld%s)",
2873 virt_dev->name, virt_dev->file_name,
2874 virt_dev->file_size >> 20, virt_dev->block_size,
2875 virt_dev->nblocks, virt_dev->nblocks/64/32,
2876 virt_dev->nblocks < 64*32 ? " !WARNING! cyln less "
2879 PRINT_INFO_PR("Removed media from SCSI target virtual cdrom %s",
2887 scst_resume_activity();
2893 virt_dev->file_name = old_fn;
2898 virt_dev->file_name = old_fn;
2903 virt_dev->file_name = old_fn;
2905 scst_resume_activity();
2906 cdrom_fileio_close(name);
2911 * Called when a file in the /proc/CDROM_FILEIO_NAME/CDROM_FILEIO_NAME is read
2914 static int cdrom_fileio_proc(char *buffer, char **start, off_t offset,
2915 int length, int *eof, struct scst_dev_type *dev_type, int inout)
2917 int res = 0, action;
2919 struct scst_fileio_dev *virt_dev;
2921 off_t begin = 0, pos = 0;
2925 if (down_interruptible(&scst_fileio_mutex) != 0) {
2930 if (inout == 0) { /* read */
2931 size = scnprintf(buffer, length, "%-17s %-9s %s\n",
2932 "Name", "Size(MB)", "File name");
2933 if (fileio_proc_update_size(size, &len, &begin, &pos,
2939 list_for_each_entry(virt_dev, &cdrom_fileio_dev_list,
2940 fileio_dev_list_entry)
2942 size = scnprintf(buffer + len, length - len,
2943 "%-17s %-9d %s\n", virt_dev->name,
2944 (uint32_t)(virt_dev->file_size >> 20),
2945 virt_dev->file_name);
2946 if (fileio_proc_update_size(size, &len, &begin,
2952 *start = buffer + (offset - begin);
2953 len -= (offset - begin);
2960 if (p[strlen(p) - 1] == '\n') {
2961 p[strlen(p) - 1] = '\0';
2963 if (!strncmp("close ", p, 6)) {
2966 } else if (!strncmp("change ", p, 5)) {
2969 } else if (!strncmp("open ", p, 5)) {
2973 PRINT_ERROR_PR("Unknown action \"%s\"", p);
2978 while (isspace(*p) && *p != '\0')
2981 while (!isspace(*p) && *p != '\0')
2984 if (*name == '\0') {
2985 PRINT_ERROR_PR("%s", "Name required");
2988 } else if (strlen(name) >= sizeof(virt_dev->name)) {
2989 PRINT_ERROR_PR("Name is too long (max %zd "
2990 "characters)", sizeof(virt_dev->name)-1);
2995 if (action == 2) { /* open */
2996 res = cdrom_fileio_open(p, name);
2999 } else if (action == 1) { /* change */
3000 res = cdrom_fileio_change(p, name);
3003 } else { /* close */
3004 res = cdrom_fileio_close(name);
3012 up(&scst_fileio_mutex);
3015 TRACE_EXIT_RES(res);
3020 static int fileio_proc_help_build(struct scst_dev_type *dev_type)
3023 struct proc_dir_entry *p, *root;
3027 root = scst_proc_get_dev_type_root(dev_type);
3029 p = create_proc_read_entry(FILEIO_PROC_HELP,
3030 S_IFREG | S_IRUGO, root,
3031 fileio_proc_help_read,
3032 (dev_type->type == TYPE_DISK) ?
3033 disk_fileio_proc_help_string :
3034 cdrom_fileio_proc_help_string);
3036 PRINT_ERROR_PR("Not enough memory to register dev "
3037 "handler %s entry %s in /proc",
3038 dev_type->name, FILEIO_PROC_HELP);
3045 TRACE_EXIT_RES(res);
3049 static void fileio_proc_help_destroy(struct scst_dev_type *dev_type)
3051 struct proc_dir_entry *root;
3055 root = scst_proc_get_dev_type_root(dev_type);
3057 remove_proc_entry(FILEIO_PROC_HELP, root);
3062 static int fileio_proc_help_read(char *buffer, char **start, off_t offset,
3063 int length, int *eof, void *data)
3066 char *s = (char*)data;
3070 if (offset < strlen(s))
3071 res = scnprintf(buffer, length, "%s", &s[offset]);
3073 TRACE_EXIT_RES(res);
3077 static int __init init_scst_fileio(struct scst_dev_type *devtype)
3083 devtype->module = THIS_MODULE;
3085 res = scst_register_virtual_dev_driver(devtype);
3089 res = scst_dev_handler_build_std_proc(devtype);
3093 res = fileio_proc_help_build(devtype);
3095 goto out_destroy_proc;
3099 TRACE_EXIT_RES(res);
3103 scst_dev_handler_destroy_std_proc(devtype);
3106 scst_unregister_virtual_dev_driver(devtype);
3110 static void __exit exit_scst_fileio(struct scst_dev_type *devtype,
3111 struct list_head *fileio_dev_list)
3115 down(&scst_fileio_mutex);
3117 struct scst_fileio_dev *virt_dev;
3119 if (list_empty(fileio_dev_list))
3122 virt_dev = list_entry(fileio_dev_list->next, typeof(*virt_dev),
3123 fileio_dev_list_entry);
3125 scst_unregister_virtual_device(virt_dev->virt_id);
3127 list_del(&virt_dev->fileio_dev_list_entry);
3129 PRINT_INFO_PR("Virtual device %s unregistered", virt_dev->name);
3130 TRACE_DBG("virt_id %d", virt_dev->virt_id);
3131 kfree(virt_dev->file_name);
3134 up(&scst_fileio_mutex);
3136 fileio_proc_help_destroy(devtype);
3137 scst_dev_handler_destroy_std_proc(devtype);
3139 scst_unregister_virtual_dev_driver(devtype);
3145 static int __init init_scst_fileio_driver(void)
3148 res = init_scst_fileio(&disk_devtype_fileio);
3152 res = init_scst_fileio(&cdrom_devtype_fileio);
3160 exit_scst_fileio(&disk_devtype_fileio, &disk_fileio_dev_list);
3164 static void __exit exit_scst_fileio_driver(void)
3166 exit_scst_fileio(&disk_devtype_fileio, &disk_fileio_dev_list);
3167 exit_scst_fileio(&cdrom_devtype_fileio, &cdrom_fileio_dev_list);
3170 * Wait for one sec. to allow the thread(s) actually exit,
3171 * otherwise we can get Oops. Any better way?
3174 unsigned long t = jiffies;
3175 TRACE_DBG("%s", "Waiting 1 sec...");
3176 while ((jiffies - t) < HZ)
3181 module_init(init_scst_fileio_driver);
3182 module_exit(exit_scst_fileio_driver);
3184 MODULE_LICENSE("GPL");