Cleanup of use of READ ONLY flag
[mirror/scst/.git] / scst / src / dev_handlers / scst_vdisk.c
1 /*
2  *  scst_vdisk.c
3  *
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.
9  *
10  *  SCSI disk (type 0) and CDROM (type 5) dev handler using files
11  *  on file systems or block devices (VDISK)
12  *
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
16  *  of the License.
17  *
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.
22  */
23
24 #include <linux/file.h>
25 #include <linux/fs.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>
43
44 #define LOG_PREFIX                      "dev_vdisk"
45
46 #include "scst.h"
47
48 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
49
50 #define TRACE_ORDER     0x80000000
51
52 static struct scst_proc_log vdisk_proc_local_trace_tbl[] =
53 {
54     { TRACE_ORDER,              "order" },
55     { 0,                        NULL }
56 };
57 #define trace_log_tbl   vdisk_proc_local_trace_tbl
58
59 #endif
60
61 #include "scst_dev_handler.h"
62
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"
68
69 #define MAX_USN_LEN                     (20+1) /* For '\0' */
70
71 #define INQ_BUF_SZ                      128
72 #define EVPD                            0x01
73 #define CMDDT                           0x02
74
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 */
80
81 #define PF                              0x10    /* page format */
82 #define SP                              0x01    /* save pages */
83 #define PS                              0x80    /* parameter saveable */
84
85 #define BYTE                            8
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
91 #define DEF_HEADS                       255
92 #define LEN_MEM                         (32 * 1024)
93 #define VDISK_NAME                      "vdisk"
94 #define VCDROM_NAME                     "vcdrom"
95
96 #define VDISK_NULLIO_SIZE               (3LL*1024*1024*1024*1024/2)
97
98 #define DEF_TST                         SCST_CONTR_MODE_SEP_TASK_SETS
99 /*
100  * Since we can't control backstorage device's reordering, we have to always
101  * report unrestricted reordering.
102  */
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
105 #define DEF_SWP                 0
106 #define DEF_TAS                 0
107
108 #define DEF_DSENSE              SCST_CONTR_MODE_FIXED_SENSE
109
110 #define VDISK_PROC_HELP         "help"
111
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,
177 };
178
179 struct scst_vdisk_dev {
180         uint32_t block_size;
181         uint64_t nblocks;
182         int block_shift;
183         loff_t file_size;       /* in bytes */
184
185         /*
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.
189          */
190         spinlock_t flags_lock;
191
192         /*
193          * Below flags are protected by flags_lock or suspended activity
194          * with scst_vdisk_mutex.
195          */
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;
206         int virt_id;
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;
213 };
214
215 struct scst_vdisk_tgt_dev {
216         /*
217          * Used without locking since SCST core ensures that only commands
218          * with the same ORDERED type per tgt_dev can be processed
219          * simultaneously.
220          */
221         enum scst_cmd_queue_type last_write_cmd_queue_type;
222 };
223
224 struct scst_vdisk_thr {
225         struct scst_thr_data_hdr hdr;
226         struct file *fd;
227         struct block_device *bdev;
228         struct iovec *iv;
229         int iv_count;
230 };
231
232 static struct kmem_cache *vdisk_thr_cachep;
233 static struct kmem_cache *blockio_work_cachep;
234
235 #define DEF_NUM_THREADS         5
236 static int num_threads = DEF_NUM_THREADS;
237
238 module_param_named(num_threads, num_threads, int, S_IRUGO);
239 MODULE_PARM_DESC(num_threads, "vdisk threads count");
240
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);
278
279 /*
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.
282  */
283
284 #define VDISK_TYPE {                                    \
285         .name =                 VDISK_NAME,             \
286         .type =                 TYPE_DISK,              \
287         .exec_sync =            1,                      \
288         .threads_num =          -1,                     \
289         .parse_atomic =         1,                      \
290         .exec_atomic =          0,                      \
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,     \
301 }
302
303 #define VDISK_BLK_TYPE {                                \
304         .name =                 VDISK_NAME "_blk",      \
305         .type =                 TYPE_DISK,              \
306         .threads_num =          0,                      \
307         .parse_atomic =         1,                      \
308         .exec_atomic =          0,                      \
309         .dev_done_atomic =      1,                      \
310         .no_proc =              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,     \
318 }
319
320 #define VDISK_NULL_TYPE {                               \
321         .name =                 VDISK_NAME "_null",     \
322         .type =                 TYPE_DISK,              \
323         .threads_num =          0,                      \
324         .parse_atomic =         1,                      \
325         .exec_atomic =          1,                      \
326         .dev_done_atomic =      1,                      \
327         .no_proc =              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,     \
335 }
336
337 #define VCDROM_TYPE {                                   \
338         .name =                 VCDROM_NAME,            \
339         .type =                 TYPE_ROM,               \
340         .exec_sync =            1,                      \
341         .threads_num =          -1,                     \
342         .parse_atomic =         1,                      \
343         .exec_atomic =          0,                      \
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,     \
354 }
355
356 static DEFINE_MUTEX(scst_vdisk_mutex);
357 static LIST_HEAD(vdisk_dev_list);
358 static LIST_HEAD(vcdrom_dev_list);
359
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;
364
365 static struct scst_vdisk_thr nullio_thr_data;
366
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";
371
372 static char *vcdrom_proc_help_string =
373         "echo \"open|change|close NAME [FILE_NAME]\" "
374         ">/proc/scsi_tgt/" VCDROM_NAME "/" VCDROM_NAME "\n";
375
376 static int scst_vdisk_ID;
377
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");
380
381
382 /**************************************************************
383  *  Function:  vdisk_open
384  *
385  *  Argument:
386  *
387  *  Returns :  fd, use IS_ERR(fd) to get error status
388  *
389  *  Description:
390  *************************************************************/
391 static struct file *vdisk_open(const struct scst_vdisk_dev *virt_dev)
392 {
393         int open_flags = 0;
394         struct file *fd;
395
396         TRACE_ENTRY();
397
398         if (virt_dev->dev->rd_only)
399                 open_flags |= O_RDONLY;
400         else
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);
409
410         TRACE_EXIT();
411         return fd;
412 }
413
414 /**************************************************************
415  *  Function:  vdisk_get_file_size
416  *
417  *  Argument:
418  *
419  *  Returns :  0 on success and file size in *file_size,
420  *             error code otherwise
421  *
422  *  Description:
423  *************************************************************/
424 static int vdisk_get_check_file_size(const char *file_name, bool blockio,
425         loff_t *file_size)
426 {
427         struct inode *inode;
428         int res = 0;
429         struct file *fd;
430
431         TRACE_ENTRY();
432
433         *file_size = 0;
434
435         fd = filp_open(file_name, O_LARGEFILE | O_RDONLY, 0600);
436         if (IS_ERR(fd)) {
437                 res = PTR_ERR(fd);
438                 PRINT_ERROR("filp_open(%s) returned error %d", file_name, res);
439                 goto out;
440         }
441
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)) {
446 #else
447         if ((fd->f_op == NULL) ||
448             (fd->f_op->aio_read == NULL) ||
449             (fd->f_op->aio_write == NULL)) {
450 #endif
451                 PRINT_ERROR("%s", "Wrong f_op or FS doesn't have required "
452                         "capabilities");
453                 res = -EINVAL;
454                 goto out_close;
455         }
456
457         inode = fd->f_dentry->d_inode;
458
459         if (blockio && !S_ISBLK(inode->i_mode)) {
460                 PRINT_ERROR("File %s is NOT a block device", file_name);
461                 res = -EINVAL;
462                 goto out_close;
463         }
464
465         if (S_ISREG(inode->i_mode))
466                 /* Nothing to do*/;
467         else if (S_ISBLK(inode->i_mode))
468                 inode = inode->i_bdev->bd_inode;
469         else {
470                 res = -EINVAL;
471                 goto out_close;
472         }
473
474         *file_size = inode->i_size;
475
476 out_close:
477         filp_close(fd, NULL);
478
479 out:
480         TRACE_EXIT_RES(res);
481         return res;
482 }
483
484 /**************************************************************
485  *  Function:  vdisk_attach
486  *
487  *  Argument:
488  *
489  *  Returns :  1 if attached, error code otherwise
490  *
491  *  Description:
492  *************************************************************/
493 static int vdisk_attach(struct scst_device *dev)
494 {
495         int res = 0;
496         loff_t err;
497         struct scst_vdisk_dev *virt_dev = NULL, *vv;
498         struct list_head *vd;
499
500         TRACE_ENTRY();
501
502         TRACE_DBG("virt_id %d (%s)", dev->virt_id, dev->virt_name);
503
504         if (dev->virt_id == 0) {
505                 PRINT_ERROR("%s", "Not a virtual device");
506                 res = -EINVAL;
507                 goto out;
508         }
509
510         vd = (dev->type == TYPE_DISK) ?
511                                 &vdisk_dev_list :
512                                 &vcdrom_dev_list;
513
514         /*
515          * scst_vdisk_mutex must be already taken before
516          * scst_register_virtual_device()
517          */
518         list_for_each_entry(vv, vd, vdisk_dev_list_entry) {
519                 if (strcmp(vv->name, dev->virt_name) == 0) {
520                         virt_dev = vv;
521                         break;
522                 }
523         }
524
525         if (virt_dev == NULL) {
526                 PRINT_ERROR("Device %s not found", dev->virt_name);
527                 res = -EINVAL;
528                 goto out;
529         }
530
531         virt_dev->dev = dev;
532
533         dev->rd_only = virt_dev->rd_only;
534         if (dev->type == TYPE_ROM)
535                 dev->rd_only = 1;
536
537         if (!virt_dev->cdrom_empty) {
538                 if (virt_dev->nullio)
539                         err = VDISK_NULLIO_SIZE;
540                 else {
541                         res = vdisk_get_check_file_size(virt_dev->file_name,
542                                 virt_dev->blockio, &err);
543                         if (res != 0)
544                                 goto out;
545                 }
546                 virt_dev->file_size = err;
547                 TRACE_DBG("size of file: %lld", (long long unsigned int)err);
548         } else
549                 virt_dev->file_size = 0;
550
551         if (dev->type == TYPE_DISK) {
552                 virt_dev->nblocks =
553                         virt_dev->file_size >> virt_dev->block_shift;
554         } else {
555                 virt_dev->block_size = DEF_CDROM_BLOCKSIZE;
556                 virt_dev->block_shift = DEF_CDROM_BLOCKSIZE_SHIFT;
557                 virt_dev->nblocks =
558                         virt_dev->file_size >> DEF_CDROM_BLOCKSIZE_SHIFT;
559         }
560
561         if (!virt_dev->cdrom_empty) {
562                 PRINT_INFO("Attached SCSI target virtual %s %s "
563                       "(file=\"%s\", fs=%lldMB, bs=%d, nblocks=%lld,"
564                       " cyln=%lld%s)",
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" : "");
572         } else {
573                 PRINT_INFO("Attached empty SCSI target virtual cdrom %s",
574                         virt_dev->name);
575         }
576
577         dev->dh_priv = virt_dev;
578
579         dev->tst = DEF_TST;
580         dev->d_sense = DEF_DSENSE;
581         if (virt_dev->wt_flag && !virt_dev->nv_cache)
582                 dev->queue_alg = DEF_QUEUE_ALG_WT;
583         else
584                 dev->queue_alg = DEF_QUEUE_ALG;
585         dev->swp = DEF_SWP;
586         dev->tas = DEF_TAS;
587
588 out:
589         TRACE_EXIT();
590         return res;
591 }
592
593 /************************************************************
594  *  Function:  vdisk_detach
595  *
596  *  Argument:
597  *
598  *  Returns :  None
599  *
600  *  Description:  Called to detach this device type driver
601  ************************************************************/
602 static void vdisk_detach(struct scst_device *dev)
603 {
604         struct scst_vdisk_dev *virt_dev =
605             (struct scst_vdisk_dev *)dev->dh_priv;
606
607         TRACE_ENTRY();
608
609         TRACE_DBG("virt_id %d", dev->virt_id);
610
611         PRINT_INFO("Detached SCSI target virtual device %s (\"%s\")",
612                       virt_dev->name, virt_dev->file_name);
613
614         /* virt_dev will be freed by the caller */
615         dev->dh_priv = NULL;
616
617         TRACE_EXIT();
618         return;
619 }
620
621 static void vdisk_free_thr_data(struct scst_thr_data_hdr *d)
622 {
623         struct scst_vdisk_thr *thr =
624                 container_of(d, struct scst_vdisk_thr, hdr);
625
626         TRACE_ENTRY();
627
628         if (thr->fd)
629                 filp_close(thr->fd, NULL);
630
631         kfree(thr->iv);
632
633         kmem_cache_free(vdisk_thr_cachep, thr);
634
635         TRACE_EXIT();
636         return;
637 }
638
639 static struct scst_vdisk_thr *vdisk_init_thr_data(
640         struct scst_tgt_dev *tgt_dev)
641 {
642         struct scst_vdisk_thr *res;
643         struct scst_vdisk_dev *virt_dev =
644             (struct scst_vdisk_dev *)tgt_dev->dev->dh_priv;
645
646         TRACE_ENTRY();
647
648         EXTRACHECKS_BUG_ON(virt_dev->nullio);
649
650 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17)
651         res = kmem_cache_alloc(vdisk_thr_cachep, GFP_KERNEL);
652         if (res != NULL)
653                 memset(res, 0, sizeof(*res));
654 #else
655         res = kmem_cache_zalloc(vdisk_thr_cachep, GFP_KERNEL);
656 #endif
657         if (res == NULL) {
658                 TRACE(TRACE_OUT_OF_MEM, "%s", "Unable to allocate struct "
659                         "scst_vdisk_thr");
660                 goto out;
661         }
662
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));
668                         goto out_free;
669                 }
670                 if (virt_dev->blockio)
671                         res->bdev = res->fd->f_dentry->d_inode->i_bdev;
672                 else
673                         res->bdev = NULL;
674         } else
675                 res->fd = NULL;
676
677         scst_add_thr_data(tgt_dev, &res->hdr, vdisk_free_thr_data);
678
679 out:
680         TRACE_EXIT_HRES((unsigned long)res);
681         return res;
682
683 out_free:
684         kmem_cache_free(vdisk_thr_cachep, res);
685         res = NULL;
686         goto out;
687 }
688
689 static int vdisk_attach_tgt(struct scst_tgt_dev *tgt_dev)
690 {
691         struct scst_vdisk_tgt_dev *ftgt_dev;
692         int res = 0;
693
694         TRACE_ENTRY();
695
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");
700                 res = -ENOMEM;
701                 goto out;
702         }
703
704         tgt_dev->dh_priv = ftgt_dev;
705
706 out:
707         TRACE_EXIT_RES(res);
708         return res;
709 }
710
711 static void vdisk_detach_tgt(struct scst_tgt_dev *tgt_dev)
712 {
713         struct scst_vdisk_tgt_dev *ftgt_dev =
714                 (struct scst_vdisk_tgt_dev *)tgt_dev->dh_priv;
715
716         TRACE_ENTRY();
717
718         scst_del_all_thr_data(tgt_dev);
719
720         kfree(ftgt_dev);
721         tgt_dev->dh_priv = NULL;
722
723         TRACE_EXIT();
724         return;
725 }
726
727 static inline int vdisk_sync_queue_type(enum scst_cmd_queue_type qt)
728 {
729         switch (qt) {
730         case SCST_CMD_QUEUE_ORDERED:
731         case SCST_CMD_QUEUE_HEAD_OF_QUEUE:
732                 return 1;
733         default:
734                 return 0;
735         }
736 }
737
738 static inline int vdisk_need_pre_sync(enum scst_cmd_queue_type cur,
739         enum scst_cmd_queue_type last)
740 {
741         if (vdisk_sync_queue_type(cur))
742                 if (!vdisk_sync_queue_type(last))
743                         return 1;
744         return 0;
745 }
746
747 static int vdisk_do_job(struct scst_cmd *cmd)
748 {
749         int rc, res;
750         uint64_t lba_start = 0;
751         loff_t data_len = 0;
752         uint8_t *cdb = cmd->cdb;
753         int opcode = cdb[0];
754         loff_t loff;
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;
761         int fua = 0;
762
763         TRACE_ENTRY();
764
765         switch (cmd->queue_type) {
766         case SCST_CMD_QUEUE_ORDERED:
767                 TRACE(TRACE_ORDER, "ORDERED cmd %p", cmd);
768                 break;
769         case SCST_CMD_QUEUE_HEAD_OF_QUEUE:
770                 TRACE(TRACE_ORDER, "HQ cmd %p", cmd);
771                 break;
772         default:
773                 break;
774         }
775
776         rc = scst_check_local_events(cmd);
777         if (unlikely(rc != 0))
778                 goto out_done;
779
780         cmd->status = 0;
781         cmd->msg_status = 0;
782         cmd->host_status = DID_OK;
783         cmd->driver_status = 0;
784
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);
789                         if (thr == NULL) {
790                                 scst_set_busy(cmd);
791                                 goto out_compl;
792                         }
793                         scst_thr_data_get(&thr->hdr);
794                 } else
795                         thr = container_of(d, struct scst_vdisk_thr, hdr);
796         } else {
797                 thr = &nullio_thr_data;
798                 scst_thr_data_get(&thr->hdr);
799         }
800
801         switch (opcode) {
802         case READ_6:
803         case WRITE_6:
804         case VERIFY_6:
805                 lba_start = (((cdb[1] & 0x1f) << (BYTE * 2)) +
806                              (cdb[2] << (BYTE * 1)) +
807                              (cdb[3] << (BYTE * 0)));
808                 data_len = cmd->bufflen;
809                 break;
810         case READ_10:
811         case READ_12:
812         case WRITE_10:
813         case WRITE_12:
814         case VERIFY:
815         case WRITE_VERIFY:
816         case WRITE_VERIFY_12:
817         case 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;
823                 break;
824         case READ_16:
825         case WRITE_16:
826         case WRITE_VERIFY_16:
827         case 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;
837                 break;
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;
845                 if (data_len == 0)
846                         data_len = virt_dev->file_size -
847                                 ((loff_t)lba_start << virt_dev->block_shift);
848                 break;
849         }
850
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));
865                 goto out_compl;
866         }
867
868         switch (opcode) {
869         case WRITE_10:
870         case WRITE_12:
871         case WRITE_16:
872                 fua = (cdb[1] & 0x8);
873                 if (fua) {
874                         TRACE(TRACE_ORDER, "FUA: loff=%lld, "
875                                 "data_len=%lld", (long long unsigned int)loff,
876                                 (long long unsigned int)data_len);
877                 }
878                 break;
879         }
880
881         switch (opcode) {
882         case READ_6:
883         case READ_10:
884         case READ_12:
885         case READ_16:
886                 if (virt_dev->blockio) {
887                         blockio_exec_rw(cmd, thr, lba_start, 0);
888                         goto out_thr;
889                 } else
890                         vdisk_exec_read(cmd, thr, loff);
891                 break;
892         case WRITE_6:
893         case WRITE_10:
894         case WRITE_12:
895         case WRITE_16:
896         {
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);
908                         do_fsync = 1;
909                         if (vdisk_fsync(thr, 0, 0, cmd) != 0)
910                                 goto out_compl;
911                 }
912                 if (virt_dev->blockio) {
913                         blockio_exec_rw(cmd, thr, lba_start, 1);
914                         goto out_thr;
915                 } else
916                         vdisk_exec_write(cmd, thr, loff);
917                 /* O_SYNC flag is used for WT devices */
918                 if (do_fsync || fua)
919                         vdisk_fsync(thr, loff, data_len, cmd);
920                 break;
921         }
922         case WRITE_VERIFY:
923         case WRITE_VERIFY_12:
924         case WRITE_VERIFY_16:
925         {
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);
938                         do_fsync = 1;
939                         if (vdisk_fsync(thr, 0, 0, cmd) != 0)
940                                 goto out_compl;
941                 }
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);
947                 else if (do_fsync)
948                         vdisk_fsync(thr, loff, data_len, cmd);
949                 break;
950         }
951         case SYNCHRONIZE_CACHE:
952         {
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);
958                 if (immed) {
959                         scst_cmd_get(cmd);
960                         cmd->completed = 1;
961                         cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT,
962                                 SCST_CONTEXT_SAME);
963                         vdisk_fsync(thr, loff, data_len, NULL);
964                         /* ToDo: vdisk_fsync() error processing */
965                         scst_cmd_put(cmd);
966                         goto out_thr;
967                 } else {
968                         vdisk_fsync(thr, loff, data_len, cmd);
969                         break;
970                 }
971         }
972         case VERIFY_6:
973         case VERIFY:
974         case VERIFY_12:
975         case VERIFY_16:
976                 vdisk_exec_verify(cmd, thr, loff);
977                 break;
978         case MODE_SENSE:
979         case MODE_SENSE_10:
980                 vdisk_exec_mode_sense(cmd);
981                 break;
982         case MODE_SELECT:
983         case MODE_SELECT_10:
984                 vdisk_exec_mode_select(cmd);
985                 break;
986         case LOG_SELECT:
987         case LOG_SENSE:
988                 vdisk_exec_log(cmd);
989                 break;
990         case ALLOW_MEDIUM_REMOVAL:
991                 vdisk_exec_prevent_allow_medium_removal(cmd);
992                 break;
993         case READ_TOC:
994                 vdisk_exec_read_toc(cmd);
995                 break;
996         case START_STOP:
997                 vdisk_fsync(thr, 0, virt_dev->file_size, cmd);
998                 break;
999         case RESERVE:
1000         case RESERVE_10:
1001         case RELEASE:
1002         case RELEASE_10:
1003         case TEST_UNIT_READY:
1004                 break;
1005         case INQUIRY:
1006                 vdisk_exec_inquiry(cmd);
1007                 break;
1008         case REQUEST_SENSE:
1009                 vdisk_exec_request_sense(cmd);
1010                 break;
1011         case READ_CAPACITY:
1012                 vdisk_exec_read_capacity(cmd);
1013                 break;
1014         case SERVICE_ACTION_IN:
1015                 if ((cmd->cdb[1] & 0x1f) == SAI_READ_CAPACITY_16) {
1016                         vdisk_exec_read_capacity16(cmd);
1017                         break;
1018                 }
1019                 /* else go through */
1020         case REPORT_LUNS:
1021         default:
1022                 TRACE_DBG("Invalid opcode %d", opcode);
1023                 scst_set_cmd_error(cmd,
1024                     SCST_LOAD_SENSE(scst_sense_invalid_opcode));
1025         }
1026
1027 out_compl:
1028         cmd->completed = 1;
1029
1030 out_done:
1031         cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
1032
1033 out_thr:
1034         if (likely(thr != NULL))
1035                 scst_thr_data_put(&thr->hdr);
1036
1037         res = SCST_EXEC_COMPLETED;
1038
1039         TRACE_EXIT_RES(res);
1040         return res;
1041 }
1042
1043 static int vdisk_get_block_shift(struct scst_cmd *cmd)
1044 {
1045         struct scst_vdisk_dev *virt_dev =
1046             (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1047         return virt_dev->block_shift;
1048 }
1049
1050 /********************************************************************
1051  *  Function:  vdisk_parse
1052  *
1053  *  Argument:
1054  *
1055  *  Returns :  The state of the command
1056  *
1057  *  Description:  This does the parsing of the command
1058  *
1059  *  Note:  Not all states are allowed on return
1060  ********************************************************************/
1061 static int vdisk_parse(struct scst_cmd *cmd)
1062 {
1063         scst_sbc_generic_parse(cmd, vdisk_get_block_shift);
1064         return SCST_CMD_STATE_DEFAULT;
1065 }
1066
1067 /********************************************************************
1068  *  Function:  vcdrom_parse
1069  *
1070  *  Argument:
1071  *
1072  *  Returns :  The state of the command
1073  *
1074  *  Description:  This does the parsing of the command
1075  *
1076  *  Note:  Not all states are allowed on return
1077  ********************************************************************/
1078 static int vcdrom_parse(struct scst_cmd *cmd)
1079 {
1080         scst_cdrom_generic_parse(cmd, vdisk_get_block_shift);
1081         return SCST_CMD_STATE_DEFAULT;
1082 }
1083
1084 /********************************************************************
1085  *  Function:  vcdrom_exec
1086  *
1087  *  Argument:
1088  *
1089  *  Returns :
1090  *
1091  *  Description:
1092  ********************************************************************/
1093 static int vcdrom_exec(struct scst_cmd *cmd)
1094 {
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;
1099
1100         TRACE_ENTRY();
1101
1102         cmd->status = 0;
1103         cmd->msg_status = 0;
1104         cmd->host_status = DID_OK;
1105         cmd->driver_status = 0;
1106
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));
1111                 goto out_done;
1112         }
1113
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);
1123                         goto out_done;
1124                 }
1125                 spin_unlock(&virt_dev->flags_lock);
1126         }
1127
1128         res = vdisk_do_job(cmd);
1129
1130 out:
1131         TRACE_EXIT_RES(res);
1132         return res;
1133
1134 out_done:
1135         cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
1136         goto out;
1137 }
1138
1139 static uint64_t vdisk_gen_dev_id_num(struct scst_vdisk_dev *virt_dev)
1140 {
1141         unsigned int dev_id_num, i;
1142
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)));
1147         }
1148
1149         return ((uint64_t)scst_vdisk_ID << 32) | dev_id_num;
1150 }
1151
1152 static void vdisk_exec_inquiry(struct scst_cmd *cmd)
1153 {
1154         int32_t length, i, resp_len = 0;
1155         uint8_t *address;
1156         uint8_t *buf;
1157         struct scst_vdisk_dev *virt_dev =
1158             (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1159
1160         /* ToDo: Performance Boost:
1161          * 1. remove kzalloc, buf
1162          * 2. do all checks before touching *address
1163          * 3. zero *address
1164          * 4. write directly to *address
1165          */
1166
1167         TRACE_ENTRY();
1168
1169         buf = kzalloc(INQ_BUF_SZ,
1170                 scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL);
1171         if (buf == NULL) {
1172                 scst_set_busy(cmd);
1173                 goto out;
1174         }
1175
1176         length = scst_get_buf_first(cmd, &address);
1177         TRACE_DBG("length %d", length);
1178         if (unlikely(length <= 0)) {
1179                 if (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));
1183                 }
1184                 goto out_free;
1185         }
1186
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));
1191                 goto out_put;
1192         }
1193
1194         buf[0] = cmd->dev->type;      /* type dev */
1195         if ((buf[0] == TYPE_ROM) || virt_dev->removable)
1196                 buf[1] = 0x80;      /* removable */
1197         /* Vital Product */
1198         if (cmd->cdb[1] & EVPD) {
1199                 uint64_t dev_id_num;
1200                 int dev_id_len;
1201                 char dev_id_str[17];
1202
1203                 dev_id_num = vdisk_gen_dev_id_num(virt_dev);
1204                 dev_id_len = scnprintf(dev_id_str, sizeof(dev_id_str), "%llx",
1205                                         dev_id_num);
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 */
1210                         buf[3] = 3;
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);
1218                         buf[1] = 0x80;
1219                         buf[3] = usn_len;
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 */
1224                         int num = 4;
1225
1226                         buf[1] = 0x83;
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);
1232                         else
1233                                 memcpy(&buf[num + 4], SCST_FIO_VENDOR, 8);
1234
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];
1241
1242 #if 0 /* This isn't required and can be misleading, so let's disable it */
1243                         num += 4;
1244
1245                         /* NAA IEEE registered identifier (faked) */
1246                         buf[num] = 0x1; /* binary */
1247                         buf[num + 1] = 0x3;
1248                         buf[num + 2] = 0x0;
1249                         buf[num + 3] = 0x8;
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;
1258                         num = num + 12 - 4;
1259 #endif
1260
1261                         resp_len = num;
1262                         buf[2] = (resp_len >> 8) & 0xFF;
1263                         buf[3] = resp_len & 0xFF;
1264                         resp_len += 4;
1265                 } else {
1266                         TRACE_DBG("INQUIRY: Unsupported EVPD page %x",
1267                                 cmd->cdb[2]);
1268                         scst_set_cmd_error(cmd,
1269                             SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1270                         goto out_put;
1271                 }
1272         } else {
1273                 int len;
1274
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));
1279                         goto out_put;
1280                 }
1281
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 */
1287
1288                 /*
1289                  * 8 byte ASCII Vendor Identification of the target
1290                  * - left aligned.
1291                  */
1292                 if (virt_dev->blockio)
1293                         memcpy(&buf[8], SCST_BIO_VENDOR, 8);
1294                 else
1295                         memcpy(&buf[8], SCST_FIO_VENDOR, 8);
1296
1297                 /*
1298                  * 16 byte ASCII Product Identification of the target - left
1299                  * aligned.
1300                  */
1301                 memset(&buf[16], ' ', 16);
1302                 len = min(strlen(virt_dev->name), (size_t)16);
1303                 memcpy(&buf[16], virt_dev->name, len);
1304
1305                 /*
1306                  * 4 byte ASCII Product Revision Level of the target - left
1307                  * aligned.
1308                  */
1309                 memcpy(&buf[32], SCST_FIO_REV, 4);
1310                 resp_len = buf[4] + 5;
1311         }
1312
1313         sBUG_ON(resp_len >= INQ_BUF_SZ);
1314         if (length > resp_len)
1315                 length = resp_len;
1316         memcpy(address, buf, length);
1317
1318 out_put:
1319         scst_put_buf(cmd, address);
1320         if (length < cmd->resp_data_len)
1321                 scst_set_resp_data_len(cmd, length);
1322
1323 out_free:
1324         kfree(buf);
1325
1326 out:
1327         TRACE_EXIT();
1328         return;
1329 }
1330
1331 static void vdisk_exec_request_sense(struct scst_cmd *cmd)
1332 {
1333         int32_t length;
1334         uint8_t *address;
1335
1336         TRACE_ENTRY();
1337
1338         length = scst_get_buf_first(cmd, &address);
1339         TRACE_DBG("length %d", length);
1340         if (unlikely(length < SCST_STANDARD_SENSE_LEN)) {
1341                 if (length != 0) {
1342                         PRINT_ERROR("scst_get_buf_first() failed or too small "
1343                                 "requested buffer (returned %d)", length);
1344                         scst_set_cmd_error(cmd,
1345                                 SCST_LOAD_SENSE(
1346                                         scst_sense_invalid_field_in_parm_list));
1347                 }
1348                 if (length > 0)
1349                         goto out_put;
1350                 else
1351                         goto out;
1352         }
1353
1354         scst_set_sense(address, length, cmd->dev->d_sense,
1355                 SCST_LOAD_SENSE(scst_sense_no_sense));
1356
1357 out_put:
1358         scst_put_buf(cmd, address);
1359
1360 out:
1361         TRACE_EXIT();
1362         return;
1363 }
1364
1365 /*
1366  * <<Following mode pages info copied from ST318451LW with some corrections>>
1367  *
1368  * ToDo: revise them
1369  */
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,
1374                                               5, 0, 0xff, 0xff};
1375
1376         memcpy(p, err_recov_pg, sizeof(err_recov_pg));
1377         if (1 == pcontrol)
1378                 memset(p + 2, 0, sizeof(err_recov_pg) - 2);
1379         return sizeof(err_recov_pg);
1380 }
1381
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};
1387
1388         memcpy(p, disconnect_pg, sizeof(disconnect_pg));
1389         if (1 == pcontrol)
1390                 memset(p + 2, 0, sizeof(disconnect_pg) - 2);
1391         return sizeof(disconnect_pg);
1392 }
1393
1394 static int vdisk_rigid_geo_pg(unsigned char *p, int pcontrol,
1395         struct scst_vdisk_dev *virt_dev)
1396 {
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;
1401         uint64_t dividend;
1402
1403         memcpy(p, geo_m_pg, sizeof(geo_m_pg));
1404         /*
1405          * Divide virt_dev->nblocks by (DEF_HEADS * DEF_SECTORS) and store
1406          * the quotient in ncyl and the remainder in rem.
1407          */
1408         dividend = virt_dev->nblocks;
1409         rem = do_div(dividend, DEF_HEADS * DEF_SECTORS);
1410         ncyl = dividend;
1411         if (rem != 0)
1412                 ncyl++;
1413         memcpy(&n, p + 2, sizeof(u32));
1414         n = n | (cpu_to_be32(ncyl) >> 8);
1415         memcpy(p + 2, &n, sizeof(u32));
1416         if (1 == pcontrol)
1417                 memset(p + 2, 0, sizeof(geo_m_pg) - 2);
1418         return sizeof(geo_m_pg);
1419 }
1420
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};
1427
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;
1433         if (1 == pcontrol)
1434                 memset(p + 2, 0, sizeof(format_pg) - 2);
1435         return sizeof(format_pg);
1436 }
1437
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};
1443
1444         memcpy(p, caching_pg, sizeof(caching_pg));
1445         p[2] |= !(virt_dev->wt_flag || virt_dev->nv_cache) ? WCE : 0;
1446         if (1 == pcontrol)
1447                 memset(p + 2, 0, sizeof(caching_pg) - 2);
1448         return sizeof(caching_pg);
1449 }
1450
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,
1455                                            0, 0, 0x2, 0x4b};
1456
1457         memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg));
1458         switch (pcontrol) {
1459         case 0:
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;
1465                 break;
1466         case 1:
1467                 memset(p + 2, 0, sizeof(ctrl_m_pg) - 2);
1468 #if 0   /*
1469          * It's too early to implement it, since we can't control the
1470          * backstorage device parameters. ToDo
1471          */
1472                 p[2] |= 7 << 5;         /* TST */
1473                 p[3] |= 0xF << 4;       /* QUEUE ALGORITHM MODIFIER */
1474 #endif
1475                 p[2] |= 1 << 2;         /* D_SENSE */
1476                 p[4] |= 1 << 3;         /* SWP */
1477                 p[5] |= 1 << 6;         /* TAS */
1478                 break;
1479         case 2:
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;
1484                 else
1485                         p[3] |= DEF_QUEUE_ALG << 4;
1486                 p[4] |= DEF_SWP << 3;
1487                 p[5] |= DEF_TAS << 6;
1488                 break;
1489         default:
1490                 sBUG();
1491         }
1492         return sizeof(ctrl_m_pg);
1493 }
1494
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,
1499                                           0, 0, 0x0, 0x0};
1500         memcpy(p, iec_m_pg, sizeof(iec_m_pg));
1501         if (1 == pcontrol)
1502                 memset(p + 2, 0, sizeof(iec_m_pg) - 2);
1503         return sizeof(iec_m_pg);
1504 }
1505
1506 static void vdisk_exec_mode_sense(struct scst_cmd *cmd)
1507 {
1508         int32_t length;
1509         uint8_t *address;
1510         uint8_t *buf;
1511         struct scst_vdisk_dev *virt_dev;
1512         uint32_t blocksize;
1513         uint64_t nblocks;
1514         unsigned char dbd, type;
1515         int pcontrol, pcode, subpcode;
1516         unsigned char dev_spec;
1517         int msense_6, offset = 0, len;
1518         unsigned char *bp;
1519
1520         TRACE_ENTRY();
1521
1522         buf = kzalloc(MSENSE_BUF_SZ,
1523                 scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL);
1524         if (buf == NULL) {
1525                 scst_set_busy(cmd);
1526                 goto out;
1527         }
1528
1529         virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1530         blocksize = virt_dev->block_size;
1531         nblocks = virt_dev->nblocks;
1532
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;
1540
1541         length = scst_get_buf_first(cmd, &address);
1542         if (unlikely(length <= 0)) {
1543                 if (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));
1547                 }
1548                 goto out_free;
1549         }
1550
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));
1555                 goto out_put;
1556         }
1557
1558         if (msense_6) {
1559                 buf[1] = type;
1560                 buf[2] = dev_spec;
1561                 offset = 4;
1562         } else {
1563                 buf[2] = type;
1564                 buf[3] = dev_spec;
1565                 offset = 8;
1566         }
1567
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));
1573                 goto out_put;
1574         }
1575
1576         if (!dbd) {
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;
1584                 } else {
1585                         /* num blks */
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;
1590                 }
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;
1595
1596                 offset += 8;                    /* increment offset */
1597         }
1598
1599         bp = buf + offset;
1600
1601         switch (pcode) {
1602         case 0x1:       /* Read-Write error recovery page, direct access */
1603                 len = vdisk_err_recov_pg(bp, pcontrol, virt_dev);
1604                 break;
1605         case 0x2:       /* Disconnect-Reconnect page, all devices */
1606                 len = vdisk_disconnect_pg(bp, pcontrol, virt_dev);
1607                 break;
1608         case 0x3:       /* Format device page, direct access */
1609                 len = vdisk_format_pg(bp, pcontrol, virt_dev);
1610                 break;
1611         case 0x4:       /* Rigid disk geometry */
1612                 len = vdisk_rigid_geo_pg(bp, pcontrol, virt_dev);
1613                 break;
1614         case 0x8:       /* Caching page, direct access */
1615                 len = vdisk_caching_pg(bp, pcontrol, virt_dev);
1616                 break;
1617         case 0xa:       /* Control Mode page, all devices */
1618                 len = vdisk_ctrl_m_pg(bp, pcontrol, virt_dev);
1619                 break;
1620         case 0x1c:      /* Informational Exceptions Mode page, all devices */
1621                 len = vdisk_iec_m_pg(bp, pcontrol, virt_dev);
1622                 break;
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);
1631                 break;
1632         default:
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));
1636                 goto out_put;
1637         }
1638
1639         offset += len;
1640
1641         if (msense_6)
1642                 buf[0] = offset - 1;
1643         else {
1644                 buf[0] = ((offset - 2) >> 8) & 0xff;
1645                 buf[1] = (offset - 2) & 0xff;
1646         }
1647
1648         if (offset > length)
1649                 offset = length;
1650         memcpy(address, buf, offset);
1651
1652 out_put:
1653         scst_put_buf(cmd, address);
1654         if (offset < cmd->resp_data_len)
1655                 scst_set_resp_data_len(cmd, offset);
1656
1657 out_free:
1658         kfree(buf);
1659
1660 out:
1661         TRACE_EXIT();
1662         return;
1663 }
1664
1665 static int vdisk_set_wt(struct scst_vdisk_dev *virt_dev, int wt)
1666 {
1667         int res = 0;
1668
1669         TRACE_ENTRY();
1670
1671         if ((virt_dev->wt_flag == wt) || virt_dev->nullio || virt_dev->nv_cache)
1672                 goto out;
1673
1674         spin_lock(&virt_dev->flags_lock);
1675         virt_dev->wt_flag = wt;
1676         spin_unlock(&virt_dev->flags_lock);
1677
1678         scst_dev_del_all_thr_data(virt_dev->dev);
1679
1680 out:
1681         TRACE_EXIT_RES(res);
1682         return res;
1683 }
1684
1685 static void vdisk_ctrl_m_pg_select(unsigned char *p,
1686         struct scst_vdisk_dev *virt_dev)
1687 {
1688         struct scst_device *dev = virt_dev->dev;
1689         int old_swp = dev->swp, old_tas = dev->tas, old_dsense = dev->d_sense;
1690
1691 #if 0
1692         /* Not implemented yet, see comment in vdisk_ctrl_m_pg() */
1693         dev->tst = p[2] >> 5;
1694         dev->queue_alg = p[3] >> 4;
1695 #endif
1696         dev->swp = (p[4] & 0x8) >> 3;
1697         dev->tas = (p[5] & 0x40) >> 6;
1698         dev->d_sense = (p[2] & 0x4) >> 2;
1699
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);
1704         return;
1705 }
1706
1707 static void vdisk_exec_mode_select(struct scst_cmd *cmd)
1708 {
1709         int32_t length;
1710         uint8_t *address;
1711         struct scst_vdisk_dev *virt_dev;
1712         int mselect_6, offset;
1713
1714         TRACE_ENTRY();
1715
1716         virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1717         mselect_6 = (MODE_SELECT == cmd->cdb[0]);
1718
1719         length = scst_get_buf_first(cmd, &address);
1720         if (unlikely(length <= 0)) {
1721                 if (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));
1725                 }
1726                 goto out;
1727         }
1728
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)",
1732                         cmd->cdb[1]);
1733                 scst_set_cmd_error(cmd,
1734                     SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1735                 goto out_put;
1736         }
1737
1738         if (mselect_6)
1739                 offset = 4;
1740         else
1741                 offset = 8;
1742
1743         if (address[offset - 1] == 8) {
1744                 offset += 8;
1745         } else if (address[offset - 1] != 0) {
1746                 PRINT_ERROR("%s", "MODE SELECT: Wrong parameters list "
1747                         "lenght");
1748                 scst_set_cmd_error(cmd,
1749                     SCST_LOAD_SENSE(scst_sense_invalid_field_in_parm_list));
1750                 goto out_put;
1751         }
1752
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));
1758                         goto out_put;
1759                 }
1760                 if ((address[offset] & 0x3f) == 0x8) {
1761                         /* Caching page */
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));
1767                                 goto out_put;
1768                         }
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));
1773                                 goto out_put;
1774                         }
1775                         break;
1776                 } else if ((address[offset] & 0x3f) == 0xA) {
1777                         /* Control page */
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));
1783                                 goto out_put;
1784                         }
1785                         vdisk_ctrl_m_pg_select(&address[offset], virt_dev);
1786                 } else {
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));
1791                         goto out_put;
1792                 }
1793                 offset += address[offset + 1];
1794         }
1795
1796 out_put:
1797         scst_put_buf(cmd, address);
1798
1799 out:
1800         TRACE_EXIT();
1801         return;
1802 }
1803
1804 static void vdisk_exec_log(struct scst_cmd *cmd)
1805 {
1806         TRACE_ENTRY();
1807
1808         /* No log pages are supported */
1809         scst_set_cmd_error(cmd,
1810                 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1811
1812         TRACE_EXIT();
1813         return;
1814 }
1815
1816 static void vdisk_exec_read_capacity(struct scst_cmd *cmd)
1817 {
1818         int32_t length;
1819         uint8_t *address;
1820         struct scst_vdisk_dev *virt_dev;
1821         uint32_t blocksize;
1822         uint64_t nblocks;
1823         uint8_t buffer[READ_CAP_LEN];
1824
1825         TRACE_ENTRY();
1826
1827         virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1828         blocksize = virt_dev->block_size;
1829         nblocks = virt_dev->nblocks;
1830
1831         /* last block on the virt_dev is (nblocks-1) */
1832         memset(buffer, 0, sizeof(buffer));
1833         if (nblocks >> 32) {
1834                 buffer[0] = 0xFF;
1835                 buffer[1] = 0xFF;
1836                 buffer[2] = 0xFF;
1837                 buffer[3] = 0xFF;
1838         } else {
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;
1843         }
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;
1848
1849         length = scst_get_buf_first(cmd, &address);
1850         if (unlikely(length <= 0)) {
1851                 if (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));
1855                 }
1856                 goto out;
1857         }
1858
1859         if (length > READ_CAP_LEN)
1860                 length = READ_CAP_LEN;
1861         memcpy(address, buffer, length);
1862
1863         scst_put_buf(cmd, address);
1864
1865         if (length < cmd->resp_data_len)
1866                 scst_set_resp_data_len(cmd, length);
1867
1868 out:
1869         TRACE_EXIT();
1870         return;
1871 }
1872
1873 static void vdisk_exec_read_capacity16(struct scst_cmd *cmd)
1874 {
1875         int32_t length;
1876         uint8_t *address;
1877         struct scst_vdisk_dev *virt_dev;
1878         uint32_t blocksize;
1879         uint64_t nblocks;
1880         uint8_t buffer[READ_CAP16_LEN];
1881
1882         TRACE_ENTRY();
1883
1884         virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1885         blocksize = virt_dev->block_size;
1886         nblocks = virt_dev->nblocks - 1;
1887
1888         memset(buffer, 0, sizeof(buffer));
1889
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;
1898
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;
1903
1904         switch (blocksize) {
1905         case 512:
1906                 buffer[13] = 3;
1907                 break;
1908         case 1024:
1909                 buffer[13] = 2;
1910                 break;
1911         case 2048:
1912                 buffer[13] = 1;
1913                 break;
1914         default:
1915                 PRINT_ERROR("%s: Unexpected block size %d",
1916                         cmd->op_name, blocksize);
1917                 /* go through */
1918         case 4096:
1919                 buffer[13] = 0;
1920                 break;
1921         }
1922
1923         length = scst_get_buf_first(cmd, &address);
1924         if (unlikely(length <= 0)) {
1925                 if (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));
1929                         }
1930                 goto out;
1931         }
1932
1933         if (length > READ_CAP16_LEN)
1934                 length = READ_CAP16_LEN;
1935         memcpy(address, buffer, length);
1936
1937         scst_put_buf(cmd, address);
1938
1939         if (length < cmd->resp_data_len)
1940                 scst_set_resp_data_len(cmd, length);
1941
1942 out:
1943         TRACE_EXIT();
1944         return;
1945 }
1946
1947 static void vdisk_exec_read_toc(struct scst_cmd *cmd)
1948 {
1949         int32_t length, off = 0;
1950         uint8_t *address;
1951         struct scst_vdisk_dev *virt_dev;
1952         uint32_t nblocks;
1953         uint8_t buffer[4+8+8] = { 0x00, 0x0a, 0x01, 0x01, 0x00, 0x14,
1954                                   0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
1955
1956         TRACE_ENTRY();
1957
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));
1962                 goto out;
1963         }
1964
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));
1969                 goto out;
1970         }
1971
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",
1975                         cmd->cdb[6]);
1976                 scst_set_cmd_error(cmd,
1977                         SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1978                 goto out;
1979         }
1980
1981         length = scst_get_buf_first(cmd, &address);
1982         if (unlikely(length <= 0)) {
1983                 if (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));
1987                 }
1988                 goto out;
1989         }
1990
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;
1994
1995         /* Header */
1996         memset(buffer, 0, sizeof(buffer));
1997         buffer[2] = 0x01;    /* First Track/Session */
1998         buffer[3] = 0x01;    /* Last Track/Session */
1999         off = 4;
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;
2005                 /* Track Number */
2006                 buffer[off+2] = 0x01;
2007                 off += 8;
2008         }
2009         if (!(cmd->cdb[2] & 0x01)) {
2010                 /* Lead-out area TOC Track Descriptor */
2011                 buffer[off+1] = 0x14;
2012                 /* Track Number */
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;
2019                 off += 8;
2020         }
2021
2022         buffer[1] = off - 2;    /* Data  Length */
2023
2024         if (off > length)
2025                 off = length;
2026         memcpy(address, buffer, off);
2027
2028         scst_put_buf(cmd, address);
2029
2030         if (off < cmd->resp_data_len)
2031                 scst_set_resp_data_len(cmd, off);
2032
2033 out:
2034         TRACE_EXIT();
2035         return;
2036 }
2037
2038 static void vdisk_exec_prevent_allow_medium_removal(struct scst_cmd *cmd)
2039 {
2040         struct scst_vdisk_dev *virt_dev =
2041                 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2042
2043         TRACE_DBG("PERSIST/PREVENT 0x%02x", cmd->cdb[4]);
2044
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);
2050         }
2051
2052         return;
2053 }
2054
2055 static int vdisk_fsync(struct scst_vdisk_thr *thr,
2056         loff_t loff, loff_t len, struct scst_cmd *cmd)
2057 {
2058         int res = 0;
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;
2064
2065         TRACE_ENTRY();
2066
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)
2070                 goto out;
2071
2072         inode = file->f_dentry->d_inode;
2073         mapping = file->f_mapping;
2074
2075         res = sync_page_range(inode, mapping, loff, len);
2076         if (unlikely(res != 0)) {
2077                 PRINT_ERROR("sync_page_range() failed (%d)", res);
2078                 if (cmd != NULL) {
2079                         scst_set_cmd_error(cmd,
2080                                 SCST_LOAD_SENSE(scst_sense_write_error));
2081                 }
2082         }
2083
2084         /* ToDo: flush the device cache, if needed */
2085
2086 out:
2087         TRACE_EXIT_RES(res);
2088         return res;
2089 }
2090
2091 static struct iovec *vdisk_alloc_iv(struct scst_cmd *cmd,
2092         struct scst_vdisk_thr *thr)
2093 {
2094         int iv_count;
2095
2096         iv_count = scst_get_buf_count(cmd);
2097         if (iv_count > thr->iv_count) {
2098                 kfree(thr->iv);
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);
2103                         scst_set_busy(cmd);
2104                         goto out;
2105                 }
2106                 thr->iv_count = iv_count;
2107         }
2108
2109 out:
2110         return thr->iv;
2111 }
2112
2113 /*
2114  * copied from <ksrc>/fs/read_write.*
2115  */
2116 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
2117 static void wait_on_retry_sync_kiocb(struct kiocb *iocb)
2118 {
2119         set_current_state(TASK_UNINTERRUPTIBLE);
2120         if (!kiocbIsKicked(iocb))
2121                 schedule();
2122         else
2123                 kiocbClearKicked(iocb);
2124         __set_current_state(TASK_RUNNING);
2125 }
2126
2127 typedef ssize_t (*iov_fn_t)(struct kiocb *, const struct iovec *,
2128                                 unsigned long, loff_t);
2129
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)
2132 {
2133         struct kiocb kiocb;
2134         ssize_t ret;
2135
2136         init_sync_kiocb(&kiocb, filp);
2137         kiocb.ki_pos = *ppos;
2138         kiocb.ki_left = len;
2139         kiocb.ki_nbytes = len;
2140
2141         for (;;) {
2142                 ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos);
2143                 if (ret != -EIOCBRETRY)
2144                         break;
2145                 wait_on_retry_sync_kiocb(&kiocb);
2146         }
2147
2148         if (ret == -EIOCBQUEUED)
2149                 ret = wait_on_sync_kiocb(&kiocb);
2150         *ppos = kiocb.ki_pos;
2151         return ret;
2152 }
2153 #endif
2154
2155 static void vdisk_exec_read(struct scst_cmd *cmd,
2156         struct scst_vdisk_thr *thr, loff_t loff)
2157 {
2158         mm_segment_t old_fs;
2159         loff_t err;
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;
2165         struct iovec *iv;
2166         int iv_count, i;
2167
2168         TRACE_ENTRY();
2169
2170         if (virt_dev->nullio)
2171                 goto out;
2172
2173         iv = vdisk_alloc_iv(cmd, thr);
2174         if (iv == NULL)
2175                 goto out;
2176
2177         iv_count = 0;
2178         full_len = 0;
2179         i = -1;
2180         length = scst_get_buf_first(cmd, (uint8_t __force **)&address);
2181         while (length > 0) {
2182                 full_len += length;
2183                 i++;
2184                 iv_count++;
2185                 iv[i].iov_base = address;
2186                 iv[i].iov_len = length;
2187                 length = scst_get_buf_next(cmd, (uint8_t __force **)&address);
2188         }
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));
2193                 goto out_put;
2194         }
2195
2196         old_fs = get_fs();
2197         set_fs(get_ds());
2198
2199         TRACE_DBG("reading(iv_count %d, full_len %zd)", iv_count, full_len);
2200         /* SEEK */
2201         if (fd->f_op->llseek)
2202                 err = fd->f_op->llseek(fd, loff, 0/*SEEK_SET*/);
2203         else
2204                 err = default_llseek(fd, loff, 0/*SEEK_SET*/);
2205         if (err != loff) {
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));
2211                 goto out_set_fs;
2212         }
2213
2214         /* READ */
2215 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
2216         err = fd->f_op->readv(fd, iv, iv_count, &fd->f_pos);
2217 #else
2218         err = do_sync_readv_writev(fd, iv, iv_count, full_len,
2219                                    &fd->f_pos, fd->f_op->aio_read);
2220 #endif
2221
2222         if ((err < 0) || (err < full_len)) {
2223                 PRINT_ERROR("readv() returned %lld from %zd",
2224                             (long long unsigned int)err,
2225                             full_len);
2226                 if (err == -EAGAIN)
2227                         scst_set_busy(cmd);
2228                 else {
2229                         scst_set_cmd_error(cmd,
2230                             SCST_LOAD_SENSE(scst_sense_read_error));
2231                 }
2232                 goto out_set_fs;
2233         }
2234
2235 out_set_fs:
2236         set_fs(old_fs);
2237
2238 out_put:
2239         for (; i >= 0; i--)
2240                 scst_put_buf(cmd, (void __force *)(iv[i].iov_base));
2241
2242 out:
2243         TRACE_EXIT();
2244         return;
2245 }
2246
2247 static void vdisk_exec_write(struct scst_cmd *cmd,
2248         struct scst_vdisk_thr *thr, loff_t loff)
2249 {
2250         mm_segment_t old_fs;
2251         loff_t err;
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;
2259
2260         TRACE_ENTRY();
2261
2262         if (virt_dev->nullio)
2263                 goto out;
2264
2265         iv = vdisk_alloc_iv(cmd, thr);
2266         if (iv == NULL)
2267                 goto out;
2268
2269         iv_count = 0;
2270         full_len = 0;
2271         length = scst_get_buf_first(cmd, (uint8_t __force **)&address);
2272         while (length > 0) {
2273                 full_len += length;
2274                 iv[iv_count].iov_base = address;
2275                 iv[iv_count].iov_len = length;
2276                 iv_count++;
2277                 length = scst_get_buf_next(cmd, (uint8_t __force **)&address);
2278         }
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));
2283                 goto out_put;
2284         }
2285
2286         old_fs = get_fs();
2287         set_fs(get_ds());
2288
2289         eiv = iv;
2290         eiv_count = iv_count;
2291 restart:
2292         TRACE_DBG("writing(eiv_count %d, full_len %zd)", eiv_count, full_len);
2293
2294         /* SEEK */
2295         if (fd->f_op->llseek)
2296                 err = fd->f_op->llseek(fd, loff, 0 /*SEEK_SET */);
2297         else
2298                 err = default_llseek(fd, loff, 0 /*SEEK_SET */);
2299         if (err != loff) {
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));
2305                 goto out_set_fs;
2306         }
2307
2308         /* WRITE */
2309 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
2310         err = fd->f_op->writev(fd, eiv, eiv_count, &fd->f_pos);
2311 #else
2312         err = do_sync_readv_writev(fd, iv, iv_count, full_len, &fd->f_pos,
2313                                         fd->f_op->aio_write);
2314 #endif
2315
2316         if (err < 0) {
2317                 PRINT_ERROR("write() returned %lld from %zd",
2318                             (long long unsigned int)err,
2319                             full_len);
2320                 if (err == -EAGAIN)
2321                         scst_set_busy(cmd);
2322                 else {
2323                         scst_set_cmd_error(cmd,
2324                             SCST_LOAD_SENSE(scst_sense_write_error));
2325                 }
2326                 goto out_set_fs;
2327         } else if (err < full_len) {
2328                 /*
2329                  * Probably that's wrong, but sometimes write() returns
2330                  * value less, than requested. Let's restart.
2331                  */
2332                 int i, e = eiv_count;
2333                 TRACE_MGMT_DBG("write() returned %d from %zd "
2334                         "(iv_count=%d)", (int)err, full_len,
2335                         eiv_count);
2336                 if (err == 0) {
2337                         PRINT_INFO("Suspicious: write() returned 0 from "
2338                                 "%zd (iv_count=%d)", full_len, eiv_count);
2339                 }
2340                 full_len -= err;
2341                 for (i = 0; i < e; i++) {
2342                         if ((long long)eiv->iov_len < err) {
2343                                 err -= eiv->iov_len;
2344                                 eiv++;
2345                                 eiv_count--;
2346                         } else {
2347                                 eiv->iov_base =
2348                                         (uint8_t __force __user *)eiv->iov_base +
2349                                         err;
2350                                 eiv->iov_len -= err;
2351                                 break;
2352                         }
2353                 }
2354                 goto restart;
2355         }
2356
2357 out_set_fs:
2358         set_fs(old_fs);
2359
2360 out_put:
2361         while (iv_count > 0) {
2362                 scst_put_buf(cmd, (void __force *)(iv[iv_count-1].iov_base));
2363                 iv_count--;
2364         }
2365
2366 out:
2367         TRACE_EXIT();
2368         return;
2369 }
2370
2371 struct scst_blockio_work {
2372         atomic_t bios_inflight;
2373         struct scst_cmd *cmd;
2374 };
2375
2376 static inline void blockio_check_finish(struct scst_blockio_work *blockio_work)
2377 {
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);
2384         }
2385         return;
2386 }
2387
2388 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
2389 static int blockio_endio(struct bio *bio, unsigned int bytes_done, int error)
2390 #else
2391 static void blockio_endio(struct bio *bio, int error)
2392 #endif
2393 {
2394         struct scst_blockio_work *blockio_work = bio->bi_private;
2395
2396 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
2397         if (bio->bi_size)
2398                 return 1;
2399 #endif
2400
2401         error = test_bit(BIO_UPTODATE, &bio->bi_flags) ? error : -EIO;
2402
2403         if (unlikely(error != 0)) {
2404                 PRINT_ERROR("cmd %p returned error %d", blockio_work->cmd,
2405                         error);
2406                 /*
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
2409                  * operations.
2410                  */
2411                 if (bio->bi_rw & WRITE)
2412                         scst_set_cmd_error(blockio_work->cmd,
2413                                 SCST_LOAD_SENSE(scst_sense_write_error));
2414                 else
2415                         scst_set_cmd_error(blockio_work->cmd,
2416                                 SCST_LOAD_SENSE(scst_sense_read_error));
2417         }
2418
2419         blockio_check_finish(blockio_work);
2420
2421         bio_put(bio);
2422 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
2423         return 0;
2424 #else
2425         return;
2426 #endif
2427 }
2428
2429 static void blockio_exec_rw(struct scst_cmd *cmd, struct scst_vdisk_thr *thr,
2430         u64 lba_start, int write)
2431 {
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;
2437         uint8_t *address;
2438         struct bio *bio = NULL, *hbio = NULL, *tbio = NULL;
2439         int need_new_bio;
2440         struct scst_blockio_work *blockio_work;
2441         int bios = 0;
2442
2443         TRACE_ENTRY();
2444
2445         if (virt_dev->nullio)
2446                 goto out;
2447
2448         /* Allocate and initialize blockio_work struct */
2449         blockio_work = kmem_cache_alloc(blockio_work_cachep, GFP_KERNEL);
2450         if (blockio_work == NULL)
2451                 goto out_no_mem;
2452
2453         blockio_work->cmd = cmd;
2454
2455         if (q)
2456                 max_nr_vecs = min(bio_get_nr_vecs(bdev), BIO_MAX_PAGES);
2457         else
2458                 max_nr_vecs = 1;
2459
2460         need_new_bio = 1;
2461
2462         length = scst_get_buf_first(cmd, &address);
2463         while (length > 0) {
2464                 int len, bytes, off, thislen;
2465                 uint8_t *addr;
2466                 u64 lba_start0;
2467
2468                 addr = address;
2469                 off = offset_in_page(addr);
2470                 len = length;
2471                 thislen = 0;
2472                 lba_start0 = lba_start;
2473
2474                 while (len > 0) {
2475                         int rc;
2476                         struct page *page = virt_to_page(addr);
2477
2478                         if (need_new_bio) {
2479                                 bio = bio_alloc(GFP_KERNEL, max_nr_vecs);
2480                                 if (!bio) {
2481                                         PRINT_ERROR("Failed to create bio "
2482                                                 "for data segment= %d cmd %p",
2483                                                 cmd->get_sg_buf_entry_num, cmd);
2484                                         goto out_no_bio;
2485                                 }
2486
2487                                 bios++;
2488                                 need_new_bio = 0;
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;
2496 #endif
2497                                 if (!hbio)
2498                                         hbio = tbio = bio;
2499                                 else
2500                                         tbio = tbio->bi_next = bio;
2501                         }
2502
2503                         bytes = min_t(unsigned int, len, PAGE_SIZE - off);
2504
2505                         rc = bio_add_page(bio, page, bytes, off);
2506                         if (rc < bytes) {
2507                                 sBUG_ON(rc != 0);
2508                                 need_new_bio = 1;
2509                                 lba_start0 += thislen >> virt_dev->block_shift;
2510                                 thislen = 0;
2511                                 continue;
2512                         }
2513
2514                         addr += PAGE_SIZE;
2515                         thislen += bytes;
2516                         len -= bytes;
2517                         off = 0;
2518                 }
2519
2520                 lba_start += length >> virt_dev->block_shift;
2521
2522                 scst_put_buf(cmd, address);
2523                 length = scst_get_buf_next(cmd, &address);
2524         }
2525
2526         /* +1 to prevent erroneous too early command completion */
2527         atomic_set(&blockio_work->bios_inflight, bios+1);
2528
2529         while (hbio) {
2530                 bio = hbio;
2531                 hbio = hbio->bi_next;
2532                 bio->bi_next = NULL;
2533                 submit_bio(write, bio);
2534         }
2535
2536         if (q && q->unplug_fn)
2537                 q->unplug_fn(q);
2538
2539         blockio_check_finish(blockio_work);
2540
2541 out:
2542         TRACE_EXIT();
2543         return;
2544
2545 out_no_bio:
2546         while (hbio) {
2547                 bio = hbio;
2548                 hbio = hbio->bi_next;
2549                 bio_put(bio);
2550         }
2551         kmem_cache_free(blockio_work_cachep, blockio_work);
2552
2553 out_no_mem:
2554         scst_set_busy(cmd);
2555         goto out;
2556 }
2557
2558 static void vdisk_exec_verify(struct scst_cmd *cmd,
2559         struct scst_vdisk_thr *thr, loff_t loff)
2560 {
2561         mm_segment_t old_fs;
2562         loff_t err;
2563         ssize_t length, len_mem = 0;
2564         uint8_t *address_sav, *address;
2565         int compare;
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;
2570
2571         TRACE_ENTRY();
2572
2573         if (vdisk_fsync(thr, loff, cmd->bufflen, cmd) != 0)
2574                 goto out;
2575
2576         /*
2577          * Until the cache is cleared prior the verifying, there is not
2578          * much point in this code. ToDo.
2579          *
2580          * Nevertherless, this code is valuable if the data have not read
2581          * from the file/disk yet.
2582          */
2583
2584         /* SEEK */
2585         old_fs = get_fs();
2586         set_fs(get_ds());
2587
2588         if (!virt_dev->nullio) {
2589                 if (fd->f_op->llseek)
2590                         err = fd->f_op->llseek(fd, loff, 0/*SEEK_SET*/);
2591                 else
2592                         err = default_llseek(fd, loff, 0/*SEEK_SET*/);
2593                 if (err != loff) {
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));
2599                         goto out_set_fs;
2600                 }
2601         }
2602
2603         mem_verify = vmalloc(LEN_MEM);
2604         if (mem_verify == NULL) {
2605                 PRINT_ERROR("Unable to allocate memory %d for verify",
2606                                LEN_MEM);
2607                 scst_set_cmd_error(cmd,
2608                                    SCST_LOAD_SENSE(scst_sense_hardw_error));
2609                 goto out_set_fs;
2610         }
2611
2612         length = scst_get_buf_first(cmd, &address);
2613         address_sav = address;
2614         if (!length && cmd->data_len) {
2615                 length = cmd->data_len;
2616                 compare = 0;
2617         } else
2618                 compare = 1;
2619
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);
2623
2624                 if (!virt_dev->nullio)
2625                         err = fd->f_op->read(fd,
2626                                 (char __force __user *)mem_verify, len_mem,
2627                                 &fd->f_pos);
2628                 else
2629                         err = 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);
2633                         if (err == -EAGAIN)
2634                                 scst_set_busy(cmd);
2635                         else {
2636                                 scst_set_cmd_error(cmd,
2637                                     SCST_LOAD_SENSE(scst_sense_read_error));
2638                         }
2639                         if (compare)
2640                                 scst_put_buf(cmd, address_sav);
2641                         goto out_set_fs;
2642                 }
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);
2648                         goto out_set_fs;
2649                 }
2650                 length -= len_mem;
2651                 address += len_mem;
2652                 if (compare && length <= 0) {
2653                         scst_put_buf(cmd, address_sav);
2654                         length = scst_get_buf_next(cmd, &address);
2655                         address_sav = address;
2656                 }
2657         }
2658
2659         if (length < 0) {
2660                 PRINT_ERROR("scst_get_buf_() failed: %zd", length);
2661                 scst_set_cmd_error(cmd,
2662                     SCST_LOAD_SENSE(scst_sense_hardw_error));
2663         }
2664
2665 out_set_fs:
2666         set_fs(old_fs);
2667         if (mem_verify)
2668                 vfree(mem_verify);
2669
2670 out:
2671         TRACE_EXIT();
2672         return;
2673 }
2674
2675 static inline struct scst_vdisk_dev *vdisk_alloc_dev(void)
2676 {
2677         struct scst_vdisk_dev *dev;
2678         dev = kzalloc(sizeof(*dev), GFP_KERNEL);
2679         if (dev == NULL) {
2680                 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of virtual "
2681                         "device failed");
2682                 goto out;
2683         }
2684         spin_lock_init(&dev->flags_lock);
2685 out:
2686         return dev;
2687 }
2688
2689 static int vdisk_task_mgmt_fn(struct scst_mgmt_cmd *mcmd,
2690         struct scst_tgt_dev *tgt_dev)
2691 {
2692         TRACE_ENTRY();
2693
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;
2699
2700                 dev->tst = DEF_TST;
2701                 dev->d_sense = DEF_DSENSE;
2702                 if (virt_dev->wt_flag && !virt_dev->nv_cache)
2703                         dev->queue_alg = DEF_QUEUE_ALG_WT;
2704                 else
2705                         dev->queue_alg = DEF_QUEUE_ALG;
2706                 dev->swp = DEF_SWP;
2707                 dev->tas = DEF_TAS;
2708
2709                 virt_dev->prevent_allow_medium_removal = 0;
2710         }
2711
2712         TRACE_EXIT();
2713         return SCST_DEV_TM_NOT_COMPLETED;
2714 }
2715
2716 /*
2717  * Called when a file in the /proc/VDISK_NAME/VDISK_NAME is read
2718  */
2719 static int vdisk_read_proc(struct seq_file *seq, struct scst_dev_type *dev_type)
2720 {
2721         int res = 0;
2722         struct scst_vdisk_dev *virt_dev;
2723
2724         TRACE_ENTRY();
2725
2726         if (mutex_lock_interruptible(&scst_vdisk_mutex) != 0) {
2727                 res = -EINTR;
2728                 goto out;
2729         }
2730
2731         seq_printf(seq, "%-17s %-11s %-11s %-15s %s\n",
2732                    "Name", "Size(MB)", "Block size", "Options", "File name");
2733
2734         list_for_each_entry(virt_dev, &vdisk_dev_list, vdisk_dev_list_entry) {
2735                 int c;
2736                 seq_printf(seq, "%-17s %-11d %-12d", virt_dev->name,
2737                         (uint32_t)(virt_dev->file_size >> 20),
2738                         virt_dev->block_size);
2739                 c = 0;
2740                 if (virt_dev->wt_flag) {
2741                         seq_printf(seq, "WT ");
2742                         c += 3;
2743                 }
2744                 if (virt_dev->nv_cache) {
2745                         seq_printf(seq, "NV ");
2746                         c += 3;
2747                 }
2748                 if (virt_dev->dev != NULL) {
2749                         if (virt_dev->dev->rd_only) {
2750                                 seq_printf(seq, "RO ");
2751                                 c += 3;
2752                         }
2753                 } else if (virt_dev->rd_only) {
2754                         seq_printf(seq, "RO ");
2755                         c += 3;
2756                 }
2757                 if (virt_dev->o_direct_flag) {
2758                         seq_printf(seq, "DR ");
2759                         c += 3;
2760                 }
2761                 if (virt_dev->nullio) {
2762                         seq_printf(seq, "NIO ");
2763                         c += 4;
2764                 }
2765                 if (virt_dev->blockio) {
2766                         seq_printf(seq, "BIO ");
2767                         c += 4;
2768                 }
2769                 if (virt_dev->removable) {
2770                         seq_printf(seq, "RM ");
2771                         c += 4;
2772                 }
2773                 while (c < 16) {
2774                         seq_printf(seq, " ");
2775                         c++;
2776                 }
2777                 seq_printf(seq, "%s\n", virt_dev->file_name);
2778         }
2779         mutex_unlock(&scst_vdisk_mutex);
2780 out:
2781         TRACE_EXIT_RES(res);
2782         return res;
2783 }
2784
2785 static void vdisk_report_registering(const char *type,
2786         const struct scst_vdisk_dev *virt_dev)
2787 {
2788         char buf[128];
2789         int i, j;
2790
2791         i = snprintf(buf, sizeof(buf), "Registering virtual %s device %s ",
2792                 type, virt_dev->name);
2793         j = i;
2794
2795         if (virt_dev->wt_flag)
2796                 i += snprintf(&buf[i], sizeof(buf) - i, "(WRITE_THROUGH");
2797
2798         if (virt_dev->nv_cache)
2799                 i += snprintf(&buf[i], sizeof(buf) - i, "%sNV_CACHE",
2800                         (j == i) ? "(" : ", ");
2801
2802         if (virt_dev->rd_only)
2803                 i += snprintf(&buf[i], sizeof(buf) - i, "%sREAD_ONLY",
2804                         (j == i) ? "(" : ", ");
2805
2806         if (virt_dev->o_direct_flag)
2807                 i += snprintf(&buf[i], sizeof(buf) - i, "%sO_DIRECT",
2808                         (j == i) ? "(" : ", ");
2809
2810         if (virt_dev->nullio)
2811                 i += snprintf(&buf[i], sizeof(buf) - i, "%sNULLIO",
2812                         (j == i) ? "(" : ", ");
2813
2814         if (virt_dev->blockio)
2815                 i += snprintf(&buf[i], sizeof(buf) - i, "%sBLOCKIO",
2816                         (j == i) ? "(" : ", ");
2817
2818         if (virt_dev->removable)
2819                 i += snprintf(&buf[i], sizeof(buf) - i, "%sREMOVABLE",
2820                         (j == i) ? "(" : ", ");
2821
2822         if (j == i)
2823                 PRINT_INFO("%s", buf);
2824         else
2825                 PRINT_INFO("%s)", buf);
2826
2827         return;
2828 }
2829
2830 /* scst_vdisk_mutex supposed to be held */
2831 static int vdisk_resync_size(struct scst_vdisk_dev *virt_dev)
2832 {
2833         loff_t err;
2834         int res = 0;
2835
2836         if (!virt_dev->nullio) {
2837                 res = vdisk_get_check_file_size(virt_dev->file_name,
2838                                 virt_dev->blockio, &err);
2839                 if (res != 0)
2840                         goto out;
2841         } else
2842                 err = VDISK_NULLIO_SIZE;
2843
2844         res = scst_suspend_activity(true);
2845         if (res != 0)
2846                 goto out;
2847
2848         virt_dev->file_size = err;
2849         virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift;
2850
2851         scst_dev_del_all_thr_data(virt_dev->dev);
2852
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 "
2860                                                 "than 1" : "");
2861
2862         scst_capacity_data_changed(virt_dev->dev);
2863
2864         scst_resume_activity();
2865
2866 out:
2867         return res;
2868 }
2869
2870 /*
2871  * Called when a file in the /proc/VDISK_NAME/VDISK_NAME is written
2872  */
2873 static int vdisk_write_proc(char *buffer, char **start, off_t offset,
2874         int length, int *eof, struct scst_dev_type *dev_type)
2875 {
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;
2881         size_t len;
2882
2883         TRACE_ENTRY();
2884
2885         /* VERY UGLY code. You can rewrite it if you want */
2886
2887         if (buffer[0] == '\0')
2888                 goto out;
2889
2890         if (mutex_lock_interruptible(&scst_vdisk_mutex) != 0) {
2891                 res = -EINTR;
2892                 goto out;
2893         }
2894
2895         p = buffer;
2896         if (p[strlen(p) - 1] == '\n')
2897                 p[strlen(p) - 1] = '\0';
2898         if (!strncmp("close ", p, 6)) {
2899                 p += 6;
2900                 action = 0;
2901         } else if (!strncmp("open ", p, 5)) {
2902                 p += 5;
2903                 action = 1;
2904         } else if (!strncmp("resync_size ", p, 12)) {
2905                 p += 12;
2906                 action = 2;
2907         } else {
2908                 PRINT_ERROR("Unknown action \"%s\"", p);
2909                 res = -EINVAL;
2910                 goto out_up;
2911         }
2912
2913         while (isspace(*p) && *p != '\0')
2914                 p++;
2915         name = p;
2916         while (!isspace(*p) && *p != '\0')
2917                 p++;
2918         *p++ = '\0';
2919         if (*name == '\0') {
2920                 PRINT_ERROR("%s", "Name required");
2921                 res = -EINVAL;
2922                 goto out_up;
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);
2926                 res = -EINVAL;
2927                 goto out_up;
2928         }
2929
2930         if (action == 1) {
2931                 /* open */
2932                 virt_dev = NULL;
2933                 list_for_each_entry(vv, &vdisk_dev_list,
2934                                         vdisk_dev_list_entry) {
2935                         if (strcmp(vv->name, name) == 0) {
2936                                 virt_dev = vv;
2937                                 break;
2938                         }
2939                 }
2940                 if (virt_dev) {
2941                         PRINT_ERROR("Virtual device with name "
2942                                    "%s already exist", name);
2943                         res = -EINVAL;
2944                         goto out_up;
2945                 }
2946
2947                 while (isspace(*p) && *p != '\0')
2948                         p++;
2949                 file_name = p;
2950                 while (!isspace(*p) && *p != '\0')
2951                         p++;
2952                 *p++ = '\0';
2953                 if (*file_name == '\0') {
2954                         PRINT_ERROR("%s", "File name required");
2955                         res = -EINVAL;
2956                         goto out_up;
2957                 }
2958
2959                 virt_dev = vdisk_alloc_dev();
2960                 if (virt_dev == NULL) {
2961                         TRACE(TRACE_OUT_OF_MEM, "%s",
2962                                   "Allocation of virt_dev failed");
2963                         res = -ENOMEM;
2964                         goto out_up;
2965                 }
2966
2967                 while (isspace(*p) && *p != '\0')
2968                         p++;
2969
2970                 if (isdigit(*p)) {
2971                         char *pp;
2972                         block_size = simple_strtoul(p, &pp, 0);
2973                         p = pp;
2974                         if ((*p != '\0') && !isspace(*p)) {
2975                                 PRINT_ERROR("Parse error: \"%s\"", p);
2976                                 res = -EINVAL;
2977                                 goto out_free_vdev;
2978                         }
2979                         while (isspace(*p) && *p != '\0')
2980                                 p++;
2981
2982                         block_shift = scst_calc_block_shift(block_size);
2983                         if (block_shift < 9) {
2984                                 res = -EINVAL;
2985                                 goto out_free_vdev;
2986                         }
2987                 }
2988                 virt_dev->block_size = block_size;
2989                 virt_dev->block_shift = block_shift;
2990
2991                 while (*p != '\0') {
2992                         if (!strncmp("WRITE_THROUGH", p, 13)) {
2993                                 p += 13;
2994                                 virt_dev->wt_flag = 1;
2995                                 TRACE_DBG("%s", "WRITE_THROUGH");
2996                         } else if (!strncmp("NV_CACHE", p, 8)) {
2997                                 p += 8;
2998                                 virt_dev->nv_cache = 1;
2999                                 TRACE_DBG("%s", "NON-VOLATILE CACHE");
3000                         } else if (!strncmp("READ_ONLY", p, 9)) {
3001                                 p += 9;
3002                                 virt_dev->rd_only = 1;
3003                                 TRACE_DBG("%s", "READ_ONLY");
3004                         } else if (!strncmp("O_DIRECT", p, 8)) {
3005                                 p += 8;
3006 #if 0
3007
3008                                 virt_dev->o_direct_flag = 1;
3009                                 TRACE_DBG("%s", "O_DIRECT");
3010 #else
3011                                 PRINT_INFO("%s flag doesn't currently"
3012                                         " work, ignoring it, use fileio_tgt "
3013                                         "in O_DIRECT mode instead", "O_DIRECT");
3014 #endif
3015                         } else if (!strncmp("NULLIO", p, 6)) {
3016                                 p += 6;
3017                                 virt_dev->nullio = 1;
3018                                 TRACE_DBG("%s", "NULLIO");
3019                         } else if (!strncmp("BLOCKIO", p, 7)) {
3020                                 p += 7;
3021                                 virt_dev->blockio = 1;
3022                                 TRACE_DBG("%s", "BLOCKIO");
3023                         } else if (!strncmp("REMOVABLE", p, 9)) {
3024                                 p += 9;
3025                                 virt_dev->removable = 1;
3026                                 TRACE_DBG("%s", "REMOVABLE");
3027                         } else {
3028                                 PRINT_ERROR("Unknown flag \"%s\"", p);
3029                                 res = -EINVAL;
3030                                 goto out_free_vdev;
3031                         }
3032                         while (isspace(*p) && *p != '\0')
3033                                 p++;
3034                 }
3035
3036                 if (!virt_dev->nullio && (*file_name != '/')) {
3037                         PRINT_ERROR("File path \"%s\" is not "
3038                                 "absolute", file_name);
3039                         res = -EINVAL;
3040                         goto out_up;
3041                 }
3042
3043                 strcpy(virt_dev->name, name);
3044
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);
3048
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");
3054                         res = -ENOMEM;
3055                         goto out_free_vdev;
3056                 }
3057                 strncpy(virt_dev->file_name, file_name, len);
3058
3059                 list_add_tail(&virt_dev->vdisk_dev_list_entry,
3060                                   &vdisk_dev_list);
3061
3062                 if (virt_dev->blockio) {
3063                         vdisk_report_registering("BLOCKIO", virt_dev);
3064                         virt_dev->virt_id =
3065                                 scst_register_virtual_device(&vdisk_blk_devtype,
3066                                                          virt_dev->name);
3067                 } else if (virt_dev->nullio) {
3068                         vdisk_report_registering("NULLIO", virt_dev);
3069                         virt_dev->virt_id =
3070                                scst_register_virtual_device(&vdisk_null_devtype,
3071                                                          virt_dev->name);
3072                 } else {
3073                         vdisk_report_registering("FILEIO", virt_dev);
3074                         virt_dev->virt_id =
3075                                scst_register_virtual_device(&vdisk_file_devtype,
3076                                                          virt_dev->name);
3077                 }
3078                 if (virt_dev->virt_id < 0) {
3079                         res = virt_dev->virt_id;
3080                         goto out_free_vpath;
3081                 }
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 */
3088                 virt_dev = NULL;
3089                 list_for_each_entry(vv, &vdisk_dev_list,
3090                                         vdisk_dev_list_entry) {
3091                         if (strcmp(vv->name, name) == 0) {
3092                                 virt_dev = vv;
3093                                 break;
3094                         }
3095                 }
3096                 if (virt_dev == NULL) {
3097                         PRINT_ERROR("Device %s not found", name);
3098                         res = -EINVAL;
3099                         goto out_up;
3100                 }
3101                 scst_unregister_virtual_device(virt_dev->virt_id);
3102                 PRINT_INFO("Virtual device %s unregistered",
3103                         virt_dev->name);
3104                 TRACE_DBG("virt_id %d unregister", virt_dev->virt_id);
3105
3106                 list_del(&virt_dev->vdisk_dev_list_entry);
3107
3108                 kfree(virt_dev->file_name);
3109                 kfree(virt_dev);
3110         } else {        /* resync_size */
3111                 virt_dev = NULL;
3112                 list_for_each_entry(vv, &vdisk_dev_list,
3113                                         vdisk_dev_list_entry) {
3114                         if (strcmp(vv->name, name) == 0) {
3115                                 virt_dev = vv;
3116                                 break;
3117                         }
3118                 }
3119                 if (virt_dev == NULL) {
3120                         PRINT_ERROR("Device %s not found", name);
3121                         res = -EINVAL;
3122                         goto out_up;
3123                 }
3124
3125                 res = vdisk_resync_size(virt_dev);
3126                 if (res != 0)
3127                         goto out_up;
3128         }
3129         res = length;
3130
3131 out_up:
3132         mutex_unlock(&scst_vdisk_mutex);
3133
3134 out:
3135         TRACE_EXIT_RES(res);
3136         return res;
3137
3138 out_free_vpath:
3139         list_del(&virt_dev->vdisk_dev_list_entry);
3140         kfree(virt_dev->file_name);
3141
3142 out_free_vdev:
3143         kfree(virt_dev);
3144         goto out_up;
3145 }
3146
3147 /* scst_vdisk_mutex supposed to be held */
3148 static int vcdrom_open(char *p, char *name)
3149 {
3150         struct scst_vdisk_dev *virt_dev, *vv;
3151         char *file_name;
3152         int len;
3153         int res = 0;
3154         int cdrom_empty;
3155
3156         virt_dev = NULL;
3157         list_for_each_entry(vv, &vcdrom_dev_list, vdisk_dev_list_entry)
3158         {
3159                 if (strcmp(vv->name, name) == 0) {
3160                         virt_dev = vv;
3161                         break;
3162                 }
3163         }
3164         if (virt_dev) {
3165                 PRINT_ERROR("Virtual device with name "
3166                        "%s already exist", name);
3167                 res = -EINVAL;
3168                 goto out;
3169         }
3170
3171         while (isspace(*p) && *p != '\0')
3172                 p++;
3173         file_name = p;
3174         while (!isspace(*p) && *p != '\0')
3175                 p++;
3176         *p++ = '\0';
3177         if (*file_name == '\0') {
3178                 cdrom_empty = 1;
3179                 TRACE_DBG("%s", "No media");
3180         } else if (*file_name != '/') {
3181                 PRINT_ERROR("File path \"%s\" is not "
3182                         "absolute", file_name);
3183                 res = -EINVAL;
3184                 goto out;
3185         } else
3186                 cdrom_empty = 0;
3187
3188         virt_dev = vdisk_alloc_dev();
3189         if (virt_dev == NULL) {
3190                 TRACE(TRACE_OUT_OF_MEM, "%s",
3191                       "Allocation of virt_dev failed");
3192                 res = -ENOMEM;
3193                 goto out;
3194         }
3195         virt_dev->cdrom_empty = cdrom_empty;
3196
3197         strcpy(virt_dev->name, name);
3198
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);
3202
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");
3209                         res = -ENOMEM;
3210                         goto out_free_vdev;
3211                 }
3212                 strncpy(virt_dev->file_name, file_name, len);
3213         }
3214
3215         list_add_tail(&virt_dev->vdisk_dev_list_entry,
3216                       &vcdrom_dev_list);
3217
3218         PRINT_INFO("Registering virtual CDROM %s", name);
3219
3220         virt_dev->virt_id =
3221             scst_register_virtual_device(&vcdrom_devtype,
3222                                          virt_dev->name);
3223         if (virt_dev->virt_id < 0) {
3224                 res = virt_dev->virt_id;
3225                 goto out_free_vpath;
3226         }
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);
3230
3231 out:
3232         return res;
3233
3234 out_free_vpath:
3235         list_del(&virt_dev->vdisk_dev_list_entry);
3236         kfree(virt_dev->file_name);
3237
3238 out_free_vdev:
3239         kfree(virt_dev);
3240         goto out;
3241 }
3242
3243 /* scst_vdisk_mutex supposed to be held */
3244 static int vcdrom_close(char *name)
3245 {
3246         struct scst_vdisk_dev *virt_dev, *vv;
3247         int res = 0;
3248
3249         virt_dev = NULL;
3250         list_for_each_entry(vv, &vcdrom_dev_list,
3251                             vdisk_dev_list_entry)
3252         {
3253                 if (strcmp(vv->name, name) == 0) {
3254                         virt_dev = vv;
3255                         break;
3256                 }
3257         }
3258         if (virt_dev == NULL) {
3259                 PRINT_ERROR("Virtual device with name "
3260                        "%s not found", name);
3261                 res = -EINVAL;
3262                 goto out;
3263         }
3264         scst_unregister_virtual_device(virt_dev->virt_id);
3265         PRINT_INFO("Virtual device %s unregistered",
3266                 virt_dev->name);
3267         TRACE_DBG("virt_id %d unregister", virt_dev->virt_id);
3268
3269         list_del(&virt_dev->vdisk_dev_list_entry);
3270
3271         kfree(virt_dev->file_name);
3272         kfree(virt_dev);
3273
3274 out:
3275         return res;
3276 }
3277
3278 /* scst_vdisk_mutex supposed to be held */
3279 static int vcdrom_change(char *p, char *name)
3280 {
3281         loff_t err;
3282         struct scst_vdisk_dev *virt_dev, *vv;
3283         char *file_name, *fn = NULL, *old_fn;
3284         int len;
3285         int res = 0;
3286
3287         virt_dev = NULL;
3288         list_for_each_entry(vv, &vcdrom_dev_list,
3289                             vdisk_dev_list_entry) {
3290                 if (strcmp(vv->name, name) == 0) {
3291                         virt_dev = vv;
3292                         break;
3293                 }
3294         }
3295         if (virt_dev == NULL) {
3296                 PRINT_ERROR("Virtual device with name "
3297                        "%s not found", name);
3298                 res = -EINVAL;
3299                 goto out;
3300         }
3301
3302         while (isspace(*p) && *p != '\0')
3303                 p++;
3304         file_name = p;
3305         while (!isspace(*p) && *p != '\0')
3306                 p++;
3307         *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);
3314                 res = -EINVAL;
3315                 goto out;
3316         } else
3317                 virt_dev->cdrom_empty = 0;
3318
3319         old_fn = virt_dev->file_name;
3320
3321         if (!virt_dev->cdrom_empty && !virt_dev->nullio) {
3322                 len = strlen(file_name) + 1;
3323                 fn = kmalloc(len, GFP_KERNEL);
3324                 if (fn == NULL) {
3325                         TRACE(TRACE_OUT_OF_MEM, "%s",
3326                                 "Allocation of file_name failed");
3327                         res = -ENOMEM;
3328                         goto out;
3329                 }
3330
3331                 strncpy(fn, file_name, len);
3332                 virt_dev->file_name = fn;
3333
3334                 res = vdisk_get_check_file_size(virt_dev->file_name,
3335                                 virt_dev->blockio, &err);
3336                 if (res != 0)
3337                         goto out_free;
3338         } else {
3339                 err = 0;
3340                 virt_dev->file_name = NULL;
3341         }
3342
3343          if (virt_dev->nullio)
3344                 err = VDISK_NULLIO_SIZE;
3345
3346         res = scst_suspend_activity(true);
3347         if (res != 0)
3348                 goto out_free;
3349
3350         if (virt_dev->prevent_allow_medium_removal) {
3351                 PRINT_ERROR("Prevent medium removal for "
3352                         "virtual device with name %s", name);
3353                 res = -EINVAL;
3354                 goto out_free_resume;
3355         }
3356
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;
3361
3362         scst_dev_del_all_thr_data(virt_dev->dev);
3363
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 "
3372                                                         "than 1" : "");
3373         } else {
3374                 PRINT_INFO("Removed media from SCSI target virtual cdrom %s",
3375                         virt_dev->name);
3376         }
3377
3378         kfree(old_fn);
3379
3380 out_resume:
3381         scst_resume_activity();
3382
3383 out:
3384         return res;
3385
3386 out_free:
3387         virt_dev->file_name = old_fn;
3388         kfree(fn);
3389         goto out;
3390
3391 out_free_resume:
3392         virt_dev->file_name = old_fn;
3393         kfree(fn);
3394         goto out_resume;
3395 }
3396
3397 /*
3398  * Called when a file in the /proc/VCDROM_NAME/VCDROM_NAME is read
3399  */
3400 static int vcdrom_read_proc(struct seq_file *seq,
3401                             struct scst_dev_type *dev_type)
3402 {
3403         int res = 0;
3404         struct scst_vdisk_dev *virt_dev;
3405
3406         TRACE_ENTRY();
3407
3408         if (mutex_lock_interruptible(&scst_vdisk_mutex) != 0) {
3409                 res = -EINTR;
3410                 goto out;
3411         }
3412
3413         seq_printf(seq, "%-17s %-9s %s\n", "Name", "Size(MB)", "File name");
3414
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);
3420         }
3421
3422         mutex_unlock(&scst_vdisk_mutex);
3423
3424 out:
3425         TRACE_EXIT_RES(res);
3426         return res;
3427 }
3428
3429 /*
3430  * Called when a file in the /proc/VCDROM_NAME/VCDROM_NAME is written
3431  */
3432 static int vcdrom_write_proc(char *buffer, char **start, off_t offset,
3433         int length, int *eof, struct scst_dev_type *dev_type)
3434 {
3435         int res = 0, action;
3436         char *p, *name;
3437         struct scst_vdisk_dev *virt_dev;
3438
3439         TRACE_ENTRY();
3440
3441         if (mutex_lock_interruptible(&scst_vdisk_mutex) != 0) {
3442