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 <linux/vmalloc.h>
36 #include <asm/atomic.h>
38 #define LOG_PREFIX "dev_fileio"
39 #include "scst_debug.h"
41 #include "scst_dev_handler.h"
43 #include "scst_debug.c"
45 /* 8 byte ASCII Vendor of the FILE IO target */
46 #define SCST_FIO_VENDOR "SCST_FIO"
47 /* 4 byte ASCII Product Revision Level of the FILE IO target - left aligned */
48 #define SCST_FIO_REV " 095"
50 #define READ_CAP_LEN 8
51 #define READ_CAP16_LEN 32
55 #define INQ_BUF_SZ 128
59 #define MSENSE_BUF_SZ 256
60 #define DBD 0x08 /* disable block descriptor */
61 #define WP 0x80 /* write protect */
62 #define DPOFUA 0x10 /* DPOFUA bit */
63 #define WCE 0x04 /* write cache enable */
65 #define PF 0x10 /* page format */
66 #define SP 0x01 /* save pages */
67 #define PS 0x80 /* parameter saveable */
70 #define DEF_DISK_BLOCKSIZE 512
71 #define DEF_DISK_BLOCKSIZE_SHIFT 9
72 #define DEF_CDROM_BLOCKSIZE 2048
73 #define DEF_CDROM_BLOCKSIZE_SHIFT 11
74 #define DEF_SECTORS_PER 63
75 #define LEN_MEM (32 * 1024)
76 #define DISK_FILEIO_NAME "disk_fileio"
77 #define CDROM_FILEIO_NAME "cdrom_fileio"
79 #define FILEIO_PROC_HELP "help"
81 #if defined(DEBUG) || defined(TRACING)
82 unsigned long trace_flag = SCST_DEFAULT_DEV_LOG_FLAGS;
85 struct scst_fileio_dev {
89 loff_t file_size; /* in bytes */
90 unsigned int rd_only_flag:1;
91 unsigned int wt_flag:1;
92 unsigned int nv_cache:1;
93 unsigned int o_direct_flag:1;
94 unsigned int media_changed:1;
95 unsigned int prevent_allow_medium_removal:1;
96 unsigned int nullio:1;
97 unsigned int cdrom_empty:1;
99 char name[16+1]; /* Name of virtual device,
100 must be <= SCSI Model + 1 */
101 char *file_name; /* File name */
102 struct list_head fileio_dev_list_entry;
103 struct list_head ftgt_list;
104 struct semaphore ftgt_list_mutex;
107 struct scst_fileio_tgt_dev {
108 spinlock_t fdev_lock;
109 enum scst_cmd_queue_type last_write_cmd_queue_type;
114 struct list_head fdev_cmd_list;
115 wait_queue_head_t fdev_waitQ;
116 struct scst_fileio_dev *virt_dev;
117 atomic_t threads_count;
118 struct semaphore shutdown_mutex;
119 struct list_head ftgt_list_entry;
122 static int fileio_attach(struct scst_device *dev);
123 static void fileio_detach(struct scst_device *dev);
124 static int fileio_attach_tgt(struct scst_tgt_dev *tgt_dev);
125 static void fileio_detach_tgt(struct scst_tgt_dev *tgt_dev);
126 static int disk_fileio_parse(struct scst_cmd *, const struct scst_info_cdb *info_cdb);
127 static int disk_fileio_exec(struct scst_cmd *cmd);
128 static int cdrom_fileio_parse(struct scst_cmd *, const struct scst_info_cdb *info_cdb);
129 static int cdrom_fileio_exec(struct scst_cmd *cmd);
130 static void fileio_exec_read(struct scst_cmd *cmd, loff_t loff);
131 static void fileio_exec_write(struct scst_cmd *cmd, loff_t loff);
132 static void fileio_exec_verify(struct scst_cmd *cmd, loff_t loff);
133 static int fileio_task_mgmt_fn(struct scst_mgmt_cmd *mcmd,
134 struct scst_tgt_dev *tgt_dev);
135 static void fileio_exec_read_capacity(struct scst_cmd *cmd);
136 static void fileio_exec_read_capacity16(struct scst_cmd *cmd);
137 static void fileio_exec_inquiry(struct scst_cmd *cmd);
138 static void fileio_exec_mode_sense(struct scst_cmd *cmd);
139 static void fileio_exec_mode_select(struct scst_cmd *cmd);
140 static void fileio_exec_read_toc(struct scst_cmd *cmd);
141 static void fileio_exec_prevent_allow_medium_removal(struct scst_cmd *cmd);
142 static int fileio_fsync(struct scst_fileio_tgt_dev *ftgt_dev,
143 loff_t loff, loff_t len, struct scst_cmd *cmd);
144 static int disk_fileio_proc(char *buffer, char **start, off_t offset,
145 int length, int *eof, struct scst_dev_type *dev_type, int inout);
146 static int cdrom_fileio_proc(char *buffer, char **start, off_t offset,
147 int length, int *eof, struct scst_dev_type *dev_type, int inout);
148 static int fileio_proc_help_read(char *buffer, char **start,off_t offset,
149 int length, int *eof, void *data);
151 #define DISK_TYPE_FILEIO { \
152 name: DISK_FILEIO_NAME, \
156 dev_done_atomic: 1, \
157 attach: fileio_attach, \
158 detach: fileio_detach, \
159 attach_tgt: fileio_attach_tgt, \
160 detach_tgt: fileio_detach_tgt, \
161 parse: disk_fileio_parse, \
162 exec: disk_fileio_exec, \
163 task_mgmt_fn: fileio_task_mgmt_fn, \
164 proc_info: disk_fileio_proc, \
167 #define CDROM_TYPE_FILEIO { \
168 name: CDROM_FILEIO_NAME, \
172 dev_done_atomic: 1, \
173 attach: fileio_attach, \
174 detach: fileio_detach, \
175 attach_tgt: fileio_attach_tgt, \
176 detach_tgt: fileio_detach_tgt, \
177 parse: cdrom_fileio_parse, \
178 exec: cdrom_fileio_exec, \
179 task_mgmt_fn: fileio_task_mgmt_fn, \
180 proc_info: cdrom_fileio_proc, \
183 DECLARE_MUTEX(scst_fileio_mutex);
184 static LIST_HEAD(disk_fileio_dev_list);
185 static LIST_HEAD(cdrom_fileio_dev_list);
187 static struct scst_dev_type disk_devtype_fileio = DISK_TYPE_FILEIO;
188 static struct scst_dev_type cdrom_devtype_fileio = CDROM_TYPE_FILEIO;
190 static char *disk_fileio_proc_help_string =
191 "echo \"open|close NAME [FILE_NAME [BLOCK_SIZE] [WRITE_THROUGH "
192 "READ_ONLY O_DIRECT NULLIO NV_CACHE]]\" >/proc/scsi_tgt/"
193 DISK_FILEIO_NAME "/" DISK_FILEIO_NAME "\n";
195 static char *cdrom_fileio_proc_help_string =
196 "echo \"open|change|close NAME [FILE_NAME]\" "
197 ">/proc/scsi_tgt/" CDROM_FILEIO_NAME "/" CDROM_FILEIO_NAME "\n";
199 #define FILEIO_THREAD_FLAGS CLONE_KERNEL
201 /**************************************************************
202 * Function: fileio_open
206 * Returns : fd, use IS_ERR(fd) to get error status
209 *************************************************************/
210 static struct file *fileio_open(const struct scst_fileio_dev *virt_dev)
217 if (virt_dev->rd_only_flag)
218 open_flags |= O_RDONLY;
220 open_flags |= O_RDWR;
221 if (virt_dev->o_direct_flag)
222 open_flags |= O_DIRECT;
223 if (virt_dev->wt_flag)
224 open_flags |= O_SYNC;
225 TRACE_DBG("Opening file %s, flags 0x%x", virt_dev->file_name, open_flags);
226 fd = filp_open(virt_dev->file_name, O_LARGEFILE | open_flags, 0600);
232 /**************************************************************
233 * Function: fileio_attach
237 * Returns : 1 if attached, error code otherwise
240 *************************************************************/
241 static int fileio_attach(struct scst_device *dev)
247 struct scst_fileio_dev *virt_dev = NULL, *vv;
248 struct list_head *fileio_dev_list;
252 TRACE_DBG("virt_id %d (%s)", dev->virt_id, dev->virt_name);
254 if (dev->virt_id == 0) {
255 PRINT_ERROR_PR("%s", "Not a virtual device");
260 fileio_dev_list = (dev->handler->type == TYPE_DISK) ?
261 &disk_fileio_dev_list :
262 &cdrom_fileio_dev_list;
265 * scst_fileio_mutex must be already taken before
266 * scst_register_virtual_device()
268 list_for_each_entry(vv, fileio_dev_list, fileio_dev_list_entry)
270 if (strcmp(vv->name, dev->virt_name) == 0) {
276 if (virt_dev == NULL) {
277 PRINT_ERROR_PR("Device %s not found", dev->virt_name);
282 if (dev->handler->type == TYPE_ROM)
283 virt_dev->rd_only_flag = 1;
285 if (!virt_dev->cdrom_empty) {
286 fd = fileio_open(virt_dev);
289 PRINT_ERROR_PR("filp_open(%s) returned an error %d",
290 virt_dev->file_name, res);
294 if ((fd->f_op == NULL) || (fd->f_op->readv == NULL) ||
295 (fd->f_op->writev == NULL))
297 PRINT_ERROR_PR("%s", "Wrong f_op or FS doesn't have "
298 "required capabilities");
306 if (fd->f_op->llseek) {
307 err = fd->f_op->llseek(fd, 0, 2/*SEEK_END*/);
309 err = default_llseek(fd, 0, 2/*SEEK_END*/);
314 PRINT_ERROR_PR("llseek %s returned an error %d",
315 virt_dev->file_name, res);
318 virt_dev->file_size = err;
319 TRACE_DBG("size of file: %Ld", (uint64_t)err);
321 filp_close(fd, NULL);
323 virt_dev->file_size = 0;
325 if (dev->handler->type == TYPE_DISK) {
326 virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift;
328 virt_dev->block_size = DEF_CDROM_BLOCKSIZE;
329 virt_dev->block_shift = DEF_CDROM_BLOCKSIZE_SHIFT;
330 virt_dev->nblocks = virt_dev->file_size >> DEF_CDROM_BLOCKSIZE_SHIFT;
333 if (!virt_dev->cdrom_empty) {
334 PRINT_INFO_PR("Attached SCSI target virtual %s %s "
335 "(file=\"%s\", fs=%LdMB, bs=%d, nblocks=%Ld, cyln=%Ld%s)",
336 (dev->handler->type == TYPE_DISK) ? "disk" : "cdrom",
337 virt_dev->name, virt_dev->file_name,
338 virt_dev->file_size >> 20, virt_dev->block_size,
339 virt_dev->nblocks, virt_dev->nblocks/64/32,
340 virt_dev->nblocks < 64*32 ? " !WARNING! cyln less than 1" : "");
342 PRINT_INFO_PR("Attached empty SCSI target virtual cdrom %s",
346 dev->dh_priv = virt_dev;
353 filp_close(fd, NULL);
357 /************************************************************
358 * Function: fileio_detach
364 * Description: Called to detach this device type driver
365 ************************************************************/
366 static void fileio_detach(struct scst_device *dev)
368 struct scst_fileio_dev *virt_dev =
369 (struct scst_fileio_dev *)dev->dh_priv;
373 TRACE_DBG("virt_id %d", dev->virt_id);
375 PRINT_INFO_PR("Detached SCSI target virtual device %s (\"%s\")",
376 virt_dev->name, virt_dev->file_name);
378 /* virt_dev will be freed by the caller */
385 static inline int fileio_sync_queue_type(enum scst_cmd_queue_type qt)
388 case SCST_CMD_QUEUE_ORDERED:
389 case SCST_CMD_QUEUE_HEAD_OF_QUEUE:
396 static inline int fileio_need_pre_sync(enum scst_cmd_queue_type cwqt,
397 enum scst_cmd_queue_type lwqt)
399 if (fileio_sync_queue_type(cwqt))
400 if (!fileio_sync_queue_type(lwqt))
405 static void fileio_do_job(struct scst_cmd *cmd)
409 int opcode = cmd->cdb[0];
411 struct scst_device *dev = cmd->dev;
412 struct scst_fileio_dev *virt_dev =
413 (struct scst_fileio_dev *)dev->dh_priv;
418 if (unlikely(test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))) {
419 TRACE_MGMT_DBG("Flag ABORTED set for "
420 "cmd %p (tag %d), skipping", cmd, cmd->tag);
429 lba_start = (((cmd->cdb[1] & 0x1f) << (BYTE * 2)) +
430 (cmd->cdb[2] << (BYTE * 1)) +
431 (cmd->cdb[3] << (BYTE * 0)));
432 data_len = cmd->bufflen;
440 case WRITE_VERIFY_12:
442 lba_start = be32_to_cpu(*(u32 *)&cmd->cdb[2]);
443 data_len = cmd->bufflen;
445 case SYNCHRONIZE_CACHE:
446 lba_start = be32_to_cpu(*(u32 *)&cmd->cdb[2]);
447 data_len = ((cmd->cdb[7] << (BYTE * 1)) +
448 (cmd->cdb[8] << (BYTE * 0))) << virt_dev->block_shift;
450 data_len = virt_dev->file_size -
451 ((loff_t)lba_start << virt_dev->block_shift);
455 case WRITE_VERIFY_16:
457 lba_start = be64_to_cpu(*(u64*)&cmd->cdb[2]);
458 data_len = cmd->bufflen;
465 loff = (loff_t)lba_start << virt_dev->block_shift;
466 TRACE_DBG("cmd %p, lba_start %Ld, loff %Ld, data_len %Ld", cmd,
467 lba_start, (uint64_t)loff, (uint64_t)data_len);
468 if (unlikely(loff < 0) || unlikely(data_len < 0) ||
469 unlikely((loff + data_len) > virt_dev->file_size)) {
470 PRINT_INFO_PR("Access beyond the end of the device "
471 "(%lld of %lld, len %Ld)", (uint64_t)loff,
472 (uint64_t)virt_dev->file_size, (uint64_t)data_len);
473 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
474 scst_sense_block_out_range_error));
482 fua = (cmd->cdb[1] & 0x8) && !virt_dev->wt_flag;
483 if (cmd->cdb[1] & 0x8) {
484 TRACE(TRACE_SCSI, "FUA(%d): loff=%Ld, "
485 "data_len=%Ld", fua, (uint64_t)loff,
496 fileio_exec_read(cmd, loff);
502 if (likely(!virt_dev->rd_only_flag)) {
504 struct scst_fileio_tgt_dev *ftgt_dev =
505 (struct scst_fileio_tgt_dev*)
506 cmd->tgt_dev->dh_priv;
507 enum scst_cmd_queue_type last_queue_type =
508 ftgt_dev->last_write_cmd_queue_type;
509 ftgt_dev->last_write_cmd_queue_type = cmd->queue_type;
510 if (fileio_need_pre_sync(cmd->queue_type, last_queue_type) &&
511 !virt_dev->wt_flag) {
512 TRACE(TRACE_SCSI/*|TRACE_SPECIAL*/, "ORDERED "
513 "WRITE(%d): loff=%Ld, data_len=%Ld",
514 cmd->queue_type, (uint64_t)loff,
517 if (fileio_fsync(ftgt_dev, 0, 0, cmd) != 0)
520 fileio_exec_write(cmd, loff);
521 /* O_SYNC flag is used for wt_flag devices */
523 fileio_fsync(ftgt_dev, loff, data_len, cmd);
525 TRACE_DBG("%s", "Attempt to write to read-only device");
526 scst_set_cmd_error(cmd,
527 SCST_LOAD_SENSE(scst_sense_data_protect));
531 case WRITE_VERIFY_12:
532 case WRITE_VERIFY_16:
533 if (likely(!virt_dev->rd_only_flag)) {
535 struct scst_fileio_tgt_dev *ftgt_dev =
536 (struct scst_fileio_tgt_dev*)
537 cmd->tgt_dev->dh_priv;
538 enum scst_cmd_queue_type last_queue_type =
539 ftgt_dev->last_write_cmd_queue_type;
540 ftgt_dev->last_write_cmd_queue_type = cmd->queue_type;
541 if (fileio_need_pre_sync(cmd->queue_type, last_queue_type) &&
542 !virt_dev->wt_flag) {
543 TRACE(TRACE_SCSI/*|TRACE_SPECIAL*/, "ORDERED "
544 "WRITE_VERIFY(%d): loff=%Ld, data_len=%Ld",
545 cmd->queue_type, (uint64_t)loff,
548 if (fileio_fsync(ftgt_dev, 0, 0, cmd) != 0)
551 fileio_exec_write(cmd, loff);
552 /* O_SYNC flag is used for wt_flag devices */
553 if (cmd->status == 0)
554 fileio_exec_verify(cmd, loff);
556 fileio_fsync(ftgt_dev, loff, data_len, cmd);
558 TRACE_DBG("%s", "Attempt to write to read-only device");
559 scst_set_cmd_error(cmd,
560 SCST_LOAD_SENSE(scst_sense_data_protect));
563 case SYNCHRONIZE_CACHE:
565 int immed = cmd->cdb[1] & 0x2;
566 struct scst_fileio_tgt_dev *ftgt_dev =
567 (struct scst_fileio_tgt_dev*)
568 cmd->tgt_dev->dh_priv;
569 TRACE(TRACE_SCSI, "SYNCHRONIZE_CACHE: "
570 "loff=%Ld, data_len=%Ld, immed=%d", (uint64_t)loff,
571 (uint64_t)data_len, immed);
575 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
576 /* cmd is dead here */
577 fileio_fsync(ftgt_dev, loff, data_len, NULL);
578 /* ToDo: fileio_fsync() error processing */
582 fileio_fsync(ftgt_dev, loff, data_len, cmd);
590 fileio_exec_verify(cmd, loff);
594 fileio_exec_mode_sense(cmd);
598 fileio_exec_mode_select(cmd);
600 case ALLOW_MEDIUM_REMOVAL:
601 fileio_exec_prevent_allow_medium_removal(cmd);
604 fileio_exec_read_toc(cmd);
613 TRACE_DBG("Invalid opcode %d", opcode);
614 scst_set_cmd_error(cmd,
615 SCST_LOAD_SENSE(scst_sense_invalid_opcode));
622 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
629 static inline int test_cmd_list(struct scst_fileio_tgt_dev *ftgt_dev)
631 int res = !list_empty(&ftgt_dev->fdev_cmd_list) ||
632 unlikely(ftgt_dev->shutdown);
636 static int fileio_cmd_thread(void *arg)
638 struct scst_fileio_tgt_dev *ftgt_dev = (struct scst_fileio_tgt_dev*)arg;
642 daemonize("scst_fileio");
644 set_user_nice(current, 10);
645 current->flags |= PF_NOFREEZE;
647 spin_lock_bh(&ftgt_dev->fdev_lock);
650 struct scst_cmd *cmd;
651 init_waitqueue_entry(&wait, current);
653 if (!test_cmd_list(ftgt_dev)) {
654 add_wait_queue_exclusive(&ftgt_dev->fdev_waitQ, &wait);
656 set_current_state(TASK_INTERRUPTIBLE);
657 if (test_cmd_list(ftgt_dev))
659 spin_unlock_bh(&ftgt_dev->fdev_lock);
661 spin_lock_bh(&ftgt_dev->fdev_lock);
663 set_current_state(TASK_RUNNING);
664 remove_wait_queue(&ftgt_dev->fdev_waitQ, &wait);
667 while (!list_empty(&ftgt_dev->fdev_cmd_list)) {
668 cmd = list_entry(ftgt_dev->fdev_cmd_list.next,
669 typeof(*cmd), fileio_cmd_list_entry);
670 cmd->fileio_in_list = 0;
671 list_del(&cmd->fileio_cmd_list_entry);
672 spin_unlock_bh(&ftgt_dev->fdev_lock);
674 spin_lock_bh(&ftgt_dev->fdev_lock);
675 if (unlikely(ftgt_dev->shutdown))
679 if (unlikely(ftgt_dev->shutdown))
682 spin_unlock_bh(&ftgt_dev->fdev_lock);
684 if (atomic_dec_and_test(&ftgt_dev->threads_count)) {
685 smp_mb__after_atomic_dec();
686 TRACE_DBG("%s", "Releasing shutdown_mutex");
687 up(&ftgt_dev->shutdown_mutex);
694 static int fileio_attach_tgt(struct scst_tgt_dev *tgt_dev)
696 struct scst_fileio_dev *virt_dev =
697 (struct scst_fileio_dev *)tgt_dev->acg_dev->dev->dh_priv;
698 struct scst_fileio_tgt_dev *ftgt_dev;
703 ftgt_dev = kzalloc(sizeof(*ftgt_dev), GFP_KERNEL);
704 if (ftgt_dev == NULL) {
705 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of per-session "
706 "virtual device failed");
711 spin_lock_init(&ftgt_dev->fdev_lock);
712 INIT_LIST_HEAD(&ftgt_dev->fdev_cmd_list);
713 init_waitqueue_head(&ftgt_dev->fdev_waitQ);
714 atomic_set(&ftgt_dev->threads_count, 0);
715 init_MUTEX_LOCKED(&ftgt_dev->shutdown_mutex);
716 ftgt_dev->virt_dev = virt_dev;
718 if (!virt_dev->cdrom_empty) {
719 ftgt_dev->fd = fileio_open(virt_dev);
720 if (IS_ERR(ftgt_dev->fd)) {
721 res = PTR_ERR(ftgt_dev->fd);
722 PRINT_ERROR_PR("filp_open(%s) returned an error %d",
723 virt_dev->file_name, res);
730 * Only ONE thread must be run here, otherwise the commands could
731 * be executed out of order !!
733 res = kernel_thread(fileio_cmd_thread, ftgt_dev, FILEIO_THREAD_FLAGS);
735 PRINT_ERROR_PR("kernel_thread() failed: %d", res);
739 atomic_inc(&ftgt_dev->threads_count);
741 tgt_dev->dh_priv = ftgt_dev;
743 down(&virt_dev->ftgt_list_mutex);
744 list_add_tail(&ftgt_dev->ftgt_list_entry,
745 &virt_dev->ftgt_list);
746 up(&virt_dev->ftgt_list_mutex);
754 filp_close(ftgt_dev->fd, NULL);
761 static void fileio_detach_tgt(struct scst_tgt_dev *tgt_dev)
763 struct scst_fileio_tgt_dev *ftgt_dev =
764 (struct scst_fileio_tgt_dev *)tgt_dev->dh_priv;
765 struct scst_fileio_dev *virt_dev =
766 (struct scst_fileio_dev *)tgt_dev->acg_dev->dev->dh_priv;
770 down(&virt_dev->ftgt_list_mutex);
771 list_del(&ftgt_dev->ftgt_list_entry);
772 up(&virt_dev->ftgt_list_mutex);
774 ftgt_dev->shutdown = 1;
775 wake_up_all(&ftgt_dev->fdev_waitQ);
776 down(&ftgt_dev->shutdown_mutex);
779 filp_close(ftgt_dev->fd, NULL);
781 if (ftgt_dev->iv != NULL)
786 tgt_dev->dh_priv = NULL;
791 /********************************************************************
792 * Function: disk_fileio_parse
796 * Returns : The state of the command
798 * Description: This does the parsing of the command
800 * Note: Not all states are allowed on return
801 ********************************************************************/
802 static int disk_fileio_parse(struct scst_cmd *cmd,
803 const struct scst_info_cdb *info_cdb)
805 int res = SCST_CMD_STATE_DEFAULT;
807 struct scst_fileio_dev *virt_dev =
808 (struct scst_fileio_dev *)cmd->dev->dh_priv;
813 * SCST sets good defaults for cmd->data_direction and cmd->bufflen
814 * based on info_cdb, therefore change them only if necessary
817 TRACE_DBG("op_name <%s> direct %d flags %d transfer_len %d",
819 info_cdb->direction, info_cdb->flags, info_cdb->transfer_len);
821 fixed = info_cdb->flags & SCST_TRANSFER_LEN_TYPE_FIXED;
822 switch (cmd->cdb[0]) {
824 cmd->bufflen = READ_CAP_LEN;
825 cmd->data_direction = SCST_DATA_READ;
827 case SERVICE_ACTION_IN:
828 if ((cmd->cdb[1] & 0x1f) == SAI_READ_CAPACITY_16) {
829 cmd->bufflen = READ_CAP16_LEN;
830 cmd->data_direction = SCST_DATA_READ;
837 if ((cmd->cdb[1] & BYTCHK) == 0) {
839 info_cdb->transfer_len << virt_dev->block_shift;
841 cmd->data_direction = SCST_DATA_NONE;
853 * No need for locks here, since *_detach() can not be
854 * called, when there are existing commands.
856 cmd->bufflen = info_cdb->transfer_len << virt_dev->block_shift;
859 TRACE_DBG("res %d, bufflen %zd, data_len %zd, direct %d",
860 res, cmd->bufflen, cmd->data_len, cmd->data_direction);
866 static inline void fileio_queue_cmd(struct scst_cmd *cmd)
868 struct scst_fileio_tgt_dev *ftgt_dev =
869 (struct scst_fileio_tgt_dev *)cmd->tgt_dev->dh_priv;
870 spin_lock_bh(&ftgt_dev->fdev_lock);
871 TRACE_DBG("Pushing cmd %p to IO thread", cmd);
872 list_add_tail(&cmd->fileio_cmd_list_entry,
873 &ftgt_dev->fdev_cmd_list);
874 cmd->fileio_in_list = 1;
875 spin_unlock_bh(&ftgt_dev->fdev_lock);
876 wake_up(&ftgt_dev->fdev_waitQ);
880 /********************************************************************
881 * Function: disk_fileio_exec
885 * Returns : always SCST_EXEC_COMPLETED, real status is in error condition
889 ********************************************************************/
890 static int disk_fileio_exec(struct scst_cmd *cmd)
893 int opcode = cmd->cdb[0];
898 cmd->masked_status = 0;
900 cmd->host_status = DID_OK;
901 cmd->driver_status = 0;
905 * Only commands that unsensible to the execution order could be
906 * performed here, in place. Other ones must be passed to the
912 fileio_exec_inquiry(cmd);
915 fileio_exec_read_capacity(cmd);
917 case SERVICE_ACTION_IN:
918 if ((cmd->cdb[1] & 0x1f) == SAI_READ_CAPACITY_16)
919 fileio_exec_read_capacity16(cmd);
924 case WRITE_VERIFY_12:
925 case WRITE_VERIFY_16:
931 /* could move READ ONLY check up to here (currenlty in do_job()) */
941 case SYNCHRONIZE_CACHE:
951 fileio_queue_cmd(cmd);
954 case TEST_UNIT_READY:
959 TRACE_DBG("Invalid opcode 0x%02x", opcode);
960 scst_set_cmd_error(cmd,
961 SCST_LOAD_SENSE(scst_sense_invalid_opcode));
966 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
970 return SCST_EXEC_COMPLETED;
973 /********************************************************************
974 * Function: cdrom_fileio_parse
978 * Returns : The state of the command
980 * Description: This does the parsing of the command
982 * Note: Not all states are allowed on return
983 ********************************************************************/
984 static int cdrom_fileio_parse(struct scst_cmd *cmd,
985 const struct scst_info_cdb *info_cdb)
987 int res = SCST_CMD_STATE_DEFAULT;
989 struct scst_fileio_dev *virt_dev =
990 (struct scst_fileio_dev *)cmd->dev->dh_priv;
995 * SCST sets good defaults for cmd->data_direction and cmd->bufflen
996 * based on info_cdb, therefore change them only if necessary
999 TRACE_DBG("op_name <%s> direct %d flags %d transfer_len %d",
1001 info_cdb->direction, info_cdb->flags, info_cdb->transfer_len);
1003 fixed = info_cdb->flags & SCST_TRANSFER_LEN_TYPE_FIXED;
1004 switch (cmd->cdb[0]) {
1006 cmd->bufflen = READ_CAP_LEN;
1007 cmd->data_direction = SCST_DATA_READ;
1013 if ((cmd->cdb[1] & BYTCHK) == 0) {
1015 info_cdb->transfer_len << virt_dev->block_shift;
1017 cmd->data_direction = SCST_DATA_NONE;
1029 * No need for locks here, since *_detach() can not be
1030 * called, when there are existing commands.
1032 cmd->bufflen = info_cdb->transfer_len << virt_dev->block_shift;
1035 TRACE_DBG("res %d, bufflen %zd, data_len %zd, direct %d",
1036 res, cmd->bufflen, cmd->data_len, cmd->data_direction);
1038 TRACE_EXIT_HRES(res);
1042 /********************************************************************
1043 * Function: cdrom_fileio_exec
1050 ********************************************************************/
1051 static int cdrom_fileio_exec(struct scst_cmd *cmd)
1054 int opcode = cmd->cdb[0];
1055 struct scst_fileio_dev *virt_dev =
1056 (struct scst_fileio_dev *)cmd->dev->dh_priv;
1061 cmd->masked_status = 0;
1062 cmd->msg_status = 0;
1063 cmd->host_status = DID_OK;
1064 cmd->driver_status = 0;
1066 if (virt_dev->cdrom_empty && (opcode != INQUIRY)) {
1067 TRACE_DBG("%s", "CDROM empty");
1068 scst_set_cmd_error(cmd,
1069 SCST_LOAD_SENSE(scst_sense_not_ready));
1074 * No protection is necessary, because media_changed set only
1075 * in suspended state and exec() is serialized
1077 if (virt_dev->media_changed && (cmd->cdb[0] != INQUIRY) &&
1078 (cmd->cdb[0] != REQUEST_SENSE) && (cmd->cdb[0] != REPORT_LUNS)) {
1079 virt_dev->media_changed = 0;
1080 TRACE_DBG("%s", "Reporting media changed");
1081 scst_set_cmd_error(cmd,
1082 SCST_LOAD_SENSE(scst_sense_medium_changed_UA));
1088 * Only commands that unsensible to the execution order could be
1089 * performed here, in place. Other ones must be passed to the
1096 fileio_exec_inquiry(cmd);
1099 fileio_exec_read_capacity(cmd);
1102 case WRITE_VERIFY_12:
1103 case WRITE_VERIFY_16:
1108 case MODE_SELECT_10:
1126 case ALLOW_MEDIUM_REMOVAL:
1128 fileio_queue_cmd(cmd);
1131 case TEST_UNIT_READY:
1135 TRACE_DBG("Invalid opcode 0x%02x", opcode);
1136 scst_set_cmd_error(cmd,
1137 SCST_LOAD_SENSE(scst_sense_invalid_opcode));
1143 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
1147 return SCST_EXEC_COMPLETED;
1150 static void fileio_exec_inquiry(struct scst_cmd *cmd)
1152 int32_t length, len, i;
1155 struct scst_fileio_dev *virt_dev =
1156 (struct scst_fileio_dev *)cmd->dev->dh_priv;
1158 /* ToDo: Performance Boost:
1159 * 1. remove kzalloc, buf
1160 * 2. do all checks before touching *address
1162 * 4. write directly to *address
1167 buf = kzalloc(INQ_BUF_SZ,
1168 scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL);
1174 length = scst_get_buf_first(cmd, &address);
1175 TRACE_DBG("length %d", length);
1176 if (unlikely(length <= 0)) {
1177 PRINT_ERROR_PR("scst_get_buf_first() failed: %d", length);
1178 scst_set_cmd_error(cmd,
1179 SCST_LOAD_SENSE(scst_sense_hardw_error));
1184 * ToDo: write through/back flags as well as read only one.
1185 * Also task queue size should be set on some value.
1188 if (cmd->cdb[1] & CMDDT) {
1189 TRACE_DBG("%s", "INQUIRY: CMDDT is unsupported");
1190 scst_set_cmd_error(cmd,
1191 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1195 memset(buf, 0, sizeof(buf));
1196 buf[0] = cmd->dev->handler->type; /* type dev */
1197 if (buf[0] == TYPE_ROM)
1198 buf[1] = 0x80; /* removable */
1200 if (cmd->cdb[1] & EVPD) {
1204 for (dev_id_num = 0, i = 0; i < strlen(virt_dev->name); i++) {
1205 dev_id_num += virt_dev->name[i];
1207 len = scnprintf(dev_id_str, 6, "%d", dev_id_num);
1208 TRACE_DBG("num %d, str <%s>, len %d",
1209 dev_id_num,dev_id_str, len);
1210 if (0 == cmd->cdb[2]) { /* supported vital product data pages */
1212 buf[4] = 0x0; /* this page */
1213 buf[5] = 0x80; /* unit serial number */
1214 buf[6] = 0x83; /* device identification */
1215 } else if (0x80 == cmd->cdb[2]) { /* unit serial number */
1218 memcpy(&buf[4], dev_id_str, len);
1219 } else if (0x83 == cmd->cdb[2]) { /* device identification */
1223 /* Two identification descriptors: */
1224 /* T10 vendor identifier field format (faked) */
1225 buf[num + 0] = 0x2; /* ASCII */
1228 memcpy(&buf[num + 4], SCST_FIO_VENDOR, 8);
1229 memset(&buf[num + 12], ' ', 16);
1230 i = strlen(virt_dev->name);
1231 i = i < 16 ? i : 16;
1232 memcpy(&buf[num + 12], virt_dev->name, len);
1233 memcpy(&buf[num + 28], dev_id_str, len);
1234 buf[num + 3] = 8 + 16 + len;
1235 num += buf[num + 3] + 4;
1236 /* NAA IEEE registered identifier (faked) */
1237 buf[num] = 0x1; /* binary */
1241 buf[num + 4] = 0x51; /* ieee company id=0x123456 (faked) */
1242 buf[num + 5] = 0x23;
1243 buf[num + 6] = 0x45;
1244 buf[num + 7] = 0x60;
1245 buf[num + 8] = (dev_id_num >> 24);
1246 buf[num + 9] = (dev_id_num >> 16) & 0xff;
1247 buf[num + 10] = (dev_id_num >> 8) & 0xff;
1248 buf[num + 11] = dev_id_num & 0xff;
1250 buf[3] = num + 12 - 4;
1252 TRACE_DBG("INQUIRY: Unsupported EVPD page %x",
1254 scst_set_cmd_error(cmd,
1255 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1259 if (cmd->cdb[2] != 0) {
1260 TRACE_DBG("INQUIRY: Unsupported page %x", cmd->cdb[2]);
1261 scst_set_cmd_error(cmd,
1262 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1266 buf[2] = 4; /* Device complies to this standard - SPC-2 */
1267 buf[3] = 2; /* data in format specified in this standard */
1268 buf[4] = 31; /* n - 4 = 35 - 4 = 31 for full 36 byte data */
1269 buf[6] = 0; buf[7] = 2; /* BQue = 0, CMDQUE = 1 commands queuing supported */
1271 /* 8 byte ASCII Vendor Identification of the target - left aligned */
1272 memcpy(&buf[8], SCST_FIO_VENDOR, 8);
1274 /* 16 byte ASCII Product Identification of the target - left aligned */
1275 memset(&buf[16], ' ', 16);
1276 len = strlen(virt_dev->name);
1277 len = len < 16 ? len : 16;
1278 memcpy(&buf[16], virt_dev->name, len);
1280 /* 4 byte ASCII Product Revision Level of the target - left aligned */
1281 memcpy(&buf[32], SCST_FIO_REV, 4);
1284 memcpy(address, buf, length < INQ_BUF_SZ ? length : INQ_BUF_SZ);
1287 scst_put_buf(cmd, address);
1298 * <<Following mode pages info copied from ST318451LW with some corrections>>
1303 static int fileio_err_recov_pg(unsigned char *p, int pcontrol,
1304 struct scst_fileio_dev *virt_dev)
1305 { /* Read-Write Error Recovery page for mode_sense */
1306 const unsigned char err_recov_pg[] = {0x1, 0xa, 0xc0, 11, 240, 0, 0, 0,
1309 memcpy(p, err_recov_pg, sizeof(err_recov_pg));
1311 memset(p + 2, 0, sizeof(err_recov_pg) - 2);
1312 return sizeof(err_recov_pg);
1315 static int fileio_disconnect_pg(unsigned char *p, int pcontrol,
1316 struct scst_fileio_dev *virt_dev)
1317 { /* Disconnect-Reconnect page for mode_sense */
1318 const unsigned char disconnect_pg[] = {0x2, 0xe, 128, 128, 0, 10, 0, 0,
1319 0, 0, 0, 0, 0, 0, 0, 0};
1321 memcpy(p, disconnect_pg, sizeof(disconnect_pg));
1323 memset(p + 2, 0, sizeof(disconnect_pg) - 2);
1324 return sizeof(disconnect_pg);
1327 static int fileio_format_pg(unsigned char *p, int pcontrol,
1328 struct scst_fileio_dev *virt_dev)
1329 { /* Format device page for mode_sense */
1330 const unsigned char format_pg[] = {0x3, 0x16, 0, 0, 0, 0, 0, 0,
1331 0, 0, 0, 0, 0, 0, 0, 0,
1332 0, 0, 0, 0, 0x40, 0, 0, 0};
1334 memcpy(p, format_pg, sizeof(format_pg));
1335 p[10] = (DEF_SECTORS_PER >> 8) & 0xff;
1336 p[11] = DEF_SECTORS_PER & 0xff;
1337 p[12] = (virt_dev->block_size >> 8) & 0xff;
1338 p[13] = virt_dev->block_size & 0xff;
1340 memset(p + 2, 0, sizeof(format_pg) - 2);
1341 return sizeof(format_pg);
1344 static int fileio_caching_pg(unsigned char *p, int pcontrol,
1345 struct scst_fileio_dev *virt_dev)
1346 { /* Caching page for mode_sense */
1347 const unsigned char caching_pg[] = {0x8, 18, 0x10, 0, 0xff, 0xff, 0, 0,
1348 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0, 0, 0, 0, 0};
1350 memcpy(p, caching_pg, sizeof(caching_pg));
1351 p[2] |= !(virt_dev->wt_flag) ? WCE : 0;
1353 memset(p + 2, 0, sizeof(caching_pg) - 2);
1354 return sizeof(caching_pg);
1357 static int fileio_ctrl_m_pg(unsigned char *p, int pcontrol,
1358 struct scst_fileio_dev *virt_dev)
1359 { /* Control mode page for mode_sense */
1360 const unsigned char ctrl_m_pg[] = {0xa, 0xa, 0x22, 0, 0, 0x40, 0, 0,
1363 memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg));
1364 if (!virt_dev->wt_flag)
1365 p[3] |= 0x10; /* Enable unrestricted reordering */
1367 memset(p + 2, 0, sizeof(ctrl_m_pg) - 2);
1368 return sizeof(ctrl_m_pg);
1371 static int fileio_iec_m_pg(unsigned char *p, int pcontrol,
1372 struct scst_fileio_dev *virt_dev)
1373 { /* Informational Exceptions control mode page for mode_sense */
1374 const unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0,
1376 memcpy(p, iec_m_pg, sizeof(iec_m_pg));
1378 memset(p + 2, 0, sizeof(iec_m_pg) - 2);
1379 return sizeof(iec_m_pg);
1382 static void fileio_exec_mode_sense(struct scst_cmd *cmd)
1387 struct scst_fileio_dev *virt_dev;
1390 unsigned char dbd, type;
1391 int pcontrol, pcode, subpcode;
1392 unsigned char dev_spec;
1393 int msense_6, offset, len;
1398 buf = kzalloc(MSENSE_BUF_SZ,
1399 scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL);
1405 virt_dev = (struct scst_fileio_dev *)cmd->dev->dh_priv;
1406 blocksize = virt_dev->block_size;
1407 nblocks = virt_dev->nblocks;
1409 type = cmd->dev->handler->type; /* type dev */
1410 dbd = cmd->cdb[1] & DBD;
1411 pcontrol = (cmd->cdb[2] & 0xc0) >> 6;
1412 pcode = cmd->cdb[2] & 0x3f;
1413 subpcode = cmd->cdb[3];
1414 msense_6 = (MODE_SENSE == cmd->cdb[0]);
1415 dev_spec = (virt_dev->rd_only_flag ? WP : 0) | DPOFUA;
1417 length = scst_get_buf_first(cmd, &address);
1418 if (unlikely(length <= 0)) {
1419 PRINT_ERROR_PR("scst_get_buf_first() failed: %d", length);
1420 scst_set_cmd_error(cmd,
1421 SCST_LOAD_SENSE(scst_sense_hardw_error));
1425 memset(buf, 0, sizeof(buf));
1427 if (0x3 == pcontrol) {
1428 TRACE_DBG("%s", "MODE SENSE: Saving values not supported");
1429 scst_set_cmd_error(cmd,
1430 SCST_LOAD_SENSE(scst_sense_saving_params_unsup));
1444 if (0 != subpcode) { /* TODO: Control Extension page */
1445 TRACE_DBG("%s", "MODE SENSE: Only subpage 0 is supported");
1446 scst_set_cmd_error(cmd,
1447 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1452 /* Create block descriptor */
1453 buf[offset - 1] = 0x08; /* block descriptor length */
1454 if (nblocks >> 32) {
1455 buf[offset + 0] = 0xFF;
1456 buf[offset + 1] = 0xFF;
1457 buf[offset + 2] = 0xFF;
1458 buf[offset + 3] = 0xFF;
1460 buf[offset + 0] = (nblocks >> (BYTE * 3)) & 0xFF;/* num blks */
1461 buf[offset + 1] = (nblocks >> (BYTE * 2)) & 0xFF;
1462 buf[offset + 2] = (nblocks >> (BYTE * 1)) & 0xFF;
1463 buf[offset + 3] = (nblocks >> (BYTE * 0)) & 0xFF;
1465 buf[offset + 4] = 0; /* density code */
1466 buf[offset + 5] = (blocksize >> (BYTE * 2)) & 0xFF;/* blklen */
1467 buf[offset + 6] = (blocksize >> (BYTE * 1)) & 0xFF;
1468 buf[offset + 7] = (blocksize >> (BYTE * 0)) & 0xFF;
1470 offset += 8; /* increment offset */
1476 case 0x1: /* Read-Write error recovery page, direct access */
1477 len = fileio_err_recov_pg(bp, pcontrol, virt_dev);
1480 case 0x2: /* Disconnect-Reconnect page, all devices */
1481 len = fileio_disconnect_pg(bp, pcontrol, virt_dev);
1484 case 0x3: /* Format device page, direct access */
1485 len = fileio_format_pg(bp, pcontrol, virt_dev);
1488 case 0x8: /* Caching page, direct access */
1489 len = fileio_caching_pg(bp, pcontrol, virt_dev);
1492 case 0xa: /* Control Mode page, all devices */
1493 len = fileio_ctrl_m_pg(bp, pcontrol, virt_dev);
1496 case 0x1c: /* Informational Exceptions Mode page, all devices */
1497 len = fileio_iec_m_pg(bp, pcontrol, virt_dev);
1500 case 0x3f: /* Read all Mode pages */
1501 len = fileio_err_recov_pg(bp, pcontrol, virt_dev);
1502 len += fileio_disconnect_pg(bp + len, pcontrol, virt_dev);
1503 len += fileio_format_pg(bp + len, pcontrol, virt_dev);
1504 len += fileio_caching_pg(bp + len, pcontrol, virt_dev);
1505 len += fileio_ctrl_m_pg(bp + len, pcontrol, virt_dev);
1506 len += fileio_iec_m_pg(bp + len, pcontrol, virt_dev);
1510 TRACE_DBG("MODE SENSE: Unsupported page %x", pcode);
1511 scst_set_cmd_error(cmd,
1512 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1516 buf[0] = offset - 1;
1518 buf[0] = ((offset - 2) >> 8) & 0xff;
1519 buf[1] = (offset - 2) & 0xff;
1522 memcpy(address, buf, min(length, offset));
1525 scst_put_buf(cmd, address);
1535 static int fileio_set_wt(struct scst_fileio_dev *virt_dev, int wt)
1538 struct scst_fileio_tgt_dev *ftgt_dev;
1543 if (virt_dev->wt_flag == wt)
1546 virt_dev->wt_flag = wt;
1548 scst_suspend_activity();
1550 down(&virt_dev->ftgt_list_mutex);
1551 list_for_each_entry(ftgt_dev, &virt_dev->ftgt_list,
1554 fd = fileio_open(virt_dev);
1557 PRINT_ERROR_PR("filp_open(%s) returned an error %d, "
1558 "unable to change the cache mode",
1559 virt_dev->file_name, res);
1560 up(&virt_dev->ftgt_list_mutex);
1561 res = 0; /* ?? ToDo */
1565 filp_close(ftgt_dev->fd, NULL);
1568 up(&virt_dev->ftgt_list_mutex);
1571 scst_resume_activity();
1574 TRACE_EXIT_RES(res);
1578 static void fileio_exec_mode_select(struct scst_cmd *cmd)
1582 struct scst_fileio_dev *virt_dev;
1583 int mselect_6, offset;
1587 virt_dev = (struct scst_fileio_dev *)cmd->dev->dh_priv;
1588 mselect_6 = (MODE_SELECT == cmd->cdb[0]);
1590 length = scst_get_buf_first(cmd, &address);
1591 if (unlikely(length <= 0)) {
1592 PRINT_ERROR_PR("scst_get_buf_first() failed: %d", length);
1593 scst_set_cmd_error(cmd,
1594 SCST_LOAD_SENSE(scst_sense_hardw_error));
1598 if (!(cmd->cdb[1] & PF) || (cmd->cdb[1] & SP)) {
1599 PRINT_ERROR_PR("MODE SELECT: PF and/or SP are wrongly set "
1600 "(cdb[1]=%x)", cmd->cdb[1]);
1601 scst_set_cmd_error(cmd,
1602 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1612 if (address[offset - 1] == 8) {
1614 } else if (address[offset - 1] != 0) {
1615 PRINT_ERROR_PR("%s", "MODE SELECT: Wrong parameters list "
1617 scst_set_cmd_error(cmd,
1618 SCST_LOAD_SENSE(scst_sense_invalid_field_in_parm_list));
1622 while (length > offset + 2) {
1623 if (address[offset] & PS) {
1624 PRINT_ERROR_PR("%s", "MODE SELECT: Illegal PS bit");
1625 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1626 scst_sense_invalid_field_in_parm_list));
1629 if ((address[offset] & 0x3f) == 0x8) { /* Caching page */
1630 if (address[offset + 1] != 18) {
1631 PRINT_ERROR_PR("%s", "MODE SELECT: Invalid "
1632 "caching page request");
1633 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1634 scst_sense_invalid_field_in_parm_list));
1637 if (fileio_set_wt(virt_dev,
1638 (address[offset + 2] & WCE) ? 0 : 1) != 0) {
1639 scst_set_cmd_error(cmd,
1640 SCST_LOAD_SENSE(scst_sense_hardw_error));
1645 offset += address[offset + 1];
1649 scst_put_buf(cmd, address);
1656 static void fileio_exec_read_capacity(struct scst_cmd *cmd)
1660 struct scst_fileio_dev *virt_dev;
1663 uint8_t buffer[READ_CAP_LEN];
1667 virt_dev = (struct scst_fileio_dev *)cmd->dev->dh_priv;
1668 blocksize = virt_dev->block_size;
1669 nblocks = virt_dev->nblocks;
1671 /* last block on the virt_dev is (nblocks-1) */
1672 memset(buffer, 0, sizeof(buffer));
1673 if (nblocks >> 32) {
1679 buffer[0] = ((nblocks - 1) >> (BYTE * 3)) & 0xFF;
1680 buffer[1] = ((nblocks - 1) >> (BYTE * 2)) & 0xFF;
1681 buffer[2] = ((nblocks - 1) >> (BYTE * 1)) & 0xFF;
1682 buffer[3] = ((nblocks - 1) >> (BYTE * 0)) & 0xFF;
1684 buffer[4] = (blocksize >> (BYTE * 3)) & 0xFF;
1685 buffer[5] = (blocksize >> (BYTE * 2)) & 0xFF;
1686 buffer[6] = (blocksize >> (BYTE * 1)) & 0xFF;
1687 buffer[7] = (blocksize >> (BYTE * 0)) & 0xFF;
1689 length = scst_get_buf_first(cmd, &address);
1690 if (unlikely(length <= 0)) {
1691 PRINT_ERROR_PR("scst_get_buf_first() failed: %d", length);
1692 scst_set_cmd_error(cmd,
1693 SCST_LOAD_SENSE(scst_sense_hardw_error));
1697 memcpy(address, buffer, length < READ_CAP_LEN ? length : READ_CAP_LEN);
1699 scst_put_buf(cmd, address);
1706 static void fileio_exec_read_capacity16(struct scst_cmd *cmd)
1710 struct scst_fileio_dev *virt_dev;
1713 uint8_t buffer[READ_CAP16_LEN];
1718 virt_dev = (struct scst_fileio_dev *)cmd->dev->dh_priv;
1719 blocksize = virt_dev->block_size;
1720 nblocks = virt_dev->nblocks;
1722 memset(buffer, 0, sizeof(buffer));
1723 data64 = (uint64_t*)buffer;
1724 data64[0] = cpu_to_be64(nblocks - 1);
1725 buffer[8] = (blocksize >> (BYTE * 3)) & 0xFF;
1726 buffer[9] = (blocksize >> (BYTE * 2)) & 0xFF;
1727 buffer[10] = (blocksize >> (BYTE * 1)) & 0xFF;
1728 buffer[11] = (blocksize >> (BYTE * 0)) & 0xFF;
1730 length = scst_get_buf_first(cmd, &address);
1731 if (unlikely(length <= 0)) {
1732 PRINT_ERROR_PR("scst_get_buf_first() failed: %d", length);
1733 scst_set_cmd_error(cmd,
1734 SCST_LOAD_SENSE(scst_sense_hardw_error));
1738 memcpy(address, buffer, length < READ_CAP16_LEN ?
1739 length : READ_CAP16_LEN);
1741 scst_put_buf(cmd, address);
1748 static void fileio_exec_read_toc(struct scst_cmd *cmd)
1750 int32_t length, off = 0;
1752 struct scst_fileio_dev *virt_dev;
1754 uint8_t buffer[4+8+8] = { 0x00, 0x0a, 0x01, 0x01, 0x00, 0x14,
1755 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
1759 if (cmd->dev->handler->type != TYPE_ROM) {
1760 PRINT_ERROR_PR("%s", "READ TOC for non-CDROM device");
1761 scst_set_cmd_error(cmd,
1762 SCST_LOAD_SENSE(scst_sense_invalid_opcode));
1766 if (cmd->cdb[2] & 0x0e/*Format*/) {
1767 PRINT_ERROR_PR("%s", "READ TOC: invalid requested data format");
1768 scst_set_cmd_error(cmd,
1769 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1773 if ((cmd->cdb[6] != 0 && (cmd->cdb[2] & 0x01)) ||
1774 (cmd->cdb[6] > 1 && cmd->cdb[6] != 0xAA)) {
1775 PRINT_ERROR_PR("READ TOC: invalid requested track number %x",
1777 scst_set_cmd_error(cmd,
1778 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1782 length = scst_get_buf_first(cmd, &address);
1783 if (unlikely(length <= 0)) {
1784 PRINT_ERROR_PR("scst_get_buf_first() failed: %d", length);
1785 scst_set_cmd_error(cmd,
1786 SCST_LOAD_SENSE(scst_sense_hardw_error));
1790 virt_dev = (struct scst_fileio_dev *)cmd->dev->dh_priv;
1791 /* FIXME when you have > 8TB ROM device. */
1792 nblocks = (uint32_t)virt_dev->nblocks;
1795 memset(buffer, 0, sizeof(buffer));
1796 buffer[2] = 0x01; /* First Track/Session */
1797 buffer[3] = 0x01; /* Last Track/Session */
1799 if (cmd->cdb[6] <= 1)
1801 /* Fistr TOC Track Descriptor */
1802 buffer[off+1] = 0x14; /* ADDR 0x10 - Q Sub-channel encodes current position data
1803 CONTROL 0x04 - Data track, recoreded uninterrupted */
1804 buffer[off+2] = 0x01; /* Track Number */
1807 if (!(cmd->cdb[2] & 0x01))
1809 /* Lead-out area TOC Track Descriptor */
1810 buffer[off+1] = 0x14;
1811 buffer[off+2] = 0xAA; /* Track Number */
1812 buffer[off+4] = (nblocks >> (BYTE * 3)) & 0xFF; /* Track Start Address */
1813 buffer[off+5] = (nblocks >> (BYTE * 2)) & 0xFF;
1814 buffer[off+6] = (nblocks >> (BYTE * 1)) & 0xFF;
1815 buffer[off+7] = (nblocks >> (BYTE * 0)) & 0xFF;
1819 buffer[1] = off - 2; /* Data Length */
1821 memcpy(address, buffer, (length < off) ? length : off);
1823 scst_put_buf(cmd, address);
1830 static void fileio_exec_prevent_allow_medium_removal(struct scst_cmd *cmd)
1832 struct scst_fileio_dev *virt_dev =
1833 (struct scst_fileio_dev *)cmd->dev->dh_priv;
1835 TRACE_DBG("PERSIST/PREVENT 0x%02x", cmd->cdb[4]);
1838 * No protection here, because in cdrom_fileio_change() the
1839 * activity is suspended and exec() is serialized
1841 if (cmd->dev->handler->type == TYPE_ROM)
1842 virt_dev->prevent_allow_medium_removal =
1843 cmd->cdb[4] & 0x01 ? 1 : 0;
1845 PRINT_ERROR_PR("%s", "Prevent allow medium removal for "
1846 "non-CDROM device");
1847 scst_set_cmd_error(cmd,
1848 SCST_LOAD_SENSE(scst_sense_invalid_opcode));
1854 static int fileio_fsync(struct scst_fileio_tgt_dev *ftgt_dev,
1855 loff_t loff, loff_t len, struct scst_cmd *cmd)
1858 struct file *file = ftgt_dev->fd;
1859 struct inode *inode = file->f_dentry->d_inode;
1860 struct address_space *mapping = file->f_mapping;
1864 if (ftgt_dev->virt_dev->nv_cache)
1867 res = sync_page_range(inode, mapping, loff, len);
1868 if (unlikely(res != 0)) {
1869 PRINT_ERROR_PR("sync_page_range() failed (%d)", res);
1871 scst_set_cmd_error(cmd,
1872 SCST_LOAD_SENSE(scst_sense_write_error));
1876 /* ToDo: flush the device cache, if needed */
1879 TRACE_EXIT_RES(res);
1883 static struct iovec *fileio_alloc_iv(struct scst_cmd *cmd,
1884 struct scst_fileio_tgt_dev *ftgt_dev)
1888 iv_count = scst_get_buf_count(cmd);
1889 if (iv_count > ftgt_dev->iv_count) {
1890 if (ftgt_dev->iv != NULL)
1891 kfree(ftgt_dev->iv);
1892 ftgt_dev->iv = kmalloc(sizeof(*ftgt_dev->iv) * iv_count, GFP_KERNEL);
1893 if (ftgt_dev->iv == NULL) {
1894 PRINT_ERROR_PR("Unable to allocate iv (%d)", iv_count);
1898 ftgt_dev->iv_count = iv_count;
1902 return ftgt_dev->iv;
1905 static void fileio_exec_read(struct scst_cmd *cmd, loff_t loff)
1907 mm_segment_t old_fs;
1909 ssize_t length, full_len;
1911 struct scst_fileio_dev *virt_dev =
1912 (struct scst_fileio_dev *)cmd->dev->dh_priv;
1913 struct scst_fileio_tgt_dev *ftgt_dev =
1914 (struct scst_fileio_tgt_dev *)cmd->tgt_dev->dh_priv;
1915 struct file *fd = ftgt_dev->fd;
1921 iv = fileio_alloc_iv(cmd, ftgt_dev);
1928 length = scst_get_buf_first(cmd, &address);
1929 while (length > 0) {
1933 iv[i].iov_base = address;
1934 iv[i].iov_len = length;
1935 length = scst_get_buf_next(cmd, &address);
1937 if (unlikely(length < 0)) {
1938 PRINT_ERROR_PR("scst_get_buf_() failed: %zd", length);
1939 scst_set_cmd_error(cmd,
1940 SCST_LOAD_SENSE(scst_sense_hardw_error));
1948 if (fd->f_op->llseek) {
1949 err = fd->f_op->llseek(fd, loff, 0/*SEEK_SET*/);
1951 err = default_llseek(fd, loff, 0/*SEEK_SET*/);
1954 PRINT_ERROR_PR("lseek trouble %Ld != %Ld", (uint64_t)err,
1956 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
1961 TRACE_DBG("reading(iv_count %d, full_len %zd)", iv_count, full_len);
1962 if (virt_dev->nullio)
1965 err = fd->f_op->readv(fd, iv, iv_count, &fd->f_pos);
1966 if ((err < 0) || (err < full_len)) {
1967 PRINT_ERROR_PR("readv() returned %Ld from %zd", (uint64_t)err,
1972 scst_set_cmd_error(cmd,
1973 SCST_LOAD_SENSE(scst_sense_read_error));
1983 scst_put_buf(cmd, iv[i].iov_base);
1990 static void fileio_exec_write(struct scst_cmd *cmd, loff_t loff)
1992 mm_segment_t old_fs;
1994 ssize_t length, full_len;
1996 struct scst_fileio_dev *virt_dev =
1997 (struct scst_fileio_dev *)cmd->dev->dh_priv;
1998 struct scst_fileio_tgt_dev *ftgt_dev =
1999 (struct scst_fileio_tgt_dev *)cmd->tgt_dev->dh_priv;
2000 struct file *fd = ftgt_dev->fd;
2001 struct iovec *iv, *eiv;
2002 int iv_count, eiv_count;
2006 iv = fileio_alloc_iv(cmd, ftgt_dev);
2012 length = scst_get_buf_first(cmd, &address);
2013 while (length > 0) {
2015 iv[iv_count].iov_base = address;
2016 iv[iv_count].iov_len = length;
2018 length = scst_get_buf_next(cmd, &address);
2020 if (unlikely(length < 0)) {
2021 PRINT_ERROR_PR("scst_get_buf_() failed: %zd", length);
2022 scst_set_cmd_error(cmd,
2023 SCST_LOAD_SENSE(scst_sense_hardw_error));
2031 if (fd->f_op->llseek) {
2032 err = fd->f_op->llseek(fd, loff, 0 /*SEEK_SET */ );
2034 err = default_llseek(fd, loff, 0 /*SEEK_SET */ );
2037 PRINT_ERROR_PR("lseek trouble %Ld != %Ld", (uint64_t)err,
2039 scst_set_cmd_error(cmd,
2040 SCST_LOAD_SENSE(scst_sense_hardw_error));
2046 eiv_count = iv_count;
2048 TRACE_DBG("writing(eiv_count %d, full_len %zd)", eiv_count, full_len);
2050 if (virt_dev->nullio)
2053 err = fd->f_op->writev(fd, eiv, eiv_count, &fd->f_pos);
2055 PRINT_ERROR_PR("write() returned %Ld from %zd",
2056 (uint64_t)err, full_len);
2060 scst_set_cmd_error(cmd,
2061 SCST_LOAD_SENSE(scst_sense_write_error));
2064 } else if (err < full_len) {
2066 * Probably that's wrong, but sometimes write() returns
2067 * value less, than requested. Let's restart.
2069 int i, e = eiv_count;
2070 TRACE_MGMT_DBG("write() returned %d from %zd "
2071 "(iv_count=%d)", (int)err, full_len,
2074 PRINT_INFO_PR("Suspicious: write() returned 0 from "
2075 "%zd (iv_count=%d)", full_len, eiv_count);
2078 for(i = 0; i < e; i++) {
2079 if (eiv->iov_len < err) {
2080 err -= eiv->iov_len;
2085 (uint8_t*)eiv->iov_base + err;
2086 eiv->iov_len -= err;
2097 while (iv_count > 0) {
2098 scst_put_buf(cmd, iv[iv_count-1].iov_base);
2107 static void fileio_exec_verify(struct scst_cmd *cmd, loff_t loff)
2109 mm_segment_t old_fs;
2111 ssize_t length, len_mem = 0;
2112 uint8_t *address_sav, *address;
2114 struct scst_fileio_tgt_dev *ftgt_dev =
2115 (struct scst_fileio_tgt_dev *)cmd->tgt_dev->dh_priv;
2116 struct file *fd = ftgt_dev->fd;
2117 uint8_t *mem_verify = NULL;
2121 if (fileio_fsync(ftgt_dev, loff, cmd->bufflen, cmd) != 0)
2125 * Until the cache is cleared prior the verifying, there is not
2126 * much point in this code. ToDo.
2128 * Nevertherless, this code is valuable if the data have not read
2129 * from the file/disk yet.
2136 if (fd->f_op->llseek) {
2137 err = fd->f_op->llseek(fd, loff, 0/*SEEK_SET*/);
2139 err = default_llseek(fd, loff, 0/*SEEK_SET*/);
2142 PRINT_ERROR_PR("lseek trouble %Ld != %Ld", (uint64_t)err,
2144 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
2148 mem_verify = vmalloc(LEN_MEM);
2149 if (mem_verify == NULL) {
2150 PRINT_ERROR_PR("Unable to allocate memory %d for verify",
2152 scst_set_cmd_error(cmd,
2153 SCST_LOAD_SENSE(scst_sense_hardw_error));
2157 length = scst_get_buf_first(cmd, &address);
2158 address_sav = address;
2159 if (!length && cmd->data_len) {
2160 length = cmd->data_len;
2165 while (length > 0) {
2166 len_mem = length > LEN_MEM ? LEN_MEM : length;
2167 TRACE_DBG("Verify: length %zd - len_mem %zd", length, len_mem);
2169 err = fd->f_op->read(fd, (char*)mem_verify, len_mem, &fd->f_pos);
2170 if ((err < 0) || (err < len_mem)) {
2171 PRINT_ERROR_PR("verify() returned %Ld from %zd",
2172 (uint64_t)err, len_mem);
2176 scst_set_cmd_error(cmd,
2177 SCST_LOAD_SENSE(scst_sense_read_error));
2179 scst_put_buf(cmd, address_sav);
2182 if (compare && memcmp(address, mem_verify, len_mem) != 0)
2184 TRACE_DBG("Verify: error memcmp length %zd", length);
2185 scst_set_cmd_error(cmd,
2186 SCST_LOAD_SENSE(scst_sense_miscompare_error));
2187 scst_put_buf(cmd, address_sav);
2192 if (compare && length <= 0)
2194 scst_put_buf(cmd, address_sav);
2195 length = scst_get_buf_next(cmd, &address);
2196 address_sav = address;
2201 PRINT_ERROR_PR("scst_get_buf_() failed: %zd", length);
2202 scst_set_cmd_error(cmd,
2203 SCST_LOAD_SENSE(scst_sense_hardw_error));
2216 /* Called with BH off. Might be called under lock and IRQ off */
2217 static int fileio_task_mgmt_fn(struct scst_mgmt_cmd *mcmd,
2218 struct scst_tgt_dev *tgt_dev)
2220 int res = SCST_DEV_TM_COMPLETED_SUCCESS;
2224 if (mcmd->fn == SCST_ABORT_TASK) {
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;
2230 * It is safe relating to scst_list_lock despite of lockdep's
2231 * warning. Just don't know how to tell it to lockdep.
2233 /* BH already off */
2234 spin_lock(&ftgt_dev->fdev_lock);
2235 if (cmd_to_abort->fileio_in_list) {
2236 TRACE(TRACE_MGMT, "Aborting cmd %p and moving it to "
2237 "the queue head", cmd_to_abort);
2238 list_del(&cmd_to_abort->fileio_cmd_list_entry);
2239 list_add(&cmd_to_abort->fileio_cmd_list_entry,
2240 &ftgt_dev->fdev_cmd_list);
2241 wake_up(&ftgt_dev->fdev_waitQ);
2243 spin_unlock(&ftgt_dev->fdev_lock);
2246 TRACE_EXIT_RES(res);
2250 static inline struct scst_fileio_dev *fileio_alloc_dev(void)
2252 struct scst_fileio_dev *dev;
2253 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
2255 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of virtual "
2259 INIT_LIST_HEAD(&dev->ftgt_list);
2260 init_MUTEX(&dev->ftgt_list_mutex);
2265 struct fileio_proc_update_struct {
2266 int len, plen, pplen;
2267 off_t begin, pbegin, ppbegin;
2271 static int fileio_proc_update_size(int size, off_t offset, int length,
2272 struct fileio_proc_update_struct *p, int is_start)
2277 p->pos = p->begin + p->len;
2278 if (p->pos <= offset) {
2281 } else if (p->pos >= offset + length) {
2287 p->begin = p->ppbegin;
2293 p->ppbegin = p->pbegin;
2295 p->pbegin = p->begin;
2303 * Called when a file in the /proc/DISK_FILEIO_NAME/DISK_FILEIO_NAME is read
2306 static int disk_fileio_proc(char *buffer, char **start, off_t offset,
2307 int length, int *eof, struct scst_dev_type *dev_type, int inout)
2309 int res = 0, action;
2310 char *p, *name, *file_name;
2311 struct scst_fileio_dev *virt_dev, *vv;
2313 struct fileio_proc_update_struct pu;
2317 memset(&pu, 0, sizeof(pu));
2319 /* VERY UGLY code. You can rewrite it if you want */
2321 if (down_interruptible(&scst_fileio_mutex) != 0) {
2326 if (inout == 0) { /* read */
2327 size = scnprintf(buffer, length, "%-17s %-11s %-11s %-15s %s\n",
2328 "Name", "Size(MB)", "Block size", "Options", "File name");
2329 if (fileio_proc_update_size(size, offset, length, &pu, 1))
2332 list_for_each_entry(virt_dev, &disk_fileio_dev_list,
2333 fileio_dev_list_entry)
2336 size = scnprintf(buffer + pu.len, length - pu.len,
2337 "%-17s %-11d %-12d", virt_dev->name,
2338 (uint32_t)(virt_dev->file_size >> 20),
2339 virt_dev->block_size);
2340 if (fileio_proc_update_size(size, offset, length, &pu,
2345 if (virt_dev->wt_flag) {
2346 size = scnprintf(buffer + pu.len, length - pu.len, "WT");
2348 if (fileio_proc_update_size(size, offset,
2353 if (virt_dev->nv_cache) {
2354 size = scnprintf(buffer + pu.len, length - pu.len,
2357 if (fileio_proc_update_size(size, offset,
2362 if (virt_dev->rd_only_flag) {
2363 size = scnprintf(buffer + pu.len, length - pu.len,
2366 if (fileio_proc_update_size(size, offset,
2371 if (virt_dev->o_direct_flag) {
2372 size = scnprintf(buffer + pu.len, length - pu.len,
2375 if (fileio_proc_update_size(size, offset,
2380 if (virt_dev->nullio) {
2381 size = scnprintf(buffer + pu.len, length - pu.len,
2382 c ? ",NIO" : "NIO");
2384 if (fileio_proc_update_size(size, offset,
2390 size = scnprintf(buffer + pu.len, length - pu.len, " ");
2391 if (fileio_proc_update_size(size, offset,
2397 size = scnprintf(buffer + pu.len, length - pu.len, "%s\n",
2398 virt_dev->file_name);
2399 if (fileio_proc_update_size(size, offset, length, &pu,
2406 } else { /* write */
2407 uint32_t block_size = DEF_DISK_BLOCKSIZE;
2408 int block_shift = DEF_DISK_BLOCKSIZE_SHIFT;
2410 if (p[strlen(p) - 1] == '\n') {
2411 p[strlen(p) - 1] = '\0';
2413 if (!strncmp("close ", p, 6)) {
2416 } else if (!strncmp("open ", p, 5)) {
2420 PRINT_ERROR_PR("Unknown action \"%s\"", p);
2425 while (isspace(*p) && *p != '\0')
2428 while (!isspace(*p) && *p != '\0')
2431 if (*name == '\0') {
2432 PRINT_ERROR_PR("%s", "Name required");
2435 } else if (strlen(name) >= sizeof(virt_dev->name)) {
2436 PRINT_ERROR_PR("Name is too long (max %zd "
2437 "characters)", sizeof(virt_dev->name)-1);
2442 if (action) { /* open */
2444 list_for_each_entry(vv, &disk_fileio_dev_list,
2445 fileio_dev_list_entry)
2447 if (strcmp(vv->name, name) == 0) {
2453 PRINT_ERROR_PR("Virtual device with name "
2454 "%s already exist", name);
2459 while (isspace(*p) && *p != '\0')
2462 while (!isspace(*p) && *p != '\0')
2465 if (*file_name == '\0') {
2466 PRINT_ERROR_PR("%s", "File name required");
2469 } else if (*file_name != '/') {
2470 PRINT_ERROR_PR("File path \"%s\" is not "
2471 "absolute", file_name);
2476 virt_dev = fileio_alloc_dev();
2477 if (virt_dev == NULL) {
2478 TRACE(TRACE_OUT_OF_MEM, "%s",
2479 "Allocation of virt_dev failed");
2484 while (isspace(*p) && *p != '\0')
2490 block_size = simple_strtoul(p, &pp, 0);
2492 if ((*p != '\0') && !isspace(*p)) {
2493 PRINT_ERROR_PR("Parse error: \"%s\"", p);
2497 while (isspace(*p) && *p != '\0')
2508 if (block_shift < 9) {
2509 PRINT_ERROR_PR("Wrong block size %d",
2515 virt_dev->block_size = block_size;
2516 virt_dev->block_shift = block_shift;
2518 while (*p != '\0') {
2519 if (!strncmp("WRITE_THROUGH", p, 13)) {
2521 virt_dev->wt_flag = 1;
2522 TRACE_DBG("%s", "WRITE_THROUGH");
2523 } else if (!strncmp("NV_CACHE", p, 8)) {
2525 virt_dev->nv_cache = 1;
2526 TRACE_DBG("%s", "NON-VOLATILE CACHE");
2527 } else if (!strncmp("READ_ONLY", p, 9)) {
2529 virt_dev->rd_only_flag = 1;
2530 TRACE_DBG("%s", "READ_ONLY");
2531 } else if (!strncmp("O_DIRECT", p, 8)) {
2535 virt_dev->o_direct_flag = 1;
2536 TRACE_DBG("%s", "O_DIRECT");
2538 PRINT_INFO_PR("%s flag doesn't currently"
2539 " work, ignoring it", "O_DIRECT");
2541 } else if (!strncmp("NULLIO", p, 6)) {
2543 virt_dev->nullio = 1;
2544 TRACE_DBG("%s", "NULLIO");
2546 PRINT_ERROR_PR("Unknown flag \"%s\"", p);
2550 while (isspace(*p) && *p != '\0')
2554 strcpy(virt_dev->name, name);
2556 pu.len = strlen(file_name) + 1;
2557 virt_dev->file_name = kmalloc(pu.len, GFP_KERNEL);
2558 if (virt_dev->file_name == NULL) {
2559 TRACE(TRACE_OUT_OF_MEM, "%s",
2560 "Allocation of file_name failed");
2564 strncpy(virt_dev->file_name, file_name, pu.len);
2566 list_add_tail(&virt_dev->fileio_dev_list_entry,
2567 &disk_fileio_dev_list);
2570 scst_register_virtual_device(&disk_devtype_fileio,
2572 if (virt_dev->virt_id < 0) {
2573 res = virt_dev->virt_id;
2574 goto out_free_vpath;
2576 TRACE_DBG("Added virt_dev (name %s, file name %s, "
2577 "id %d, block size %d) to "
2578 "disk_fileio_dev_list", virt_dev->name,
2579 virt_dev->file_name, virt_dev->virt_id,
2580 virt_dev->block_size);
2581 } else { /* close */
2583 list_for_each_entry(vv, &disk_fileio_dev_list,
2584 fileio_dev_list_entry)
2586 if (strcmp(vv->name, name) == 0) {
2591 if (virt_dev == NULL) {
2592 PRINT_ERROR_PR("Device %s not found", name);
2596 scst_unregister_virtual_device(virt_dev->virt_id);
2597 PRINT_INFO_PR("Virtual device %s unregistered",
2599 TRACE_DBG("virt_id %d unregister", virt_dev->virt_id);
2601 list_del(&virt_dev->fileio_dev_list_entry);
2603 kfree(virt_dev->file_name);
2610 up(&scst_fileio_mutex);
2613 TRACE_EXIT_RES(res);
2617 *start = buffer + (offset - pu.begin);
2618 pu.len -= (offset - pu.begin);
2619 if (pu.len > length)
2621 res = max(0, pu.len);
2625 list_del(&virt_dev->fileio_dev_list_entry);
2626 kfree(virt_dev->file_name);
2633 /* scst_fileio_mutex supposed to be held */
2634 static int cdrom_fileio_open(char *p, char *name)
2636 struct scst_fileio_dev *virt_dev, *vv;
2643 list_for_each_entry(vv, &cdrom_fileio_dev_list,
2644 fileio_dev_list_entry)
2646 if (strcmp(vv->name, name) == 0) {
2652 PRINT_ERROR_PR("Virtual device with name "
2653 "%s already exist", name);
2658 while (isspace(*p) && *p != '\0')
2661 while (!isspace(*p) && *p != '\0')
2664 if (*file_name == '\0') {
2666 TRACE_DBG("%s", "No media");
2667 } else if (*file_name != '/') {
2668 PRINT_ERROR_PR("File path \"%s\" is not "
2669 "absolute", file_name);
2675 virt_dev = fileio_alloc_dev();
2676 if (virt_dev == NULL) {
2677 TRACE(TRACE_OUT_OF_MEM, "%s",
2678 "Allocation of virt_dev failed");
2682 virt_dev->cdrom_empty = cdrom_empty;
2684 strcpy(virt_dev->name, name);
2686 if (!virt_dev->cdrom_empty) {
2687 len = strlen(file_name) + 1;
2688 virt_dev->file_name = kmalloc(len, GFP_KERNEL);
2689 if (virt_dev->file_name == NULL) {
2690 TRACE(TRACE_OUT_OF_MEM, "%s",
2691 "Allocation of file_name failed");
2695 strncpy(virt_dev->file_name, file_name, len);
2698 list_add_tail(&virt_dev->fileio_dev_list_entry,
2699 &cdrom_fileio_dev_list);
2702 scst_register_virtual_device(&cdrom_devtype_fileio,
2704 if (virt_dev->virt_id < 0) {
2705 res = virt_dev->virt_id;
2706 goto out_free_vpath;
2708 TRACE_DBG("Added virt_dev (name %s file_name %s id %d) "
2709 "to cdrom_fileio_dev_list", virt_dev->name,
2710 virt_dev->file_name, virt_dev->virt_id);
2716 list_del(&virt_dev->fileio_dev_list_entry);
2717 kfree(virt_dev->file_name);
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 kfree(virt_dev->file_name);
2760 /* scst_fileio_mutex supposed to be held */
2761 static int cdrom_fileio_change(char *p, char *name)
2764 struct scst_fileio_tgt_dev *ftgt_dev;
2766 mm_segment_t old_fs;
2767 struct scst_fileio_dev *virt_dev, *vv;
2768 char *file_name, *fn, *old_fn;
2773 list_for_each_entry(vv, &cdrom_fileio_dev_list,
2774 fileio_dev_list_entry)
2776 if (strcmp(vv->name, name) == 0) {
2781 if (virt_dev == NULL) {
2782 PRINT_ERROR_PR("Virtual device with name "
2783 "%s not found", name);
2788 while (isspace(*p) && *p != '\0')
2791 while (!isspace(*p) && *p != '\0')
2794 if (*file_name == '\0') {
2795 virt_dev->cdrom_empty = 1;
2796 TRACE_DBG("%s", "No media");
2797 } else if (*file_name != '/') {
2798 PRINT_ERROR_PR("File path \"%s\" is not "
2799 "absolute", file_name);
2803 virt_dev->cdrom_empty = 0;
2805 old_fn = virt_dev->file_name;
2807 if (!virt_dev->cdrom_empty) {
2808 len = strlen(file_name) + 1;
2809 fn = kmalloc(len, GFP_KERNEL);
2811 TRACE(TRACE_OUT_OF_MEM, "%s",
2812 "Allocation of file_name failed");
2817 strncpy(fn, file_name, len);
2818 virt_dev->file_name = fn;
2820 fd = fileio_open(virt_dev);
2823 PRINT_ERROR_PR("filp_open(%s) returned an error %d",
2824 virt_dev->file_name, res);
2827 if ((fd->f_op == NULL) || (fd->f_op->readv == NULL)) {
2828 PRINT_ERROR_PR("%s", "Wrong f_op or FS doesn't "
2829 "have required capabilities");
2831 filp_close(fd, NULL);
2838 if (fd->f_op->llseek) {
2839 err = fd->f_op->llseek(fd, 0, 2/*SEEK_END*/);
2841 err = default_llseek(fd, 0, 2/*SEEK_END*/);
2844 filp_close(fd, NULL);
2847 PRINT_ERROR_PR("llseek %s returned an error %d",
2848 virt_dev->file_name, res);
2855 virt_dev->file_name = fn;
2858 scst_suspend_activity();
2860 if (virt_dev->prevent_allow_medium_removal) {
2861 PRINT_ERROR_PR("Prevent medium removal for "
2862 "virtual device with name %s", name);
2864 goto out_free_resume;
2867 virt_dev->file_size = err;
2868 virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift;
2869 if (!virt_dev->cdrom_empty)
2870 virt_dev->media_changed = 1;
2872 down(&virt_dev->ftgt_list_mutex);
2873 list_for_each_entry(ftgt_dev, &virt_dev->ftgt_list,
2876 if (!virt_dev->cdrom_empty) {
2877 fd = fileio_open(virt_dev);
2880 PRINT_ERROR_PR("filp_open(%s) returned an error %d, "
2881 "closing the device", virt_dev->file_name, res);
2882 up(&virt_dev->ftgt_list_mutex);
2883 goto out_err_resume;
2888 filp_close(ftgt_dev->fd, NULL);
2891 up(&virt_dev->ftgt_list_mutex);
2893 if (!virt_dev->cdrom_empty) {
2894 PRINT_INFO_PR("Changed SCSI target virtual cdrom %s "
2895 "(file=\"%s\", fs=%LdMB, bs=%d, nblocks=%Ld, cyln=%Ld%s)",
2896 virt_dev->name, virt_dev->file_name,
2897 virt_dev->file_size >> 20, virt_dev->block_size,
2898 virt_dev->nblocks, virt_dev->nblocks/64/32,
2899 virt_dev->nblocks < 64*32 ? " !WARNING! cyln less "
2902 PRINT_INFO_PR("Removed media from SCSI target virtual cdrom %s",
2910 scst_resume_activity();
2916 virt_dev->file_name = old_fn;
2921 virt_dev->file_name = old_fn;
2926 virt_dev->file_name = old_fn;
2928 scst_resume_activity();
2929 cdrom_fileio_close(name);
2934 * Called when a file in the /proc/CDROM_FILEIO_NAME/CDROM_FILEIO_NAME is read
2937 static int cdrom_fileio_proc(char *buffer, char **start, off_t offset,
2938 int length, int *eof, struct scst_dev_type *dev_type, int inout)
2940 int res = 0, action;
2942 struct scst_fileio_dev *virt_dev;
2944 struct fileio_proc_update_struct pu;
2948 memset(&pu, 0, sizeof(pu));
2950 if (down_interruptible(&scst_fileio_mutex) != 0) {
2955 if (inout == 0) { /* read */
2956 size = scnprintf(buffer, length, "%-17s %-9s %s\n",
2957 "Name", "Size(MB)", "File name");
2958 if (fileio_proc_update_size(size, offset, length, &pu, 1))
2961 list_for_each_entry(virt_dev, &cdrom_fileio_dev_list,
2962 fileio_dev_list_entry)
2964 size = scnprintf(buffer + pu.len, length - pu.len,
2965 "%-17s %-9d %s\n", virt_dev->name,
2966 (uint32_t)(virt_dev->file_size >> 20),
2967 virt_dev->file_name);
2968 if (fileio_proc_update_size(size, offset, length, &pu,
2975 } else { /* write */
2977 if (p[strlen(p) - 1] == '\n') {
2978 p[strlen(p) - 1] = '\0';
2980 if (!strncmp("close ", p, 6)) {
2983 } else if (!strncmp("change ", p, 5)) {
2986 } else if (!strncmp("open ", p, 5)) {
2990 PRINT_ERROR_PR("Unknown action \"%s\"", p);
2995 while (isspace(*p) && *p != '\0')
2998 while (!isspace(*p) && *p != '\0')
3001 if (*name == '\0') {
3002 PRINT_ERROR_PR("%s", "Name required");
3005 } else if (strlen(name) >= sizeof(virt_dev->name)) {
3006 PRINT_ERROR_PR("Name is too long (max %zd "
3007 "characters)", sizeof(virt_dev->name)-1);
3012 if (action == 2) { /* open */
3013 res = cdrom_fileio_open(p, name);
3016 } else if (action == 1) { /* change */
3017 res = cdrom_fileio_change(p, name);
3020 } else { /* close */
3021 res = cdrom_fileio_close(name);
3029 up(&scst_fileio_mutex);
3032 TRACE_EXIT_RES(res);
3036 *start = buffer + (offset - pu.begin);
3037 pu.len -= (offset - pu.begin);
3038 if (pu.len > length)
3044 static int fileio_proc_help_build(struct scst_dev_type *dev_type)
3047 struct proc_dir_entry *p, *root;
3051 root = scst_proc_get_dev_type_root(dev_type);
3053 p = create_proc_read_entry(FILEIO_PROC_HELP,
3054 S_IFREG | S_IRUGO, root,
3055 fileio_proc_help_read,
3056 (dev_type->type == TYPE_DISK) ?
3057 disk_fileio_proc_help_string :
3058 cdrom_fileio_proc_help_string);
3060 PRINT_ERROR_PR("Not enough memory to register dev "
3061 "handler %s entry %s in /proc",
3062 dev_type->name, FILEIO_PROC_HELP);
3069 TRACE_EXIT_RES(res);
3073 static void fileio_proc_help_destroy(struct scst_dev_type *dev_type)
3075 struct proc_dir_entry *root;
3079 root = scst_proc_get_dev_type_root(dev_type);
3081 remove_proc_entry(FILEIO_PROC_HELP, root);
3086 static int fileio_proc_help_read(char *buffer, char **start, off_t offset,
3087 int length, int *eof, void *data)
3090 char *s = (char*)data;
3094 if (offset < strlen(s))
3095 res = scnprintf(buffer, length, "%s", &s[offset]);
3097 TRACE_EXIT_RES(res);
3101 static int __init init_scst_fileio(struct scst_dev_type *devtype)
3107 devtype->module = THIS_MODULE;
3109 res = scst_register_virtual_dev_driver(devtype);
3113 res = scst_dev_handler_build_std_proc(devtype);
3117 res = fileio_proc_help_build(devtype);
3119 goto out_destroy_proc;
3123 TRACE_EXIT_RES(res);
3127 scst_dev_handler_destroy_std_proc(devtype);
3130 scst_unregister_virtual_dev_driver(devtype);
3134 static void __exit exit_scst_fileio(struct scst_dev_type *devtype,
3135 struct list_head *fileio_dev_list)
3139 down(&scst_fileio_mutex);
3141 struct scst_fileio_dev *virt_dev;
3143 if (list_empty(fileio_dev_list))
3146 virt_dev = list_entry(fileio_dev_list->next, typeof(*virt_dev),
3147 fileio_dev_list_entry);
3149 scst_unregister_virtual_device(virt_dev->virt_id);
3151 list_del(&virt_dev->fileio_dev_list_entry);
3153 PRINT_INFO_PR("Virtual device %s unregistered", virt_dev->name);
3154 TRACE_DBG("virt_id %d", virt_dev->virt_id);
3155 kfree(virt_dev->file_name);
3158 up(&scst_fileio_mutex);
3160 fileio_proc_help_destroy(devtype);
3161 scst_dev_handler_destroy_std_proc(devtype);
3163 scst_unregister_virtual_dev_driver(devtype);
3169 static int __init init_scst_fileio_driver(void)
3172 res = init_scst_fileio(&disk_devtype_fileio);
3176 res = init_scst_fileio(&cdrom_devtype_fileio);
3184 exit_scst_fileio(&disk_devtype_fileio, &disk_fileio_dev_list);
3188 static void __exit exit_scst_fileio_driver(void)
3190 exit_scst_fileio(&disk_devtype_fileio, &disk_fileio_dev_list);
3191 exit_scst_fileio(&cdrom_devtype_fileio, &cdrom_fileio_dev_list);
3194 * Wait for one sec. to allow the thread(s) actually exit,
3195 * otherwise we can get Oops. Any better way?
3198 unsigned long t = jiffies;
3199 TRACE_DBG("%s", "Waiting 1 sec...");
3200 while ((jiffies - t) < HZ)
3205 module_init(init_scst_fileio_driver);
3206 module_exit(exit_scst_fileio_driver);
3208 MODULE_LICENSE("GPL");