4 * Copyright (C) 2004 - 2009 Vladislav Bolkhovitin <vst@vlnb.net>
5 * Copyright (C) 2004 - 2005 Leonid Stoljar
6 * Copyright (C) 2007 Ming Zhang <blackmagic02881 at gmail dot com>
7 * Copyright (C) 2007 Ross Walker <rswwalker at hotmail dot com>
8 * Copyright (C) 2007 - 2009 ID7 Ltd.
10 * SCSI disk (type 0) and CDROM (type 5) dev handler using files
11 * on file systems or block devices (VDISK)
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation, version 2
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
24 #include <linux/file.h>
26 #include <linux/string.h>
27 #include <linux/types.h>
28 #include <linux/unistd.h>
29 #include <linux/smp_lock.h>
30 #include <linux/spinlock.h>
31 #include <linux/init.h>
32 #include <linux/uio.h>
33 #include <linux/proc_fs.h>
34 #include <linux/list.h>
35 #include <linux/ctype.h>
36 #include <linux/writeback.h>
37 #include <linux/vmalloc.h>
38 #include <asm/atomic.h>
39 #include <linux/kthread.h>
40 #include <linux/sched.h>
41 #include <linux/version.h>
42 #include <asm/div64.h>
44 #define LOG_PREFIX "dev_vdisk"
48 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
50 #define TRACE_ORDER 0x80000000
52 static struct scst_proc_log vdisk_proc_local_trace_tbl[] =
54 { TRACE_ORDER, "order" },
57 #define trace_log_tbl vdisk_proc_local_trace_tbl
61 #include "scst_dev_handler.h"
63 /* 8 byte ASCII Vendor */
64 #define SCST_FIO_VENDOR "SCST_FIO"
65 #define SCST_BIO_VENDOR "SCST_BIO"
66 /* 4 byte ASCII Product Revision Level - left aligned */
67 #define SCST_FIO_REV " 102"
69 #define MAX_USN_LEN (20+1) /* For '\0' */
71 #define INQ_BUF_SZ 128
75 #define MSENSE_BUF_SZ 256
76 #define DBD 0x08 /* disable block descriptor */
77 #define WP 0x80 /* write protect */
78 #define DPOFUA 0x10 /* DPOFUA bit */
79 #define WCE 0x04 /* write cache enable */
81 #define PF 0x10 /* page format */
82 #define SP 0x01 /* save pages */
83 #define PS 0x80 /* parameter saveable */
86 #define DEF_DISK_BLOCKSIZE_SHIFT 9
87 #define DEF_DISK_BLOCKSIZE (1 << DEF_DISK_BLOCKSIZE_SHIFT)
88 #define DEF_CDROM_BLOCKSIZE_SHIFT 11
89 #define DEF_CDROM_BLOCKSIZE (1 << DEF_CDROM_BLOCKSIZE_SHIFT)
90 #define DEF_SECTORS 56
92 #define LEN_MEM (32 * 1024)
93 #define VDISK_NAME "vdisk"
94 #define VCDROM_NAME "vcdrom"
96 #define VDISK_NULLIO_SIZE (3LL*1024*1024*1024*1024/2)
98 #define DEF_TST SCST_CONTR_MODE_SEP_TASK_SETS
100 * Since we can't control backstorage device's reordering, we have to always
101 * report unrestricted reordering.
103 #define DEF_QUEUE_ALG_WT SCST_CONTR_MODE_QUEUE_ALG_UNRESTRICTED_REORDER
104 #define DEF_QUEUE_ALG SCST_CONTR_MODE_QUEUE_ALG_UNRESTRICTED_REORDER
108 #define DEF_DSENSE SCST_CONTR_MODE_FIXED_SENSE
110 #define VDISK_PROC_HELP "help"
112 static unsigned int random_values[256] = {
113 9862592UL, 3744545211UL, 2348289082UL, 4036111983UL,
114 435574201UL, 3110343764UL, 2383055570UL, 1826499182UL,
115 4076766377UL, 1549935812UL, 3696752161UL, 1200276050UL,
116 3878162706UL, 1783530428UL, 2291072214UL, 125807985UL,
117 3407668966UL, 547437109UL, 3961389597UL, 969093968UL,
118 56006179UL, 2591023451UL, 1849465UL, 1614540336UL,
119 3699757935UL, 479961779UL, 3768703953UL, 2529621525UL,
120 4157893312UL, 3673555386UL, 4091110867UL, 2193909423UL,
121 2800464448UL, 3052113233UL, 450394455UL, 3424338713UL,
122 2113709130UL, 4082064373UL, 3708640918UL, 3841182218UL,
123 3141803315UL, 1032476030UL, 1166423150UL, 1169646901UL,
124 2686611738UL, 575517645UL, 2829331065UL, 1351103339UL,
125 2856560215UL, 2402488288UL, 867847666UL, 8524618UL,
126 704790297UL, 2228765657UL, 231508411UL, 1425523814UL,
127 2146764591UL, 1287631730UL, 4142687914UL, 3879884598UL,
128 729945311UL, 310596427UL, 2263511876UL, 1983091134UL,
129 3500916580UL, 1642490324UL, 3858376049UL, 695342182UL,
130 780528366UL, 1372613640UL, 1100993200UL, 1314818946UL,
131 572029783UL, 3775573540UL, 776262915UL, 2684520905UL,
132 1007252738UL, 3505856396UL, 1974886670UL, 3115856627UL,
133 4194842288UL, 2135793908UL, 3566210707UL, 7929775UL,
134 1321130213UL, 2627281746UL, 3587067247UL, 2025159890UL,
135 2587032000UL, 3098513342UL, 3289360258UL, 130594898UL,
136 2258149812UL, 2275857755UL, 3966929942UL, 1521739999UL,
137 4191192765UL, 958953550UL, 4153558347UL, 1011030335UL,
138 524382185UL, 4099757640UL, 498828115UL, 2396978754UL,
139 328688935UL, 826399828UL, 3174103611UL, 3921966365UL,
140 2187456284UL, 2631406787UL, 3930669674UL, 4282803915UL,
141 1776755417UL, 374959755UL, 2483763076UL, 844956392UL,
142 2209187588UL, 3647277868UL, 291047860UL, 3485867047UL,
143 2223103546UL, 2526736133UL, 3153407604UL, 3828961796UL,
144 3355731910UL, 2322269798UL, 2752144379UL, 519897942UL,
145 3430536488UL, 1801511593UL, 1953975728UL, 3286944283UL,
146 1511612621UL, 1050133852UL, 409321604UL, 1037601109UL,
147 3352316843UL, 4198371381UL, 617863284UL, 994672213UL,
148 1540735436UL, 2337363549UL, 1242368492UL, 665473059UL,
149 2330728163UL, 3443103219UL, 2291025133UL, 3420108120UL,
150 2663305280UL, 1608969839UL, 2278959931UL, 1389747794UL,
151 2226946970UL, 2131266900UL, 3856979144UL, 1894169043UL,
152 2692697628UL, 3797290626UL, 3248126844UL, 3922786277UL,
153 343705271UL, 3739749888UL, 2191310783UL, 2962488787UL,
154 4119364141UL, 1403351302UL, 2984008923UL, 3822407178UL,
155 1932139782UL, 2323869332UL, 2793574182UL, 1852626483UL,
156 2722460269UL, 1136097522UL, 1005121083UL, 1805201184UL,
157 2212824936UL, 2979547931UL, 4133075915UL, 2585731003UL,
158 2431626071UL, 134370235UL, 3763236829UL, 1171434827UL,
159 2251806994UL, 1289341038UL, 3616320525UL, 392218563UL,
160 1544502546UL, 2993937212UL, 1957503701UL, 3579140080UL,
161 4270846116UL, 2030149142UL, 1792286022UL, 366604999UL,
162 2625579499UL, 790898158UL, 770833822UL, 815540197UL,
163 2747711781UL, 3570468835UL, 3976195842UL, 1257621341UL,
164 1198342980UL, 1860626190UL, 3247856686UL, 351473955UL,
165 993440563UL, 340807146UL, 1041994520UL, 3573925241UL,
166 480246395UL, 2104806831UL, 1020782793UL, 3362132583UL,
167 2272911358UL, 3440096248UL, 2356596804UL, 259492703UL,
168 3899500740UL, 252071876UL, 2177024041UL, 4284810959UL,
169 2775999888UL, 2653420445UL, 2876046047UL, 1025771859UL,
170 1994475651UL, 3564987377UL, 4112956647UL, 1821511719UL,
171 3113447247UL, 455315102UL, 1585273189UL, 2311494568UL,
172 774051541UL, 1898115372UL, 2637499516UL, 247231365UL,
173 1475014417UL, 803585727UL, 3911097303UL, 1714292230UL,
174 476579326UL, 2496900974UL, 3397613314UL, 341202244UL,
175 807790202UL, 4221326173UL, 499979741UL, 1301488547UL,
176 1056807896UL, 3525009458UL, 1174811641UL, 3049738746UL,
179 struct scst_vdisk_dev {
183 loff_t file_size; /* in bytes */
186 * This lock can be taken on both SIRQ and thread context, but in
187 * all cases for each particular instance it's taken consistenly either
188 * on SIRQ or thread context. Mix of them is impossible.
190 spinlock_t flags_lock;
193 * Below flags are protected by flags_lock or suspended activity
194 * with scst_vdisk_mutex.
196 unsigned int rd_only:1;
197 unsigned int wt_flag:1;
198 unsigned int nv_cache:1;
199 unsigned int o_direct_flag:1;
200 unsigned int media_changed:1;
201 unsigned int prevent_allow_medium_removal:1;
202 unsigned int nullio:1;
203 unsigned int blockio:1;
204 unsigned int cdrom_empty:1;
205 unsigned int removable:1;
207 char name[16+1]; /* Name of virtual device,
208 must be <= SCSI Model + 1 */
209 char *file_name; /* File name */
210 char usn[MAX_USN_LEN];
211 struct scst_device *dev;
212 struct list_head vdisk_dev_list_entry;
215 struct scst_vdisk_tgt_dev {
217 * Used without locking since SCST core ensures that only commands
218 * with the same ORDERED type per tgt_dev can be processed
221 enum scst_cmd_queue_type last_write_cmd_queue_type;
224 struct scst_vdisk_thr {
225 struct scst_thr_data_hdr hdr;
227 struct block_device *bdev;
232 static struct kmem_cache *vdisk_thr_cachep;
233 static struct kmem_cache *blockio_work_cachep;
235 #define DEF_NUM_THREADS 5
236 static int num_threads = DEF_NUM_THREADS;
238 module_param_named(num_threads, num_threads, int, S_IRUGO);
239 MODULE_PARM_DESC(num_threads, "vdisk threads count");
241 static int vdisk_attach(struct scst_device *dev);
242 static void vdisk_detach(struct scst_device *dev);
243 static int vdisk_attach_tgt(struct scst_tgt_dev *tgt_dev);
244 static void vdisk_detach_tgt(struct scst_tgt_dev *tgt_dev);
245 static int vdisk_parse(struct scst_cmd *);
246 static int vdisk_do_job(struct scst_cmd *cmd);
247 static int vcdrom_parse(struct scst_cmd *);
248 static int vcdrom_exec(struct scst_cmd *cmd);
249 static void vdisk_exec_read(struct scst_cmd *cmd,
250 struct scst_vdisk_thr *thr, loff_t loff);
251 static void vdisk_exec_write(struct scst_cmd *cmd,
252 struct scst_vdisk_thr *thr, loff_t loff);
253 static void blockio_exec_rw(struct scst_cmd *cmd, struct scst_vdisk_thr *thr,
254 u64 lba_start, int write);
255 static void vdisk_exec_verify(struct scst_cmd *cmd,
256 struct scst_vdisk_thr *thr, loff_t loff);
257 static void vdisk_exec_read_capacity(struct scst_cmd *cmd);
258 static void vdisk_exec_read_capacity16(struct scst_cmd *cmd);
259 static void vdisk_exec_inquiry(struct scst_cmd *cmd);
260 static void vdisk_exec_request_sense(struct scst_cmd *cmd);
261 static void vdisk_exec_mode_sense(struct scst_cmd *cmd);
262 static void vdisk_exec_mode_select(struct scst_cmd *cmd);
263 static void vdisk_exec_log(struct scst_cmd *cmd);
264 static void vdisk_exec_read_toc(struct scst_cmd *cmd);
265 static void vdisk_exec_prevent_allow_medium_removal(struct scst_cmd *cmd);
266 static int vdisk_fsync(struct scst_vdisk_thr *thr,
267 loff_t loff, loff_t len, struct scst_cmd *cmd);
268 static int vdisk_read_proc(struct seq_file *seq,
269 struct scst_dev_type *dev_type);
270 static int vdisk_write_proc(char *buffer, char **start, off_t offset,
271 int length, int *eof, struct scst_dev_type *dev_type);
272 static int vcdrom_read_proc(struct seq_file *seq,
273 struct scst_dev_type *dev_type);
274 static int vcdrom_write_proc(char *buffer, char **start, off_t offset,
275 int length, int *eof, struct scst_dev_type *dev_type);
276 static int vdisk_task_mgmt_fn(struct scst_mgmt_cmd *mcmd,
277 struct scst_tgt_dev *tgt_dev);
280 * Name of FILEIO vdisk can't be changed from "vdisk", since it is the name
281 * of the corresponding /proc/scsi_tgt entry, hence a part of user space ABI.
284 #define VDISK_TYPE { \
285 .name = VDISK_NAME, \
291 .dev_done_atomic = 1, \
292 .attach = vdisk_attach, \
293 .detach = vdisk_detach, \
294 .attach_tgt = vdisk_attach_tgt, \
295 .detach_tgt = vdisk_detach_tgt, \
296 .parse = vdisk_parse, \
297 .exec = vdisk_do_job, \
298 .read_proc = vdisk_read_proc, \
299 .write_proc = vdisk_write_proc, \
300 .task_mgmt_fn = vdisk_task_mgmt_fn, \
303 #define VDISK_BLK_TYPE { \
304 .name = VDISK_NAME "_blk", \
309 .dev_done_atomic = 1, \
311 .attach = vdisk_attach, \
312 .detach = vdisk_detach, \
313 .attach_tgt = vdisk_attach_tgt, \
314 .detach_tgt = vdisk_detach_tgt, \
315 .parse = vdisk_parse, \
316 .exec = vdisk_do_job, \
317 .task_mgmt_fn = vdisk_task_mgmt_fn, \
320 #define VDISK_NULL_TYPE { \
321 .name = VDISK_NAME "_null", \
326 .dev_done_atomic = 1, \
328 .attach = vdisk_attach, \
329 .detach = vdisk_detach, \
330 .attach_tgt = vdisk_attach_tgt, \
331 .detach_tgt = vdisk_detach_tgt, \
332 .parse = vdisk_parse, \
333 .exec = vdisk_do_job, \
334 .task_mgmt_fn = vdisk_task_mgmt_fn, \
337 #define VCDROM_TYPE { \
338 .name = VCDROM_NAME, \
344 .dev_done_atomic = 1, \
345 .attach = vdisk_attach, \
346 .detach = vdisk_detach, \
347 .attach_tgt = vdisk_attach_tgt, \
348 .detach_tgt = vdisk_detach_tgt, \
349 .parse = vcdrom_parse, \
350 .exec = vcdrom_exec, \
351 .read_proc = vcdrom_read_proc, \
352 .write_proc = vcdrom_write_proc, \
353 .task_mgmt_fn = vdisk_task_mgmt_fn, \
356 static DEFINE_MUTEX(scst_vdisk_mutex);
357 static LIST_HEAD(vdisk_dev_list);
358 static LIST_HEAD(vcdrom_dev_list);
360 static struct scst_dev_type vdisk_file_devtype = VDISK_TYPE;
361 static struct scst_dev_type vdisk_blk_devtype = VDISK_BLK_TYPE;
362 static struct scst_dev_type vdisk_null_devtype = VDISK_NULL_TYPE;
363 static struct scst_dev_type vcdrom_devtype = VCDROM_TYPE;
365 static struct scst_vdisk_thr nullio_thr_data;
367 static char *vdisk_proc_help_string =
368 "echo \"open|close|resync_size NAME [FILE_NAME [BLOCK_SIZE] "
369 "[WRITE_THROUGH READ_ONLY O_DIRECT NULLIO NV_CACHE BLOCKIO]]\" "
370 ">/proc/scsi_tgt/" VDISK_NAME "/" VDISK_NAME "\n";
372 static char *vcdrom_proc_help_string =
373 "echo \"open|change|close NAME [FILE_NAME]\" "
374 ">/proc/scsi_tgt/" VCDROM_NAME "/" VCDROM_NAME "\n";
376 static int scst_vdisk_ID;
378 module_param_named(scst_vdisk_ID, scst_vdisk_ID, int, S_IRUGO);
379 MODULE_PARM_DESC(scst_vdisk_ID, "SCST virtual disk subsystem ID");
382 /**************************************************************
383 * Function: vdisk_open
387 * Returns : fd, use IS_ERR(fd) to get error status
390 *************************************************************/
391 static struct file *vdisk_open(const struct scst_vdisk_dev *virt_dev)
398 if (virt_dev->dev->rd_only)
399 open_flags |= O_RDONLY;
401 open_flags |= O_RDWR;
402 if (virt_dev->o_direct_flag)
403 open_flags |= O_DIRECT;
404 if (virt_dev->wt_flag && !virt_dev->nv_cache)
405 open_flags |= O_SYNC;
406 TRACE_DBG("Opening file %s, flags 0x%x",
407 virt_dev->file_name, open_flags);
408 fd = filp_open(virt_dev->file_name, O_LARGEFILE | open_flags, 0600);
414 /**************************************************************
415 * Function: vdisk_get_file_size
419 * Returns : 0 on success and file size in *file_size,
420 * error code otherwise
423 *************************************************************/
424 static int vdisk_get_check_file_size(const char *file_name, bool blockio,
435 fd = filp_open(file_name, O_LARGEFILE | O_RDONLY, 0600);
438 PRINT_ERROR("filp_open(%s) returned error %d", file_name, res);
442 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
443 if ((fd->f_op == NULL) ||
444 (fd->f_op->readv == NULL) ||
445 (fd->f_op->writev == NULL)) {
447 if ((fd->f_op == NULL) ||
448 (fd->f_op->aio_read == NULL) ||
449 (fd->f_op->aio_write == NULL)) {
451 PRINT_ERROR("%s", "Wrong f_op or FS doesn't have required "
457 inode = fd->f_dentry->d_inode;
459 if (blockio && !S_ISBLK(inode->i_mode)) {
460 PRINT_ERROR("File %s is NOT a block device", file_name);
465 if (S_ISREG(inode->i_mode))
467 else if (S_ISBLK(inode->i_mode))
468 inode = inode->i_bdev->bd_inode;
474 *file_size = inode->i_size;
477 filp_close(fd, NULL);
484 /**************************************************************
485 * Function: vdisk_attach
489 * Returns : 1 if attached, error code otherwise
492 *************************************************************/
493 static int vdisk_attach(struct scst_device *dev)
497 struct scst_vdisk_dev *virt_dev = NULL, *vv;
498 struct list_head *vd;
502 TRACE_DBG("virt_id %d (%s)", dev->virt_id, dev->virt_name);
504 if (dev->virt_id == 0) {
505 PRINT_ERROR("%s", "Not a virtual device");
510 vd = (dev->type == TYPE_DISK) ?
515 * scst_vdisk_mutex must be already taken before
516 * scst_register_virtual_device()
518 list_for_each_entry(vv, vd, vdisk_dev_list_entry) {
519 if (strcmp(vv->name, dev->virt_name) == 0) {
525 if (virt_dev == NULL) {
526 PRINT_ERROR("Device %s not found", dev->virt_name);
533 dev->rd_only = virt_dev->rd_only;
534 if (dev->type == TYPE_ROM)
537 if (!virt_dev->cdrom_empty) {
538 if (virt_dev->nullio)
539 err = VDISK_NULLIO_SIZE;
541 res = vdisk_get_check_file_size(virt_dev->file_name,
542 virt_dev->blockio, &err);
546 virt_dev->file_size = err;
547 TRACE_DBG("size of file: %lld", (long long unsigned int)err);
549 virt_dev->file_size = 0;
551 if (dev->type == TYPE_DISK) {
553 virt_dev->file_size >> virt_dev->block_shift;
555 virt_dev->block_size = DEF_CDROM_BLOCKSIZE;
556 virt_dev->block_shift = DEF_CDROM_BLOCKSIZE_SHIFT;
558 virt_dev->file_size >> DEF_CDROM_BLOCKSIZE_SHIFT;
561 if (!virt_dev->cdrom_empty) {
562 PRINT_INFO("Attached SCSI target virtual %s %s "
563 "(file=\"%s\", fs=%lldMB, bs=%d, nblocks=%lld,"
565 (dev->type == TYPE_DISK) ? "disk" : "cdrom",
566 virt_dev->name, virt_dev->file_name,
567 virt_dev->file_size >> 20, virt_dev->block_size,
568 (long long unsigned int)virt_dev->nblocks,
569 (long long unsigned int)virt_dev->nblocks/64/32,
570 virt_dev->nblocks < 64*32
571 ? " !WARNING! cyln less than 1" : "");
573 PRINT_INFO("Attached empty SCSI target virtual cdrom %s",
577 dev->dh_priv = virt_dev;
580 dev->d_sense = DEF_DSENSE;
581 if (virt_dev->wt_flag && !virt_dev->nv_cache)
582 dev->queue_alg = DEF_QUEUE_ALG_WT;
584 dev->queue_alg = DEF_QUEUE_ALG;
593 /************************************************************
594 * Function: vdisk_detach
600 * Description: Called to detach this device type driver
601 ************************************************************/
602 static void vdisk_detach(struct scst_device *dev)
604 struct scst_vdisk_dev *virt_dev =
605 (struct scst_vdisk_dev *)dev->dh_priv;
609 TRACE_DBG("virt_id %d", dev->virt_id);
611 PRINT_INFO("Detached SCSI target virtual device %s (\"%s\")",
612 virt_dev->name, virt_dev->file_name);
614 /* virt_dev will be freed by the caller */
621 static void vdisk_free_thr_data(struct scst_thr_data_hdr *d)
623 struct scst_vdisk_thr *thr =
624 container_of(d, struct scst_vdisk_thr, hdr);
629 filp_close(thr->fd, NULL);
633 kmem_cache_free(vdisk_thr_cachep, thr);
639 static struct scst_vdisk_thr *vdisk_init_thr_data(
640 struct scst_tgt_dev *tgt_dev)
642 struct scst_vdisk_thr *res;
643 struct scst_vdisk_dev *virt_dev =
644 (struct scst_vdisk_dev *)tgt_dev->dev->dh_priv;
648 EXTRACHECKS_BUG_ON(virt_dev->nullio);
650 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17)
651 res = kmem_cache_alloc(vdisk_thr_cachep, GFP_KERNEL);
653 memset(res, 0, sizeof(*res));
655 res = kmem_cache_zalloc(vdisk_thr_cachep, GFP_KERNEL);
658 TRACE(TRACE_OUT_OF_MEM, "%s", "Unable to allocate struct "
663 if (!virt_dev->cdrom_empty) {
664 res->fd = vdisk_open(virt_dev);
665 if (IS_ERR(res->fd)) {
666 PRINT_ERROR("filp_open(%s) returned an error %ld",
667 virt_dev->file_name, PTR_ERR(res->fd));
670 if (virt_dev->blockio)
671 res->bdev = res->fd->f_dentry->d_inode->i_bdev;
677 scst_add_thr_data(tgt_dev, &res->hdr, vdisk_free_thr_data);
680 TRACE_EXIT_HRES((unsigned long)res);
684 kmem_cache_free(vdisk_thr_cachep, res);
689 static int vdisk_attach_tgt(struct scst_tgt_dev *tgt_dev)
691 struct scst_vdisk_tgt_dev *ftgt_dev;
696 ftgt_dev = kzalloc(sizeof(*ftgt_dev), GFP_KERNEL);
697 if (ftgt_dev == NULL) {
698 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of per-session "
699 "virtual device failed");
704 tgt_dev->dh_priv = ftgt_dev;
711 static void vdisk_detach_tgt(struct scst_tgt_dev *tgt_dev)
713 struct scst_vdisk_tgt_dev *ftgt_dev =
714 (struct scst_vdisk_tgt_dev *)tgt_dev->dh_priv;
718 scst_del_all_thr_data(tgt_dev);
721 tgt_dev->dh_priv = NULL;
727 static inline int vdisk_sync_queue_type(enum scst_cmd_queue_type qt)
730 case SCST_CMD_QUEUE_ORDERED:
731 case SCST_CMD_QUEUE_HEAD_OF_QUEUE:
738 static inline int vdisk_need_pre_sync(enum scst_cmd_queue_type cur,
739 enum scst_cmd_queue_type last)
741 if (vdisk_sync_queue_type(cur))
742 if (!vdisk_sync_queue_type(last))
747 static int vdisk_do_job(struct scst_cmd *cmd)
750 uint64_t lba_start = 0;
752 uint8_t *cdb = cmd->cdb;
755 struct scst_device *dev = cmd->dev;
756 struct scst_tgt_dev *tgt_dev = cmd->tgt_dev;
757 struct scst_vdisk_dev *virt_dev =
758 (struct scst_vdisk_dev *)dev->dh_priv;
759 struct scst_thr_data_hdr *d;
760 struct scst_vdisk_thr *thr = NULL;
765 switch (cmd->queue_type) {
766 case SCST_CMD_QUEUE_ORDERED:
767 TRACE(TRACE_ORDER, "ORDERED cmd %p", cmd);
769 case SCST_CMD_QUEUE_HEAD_OF_QUEUE:
770 TRACE(TRACE_ORDER, "HQ cmd %p", cmd);
776 rc = scst_check_local_events(cmd);
777 if (unlikely(rc != 0))
782 cmd->host_status = DID_OK;
783 cmd->driver_status = 0;
785 if (!virt_dev->nullio) {
786 d = scst_find_thr_data(tgt_dev);
787 if (unlikely(d == NULL)) {
788 thr = vdisk_init_thr_data(tgt_dev);
793 scst_thr_data_get(&thr->hdr);
795 thr = container_of(d, struct scst_vdisk_thr, hdr);
797 thr = &nullio_thr_data;
798 scst_thr_data_get(&thr->hdr);
805 lba_start = (((cdb[1] & 0x1f) << (BYTE * 2)) +
806 (cdb[2] << (BYTE * 1)) +
807 (cdb[3] << (BYTE * 0)));
808 data_len = cmd->bufflen;
816 case WRITE_VERIFY_12:
818 lba_start |= ((u64)cdb[2]) << 24;
819 lba_start |= ((u64)cdb[3]) << 16;
820 lba_start |= ((u64)cdb[4]) << 8;
821 lba_start |= ((u64)cdb[5]);
822 data_len = cmd->bufflen;
826 case WRITE_VERIFY_16:
828 lba_start |= ((u64)cdb[2]) << 56;
829 lba_start |= ((u64)cdb[3]) << 48;
830 lba_start |= ((u64)cdb[4]) << 40;
831 lba_start |= ((u64)cdb[5]) << 32;
832 lba_start |= ((u64)cdb[6]) << 24;
833 lba_start |= ((u64)cdb[7]) << 16;
834 lba_start |= ((u64)cdb[8]) << 8;
835 lba_start |= ((u64)cdb[9]);
836 data_len = cmd->bufflen;
838 case SYNCHRONIZE_CACHE:
839 lba_start |= ((u64)cdb[2]) << 24;
840 lba_start |= ((u64)cdb[3]) << 16;
841 lba_start |= ((u64)cdb[4]) << 8;
842 lba_start |= ((u64)cdb[5]);
843 data_len = ((cdb[7] << (BYTE * 1)) + (cdb[8] << (BYTE * 0)))
844 << virt_dev->block_shift;
846 data_len = virt_dev->file_size -
847 ((loff_t)lba_start << virt_dev->block_shift);
851 loff = (loff_t)lba_start << virt_dev->block_shift;
852 TRACE_DBG("cmd %p, lba_start %lld, loff %lld, data_len %lld", cmd,
853 (long long unsigned int)lba_start,
854 (long long unsigned int)loff,
855 (long long unsigned int)data_len);
856 if (unlikely(loff < 0) || unlikely(data_len < 0) ||
857 unlikely((loff + data_len) > virt_dev->file_size)) {
858 PRINT_INFO("Access beyond the end of the device "
859 "(%lld of %lld, len %lld)",
860 (long long unsigned int)loff,
861 (long long unsigned int)virt_dev->file_size,
862 (long long unsigned int)data_len);
863 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
864 scst_sense_block_out_range_error));
872 fua = (cdb[1] & 0x8);
874 TRACE(TRACE_ORDER, "FUA: loff=%lld, "
875 "data_len=%lld", (long long unsigned int)loff,
876 (long long unsigned int)data_len);
886 if (virt_dev->blockio) {
887 blockio_exec_rw(cmd, thr, lba_start, 0);
890 vdisk_exec_read(cmd, thr, loff);
897 int do_fsync = vdisk_sync_queue_type(cmd->queue_type);
898 struct scst_vdisk_tgt_dev *ftgt_dev =
899 (struct scst_vdisk_tgt_dev *)tgt_dev->dh_priv;
900 enum scst_cmd_queue_type last_queue_type =
901 ftgt_dev->last_write_cmd_queue_type;
902 ftgt_dev->last_write_cmd_queue_type = cmd->queue_type;
903 if (vdisk_need_pre_sync(cmd->queue_type, last_queue_type)) {
904 TRACE(TRACE_ORDER, "ORDERED WRITE(%d): loff=%lld, "
905 "data_len=%lld", cmd->queue_type,
906 (long long unsigned int)loff,
907 (long long unsigned int)data_len);
909 if (vdisk_fsync(thr, 0, 0, cmd) != 0)
912 if (virt_dev->blockio) {
913 blockio_exec_rw(cmd, thr, lba_start, 1);
916 vdisk_exec_write(cmd, thr, loff);
917 /* O_SYNC flag is used for WT devices */
919 vdisk_fsync(thr, loff, data_len, cmd);
923 case WRITE_VERIFY_12:
924 case WRITE_VERIFY_16:
926 int do_fsync = vdisk_sync_queue_type(cmd->queue_type);
927 struct scst_vdisk_tgt_dev *ftgt_dev =
928 (struct scst_vdisk_tgt_dev *) tgt_dev->dh_priv;
929 enum scst_cmd_queue_type last_queue_type =
930 ftgt_dev->last_write_cmd_queue_type;
931 ftgt_dev->last_write_cmd_queue_type = cmd->queue_type;
932 if (vdisk_need_pre_sync(cmd->queue_type, last_queue_type)) {
933 TRACE(TRACE_ORDER, "ORDERED "
934 "WRITE_VERIFY(%d): loff=%lld,"
935 " data_len=%lld", cmd->queue_type,
936 (long long unsigned int)loff,
937 (long long unsigned int)data_len);
939 if (vdisk_fsync(thr, 0, 0, cmd) != 0)
942 /* ToDo: BLOCKIO VERIFY */
943 vdisk_exec_write(cmd, thr, loff);
944 /* O_SYNC flag is used for WT devices */
945 if (scsi_status_is_good(cmd->status))
946 vdisk_exec_verify(cmd, thr, loff);
948 vdisk_fsync(thr, loff, data_len, cmd);
951 case SYNCHRONIZE_CACHE:
953 int immed = cdb[1] & 0x2;
954 TRACE(TRACE_ORDER, "SYNCHRONIZE_CACHE: "
955 "loff=%lld, data_len=%lld, immed=%d",
956 (long long unsigned int)loff,
957 (long long unsigned int)data_len, immed);
961 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT,
963 vdisk_fsync(thr, loff, data_len, NULL);
964 /* ToDo: vdisk_fsync() error processing */
968 vdisk_fsync(thr, loff, data_len, cmd);
976 vdisk_exec_verify(cmd, thr, loff);
980 vdisk_exec_mode_sense(cmd);
984 vdisk_exec_mode_select(cmd);
990 case ALLOW_MEDIUM_REMOVAL:
991 vdisk_exec_prevent_allow_medium_removal(cmd);
994 vdisk_exec_read_toc(cmd);
997 vdisk_fsync(thr, 0, virt_dev->file_size, cmd);
1003 case TEST_UNIT_READY:
1006 vdisk_exec_inquiry(cmd);
1009 vdisk_exec_request_sense(cmd);
1012 vdisk_exec_read_capacity(cmd);
1014 case SERVICE_ACTION_IN:
1015 if ((cmd->cdb[1] & 0x1f) == SAI_READ_CAPACITY_16) {
1016 vdisk_exec_read_capacity16(cmd);
1019 /* else go through */
1022 TRACE_DBG("Invalid opcode %d", opcode);
1023 scst_set_cmd_error(cmd,
1024 SCST_LOAD_SENSE(scst_sense_invalid_opcode));
1031 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
1034 if (likely(thr != NULL))
1035 scst_thr_data_put(&thr->hdr);
1037 res = SCST_EXEC_COMPLETED;
1039 TRACE_EXIT_RES(res);
1043 static int vdisk_get_block_shift(struct scst_cmd *cmd)
1045 struct scst_vdisk_dev *virt_dev =
1046 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1047 return virt_dev->block_shift;
1050 /********************************************************************
1051 * Function: vdisk_parse
1055 * Returns : The state of the command
1057 * Description: This does the parsing of the command
1059 * Note: Not all states are allowed on return
1060 ********************************************************************/
1061 static int vdisk_parse(struct scst_cmd *cmd)
1063 scst_sbc_generic_parse(cmd, vdisk_get_block_shift);
1064 return SCST_CMD_STATE_DEFAULT;
1067 /********************************************************************
1068 * Function: vcdrom_parse
1072 * Returns : The state of the command
1074 * Description: This does the parsing of the command
1076 * Note: Not all states are allowed on return
1077 ********************************************************************/
1078 static int vcdrom_parse(struct scst_cmd *cmd)
1080 scst_cdrom_generic_parse(cmd, vdisk_get_block_shift);
1081 return SCST_CMD_STATE_DEFAULT;
1084 /********************************************************************
1085 * Function: vcdrom_exec
1092 ********************************************************************/
1093 static int vcdrom_exec(struct scst_cmd *cmd)
1095 int res = SCST_EXEC_COMPLETED;
1096 int opcode = cmd->cdb[0];
1097 struct scst_vdisk_dev *virt_dev =
1098 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1103 cmd->msg_status = 0;
1104 cmd->host_status = DID_OK;
1105 cmd->driver_status = 0;
1107 if (virt_dev->cdrom_empty && (opcode != INQUIRY)) {
1108 TRACE_DBG("%s", "CDROM empty");
1109 scst_set_cmd_error(cmd,
1110 SCST_LOAD_SENSE(scst_sense_not_ready));
1114 if (virt_dev->media_changed && (cmd->cdb[0] != INQUIRY) &&
1115 (cmd->cdb[0] != REQUEST_SENSE) && (cmd->cdb[0] != REPORT_LUNS)) {
1116 spin_lock(&virt_dev->flags_lock);
1117 if (virt_dev->media_changed) {
1118 virt_dev->media_changed = 0;
1119 TRACE_DBG("%s", "Reporting media changed");
1120 scst_set_cmd_error(cmd,
1121 SCST_LOAD_SENSE(scst_sense_medium_changed_UA));
1122 spin_unlock(&virt_dev->flags_lock);
1125 spin_unlock(&virt_dev->flags_lock);
1128 res = vdisk_do_job(cmd);
1131 TRACE_EXIT_RES(res);
1135 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
1139 static uint64_t vdisk_gen_dev_id_num(struct scst_vdisk_dev *virt_dev)
1141 unsigned int dev_id_num, i;
1143 for (dev_id_num = 0, i = 0; i < strlen(virt_dev->name); i++) {
1144 unsigned int rv = random_values[(int)(virt_dev->name[i])];
1145 /* Do some rotating of the bits */
1146 dev_id_num ^= ((rv << i) | (rv >> (32 - i)));
1149 return ((uint64_t)scst_vdisk_ID << 32) | dev_id_num;
1152 static void vdisk_exec_inquiry(struct scst_cmd *cmd)
1154 int32_t length, i, resp_len = 0;
1157 struct scst_vdisk_dev *virt_dev =
1158 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1160 /* ToDo: Performance Boost:
1161 * 1. remove kzalloc, buf
1162 * 2. do all checks before touching *address
1164 * 4. write directly to *address
1169 buf = kzalloc(INQ_BUF_SZ,
1170 scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL);
1176 length = scst_get_buf_first(cmd, &address);
1177 TRACE_DBG("length %d", length);
1178 if (unlikely(length <= 0)) {
1180 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1181 scst_set_cmd_error(cmd,
1182 SCST_LOAD_SENSE(scst_sense_hardw_error));
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 buf[0] = cmd->dev->type; /* type dev */
1195 if ((buf[0] == TYPE_ROM) || virt_dev->removable)
1196 buf[1] = 0x80; /* removable */
1198 if (cmd->cdb[1] & EVPD) {
1199 uint64_t dev_id_num;
1201 char dev_id_str[17];
1203 dev_id_num = vdisk_gen_dev_id_num(virt_dev);
1204 dev_id_len = scnprintf(dev_id_str, sizeof(dev_id_str), "%llx",
1206 TRACE_DBG("dev_id num %lld, str %s, len %d", dev_id_num,
1207 dev_id_str, dev_id_len);
1208 if (0 == cmd->cdb[2]) {
1209 /* 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 resp_len = buf[3] + 4;
1215 } else if (0x80 == cmd->cdb[2]) {
1216 /* unit serial number */
1217 int usn_len = strlen(virt_dev->usn);
1220 strncpy(&buf[4], virt_dev->usn, usn_len);
1221 resp_len = buf[3] + 4;
1222 } else if (0x83 == cmd->cdb[2]) {
1223 /* device identification */
1227 /* T10 vendor identifier field format (faked) */
1228 buf[num + 0] = 0x2; /* ASCII */
1229 buf[num + 1] = 0x1; /* Vendor ID */
1230 if (virt_dev->blockio)
1231 memcpy(&buf[num + 4], SCST_BIO_VENDOR, 8);
1233 memcpy(&buf[num + 4], SCST_FIO_VENDOR, 8);
1235 i = strlen(virt_dev->name) + 1; /* for ' ' */
1236 memset(&buf[num + 12], ' ', i + dev_id_len);
1237 memcpy(&buf[num + 12], virt_dev->name, i-1);
1238 memcpy(&buf[num + 12 + i], dev_id_str, dev_id_len);
1239 buf[num + 3] = 8 + i + dev_id_len;
1240 num += buf[num + 3];
1242 #if 0 /* This isn't required and can be misleading, so let's disable it */
1245 /* NAA IEEE registered identifier (faked) */
1246 buf[num] = 0x1; /* binary */
1250 buf[num + 4] = 0x51; /* IEEE OUI=0x123456 (faked) */
1251 buf[num + 5] = 0x23;
1252 buf[num + 6] = 0x45;
1253 buf[num + 7] = 0x60;
1254 buf[num + 8] = (dev_id_num >> 24);
1255 buf[num + 9] = (dev_id_num >> 16) & 0xff;
1256 buf[num + 10] = (dev_id_num >> 8) & 0xff;
1257 buf[num + 11] = dev_id_num & 0xff;
1262 buf[2] = (resp_len >> 8) & 0xFF;
1263 buf[3] = resp_len & 0xFF;
1266 TRACE_DBG("INQUIRY: Unsupported EVPD page %x",
1268 scst_set_cmd_error(cmd,
1269 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1275 if (cmd->cdb[2] != 0) {
1276 TRACE_DBG("INQUIRY: Unsupported page %x", cmd->cdb[2]);
1277 scst_set_cmd_error(cmd,
1278 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1282 buf[2] = 4; /* Device complies to this standard - SPC-2 */
1283 buf[3] = 0x12; /* HiSup + data in format specified in SPC-2 */
1284 buf[4] = 31;/* n - 4 = 35 - 4 = 31 for full 36 byte data */
1285 buf[6] = 1; /* MultiP 1 */
1286 buf[7] = 2; /* CMDQUE 1, BQue 0 => commands queuing supported */
1289 * 8 byte ASCII Vendor Identification of the target
1292 if (virt_dev->blockio)
1293 memcpy(&buf[8], SCST_BIO_VENDOR, 8);
1295 memcpy(&buf[8], SCST_FIO_VENDOR, 8);
1298 * 16 byte ASCII Product Identification of the target - left
1301 memset(&buf[16], ' ', 16);
1302 len = min(strlen(virt_dev->name), (size_t)16);
1303 memcpy(&buf[16], virt_dev->name, len);
1306 * 4 byte ASCII Product Revision Level of the target - left
1309 memcpy(&buf[32], SCST_FIO_REV, 4);
1310 resp_len = buf[4] + 5;
1313 sBUG_ON(resp_len >= INQ_BUF_SZ);
1314 if (length > resp_len)
1316 memcpy(address, buf, length);
1319 scst_put_buf(cmd, address);
1320 if (length < cmd->resp_data_len)
1321 scst_set_resp_data_len(cmd, length);
1331 static void vdisk_exec_request_sense(struct scst_cmd *cmd)
1338 length = scst_get_buf_first(cmd, &address);
1339 TRACE_DBG("length %d", length);
1340 if (unlikely(length < SCST_STANDARD_SENSE_LEN)) {
1342 PRINT_ERROR("scst_get_buf_first() failed or too small "
1343 "requested buffer (returned %d)", length);
1344 scst_set_cmd_error(cmd,
1346 scst_sense_invalid_field_in_parm_list));
1354 scst_set_sense(address, length, cmd->dev->d_sense,
1355 SCST_LOAD_SENSE(scst_sense_no_sense));
1358 scst_put_buf(cmd, address);
1366 * <<Following mode pages info copied from ST318451LW with some corrections>>
1370 static int vdisk_err_recov_pg(unsigned char *p, int pcontrol,
1371 struct scst_vdisk_dev *virt_dev)
1372 { /* Read-Write Error Recovery page for mode_sense */
1373 const unsigned char err_recov_pg[] = {0x1, 0xa, 0xc0, 11, 240, 0, 0, 0,
1376 memcpy(p, err_recov_pg, sizeof(err_recov_pg));
1378 memset(p + 2, 0, sizeof(err_recov_pg) - 2);
1379 return sizeof(err_recov_pg);
1382 static int vdisk_disconnect_pg(unsigned char *p, int pcontrol,
1383 struct scst_vdisk_dev *virt_dev)
1384 { /* Disconnect-Reconnect page for mode_sense */
1385 const unsigned char disconnect_pg[] = {0x2, 0xe, 128, 128, 0, 10, 0, 0,
1386 0, 0, 0, 0, 0, 0, 0, 0};
1388 memcpy(p, disconnect_pg, sizeof(disconnect_pg));
1390 memset(p + 2, 0, sizeof(disconnect_pg) - 2);
1391 return sizeof(disconnect_pg);
1394 static int vdisk_rigid_geo_pg(unsigned char *p, int pcontrol,
1395 struct scst_vdisk_dev *virt_dev)
1397 unsigned char geo_m_pg[] = {0x04, 0x16, 0, 0, 0, DEF_HEADS, 0, 0,
1398 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1399 0x3a, 0x98/* 15K RPM */, 0, 0};
1400 int32_t ncyl, n, rem;
1403 memcpy(p, geo_m_pg, sizeof(geo_m_pg));
1405 * Divide virt_dev->nblocks by (DEF_HEADS * DEF_SECTORS) and store
1406 * the quotient in ncyl and the remainder in rem.
1408 dividend = virt_dev->nblocks;
1409 rem = do_div(dividend, DEF_HEADS * DEF_SECTORS);
1413 memcpy(&n, p + 2, sizeof(u32));
1414 n = n | (cpu_to_be32(ncyl) >> 8);
1415 memcpy(p + 2, &n, sizeof(u32));
1417 memset(p + 2, 0, sizeof(geo_m_pg) - 2);
1418 return sizeof(geo_m_pg);
1421 static int vdisk_format_pg(unsigned char *p, int pcontrol,
1422 struct scst_vdisk_dev *virt_dev)
1423 { /* Format device page for mode_sense */
1424 const unsigned char format_pg[] = {0x3, 0x16, 0, 0, 0, 0, 0, 0,
1425 0, 0, 0, 0, 0, 0, 0, 0,
1426 0, 0, 0, 0, 0x40, 0, 0, 0};
1428 memcpy(p, format_pg, sizeof(format_pg));
1429 p[10] = (DEF_SECTORS >> 8) & 0xff;
1430 p[11] = DEF_SECTORS & 0xff;
1431 p[12] = (virt_dev->block_size >> 8) & 0xff;
1432 p[13] = virt_dev->block_size & 0xff;
1434 memset(p + 2, 0, sizeof(format_pg) - 2);
1435 return sizeof(format_pg);
1438 static int vdisk_caching_pg(unsigned char *p, int pcontrol,
1439 struct scst_vdisk_dev *virt_dev)
1440 { /* Caching page for mode_sense */
1441 const unsigned char caching_pg[] = {0x8, 18, 0x10, 0, 0xff, 0xff, 0, 0,
1442 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0, 0, 0, 0, 0};
1444 memcpy(p, caching_pg, sizeof(caching_pg));
1445 p[2] |= !(virt_dev->wt_flag || virt_dev->nv_cache) ? WCE : 0;
1447 memset(p + 2, 0, sizeof(caching_pg) - 2);
1448 return sizeof(caching_pg);
1451 static int vdisk_ctrl_m_pg(unsigned char *p, int pcontrol,
1452 struct scst_vdisk_dev *virt_dev)
1453 { /* Control mode page for mode_sense */
1454 const unsigned char ctrl_m_pg[] = {0xa, 0xa, 0, 0, 0, 0, 0, 0,
1457 memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg));
1460 p[2] |= virt_dev->dev->tst << 5;
1461 p[2] |= virt_dev->dev->d_sense << 2;
1462 p[3] |= virt_dev->dev->queue_alg << 4;
1463 p[4] |= virt_dev->dev->swp << 3;
1464 p[5] |= virt_dev->dev->tas << 6;
1467 memset(p + 2, 0, sizeof(ctrl_m_pg) - 2);
1469 * It's too early to implement it, since we can't control the
1470 * backstorage device parameters. ToDo
1472 p[2] |= 7 << 5; /* TST */
1473 p[3] |= 0xF << 4; /* QUEUE ALGORITHM MODIFIER */
1475 p[2] |= 1 << 2; /* D_SENSE */
1476 p[4] |= 1 << 3; /* SWP */
1477 p[5] |= 1 << 6; /* TAS */
1480 p[2] |= DEF_TST << 5;
1481 p[2] |= DEF_DSENSE << 2;
1482 if (virt_dev->wt_flag || virt_dev->nv_cache)
1483 p[3] |= DEF_QUEUE_ALG_WT << 4;
1485 p[3] |= DEF_QUEUE_ALG << 4;
1486 p[4] |= DEF_SWP << 3;
1487 p[5] |= DEF_TAS << 6;
1492 return sizeof(ctrl_m_pg);
1495 static int vdisk_iec_m_pg(unsigned char *p, int pcontrol,
1496 struct scst_vdisk_dev *virt_dev)
1497 { /* Informational Exceptions control mode page for mode_sense */
1498 const unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0,
1500 memcpy(p, iec_m_pg, sizeof(iec_m_pg));
1502 memset(p + 2, 0, sizeof(iec_m_pg) - 2);
1503 return sizeof(iec_m_pg);
1506 static void vdisk_exec_mode_sense(struct scst_cmd *cmd)
1511 struct scst_vdisk_dev *virt_dev;
1514 unsigned char dbd, type;
1515 int pcontrol, pcode, subpcode;
1516 unsigned char dev_spec;
1517 int msense_6, offset = 0, len;
1522 buf = kzalloc(MSENSE_BUF_SZ,
1523 scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL);
1529 virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1530 blocksize = virt_dev->block_size;
1531 nblocks = virt_dev->nblocks;
1533 type = cmd->dev->type; /* type dev */
1534 dbd = cmd->cdb[1] & DBD;
1535 pcontrol = (cmd->cdb[2] & 0xc0) >> 6;
1536 pcode = cmd->cdb[2] & 0x3f;
1537 subpcode = cmd->cdb[3];
1538 msense_6 = (MODE_SENSE == cmd->cdb[0]);
1539 dev_spec = (virt_dev->dev->rd_only ? WP : 0) | DPOFUA;
1541 length = scst_get_buf_first(cmd, &address);
1542 if (unlikely(length <= 0)) {
1544 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1545 scst_set_cmd_error(cmd,
1546 SCST_LOAD_SENSE(scst_sense_hardw_error));
1551 if (0x3 == pcontrol) {
1552 TRACE_DBG("%s", "MODE SENSE: Saving values not supported");
1553 scst_set_cmd_error(cmd,
1554 SCST_LOAD_SENSE(scst_sense_saving_params_unsup));
1568 if (0 != subpcode) {
1569 /* TODO: Control Extension page */
1570 TRACE_DBG("%s", "MODE SENSE: Only subpage 0 is supported");
1571 scst_set_cmd_error(cmd,
1572 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1577 /* Create block descriptor */
1578 buf[offset - 1] = 0x08; /* block descriptor length */
1579 if (nblocks >> 32) {
1580 buf[offset + 0] = 0xFF;
1581 buf[offset + 1] = 0xFF;
1582 buf[offset + 2] = 0xFF;
1583 buf[offset + 3] = 0xFF;
1586 buf[offset + 0] = (nblocks >> (BYTE * 3)) & 0xFF;
1587 buf[offset + 1] = (nblocks >> (BYTE * 2)) & 0xFF;
1588 buf[offset + 2] = (nblocks >> (BYTE * 1)) & 0xFF;
1589 buf[offset + 3] = (nblocks >> (BYTE * 0)) & 0xFF;
1591 buf[offset + 4] = 0; /* density code */
1592 buf[offset + 5] = (blocksize >> (BYTE * 2)) & 0xFF;/* blklen */
1593 buf[offset + 6] = (blocksize >> (BYTE * 1)) & 0xFF;
1594 buf[offset + 7] = (blocksize >> (BYTE * 0)) & 0xFF;
1596 offset += 8; /* increment offset */
1602 case 0x1: /* Read-Write error recovery page, direct access */
1603 len = vdisk_err_recov_pg(bp, pcontrol, virt_dev);
1605 case 0x2: /* Disconnect-Reconnect page, all devices */
1606 len = vdisk_disconnect_pg(bp, pcontrol, virt_dev);
1608 case 0x3: /* Format device page, direct access */
1609 len = vdisk_format_pg(bp, pcontrol, virt_dev);
1611 case 0x4: /* Rigid disk geometry */
1612 len = vdisk_rigid_geo_pg(bp, pcontrol, virt_dev);
1614 case 0x8: /* Caching page, direct access */
1615 len = vdisk_caching_pg(bp, pcontrol, virt_dev);
1617 case 0xa: /* Control Mode page, all devices */
1618 len = vdisk_ctrl_m_pg(bp, pcontrol, virt_dev);
1620 case 0x1c: /* Informational Exceptions Mode page, all devices */
1621 len = vdisk_iec_m_pg(bp, pcontrol, virt_dev);
1623 case 0x3f: /* Read all Mode pages */
1624 len = vdisk_err_recov_pg(bp, pcontrol, virt_dev);
1625 len += vdisk_disconnect_pg(bp + len, pcontrol, virt_dev);
1626 len += vdisk_format_pg(bp + len, pcontrol, virt_dev);
1627 len += vdisk_caching_pg(bp + len, pcontrol, virt_dev);
1628 len += vdisk_ctrl_m_pg(bp + len, pcontrol, virt_dev);
1629 len += vdisk_iec_m_pg(bp + len, pcontrol, virt_dev);
1630 len += vdisk_rigid_geo_pg(bp + len, pcontrol, virt_dev);
1633 TRACE_DBG("MODE SENSE: Unsupported page %x", pcode);
1634 scst_set_cmd_error(cmd,
1635 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1642 buf[0] = offset - 1;
1644 buf[0] = ((offset - 2) >> 8) & 0xff;
1645 buf[1] = (offset - 2) & 0xff;
1648 if (offset > length)
1650 memcpy(address, buf, offset);
1653 scst_put_buf(cmd, address);
1654 if (offset < cmd->resp_data_len)
1655 scst_set_resp_data_len(cmd, offset);
1665 static int vdisk_set_wt(struct scst_vdisk_dev *virt_dev, int wt)
1671 if ((virt_dev->wt_flag == wt) || virt_dev->nullio || virt_dev->nv_cache)
1674 spin_lock(&virt_dev->flags_lock);
1675 virt_dev->wt_flag = wt;
1676 spin_unlock(&virt_dev->flags_lock);
1678 scst_dev_del_all_thr_data(virt_dev->dev);
1681 TRACE_EXIT_RES(res);
1685 static void vdisk_ctrl_m_pg_select(unsigned char *p,
1686 struct scst_vdisk_dev *virt_dev)
1688 struct scst_device *dev = virt_dev->dev;
1689 int old_swp = dev->swp, old_tas = dev->tas, old_dsense = dev->d_sense;
1692 /* Not implemented yet, see comment in vdisk_ctrl_m_pg() */
1693 dev->tst = p[2] >> 5;
1694 dev->queue_alg = p[3] >> 4;
1696 dev->swp = (p[4] & 0x8) >> 3;
1697 dev->tas = (p[5] & 0x40) >> 6;
1698 dev->d_sense = (p[2] & 0x4) >> 2;
1700 PRINT_INFO("Device %s: new control mode page parameters: SWP %x "
1701 "(was %x), TAS %x (was %x), D_SENSE %d (was %d)",
1702 virt_dev->name, dev->swp, old_swp, dev->tas, old_tas,
1703 dev->d_sense, old_dsense);
1707 static void vdisk_exec_mode_select(struct scst_cmd *cmd)
1711 struct scst_vdisk_dev *virt_dev;
1712 int mselect_6, offset;
1716 virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1717 mselect_6 = (MODE_SELECT == cmd->cdb[0]);
1719 length = scst_get_buf_first(cmd, &address);
1720 if (unlikely(length <= 0)) {
1722 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1723 scst_set_cmd_error(cmd,
1724 SCST_LOAD_SENSE(scst_sense_hardw_error));
1729 if (!(cmd->cdb[1] & PF) || (cmd->cdb[1] & SP)) {
1730 TRACE(TRACE_MINOR|TRACE_SCSI, "MODE SELECT: Unsupported "
1731 "value(s) of PF and/or SP bits (cdb[1]=%x)",
1733 scst_set_cmd_error(cmd,
1734 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1743 if (address[offset - 1] == 8) {
1745 } else if (address[offset - 1] != 0) {
1746 PRINT_ERROR("%s", "MODE SELECT: Wrong parameters list "
1748 scst_set_cmd_error(cmd,
1749 SCST_LOAD_SENSE(scst_sense_invalid_field_in_parm_list));
1753 while (length > offset + 2) {
1754 if (address[offset] & PS) {
1755 PRINT_ERROR("%s", "MODE SELECT: Illegal PS bit");
1756 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1757 scst_sense_invalid_field_in_parm_list));
1760 if ((address[offset] & 0x3f) == 0x8) {
1762 if (address[offset + 1] != 18) {
1763 PRINT_ERROR("%s", "MODE SELECT: Invalid "
1764 "caching page request");
1765 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1766 scst_sense_invalid_field_in_parm_list));
1769 if (vdisk_set_wt(virt_dev,
1770 (address[offset + 2] & WCE) ? 0 : 1) != 0) {
1771 scst_set_cmd_error(cmd,
1772 SCST_LOAD_SENSE(scst_sense_hardw_error));
1776 } else if ((address[offset] & 0x3f) == 0xA) {
1778 if (address[offset + 1] != 0xA) {
1779 PRINT_ERROR("%s", "MODE SELECT: Invalid "
1780 "control page request");
1781 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1782 scst_sense_invalid_field_in_parm_list));
1785 vdisk_ctrl_m_pg_select(&address[offset], virt_dev);
1787 PRINT_ERROR("MODE SELECT: Invalid request %x",
1788 address[offset] & 0x3f);
1789 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1790 scst_sense_invalid_field_in_parm_list));
1793 offset += address[offset + 1];
1797 scst_put_buf(cmd, address);
1804 static void vdisk_exec_log(struct scst_cmd *cmd)
1808 /* No log pages are supported */
1809 scst_set_cmd_error(cmd,
1810 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1816 static void vdisk_exec_read_capacity(struct scst_cmd *cmd)
1820 struct scst_vdisk_dev *virt_dev;
1823 uint8_t buffer[READ_CAP_LEN];
1827 virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1828 blocksize = virt_dev->block_size;
1829 nblocks = virt_dev->nblocks;
1831 /* last block on the virt_dev is (nblocks-1) */
1832 memset(buffer, 0, sizeof(buffer));
1833 if (nblocks >> 32) {
1839 buffer[0] = ((nblocks - 1) >> (BYTE * 3)) & 0xFF;
1840 buffer[1] = ((nblocks - 1) >> (BYTE * 2)) & 0xFF;
1841 buffer[2] = ((nblocks - 1) >> (BYTE * 1)) & 0xFF;
1842 buffer[3] = ((nblocks - 1) >> (BYTE * 0)) & 0xFF;
1844 buffer[4] = (blocksize >> (BYTE * 3)) & 0xFF;
1845 buffer[5] = (blocksize >> (BYTE * 2)) & 0xFF;
1846 buffer[6] = (blocksize >> (BYTE * 1)) & 0xFF;
1847 buffer[7] = (blocksize >> (BYTE * 0)) & 0xFF;
1849 length = scst_get_buf_first(cmd, &address);
1850 if (unlikely(length <= 0)) {
1852 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1853 scst_set_cmd_error(cmd,
1854 SCST_LOAD_SENSE(scst_sense_hardw_error));
1859 if (length > READ_CAP_LEN)
1860 length = READ_CAP_LEN;
1861 memcpy(address, buffer, length);
1863 scst_put_buf(cmd, address);
1865 if (length < cmd->resp_data_len)
1866 scst_set_resp_data_len(cmd, length);
1873 static void vdisk_exec_read_capacity16(struct scst_cmd *cmd)
1877 struct scst_vdisk_dev *virt_dev;
1880 uint8_t buffer[READ_CAP16_LEN];
1884 virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1885 blocksize = virt_dev->block_size;
1886 nblocks = virt_dev->nblocks - 1;
1888 memset(buffer, 0, sizeof(buffer));
1890 buffer[0] = nblocks >> 56;
1891 buffer[1] = (nblocks >> 48) & 0xFF;
1892 buffer[2] = (nblocks >> 40) & 0xFF;
1893 buffer[3] = (nblocks >> 32) & 0xFF;
1894 buffer[4] = (nblocks >> 24) & 0xFF;
1895 buffer[5] = (nblocks >> 16) & 0xFF;
1896 buffer[6] = (nblocks >> 8) & 0xFF;
1897 buffer[7] = nblocks & 0xFF;
1899 buffer[8] = (blocksize >> (BYTE * 3)) & 0xFF;
1900 buffer[9] = (blocksize >> (BYTE * 2)) & 0xFF;
1901 buffer[10] = (blocksize >> (BYTE * 1)) & 0xFF;
1902 buffer[11] = (blocksize >> (BYTE * 0)) & 0xFF;
1904 switch (blocksize) {
1915 PRINT_ERROR("%s: Unexpected block size %d",
1916 cmd->op_name, blocksize);
1923 length = scst_get_buf_first(cmd, &address);
1924 if (unlikely(length <= 0)) {
1926 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1927 scst_set_cmd_error(cmd,
1928 SCST_LOAD_SENSE(scst_sense_hardw_error));
1933 if (length > READ_CAP16_LEN)
1934 length = READ_CAP16_LEN;
1935 memcpy(address, buffer, length);
1937 scst_put_buf(cmd, address);
1939 if (length < cmd->resp_data_len)
1940 scst_set_resp_data_len(cmd, length);
1947 static void vdisk_exec_read_toc(struct scst_cmd *cmd)
1949 int32_t length, off = 0;
1951 struct scst_vdisk_dev *virt_dev;
1953 uint8_t buffer[4+8+8] = { 0x00, 0x0a, 0x01, 0x01, 0x00, 0x14,
1954 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
1958 if (cmd->dev->type != TYPE_ROM) {
1959 PRINT_ERROR("%s", "READ TOC for non-CDROM device");
1960 scst_set_cmd_error(cmd,
1961 SCST_LOAD_SENSE(scst_sense_invalid_opcode));
1965 if (cmd->cdb[2] & 0x0e/*Format*/) {
1966 PRINT_ERROR("%s", "READ TOC: invalid requested data format");
1967 scst_set_cmd_error(cmd,
1968 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1972 if ((cmd->cdb[6] != 0 && (cmd->cdb[2] & 0x01)) ||
1973 (cmd->cdb[6] > 1 && cmd->cdb[6] != 0xAA)) {
1974 PRINT_ERROR("READ TOC: invalid requested track number %x",
1976 scst_set_cmd_error(cmd,
1977 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1981 length = scst_get_buf_first(cmd, &address);
1982 if (unlikely(length <= 0)) {
1984 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1985 scst_set_cmd_error(cmd,
1986 SCST_LOAD_SENSE(scst_sense_hardw_error));
1991 virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1992 /* ToDo when you have > 8TB ROM device. */
1993 nblocks = (uint32_t)virt_dev->nblocks;
1996 memset(buffer, 0, sizeof(buffer));
1997 buffer[2] = 0x01; /* First Track/Session */
1998 buffer[3] = 0x01; /* Last Track/Session */
2000 if (cmd->cdb[6] <= 1) {
2001 /* Fistr TOC Track Descriptor */
2002 /* ADDR 0x10 - Q Sub-channel encodes current position data
2003 CONTROL 0x04 - Data track, recoreded uninterrupted */
2004 buffer[off+1] = 0x14;
2006 buffer[off+2] = 0x01;
2009 if (!(cmd->cdb[2] & 0x01)) {
2010 /* Lead-out area TOC Track Descriptor */
2011 buffer[off+1] = 0x14;
2013 buffer[off+2] = 0xAA;
2014 /* Track Start Address */
2015 buffer[off+4] = (nblocks >> (BYTE * 3)) & 0xFF;
2016 buffer[off+5] = (nblocks >> (BYTE * 2)) & 0xFF;
2017 buffer[off+6] = (nblocks >> (BYTE * 1)) & 0xFF;
2018 buffer[off+7] = (nblocks >> (BYTE * 0)) & 0xFF;
2022 buffer[1] = off - 2; /* Data Length */
2026 memcpy(address, buffer, off);
2028 scst_put_buf(cmd, address);
2030 if (off < cmd->resp_data_len)
2031 scst_set_resp_data_len(cmd, off);
2038 static void vdisk_exec_prevent_allow_medium_removal(struct scst_cmd *cmd)
2040 struct scst_vdisk_dev *virt_dev =
2041 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2043 TRACE_DBG("PERSIST/PREVENT 0x%02x", cmd->cdb[4]);
2045 if (cmd->dev->type == TYPE_ROM) {
2046 spin_lock(&virt_dev->flags_lock);
2047 virt_dev->prevent_allow_medium_removal =
2048 cmd->cdb[4] & 0x01 ? 1 : 0;
2049 spin_unlock(&virt_dev->flags_lock);
2055 static int vdisk_fsync(struct scst_vdisk_thr *thr,
2056 loff_t loff, loff_t len, struct scst_cmd *cmd)
2059 struct scst_vdisk_dev *virt_dev =
2060 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2061 struct file *file = thr->fd;
2062 struct inode *inode;
2063 struct address_space *mapping;
2067 /* Hopefully, the compiler will generate the single comparison */
2068 if (virt_dev->nv_cache || virt_dev->blockio || virt_dev->wt_flag ||
2069 virt_dev->o_direct_flag || virt_dev->nullio)
2072 inode = file->f_dentry->d_inode;
2073 mapping = file->f_mapping;
2075 res = sync_page_range(inode, mapping, loff, len);
2076 if (unlikely(res != 0)) {
2077 PRINT_ERROR("sync_page_range() failed (%d)", res);
2079 scst_set_cmd_error(cmd,
2080 SCST_LOAD_SENSE(scst_sense_write_error));
2084 /* ToDo: flush the device cache, if needed */
2087 TRACE_EXIT_RES(res);
2091 static struct iovec *vdisk_alloc_iv(struct scst_cmd *cmd,
2092 struct scst_vdisk_thr *thr)
2096 iv_count = scst_get_buf_count(cmd);
2097 if (iv_count > thr->iv_count) {
2099 /* It can't be called in atomic context */
2100 thr->iv = kmalloc(sizeof(*thr->iv) * iv_count, GFP_KERNEL);
2101 if (thr->iv == NULL) {
2102 PRINT_ERROR("Unable to allocate iv (%d)", iv_count);
2106 thr->iv_count = iv_count;
2114 * copied from <ksrc>/fs/read_write.*
2116 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
2117 static void wait_on_retry_sync_kiocb(struct kiocb *iocb)
2119 set_current_state(TASK_UNINTERRUPTIBLE);
2120 if (!kiocbIsKicked(iocb))
2123 kiocbClearKicked(iocb);
2124 __set_current_state(TASK_RUNNING);
2127 typedef ssize_t (*iov_fn_t)(struct kiocb *, const struct iovec *,
2128 unsigned long, loff_t);
2130 static ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
2131 unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn)
2136 init_sync_kiocb(&kiocb, filp);
2137 kiocb.ki_pos = *ppos;
2138 kiocb.ki_left = len;
2139 kiocb.ki_nbytes = len;
2142 ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos);
2143 if (ret != -EIOCBRETRY)
2145 wait_on_retry_sync_kiocb(&kiocb);
2148 if (ret == -EIOCBQUEUED)
2149 ret = wait_on_sync_kiocb(&kiocb);
2150 *ppos = kiocb.ki_pos;
2155 static void vdisk_exec_read(struct scst_cmd *cmd,
2156 struct scst_vdisk_thr *thr, loff_t loff)
2158 mm_segment_t old_fs;
2160 ssize_t length, full_len;
2161 uint8_t __user *address;
2162 struct scst_vdisk_dev *virt_dev =
2163 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2164 struct file *fd = thr->fd;
2170 if (virt_dev->nullio)
2173 iv = vdisk_alloc_iv(cmd, thr);
2180 length = scst_get_buf_first(cmd, (uint8_t __force **)&address);
2181 while (length > 0) {
2185 iv[i].iov_base = address;
2186 iv[i].iov_len = length;
2187 length = scst_get_buf_next(cmd, (uint8_t __force **)&address);
2189 if (unlikely(length < 0)) {
2190 PRINT_ERROR("scst_get_buf_() failed: %zd", length);
2191 scst_set_cmd_error(cmd,
2192 SCST_LOAD_SENSE(scst_sense_hardw_error));
2199 TRACE_DBG("reading(iv_count %d, full_len %zd)", iv_count, full_len);
2201 if (fd->f_op->llseek)
2202 err = fd->f_op->llseek(fd, loff, 0/*SEEK_SET*/);
2204 err = default_llseek(fd, loff, 0/*SEEK_SET*/);
2206 PRINT_ERROR("lseek trouble %lld != %lld",
2207 (long long unsigned int)err,
2208 (long long unsigned int)loff);
2209 scst_set_cmd_error(cmd,
2210 SCST_LOAD_SENSE(scst_sense_hardw_error));
2215 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
2216 err = fd->f_op->readv(fd, iv, iv_count, &fd->f_pos);
2218 err = do_sync_readv_writev(fd, iv, iv_count, full_len,
2219 &fd->f_pos, fd->f_op->aio_read);
2222 if ((err < 0) || (err < full_len)) {
2223 PRINT_ERROR("readv() returned %lld from %zd",
2224 (long long unsigned int)err,
2229 scst_set_cmd_error(cmd,
2230 SCST_LOAD_SENSE(scst_sense_read_error));
2240 scst_put_buf(cmd, (void __force *)(iv[i].iov_base));
2247 static void vdisk_exec_write(struct scst_cmd *cmd,
2248 struct scst_vdisk_thr *thr, loff_t loff)
2250 mm_segment_t old_fs;
2252 ssize_t length, full_len;
2253 uint8_t __user *address;
2254 struct scst_vdisk_dev *virt_dev =
2255 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2256 struct file *fd = thr->fd;
2257 struct iovec *iv, *eiv;
2258 int iv_count, eiv_count;
2262 if (virt_dev->nullio)
2265 iv = vdisk_alloc_iv(cmd, thr);
2271 length = scst_get_buf_first(cmd, (uint8_t __force **)&address);
2272 while (length > 0) {
2274 iv[iv_count].iov_base = address;
2275 iv[iv_count].iov_len = length;
2277 length = scst_get_buf_next(cmd, (uint8_t __force **)&address);
2279 if (unlikely(length < 0)) {
2280 PRINT_ERROR("scst_get_buf_() failed: %zd", length);
2281 scst_set_cmd_error(cmd,
2282 SCST_LOAD_SENSE(scst_sense_hardw_error));
2290 eiv_count = iv_count;
2292 TRACE_DBG("writing(eiv_count %d, full_len %zd)", eiv_count, full_len);
2295 if (fd->f_op->llseek)
2296 err = fd->f_op->llseek(fd, loff, 0 /*SEEK_SET */);
2298 err = default_llseek(fd, loff, 0 /*SEEK_SET */);
2300 PRINT_ERROR("lseek trouble %lld != %lld",
2301 (long long unsigned int)err,
2302 (long long unsigned int)loff);
2303 scst_set_cmd_error(cmd,
2304 SCST_LOAD_SENSE(scst_sense_hardw_error));
2309 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
2310 err = fd->f_op->writev(fd, eiv, eiv_count, &fd->f_pos);
2312 err = do_sync_readv_writev(fd, iv, iv_count, full_len, &fd->f_pos,
2313 fd->f_op->aio_write);
2317 PRINT_ERROR("write() returned %lld from %zd",
2318 (long long unsigned int)err,
2323 scst_set_cmd_error(cmd,
2324 SCST_LOAD_SENSE(scst_sense_write_error));
2327 } else if (err < full_len) {
2329 * Probably that's wrong, but sometimes write() returns
2330 * value less, than requested. Let's restart.
2332 int i, e = eiv_count;
2333 TRACE_MGMT_DBG("write() returned %d from %zd "
2334 "(iv_count=%d)", (int)err, full_len,
2337 PRINT_INFO("Suspicious: write() returned 0 from "
2338 "%zd (iv_count=%d)", full_len, eiv_count);
2341 for (i = 0; i < e; i++) {
2342 if ((long long)eiv->iov_len < err) {
2343 err -= eiv->iov_len;
2348 (uint8_t __force __user *)eiv->iov_base +
2350 eiv->iov_len -= err;
2361 while (iv_count > 0) {
2362 scst_put_buf(cmd, (void __force *)(iv[iv_count-1].iov_base));
2371 struct scst_blockio_work {
2372 atomic_t bios_inflight;
2373 struct scst_cmd *cmd;
2376 static inline void blockio_check_finish(struct scst_blockio_work *blockio_work)
2378 /* Decrement the bios in processing, and if zero signal completion */
2379 if (atomic_dec_and_test(&blockio_work->bios_inflight)) {
2380 blockio_work->cmd->completed = 1;
2381 blockio_work->cmd->scst_cmd_done(blockio_work->cmd,
2382 SCST_CMD_STATE_DEFAULT, scst_estimate_context());
2383 kmem_cache_free(blockio_work_cachep, blockio_work);
2388 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
2389 static int blockio_endio(struct bio *bio, unsigned int bytes_done, int error)
2391 static void blockio_endio(struct bio *bio, int error)
2394 struct scst_blockio_work *blockio_work = bio->bi_private;
2396 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
2401 error = test_bit(BIO_UPTODATE, &bio->bi_flags) ? error : -EIO;
2403 if (unlikely(error != 0)) {
2404 PRINT_ERROR("cmd %p returned error %d", blockio_work->cmd,
2407 * The race with other such bio's doesn't matter, since all
2408 * scst_set_cmd_error() calls do the same local to this cmd
2411 if (bio->bi_rw & WRITE)
2412 scst_set_cmd_error(blockio_work->cmd,
2413 SCST_LOAD_SENSE(scst_sense_write_error));
2415 scst_set_cmd_error(blockio_work->cmd,
2416 SCST_LOAD_SENSE(scst_sense_read_error));
2419 blockio_check_finish(blockio_work);
2422 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
2429 static void blockio_exec_rw(struct scst_cmd *cmd, struct scst_vdisk_thr *thr,
2430 u64 lba_start, int write)
2432 struct scst_vdisk_dev *virt_dev =
2433 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2434 struct block_device *bdev = thr->bdev;
2435 struct request_queue *q = bdev_get_queue(bdev);
2436 int length, max_nr_vecs = 0;
2438 struct bio *bio = NULL, *hbio = NULL, *tbio = NULL;
2440 struct scst_blockio_work *blockio_work;
2445 if (virt_dev->nullio)
2448 /* Allocate and initialize blockio_work struct */
2449 blockio_work = kmem_cache_alloc(blockio_work_cachep, GFP_KERNEL);
2450 if (blockio_work == NULL)
2453 blockio_work->cmd = cmd;
2456 max_nr_vecs = min(bio_get_nr_vecs(bdev), BIO_MAX_PAGES);
2462 length = scst_get_buf_first(cmd, &address);
2463 while (length > 0) {
2464 int len, bytes, off, thislen;
2469 off = offset_in_page(addr);
2472 lba_start0 = lba_start;
2476 struct page *page = virt_to_page(addr);
2479 bio = bio_alloc(GFP_KERNEL, max_nr_vecs);
2481 PRINT_ERROR("Failed to create bio "
2482 "for data segment= %d cmd %p",
2483 cmd->get_sg_buf_entry_num, cmd);
2489 bio->bi_end_io = blockio_endio;
2490 bio->bi_sector = lba_start0 <<
2491 (virt_dev->block_shift - 9);
2492 bio->bi_bdev = bdev;
2493 bio->bi_private = blockio_work;
2494 #if 0 /* It could be win, but could be not, so a performance study is needed */
2495 bio->bi_rw |= 1 << BIO_RW_SYNC;
2500 tbio = tbio->bi_next = bio;
2503 bytes = min_t(unsigned int, len, PAGE_SIZE - off);
2505 rc = bio_add_page(bio, page, bytes, off);
2509 lba_start0 += thislen >> virt_dev->block_shift;
2520 lba_start += length >> virt_dev->block_shift;
2522 scst_put_buf(cmd, address);
2523 length = scst_get_buf_next(cmd, &address);
2526 /* +1 to prevent erroneous too early command completion */
2527 atomic_set(&blockio_work->bios_inflight, bios+1);
2531 hbio = hbio->bi_next;
2532 bio->bi_next = NULL;
2533 submit_bio(write, bio);
2536 if (q && q->unplug_fn)
2539 blockio_check_finish(blockio_work);
2548 hbio = hbio->bi_next;
2551 kmem_cache_free(blockio_work_cachep, blockio_work);
2558 static void vdisk_exec_verify(struct scst_cmd *cmd,
2559 struct scst_vdisk_thr *thr, loff_t loff)
2561 mm_segment_t old_fs;
2563 ssize_t length, len_mem = 0;
2564 uint8_t *address_sav, *address;
2566 struct scst_vdisk_dev *virt_dev =
2567 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2568 struct file *fd = thr->fd;
2569 uint8_t *mem_verify = NULL;
2573 if (vdisk_fsync(thr, loff, cmd->bufflen, cmd) != 0)
2577 * Until the cache is cleared prior the verifying, there is not
2578 * much point in this code. ToDo.
2580 * Nevertherless, this code is valuable if the data have not read
2581 * from the file/disk yet.
2588 if (!virt_dev->nullio) {
2589 if (fd->f_op->llseek)
2590 err = fd->f_op->llseek(fd, loff, 0/*SEEK_SET*/);
2592 err = default_llseek(fd, loff, 0/*SEEK_SET*/);
2594 PRINT_ERROR("lseek trouble %lld != %lld",
2595 (long long unsigned int)err,
2596 (long long unsigned int)loff);
2597 scst_set_cmd_error(cmd,
2598 SCST_LOAD_SENSE(scst_sense_hardw_error));
2603 mem_verify = vmalloc(LEN_MEM);
2604 if (mem_verify == NULL) {
2605 PRINT_ERROR("Unable to allocate memory %d for verify",
2607 scst_set_cmd_error(cmd,
2608 SCST_LOAD_SENSE(scst_sense_hardw_error));
2612 length = scst_get_buf_first(cmd, &address);
2613 address_sav = address;
2614 if (!length && cmd->data_len) {
2615 length = cmd->data_len;
2620 while (length > 0) {
2621 len_mem = (length > LEN_MEM) ? LEN_MEM : length;
2622 TRACE_DBG("Verify: length %zd - len_mem %zd", length, len_mem);
2624 if (!virt_dev->nullio)
2625 err = fd->f_op->read(fd,
2626 (char __force __user *)mem_verify, len_mem,
2630 if ((err < 0) || (err < len_mem)) {
2631 PRINT_ERROR("verify() returned %lld from %zd",
2632 (long long unsigned int)err, len_mem);
2636 scst_set_cmd_error(cmd,
2637 SCST_LOAD_SENSE(scst_sense_read_error));
2640 scst_put_buf(cmd, address_sav);
2643 if (compare && memcmp(address, mem_verify, len_mem) != 0) {
2644 TRACE_DBG("Verify: error memcmp length %zd", length);
2645 scst_set_cmd_error(cmd,
2646 SCST_LOAD_SENSE(scst_sense_miscompare_error));
2647 scst_put_buf(cmd, address_sav);
2652 if (compare && length <= 0) {
2653 scst_put_buf(cmd, address_sav);
2654 length = scst_get_buf_next(cmd, &address);
2655 address_sav = address;
2660 PRINT_ERROR("scst_get_buf_() failed: %zd", length);
2661 scst_set_cmd_error(cmd,
2662 SCST_LOAD_SENSE(scst_sense_hardw_error));
2675 static inline struct scst_vdisk_dev *vdisk_alloc_dev(void)
2677 struct scst_vdisk_dev *dev;
2678 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
2680 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of virtual "
2684 spin_lock_init(&dev->flags_lock);
2689 static int vdisk_task_mgmt_fn(struct scst_mgmt_cmd *mcmd,
2690 struct scst_tgt_dev *tgt_dev)
2694 if ((mcmd->fn == SCST_LUN_RESET) || (mcmd->fn == SCST_TARGET_RESET)) {
2695 /* Restore default values */
2696 struct scst_device *dev = tgt_dev->dev;
2697 struct scst_vdisk_dev *virt_dev =
2698 (struct scst_vdisk_dev *)dev->dh_priv;
2701 dev->d_sense = DEF_DSENSE;
2702 if (virt_dev->wt_flag && !virt_dev->nv_cache)
2703 dev->queue_alg = DEF_QUEUE_ALG_WT;
2705 dev->queue_alg = DEF_QUEUE_ALG;
2709 virt_dev->prevent_allow_medium_removal = 0;
2713 return SCST_DEV_TM_NOT_COMPLETED;
2717 * Called when a file in the /proc/VDISK_NAME/VDISK_NAME is read
2719 static int vdisk_read_proc(struct seq_file *seq, struct scst_dev_type *dev_type)
2722 struct scst_vdisk_dev *virt_dev;
2726 if (mutex_lock_interruptible(&scst_vdisk_mutex) != 0) {
2731 seq_printf(seq, "%-17s %-11s %-11s %-15s %s\n",
2732 "Name", "Size(MB)", "Block size", "Options", "File name");
2734 list_for_each_entry(virt_dev, &vdisk_dev_list, vdisk_dev_list_entry) {
2736 seq_printf(seq, "%-17s %-11d %-12d", virt_dev->name,
2737 (uint32_t)(virt_dev->file_size >> 20),
2738 virt_dev->block_size);
2740 if (virt_dev->wt_flag) {
2741 seq_printf(seq, "WT ");
2744 if (virt_dev->nv_cache) {
2745 seq_printf(seq, "NV ");
2748 if (virt_dev->dev != NULL) {
2749 if (virt_dev->dev->rd_only) {
2750 seq_printf(seq, "RO ");
2753 } else if (virt_dev->rd_only) {
2754 seq_printf(seq, "RO ");
2757 if (virt_dev->o_direct_flag) {
2758 seq_printf(seq, "DR ");
2761 if (virt_dev->nullio) {
2762 seq_printf(seq, "NIO ");
2765 if (virt_dev->blockio) {
2766 seq_printf(seq, "BIO ");
2769 if (virt_dev->removable) {
2770 seq_printf(seq, "RM ");
2774 seq_printf(seq, " ");
2777 seq_printf(seq, "%s\n", virt_dev->file_name);
2779 mutex_unlock(&scst_vdisk_mutex);
2781 TRACE_EXIT_RES(res);
2785 static void vdisk_report_registering(const char *type,
2786 const struct scst_vdisk_dev *virt_dev)
2791 i = snprintf(buf, sizeof(buf), "Registering virtual %s device %s ",
2792 type, virt_dev->name);
2795 if (virt_dev->wt_flag)
2796 i += snprintf(&buf[i], sizeof(buf) - i, "(WRITE_THROUGH");
2798 if (virt_dev->nv_cache)
2799 i += snprintf(&buf[i], sizeof(buf) - i, "%sNV_CACHE",
2800 (j == i) ? "(" : ", ");
2802 if (virt_dev->rd_only)
2803 i += snprintf(&buf[i], sizeof(buf) - i, "%sREAD_ONLY",
2804 (j == i) ? "(" : ", ");
2806 if (virt_dev->o_direct_flag)
2807 i += snprintf(&buf[i], sizeof(buf) - i, "%sO_DIRECT",
2808 (j == i) ? "(" : ", ");
2810 if (virt_dev->nullio)
2811 i += snprintf(&buf[i], sizeof(buf) - i, "%sNULLIO",
2812 (j == i) ? "(" : ", ");
2814 if (virt_dev->blockio)
2815 i += snprintf(&buf[i], sizeof(buf) - i, "%sBLOCKIO",
2816 (j == i) ? "(" : ", ");
2818 if (virt_dev->removable)
2819 i += snprintf(&buf[i], sizeof(buf) - i, "%sREMOVABLE",
2820 (j == i) ? "(" : ", ");
2823 PRINT_INFO("%s", buf);
2825 PRINT_INFO("%s)", buf);
2830 /* scst_vdisk_mutex supposed to be held */
2831 static int vdisk_resync_size(struct scst_vdisk_dev *virt_dev)
2836 if (!virt_dev->nullio) {
2837 res = vdisk_get_check_file_size(virt_dev->file_name,
2838 virt_dev->blockio, &err);
2842 err = VDISK_NULLIO_SIZE;
2844 res = scst_suspend_activity(true);
2848 virt_dev->file_size = err;
2849 virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift;
2851 scst_dev_del_all_thr_data(virt_dev->dev);
2853 PRINT_INFO("New size of SCSI target virtual disk %s "
2854 "(fs=%lldMB, bs=%d, nblocks=%lld, cyln=%lld%s)",
2855 virt_dev->name, virt_dev->file_size >> 20,
2856 virt_dev->block_size,
2857 (long long unsigned int)virt_dev->nblocks,
2858 (long long unsigned int)virt_dev->nblocks/64/32,
2859 virt_dev->nblocks < 64*32 ? " !WARNING! cyln less "
2862 scst_capacity_data_changed(virt_dev->dev);
2864 scst_resume_activity();
2871 * Called when a file in the /proc/VDISK_NAME/VDISK_NAME is written
2873 static int vdisk_write_proc(char *buffer, char **start, off_t offset,
2874 int length, int *eof, struct scst_dev_type *dev_type)
2876 int res = 0, action;
2877 char *p, *name, *file_name;
2878 struct scst_vdisk_dev *virt_dev, *vv;
2879 uint32_t block_size = DEF_DISK_BLOCKSIZE;
2880 int block_shift = DEF_DISK_BLOCKSIZE_SHIFT;
2885 /* VERY UGLY code. You can rewrite it if you want */
2887 if (buffer[0] == '\0')
2890 if (mutex_lock_interruptible(&scst_vdisk_mutex) != 0) {
2896 if (p[strlen(p) - 1] == '\n')
2897 p[strlen(p) - 1] = '\0';
2898 if (!strncmp("close ", p, 6)) {
2901 } else if (!strncmp("open ", p, 5)) {
2904 } else if (!strncmp("resync_size ", p, 12)) {
2908 PRINT_ERROR("Unknown action \"%s\"", p);
2913 while (isspace(*p) && *p != '\0')
2916 while (!isspace(*p) && *p != '\0')
2919 if (*name == '\0') {
2920 PRINT_ERROR("%s", "Name required");
2923 } else if (strlen(name) >= sizeof(virt_dev->name)) {
2924 PRINT_ERROR("Name is too long (max %zd "
2925 "characters)", sizeof(virt_dev->name)-1);
2933 list_for_each_entry(vv, &vdisk_dev_list,
2934 vdisk_dev_list_entry) {
2935 if (strcmp(vv->name, name) == 0) {
2941 PRINT_ERROR("Virtual device with name "
2942 "%s already exist", name);
2947 while (isspace(*p) && *p != '\0')
2950 while (!isspace(*p) && *p != '\0')
2953 if (*file_name == '\0') {
2954 PRINT_ERROR("%s", "File name required");
2959 virt_dev = vdisk_alloc_dev();
2960 if (virt_dev == NULL) {
2961 TRACE(TRACE_OUT_OF_MEM, "%s",
2962 "Allocation of virt_dev failed");
2967 while (isspace(*p) && *p != '\0')
2972 block_size = simple_strtoul(p, &pp, 0);
2974 if ((*p != '\0') && !isspace(*p)) {
2975 PRINT_ERROR("Parse error: \"%s\"", p);
2979 while (isspace(*p) && *p != '\0')
2982 block_shift = scst_calc_block_shift(block_size);
2983 if (block_shift < 9) {
2988 virt_dev->block_size = block_size;
2989 virt_dev->block_shift = block_shift;
2991 while (*p != '\0') {
2992 if (!strncmp("WRITE_THROUGH", p, 13)) {
2994 virt_dev->wt_flag = 1;
2995 TRACE_DBG("%s", "WRITE_THROUGH");
2996 } else if (!strncmp("NV_CACHE", p, 8)) {
2998 virt_dev->nv_cache = 1;
2999 TRACE_DBG("%s", "NON-VOLATILE CACHE");
3000 } else if (!strncmp("READ_ONLY", p, 9)) {
3002 virt_dev->rd_only = 1;
3003 TRACE_DBG("%s", "READ_ONLY");
3004 } else if (!strncmp("O_DIRECT", p, 8)) {
3008 virt_dev->o_direct_flag = 1;
3009 TRACE_DBG("%s", "O_DIRECT");
3011 PRINT_INFO("%s flag doesn't currently"
3012 " work, ignoring it, use fileio_tgt "
3013 "in O_DIRECT mode instead", "O_DIRECT");
3015 } else if (!strncmp("NULLIO", p, 6)) {
3017 virt_dev->nullio = 1;
3018 TRACE_DBG("%s", "NULLIO");
3019 } else if (!strncmp("BLOCKIO", p, 7)) {
3021 virt_dev->blockio = 1;
3022 TRACE_DBG("%s", "BLOCKIO");
3023 } else if (!strncmp("REMOVABLE", p, 9)) {
3025 virt_dev->removable = 1;
3026 TRACE_DBG("%s", "REMOVABLE");
3028 PRINT_ERROR("Unknown flag \"%s\"", p);
3032 while (isspace(*p) && *p != '\0')
3036 if (!virt_dev->nullio && (*file_name != '/')) {
3037 PRINT_ERROR("File path \"%s\" is not "
3038 "absolute", file_name);
3043 strcpy(virt_dev->name, name);
3045 scnprintf(virt_dev->usn, sizeof(virt_dev->usn), "%llx",
3046 vdisk_gen_dev_id_num(virt_dev));
3047 TRACE_DBG("usn %s", virt_dev->usn);
3049 len = strlen(file_name) + 1;
3050 virt_dev->file_name = kmalloc(len, GFP_KERNEL);
3051 if (virt_dev->file_name == NULL) {
3052 TRACE(TRACE_OUT_OF_MEM, "%s",
3053 "Allocation of file_name failed");
3057 strncpy(virt_dev->file_name, file_name, len);
3059 list_add_tail(&virt_dev->vdisk_dev_list_entry,
3062 if (virt_dev->blockio) {
3063 vdisk_report_registering("BLOCKIO", virt_dev);
3065 scst_register_virtual_device(&vdisk_blk_devtype,
3067 } else if (virt_dev->nullio) {
3068 vdisk_report_registering("NULLIO", virt_dev);
3070 scst_register_virtual_device(&vdisk_null_devtype,
3073 vdisk_report_registering("FILEIO", virt_dev);
3075 scst_register_virtual_device(&vdisk_file_devtype,
3078 if (virt_dev->virt_id < 0) {
3079 res = virt_dev->virt_id;
3080 goto out_free_vpath;
3082 TRACE_DBG("Added virt_dev (name %s, file name %s, "
3083 "id %d, block size %d) to "
3084 "vdisk_dev_list", virt_dev->name,
3085 virt_dev->file_name, virt_dev->virt_id,
3086 virt_dev->block_size);
3087 } else if (action == 0) { /* close */
3089 list_for_each_entry(vv, &vdisk_dev_list,
3090 vdisk_dev_list_entry) {
3091 if (strcmp(vv->name, name) == 0) {
3096 if (virt_dev == NULL) {
3097 PRINT_ERROR("Device %s not found", name);
3101 scst_unregister_virtual_device(virt_dev->virt_id);
3102 PRINT_INFO("Virtual device %s unregistered",
3104 TRACE_DBG("virt_id %d unregister", virt_dev->virt_id);
3106 list_del(&virt_dev->vdisk_dev_list_entry);
3108 kfree(virt_dev->file_name);
3110 } else { /* resync_size */
3112 list_for_each_entry(vv, &vdisk_dev_list,
3113 vdisk_dev_list_entry) {
3114 if (strcmp(vv->name, name) == 0) {
3119 if (virt_dev == NULL) {
3120 PRINT_ERROR("Device %s not found", name);
3125 res = vdisk_resync_size(virt_dev);
3132 mutex_unlock(&scst_vdisk_mutex);
3135 TRACE_EXIT_RES(res);
3139 list_del(&virt_dev->vdisk_dev_list_entry);
3140 kfree(virt_dev->file_name);
3147 /* scst_vdisk_mutex supposed to be held */
3148 static int vcdrom_open(char *p, char *name)
3150 struct scst_vdisk_dev *virt_dev, *vv;
3157 list_for_each_entry(vv, &vcdrom_dev_list, vdisk_dev_list_entry)
3159 if (strcmp(vv->name, name) == 0) {
3165 PRINT_ERROR("Virtual device with name "
3166 "%s already exist", name);
3171 while (isspace(*p) && *p != '\0')
3174 while (!isspace(*p) && *p != '\0')
3177 if (*file_name == '\0') {
3179 TRACE_DBG("%s", "No media");
3180 } else if (*file_name != '/') {
3181 PRINT_ERROR("File path \"%s\" is not "
3182 "absolute", file_name);
3188 virt_dev = vdisk_alloc_dev();
3189 if (virt_dev == NULL) {
3190 TRACE(TRACE_OUT_OF_MEM, "%s",
3191 "Allocation of virt_dev failed");
3195 virt_dev->cdrom_empty = cdrom_empty;
3197 strcpy(virt_dev->name, name);
3199 scnprintf(virt_dev->usn, sizeof(virt_dev->usn), "%llx",
3200 vdisk_gen_dev_id_num(virt_dev));
3201 TRACE_DBG("usn %s", virt_dev->usn);
3203 if (!virt_dev->cdrom_empty) {
3204 len = strlen(file_name) + 1;
3205 virt_dev->file_name = kmalloc(len, GFP_KERNEL);
3206 if (virt_dev->file_name == NULL) {
3207 TRACE(TRACE_OUT_OF_MEM, "%s",
3208 "Allocation of file_name failed");
3212 strncpy(virt_dev->file_name, file_name, len);
3215 list_add_tail(&virt_dev->vdisk_dev_list_entry,
3218 PRINT_INFO("Registering virtual CDROM %s", name);
3221 scst_register_virtual_device(&vcdrom_devtype,
3223 if (virt_dev->virt_id < 0) {
3224 res = virt_dev->virt_id;
3225 goto out_free_vpath;
3227 TRACE_DBG("Added virt_dev (name %s file_name %s id %d) "
3228 "to vcdrom_dev_list", virt_dev->name,
3229 virt_dev->file_name, virt_dev->virt_id);
3235 list_del(&virt_dev->vdisk_dev_list_entry);
3236 kfree(virt_dev->file_name);
3243 /* scst_vdisk_mutex supposed to be held */
3244 static int vcdrom_close(char *name)
3246 struct scst_vdisk_dev *virt_dev, *vv;
3250 list_for_each_entry(vv, &vcdrom_dev_list,
3251 vdisk_dev_list_entry)
3253 if (strcmp(vv->name, name) == 0) {
3258 if (virt_dev == NULL) {
3259 PRINT_ERROR("Virtual device with name "
3260 "%s not found", name);
3264 scst_unregister_virtual_device(virt_dev->virt_id);
3265 PRINT_INFO("Virtual device %s unregistered",
3267 TRACE_DBG("virt_id %d unregister", virt_dev->virt_id);
3269 list_del(&virt_dev->vdisk_dev_list_entry);
3271 kfree(virt_dev->file_name);
3278 /* scst_vdisk_mutex supposed to be held */
3279 static int vcdrom_change(char *p, char *name)
3282 struct scst_vdisk_dev *virt_dev, *vv;
3283 char *file_name, *fn = NULL, *old_fn;
3288 list_for_each_entry(vv, &vcdrom_dev_list,
3289 vdisk_dev_list_entry) {
3290 if (strcmp(vv->name, name) == 0) {
3295 if (virt_dev == NULL) {
3296 PRINT_ERROR("Virtual device with name "
3297 "%s not found", name);
3302 while (isspace(*p) && *p != '\0')
3305 while (!isspace(*p) && *p != '\0')
3308 if (*file_name == '\0') {
3309 virt_dev->cdrom_empty = 1;
3310 TRACE_DBG("%s", "No media");
3311 } else if (*file_name != '/') {
3312 PRINT_ERROR("File path \"%s\" is not "
3313 "absolute", file_name);
3317 virt_dev->cdrom_empty = 0;
3319 old_fn = virt_dev->file_name;
3321 if (!virt_dev->cdrom_empty && !virt_dev->nullio) {
3322 len = strlen(file_name) + 1;
3323 fn = kmalloc(len, GFP_KERNEL);
3325 TRACE(TRACE_OUT_OF_MEM, "%s",
3326 "Allocation of file_name failed");
3331 strncpy(fn, file_name, len);
3332 virt_dev->file_name = fn;
3334 res = vdisk_get_check_file_size(virt_dev->file_name,
3335 virt_dev->blockio, &err);
3340 virt_dev->file_name = NULL;
3343 if (virt_dev->nullio)
3344 err = VDISK_NULLIO_SIZE;
3346 res = scst_suspend_activity(true);
3350 if (virt_dev->prevent_allow_medium_removal) {
3351 PRINT_ERROR("Prevent medium removal for "
3352 "virtual device with name %s", name);
3354 goto out_free_resume;
3357 virt_dev->file_size = err;
3358 virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift;
3359 if (!virt_dev->cdrom_empty)
3360 virt_dev->media_changed = 1;
3362 scst_dev_del_all_thr_data(virt_dev->dev);
3364 if (!virt_dev->cdrom_empty) {
3365 PRINT_INFO("Changed SCSI target virtual cdrom %s "
3366 "(file=\"%s\", fs=%lldMB, bs=%d, nblocks=%lld,"
3367 " cyln=%lld%s)", virt_dev->name, virt_dev->file_name,
3368 virt_dev->file_size >> 20, virt_dev->block_size,
3369 (long long unsigned int)virt_dev->nblocks,
3370 (long long unsigned int)virt_dev->nblocks/64/32,
3371 virt_dev->nblocks < 64*32 ? " !WARNING! cyln less "
3374 PRINT_INFO("Removed media from SCSI target virtual cdrom %s",
3381 scst_resume_activity();
3387 virt_dev->file_name = old_fn;
3392 virt_dev->file_name = old_fn;
3398 * Called when a file in the /proc/VCDROM_NAME/VCDROM_NAME is read
3400 static int vcdrom_read_proc(struct seq_file *seq,
3401 struct scst_dev_type *dev_type)
3404 struct scst_vdisk_dev *virt_dev;
3408 if (mutex_lock_interruptible(&scst_vdisk_mutex) != 0) {
3413 seq_printf(seq, "%-17s %-9s %s\n", "Name", "Size(MB)", "File name");
3415 list_for_each_entry(virt_dev, &vcdrom_dev_list,
3416 vdisk_dev_list_entry) {
3417 seq_printf(seq, "%-17s %-9d %s\n", virt_dev->name,
3418 (uint32_t)(virt_dev->file_size >> 20),
3419 virt_dev->file_name);
3422 mutex_unlock(&scst_vdisk_mutex);
3425 TRACE_EXIT_RES(res);
3430 * Called when a file in the /proc/VCDROM_NAME/VCDROM_NAME is written
3432 static int vcdrom_write_proc(char *buffer, char **start, off_t offset,
3433 int length, int *eof, struct scst_dev_type *dev_type)
3435 int res = 0, action;
3437 struct scst_vdisk_dev *virt_dev;
3441 if (mutex_lock_interruptible(&scst_vdisk_mutex) != 0) {