- Use vfs_readv/vfs_writev instead of direct calls to VFS functions
[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/list.h>
34 #include <linux/ctype.h>
35 #include <linux/writeback.h>
36 #include <linux/vmalloc.h>
37 #include <asm/atomic.h>
38 #include <linux/kthread.h>
39 #include <linux/sched.h>
40 #include <linux/version.h>
41 #include <asm/div64.h>
42
43 #define LOG_PREFIX                      "dev_vdisk"
44
45 #include "scst.h"
46
47 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
48
49 #define TRACE_ORDER     0x80000000
50
51 static struct scst_trace_log vdisk_local_trace_tbl[] =
52 {
53     { TRACE_ORDER,              "order" },
54     { 0,                        NULL }
55 };
56 #define trace_log_tbl                   vdisk_local_trace_tbl
57
58 #define VDISK_TRACE_TLB_HELP    ", order"
59
60 #endif
61
62 #include "scst_dev_handler.h"
63
64 /* 8 byte ASCII Vendor */
65 #define SCST_FIO_VENDOR                 "SCST_FIO"
66 #define SCST_BIO_VENDOR                 "SCST_BIO"
67 /* 4 byte ASCII Product Revision Level - left aligned */
68 #define SCST_FIO_REV                    " 200"
69
70 #define MAX_USN_LEN                     (20+1) /* For '\0' */
71
72 #define INQ_BUF_SZ                      128
73 #define EVPD                            0x01
74 #define CMDDT                           0x02
75
76 #define MSENSE_BUF_SZ                   256
77 #define DBD                             0x08    /* disable block descriptor */
78 #define WP                              0x80    /* write protect */
79 #define DPOFUA                          0x10    /* DPOFUA bit */
80 #define WCE                             0x04    /* write cache enable */
81
82 #define PF                              0x10    /* page format */
83 #define SP                              0x01    /* save pages */
84 #define PS                              0x80    /* parameter saveable */
85
86 #define BYTE                            8
87 #define DEF_DISK_BLOCKSIZE_SHIFT        9
88 #define DEF_DISK_BLOCKSIZE              (1 << DEF_DISK_BLOCKSIZE_SHIFT)
89 #define DEF_CDROM_BLOCKSIZE_SHIFT       11
90 #define DEF_CDROM_BLOCKSIZE             (1 << DEF_CDROM_BLOCKSIZE_SHIFT)
91 #define DEF_SECTORS                     56
92 #define DEF_HEADS                       255
93 #define LEN_MEM                         (32 * 1024)
94
95 #define VDISK_NULLIO_SIZE               (3LL*1024*1024*1024*1024/2)
96
97 #define VDEV_NONE_FILENAME              "none"
98
99 #define DEF_TST                         SCST_CONTR_MODE_SEP_TASK_SETS
100 /*
101  * Since we can't control backstorage device's reordering, we have to always
102  * report unrestricted reordering.
103  */
104 #define DEF_QUEUE_ALG_WT        SCST_CONTR_MODE_QUEUE_ALG_UNRESTRICTED_REORDER
105 #define DEF_QUEUE_ALG           SCST_CONTR_MODE_QUEUE_ALG_UNRESTRICTED_REORDER
106 #define DEF_SWP                 0
107 #define DEF_TAS                 0
108
109 #define DEF_DSENSE              SCST_CONTR_MODE_FIXED_SENSE
110
111 #ifdef CONFIG_SCST_PROC
112 #define VDISK_PROC_HELP         "help"
113 #endif
114
115 static unsigned int random_values[256] = {
116             9862592UL,  3744545211UL,  2348289082UL,  4036111983UL,
117           435574201UL,  3110343764UL,  2383055570UL,  1826499182UL,
118          4076766377UL,  1549935812UL,  3696752161UL,  1200276050UL,
119          3878162706UL,  1783530428UL,  2291072214UL,   125807985UL,
120          3407668966UL,   547437109UL,  3961389597UL,   969093968UL,
121            56006179UL,  2591023451UL,     1849465UL,  1614540336UL,
122          3699757935UL,   479961779UL,  3768703953UL,  2529621525UL,
123          4157893312UL,  3673555386UL,  4091110867UL,  2193909423UL,
124          2800464448UL,  3052113233UL,   450394455UL,  3424338713UL,
125          2113709130UL,  4082064373UL,  3708640918UL,  3841182218UL,
126          3141803315UL,  1032476030UL,  1166423150UL,  1169646901UL,
127          2686611738UL,   575517645UL,  2829331065UL,  1351103339UL,
128          2856560215UL,  2402488288UL,   867847666UL,     8524618UL,
129           704790297UL,  2228765657UL,   231508411UL,  1425523814UL,
130          2146764591UL,  1287631730UL,  4142687914UL,  3879884598UL,
131           729945311UL,   310596427UL,  2263511876UL,  1983091134UL,
132          3500916580UL,  1642490324UL,  3858376049UL,   695342182UL,
133           780528366UL,  1372613640UL,  1100993200UL,  1314818946UL,
134           572029783UL,  3775573540UL,   776262915UL,  2684520905UL,
135          1007252738UL,  3505856396UL,  1974886670UL,  3115856627UL,
136          4194842288UL,  2135793908UL,  3566210707UL,     7929775UL,
137          1321130213UL,  2627281746UL,  3587067247UL,  2025159890UL,
138          2587032000UL,  3098513342UL,  3289360258UL,   130594898UL,
139          2258149812UL,  2275857755UL,  3966929942UL,  1521739999UL,
140          4191192765UL,   958953550UL,  4153558347UL,  1011030335UL,
141           524382185UL,  4099757640UL,   498828115UL,  2396978754UL,
142           328688935UL,   826399828UL,  3174103611UL,  3921966365UL,
143          2187456284UL,  2631406787UL,  3930669674UL,  4282803915UL,
144          1776755417UL,   374959755UL,  2483763076UL,   844956392UL,
145          2209187588UL,  3647277868UL,   291047860UL,  3485867047UL,
146          2223103546UL,  2526736133UL,  3153407604UL,  3828961796UL,
147          3355731910UL,  2322269798UL,  2752144379UL,   519897942UL,
148          3430536488UL,  1801511593UL,  1953975728UL,  3286944283UL,
149          1511612621UL,  1050133852UL,   409321604UL,  1037601109UL,
150          3352316843UL,  4198371381UL,   617863284UL,   994672213UL,
151          1540735436UL,  2337363549UL,  1242368492UL,   665473059UL,
152          2330728163UL,  3443103219UL,  2291025133UL,  3420108120UL,
153          2663305280UL,  1608969839UL,  2278959931UL,  1389747794UL,
154          2226946970UL,  2131266900UL,  3856979144UL,  1894169043UL,
155          2692697628UL,  3797290626UL,  3248126844UL,  3922786277UL,
156           343705271UL,  3739749888UL,  2191310783UL,  2962488787UL,
157          4119364141UL,  1403351302UL,  2984008923UL,  3822407178UL,
158          1932139782UL,  2323869332UL,  2793574182UL,  1852626483UL,
159          2722460269UL,  1136097522UL,  1005121083UL,  1805201184UL,
160          2212824936UL,  2979547931UL,  4133075915UL,  2585731003UL,
161          2431626071UL,   134370235UL,  3763236829UL,  1171434827UL,
162          2251806994UL,  1289341038UL,  3616320525UL,   392218563UL,
163          1544502546UL,  2993937212UL,  1957503701UL,  3579140080UL,
164          4270846116UL,  2030149142UL,  1792286022UL,   366604999UL,
165          2625579499UL,   790898158UL,   770833822UL,   815540197UL,
166          2747711781UL,  3570468835UL,  3976195842UL,  1257621341UL,
167          1198342980UL,  1860626190UL,  3247856686UL,   351473955UL,
168           993440563UL,   340807146UL,  1041994520UL,  3573925241UL,
169           480246395UL,  2104806831UL,  1020782793UL,  3362132583UL,
170          2272911358UL,  3440096248UL,  2356596804UL,   259492703UL,
171          3899500740UL,   252071876UL,  2177024041UL,  4284810959UL,
172          2775999888UL,  2653420445UL,  2876046047UL,  1025771859UL,
173          1994475651UL,  3564987377UL,  4112956647UL,  1821511719UL,
174          3113447247UL,   455315102UL,  1585273189UL,  2311494568UL,
175           774051541UL,  1898115372UL,  2637499516UL,   247231365UL,
176          1475014417UL,   803585727UL,  3911097303UL,  1714292230UL,
177           476579326UL,  2496900974UL,  3397613314UL,   341202244UL,
178           807790202UL,  4221326173UL,   499979741UL,  1301488547UL,
179          1056807896UL,  3525009458UL,  1174811641UL,  3049738746UL,
180 };
181
182 struct vdev_type;
183
184 struct scst_vdisk_dev {
185         uint32_t block_size;
186         uint64_t nblocks;
187         int block_shift;
188         loff_t file_size;       /* in bytes */
189
190         /*
191          * This lock can be taken on both SIRQ and thread context, but in
192          * all cases for each particular instance it's taken consistenly either
193          * on SIRQ or thread context. Mix of them is forbidden.
194          */
195         spinlock_t flags_lock;
196
197         /*
198          * Below flags are protected by flags_lock or suspended activity
199          * with scst_vdisk_mutex.
200          */
201         unsigned int rd_only:1;
202         unsigned int wt_flag:1;
203         unsigned int nv_cache:1;
204         unsigned int o_direct_flag:1;
205         unsigned int media_changed:1;
206         unsigned int prevent_allow_medium_removal:1;
207         unsigned int nullio:1;
208         unsigned int blockio:1;
209         unsigned int cdrom_empty:1;
210         unsigned int removable:1;
211
212         int virt_id;
213         char name[16+1];        /* Name of the virtual device,
214                                    must be <= SCSI Model + 1 */
215         char *file_name;        /* File name */
216         char usn[MAX_USN_LEN];
217         struct scst_device *dev;
218         struct list_head vdisk_dev_list_entry;
219
220         const struct vdev_type *vdt;
221 };
222
223 struct scst_vdisk_tgt_dev {
224         /*
225          * Used without locking since SCST core ensures that only commands
226          * with the same ORDERED type per tgt_dev can be processed
227          * simultaneously.
228          */
229         enum scst_cmd_queue_type last_write_cmd_queue_type;
230 };
231
232 struct scst_vdisk_thr {
233         struct scst_thr_data_hdr hdr;
234         struct file *fd;
235         struct block_device *bdev;
236         struct iovec *iv;
237         int iv_count;
238 };
239
240 /***
241  *** We make virtual devices emulation in OOP-like fashion: vdev is
242  *** an abstract class serving SPC set of commands and some common management
243  *** tasks, vdisk - an SBC (abstract) class with fileio, blockio and nullio
244  *** end classes, vcdrom - an MMC device class.
245  ***
246  *** Unfortunately, C doesn't support encapsulation and inheritance, so we
247  *** have to open code it, which makes the code look much less beautiful, than
248  *** it should.
249  ***
250  *** Only part to of the work is done. The second half is ToDo.
251  ***/
252
253 /* VDEV sysfs actions */
254 #define VDEV_ACTION_OPEN                0
255 #define VDEV_ACTION_CLOSE               1
256
257 /* VDISK sysfs actions */
258 #define VDISK_ACTION_RESYNC_SIZE        100
259
260 /* VCDROM sysfs actions */
261 #define VCDROM_ACTION_CHANGE            100
262
263 struct vdev_type_funcs {
264         struct scst_vdisk_dev *(*vdev_create) (struct vdev_type *vdt);
265         void (*vdev_destroy) (struct scst_vdisk_dev *virt_dev);
266
267         void (*vdev_init) (struct vdev_type *vdt,
268                 struct scst_vdisk_dev *virt_dev);
269         void (*vdev_deinit) (struct scst_vdisk_dev *virt_dev);
270
271         /* Both supposed to be called under scst_vdisk_mutex */
272         int (*vdev_open) (struct vdev_type *vdt, char *p, const char *name);
273         int (*vdev_close) (struct vdev_type *vdt, const char *name);
274
275         /* All 3 supposed to be called under scst_vdisk_mutex */
276         void (*vdev_add) (struct scst_vdisk_dev *virt_dev);
277         void (*vdev_del) (struct scst_vdisk_dev *virt_dev);
278         struct scst_vdisk_dev *(*vdev_find) (const char *name);
279
280         int (*parse_cmd) (struct vdev_type *vdt, char *p, int *action);
281
282         /* Supposed to be called under scst_vdisk_mutex */
283         int (*perform_cmd) (struct vdev_type *vdt, int action, char *p,
284                                 char *name);
285
286         int (*parse_option) (struct scst_vdisk_dev *virt_dev, char *p);
287
288         int (*pre_register) (struct scst_vdisk_dev *virt_dev);
289 };
290
291 struct vdev_type {
292         const char *vdt_name;
293         const char *help_string;
294
295         struct scst_dev_type *vdt_devt;
296
297         struct vdev_type_funcs vfns;
298 };
299
300 struct vdisk_fileio_type {
301         struct vdev_type parent_vdt;
302         struct vdev_type_funcs parent_vdt_vfns;
303 };
304
305 struct vdisk_blockio_type {
306         struct vdev_type parent_vdt;
307         struct vdev_type_funcs parent_vdt_vfns;
308 };
309
310 struct vdisk_nullio_type {
311         struct vdev_type parent_vdt;
312         struct vdev_type_funcs parent_vdt_vfns;
313 };
314
315 struct vcdrom_type {
316         struct vdev_type parent_vdt;
317         struct vdev_type_funcs parent_vdt_vfns;
318 };
319
320 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
321 #define DEF_NUM_THREADS         5
322 #else
323 /* Context RA patch supposed to be applied on the kernel */
324 #define DEF_NUM_THREADS         8
325 #endif
326 static int num_threads = DEF_NUM_THREADS;
327
328 module_param_named(num_threads, num_threads, int, S_IRUGO);
329 MODULE_PARM_DESC(num_threads, "vdisk threads count");
330
331 static int vdisk_attach(struct scst_device *dev);
332 static void vdisk_detach(struct scst_device *dev);
333 static int vdisk_attach_tgt(struct scst_tgt_dev *tgt_dev);
334 static void vdisk_detach_tgt(struct scst_tgt_dev *tgt_dev);
335 static int vdisk_parse(struct scst_cmd *);
336 static int vdisk_do_job(struct scst_cmd *cmd);
337 static int vcdrom_parse(struct scst_cmd *);
338 static int vcdrom_exec(struct scst_cmd *cmd);
339 static void vdisk_exec_read(struct scst_cmd *cmd,
340         struct scst_vdisk_thr *thr, loff_t loff);
341 static void vdisk_exec_write(struct scst_cmd *cmd,
342         struct scst_vdisk_thr *thr, loff_t loff);
343 static void blockio_exec_rw(struct scst_cmd *cmd, struct scst_vdisk_thr *thr,
344         u64 lba_start, int write);
345 static void vdisk_exec_verify(struct scst_cmd *cmd,
346         struct scst_vdisk_thr *thr, loff_t loff);
347 static void vdisk_exec_read_capacity(struct scst_cmd *cmd);
348 static void vdisk_exec_read_capacity16(struct scst_cmd *cmd);
349 static void vdisk_exec_inquiry(struct scst_cmd *cmd);
350 static void vdisk_exec_request_sense(struct scst_cmd *cmd);
351 static void vdisk_exec_mode_sense(struct scst_cmd *cmd);
352 static void vdisk_exec_mode_select(struct scst_cmd *cmd);
353 static void vdisk_exec_log(struct scst_cmd *cmd);
354 static void vdisk_exec_read_toc(struct scst_cmd *cmd);
355 static void vdisk_exec_prevent_allow_medium_removal(struct scst_cmd *cmd);
356 static int vdisk_fsync(struct scst_vdisk_thr *thr, loff_t loff,
357         loff_t len, struct scst_cmd *cmd, struct scst_device *dev);
358 #ifdef CONFIG_SCST_PROC
359 static int vdisk_read_proc(struct seq_file *seq,
360         struct scst_dev_type *dev_type);
361 static int vdisk_write_proc(char *buffer, char **start, off_t offset,
362         int length, int *eof, struct scst_dev_type *dev_type);
363 static int vcdrom_read_proc(struct seq_file *seq,
364         struct scst_dev_type *dev_type);
365 static int vcdrom_write_proc(char *buffer, char **start, off_t offset,
366         int length, int *eof, struct scst_dev_type *dev_type);
367 #endif
368 static int vdisk_task_mgmt_fn(struct scst_mgmt_cmd *mcmd,
369         struct scst_tgt_dev *tgt_dev);
370
371 /** SYSFS **/
372
373 #ifndef CONFIG_SCST_PROC
374
375 static ssize_t vdisk_mgmt_show(struct kobject *kobj,
376         struct kobj_attribute *attr, char *buf);
377 static ssize_t vdisk_mgmt_store(struct kobject *kobj,
378         struct kobj_attribute *attr, const char *buf, size_t count);
379
380 struct kobj_attribute vdisk_mgmt_attr =
381         __ATTR(mgmt, S_IRUGO | S_IWUSR, vdisk_mgmt_show, vdisk_mgmt_store);
382
383 static const struct attribute *vdisk_attrs[] = {
384         &vdisk_mgmt_attr.attr,
385         NULL,
386 };
387
388 static ssize_t vdisk_sysfs_size_show(struct kobject *kobj,
389         struct kobj_attribute *attr, char *buf);
390 static ssize_t vdisk_sysfs_blocksize_show(struct kobject *kobj,
391         struct kobj_attribute *attr, char *buf);
392 static ssize_t vdisk_sysfs_rd_only_show(struct kobject *kobj,
393         struct kobj_attribute *attr, char *buf);
394 static ssize_t vdisk_sysfs_wt_show(struct kobject *kobj,
395         struct kobj_attribute *attr, char *buf);
396 static ssize_t vdisk_sysfs_nv_cache_show(struct kobject *kobj,
397         struct kobj_attribute *attr, char *buf);
398 static ssize_t vdisk_sysfs_o_direct_show(struct kobject *kobj,
399         struct kobj_attribute *attr, char *buf);
400 static ssize_t vdisk_sysfs_removable_show(struct kobject *kobj,
401         struct kobj_attribute *attr, char *buf);
402 static ssize_t vdisk_sysfs_filename_show(struct kobject *kobj,
403         struct kobj_attribute *attr, char *buf);
404 static ssize_t vdisk_sysfs_resync_size_store(struct kobject *kobj,
405         struct kobj_attribute *attr, const char *buf, size_t count);
406
407 static struct kobj_attribute vdisk_size_attr =
408         __ATTR(size, S_IRUGO, vdisk_sysfs_size_show, NULL);
409 static struct kobj_attribute vdisk_blocksize_attr =
410         __ATTR(block_size, S_IRUGO, vdisk_sysfs_blocksize_show, NULL);
411 static struct kobj_attribute vdisk_rd_only_attr =
412         __ATTR(read_only, S_IRUGO, vdisk_sysfs_rd_only_show, NULL);
413 static struct kobj_attribute vdisk_wt_attr =
414         __ATTR(write_through, S_IRUGO, vdisk_sysfs_wt_show, NULL);
415 static struct kobj_attribute vdisk_nv_cache_attr =
416         __ATTR(nv_cache, S_IRUGO, vdisk_sysfs_nv_cache_show, NULL);
417 static struct kobj_attribute vdisk_o_direct_attr =
418         __ATTR(o_direct, S_IRUGO, vdisk_sysfs_o_direct_show, NULL);
419 static struct kobj_attribute vdisk_removable_attr =
420         __ATTR(removable, S_IRUGO, vdisk_sysfs_removable_show, NULL);
421 static struct kobj_attribute vdisk_filename_attr =
422         __ATTR(filename, S_IRUGO, vdisk_sysfs_filename_show, NULL);
423 static struct kobj_attribute vdisk_resync_size_attr =
424         __ATTR(resync_size, S_IWUSR, NULL, vdisk_sysfs_resync_size_store);
425
426 static const struct attribute *vdisk_fileio_attrs[] = {
427         &vdisk_size_attr.attr,
428         &vdisk_blocksize_attr.attr,
429         &vdisk_rd_only_attr.attr,
430         &vdisk_wt_attr.attr,
431         &vdisk_nv_cache_attr.attr,
432         &vdisk_o_direct_attr.attr,
433         &vdisk_removable_attr.attr,
434         &vdisk_filename_attr.attr,
435         &vdisk_resync_size_attr.attr,
436         NULL,
437 };
438
439 static const struct attribute *vdisk_blockio_attrs[] = {
440         &vdisk_size_attr.attr,
441         &vdisk_blocksize_attr.attr,
442         &vdisk_rd_only_attr.attr,
443         &vdisk_removable_attr.attr,
444         &vdisk_filename_attr.attr,
445         &vdisk_resync_size_attr.attr,
446         NULL,
447 };
448
449 static const struct attribute *vdisk_nullio_attrs[] = {
450         &vdisk_size_attr.attr,
451         &vdisk_blocksize_attr.attr,
452         &vdisk_rd_only_attr.attr,
453         &vdisk_removable_attr.attr,
454         NULL,
455 };
456
457 static const struct attribute *vcdrom_attrs[] = {
458         &vdisk_size_attr.attr,
459         &vdisk_removable_attr.attr,
460         &vdisk_filename_attr.attr,
461         NULL,
462 };
463
464 #endif /* CONFIG_SCST_PROC */
465
466 static DEFINE_MUTEX(scst_vdisk_mutex);
467
468 /* Both protected by scst_vdisk_mutex */
469 static LIST_HEAD(vdisk_dev_list);
470 static LIST_HEAD(vcdrom_dev_list);
471
472 static struct vdisk_fileio_type fileio_type;
473 static struct kmem_cache *vdisk_thr_cachep;
474
475 /*
476  * Be careful changing "name" field, since it is the name of the corresponding
477  * /sys/kernel/scst_tgt entry, hence a part of user space ABI.
478  */
479
480 static struct scst_dev_type vdisk_file_devtype = {
481         .name =                 "vdisk_fileio",
482         .type =                 TYPE_DISK,
483         .exec_sync =            1,
484         .threads_num =          -1,
485         .parse_atomic =         1,
486         .exec_atomic =          0,
487         .dev_done_atomic =      1,
488         .attach =               vdisk_attach,
489         .detach =               vdisk_detach,
490         .attach_tgt =           vdisk_attach_tgt,
491         .detach_tgt =           vdisk_detach_tgt,
492         .parse =                vdisk_parse,
493         .exec =                 vdisk_do_job,
494         .task_mgmt_fn =         vdisk_task_mgmt_fn,
495 #ifdef CONFIG_SCST_PROC
496         .read_proc =            vdisk_read_proc,
497         .write_proc =           vdisk_write_proc,
498 #else
499         .devt_attrs =           vdisk_attrs,
500         .dev_attrs =            vdisk_fileio_attrs,
501 #endif
502 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
503         .default_trace_flags =  SCST_DEFAULT_DEV_LOG_FLAGS,
504         .trace_flags =          &trace_flag,
505         .trace_tbl =            vdisk_local_trace_tbl,
506         .trace_tbl_help =       VDISK_TRACE_TLB_HELP,
507 #endif
508 };
509
510 static struct vdisk_blockio_type blockio_type;
511 static struct kmem_cache *blockio_work_cachep;
512
513 static struct scst_dev_type vdisk_blk_devtype = {
514         .name =                 "vdisk_blockio",
515         .type =                 TYPE_DISK,
516         .threads_num =          0,
517         .parse_atomic =         1,
518         .exec_atomic =          0,
519         .dev_done_atomic =      1,
520 #ifdef CONFIG_SCST_PROC
521         .no_proc =              1,
522 #endif
523         .attach =               vdisk_attach,
524         .detach =               vdisk_detach,
525         .attach_tgt =           vdisk_attach_tgt,
526         .detach_tgt =           vdisk_detach_tgt,
527         .parse =                vdisk_parse,
528         .exec =                 vdisk_do_job,
529         .task_mgmt_fn =         vdisk_task_mgmt_fn,
530 #ifndef CONFIG_SCST_PROC
531         .devt_attrs =           vdisk_attrs,
532         .dev_attrs =            vdisk_blockio_attrs,
533 #endif
534 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
535         .default_trace_flags =  SCST_DEFAULT_DEV_LOG_FLAGS,
536         .trace_flags =          &trace_flag,
537         .trace_tbl =            vdisk_local_trace_tbl,
538         .trace_tbl_help =       VDISK_TRACE_TLB_HELP,
539 #endif
540 };
541
542 static struct vdisk_blockio_type nullio_type;
543 static struct scst_dev_type vdisk_null_devtype = {
544         .name =                 "vdisk_nullio",
545         .type =                 TYPE_DISK,
546         .threads_num =          0,
547         .parse_atomic =         1,
548         .exec_atomic =          1,
549         .dev_done_atomic =      1,
550 #ifdef CONFIG_SCST_PROC
551         .no_proc =              1,
552 #endif
553         .attach =               vdisk_attach,
554         .detach =               vdisk_detach,
555         .attach_tgt =           vdisk_attach_tgt,
556         .detach_tgt =           vdisk_detach_tgt,
557         .parse =                vdisk_parse,
558         .exec =                 vdisk_do_job,
559         .task_mgmt_fn =         vdisk_task_mgmt_fn,
560 #ifndef CONFIG_SCST_PROC
561         .devt_attrs =           vdisk_attrs,
562         .dev_attrs =            vdisk_nullio_attrs,
563 #endif
564 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
565         .default_trace_flags =  SCST_DEFAULT_DEV_LOG_FLAGS,
566         .trace_flags =          &trace_flag,
567         .trace_tbl =            vdisk_local_trace_tbl,
568         .trace_tbl_help =       VDISK_TRACE_TLB_HELP,
569 #endif
570 };
571
572 static struct vcdrom_type vcdrom_type;
573 static struct scst_dev_type vcdrom_devtype = {
574         .name =                 "vcdrom",
575         .type =                 TYPE_ROM,
576         .exec_sync =            1,
577         .threads_num =          -1,
578         .parse_atomic =         1,
579         .exec_atomic =          0,
580         .dev_done_atomic =      1,
581         .attach =               vdisk_attach,
582         .detach =               vdisk_detach,
583         .attach_tgt =           vdisk_attach_tgt,
584         .detach_tgt =           vdisk_detach_tgt,
585         .parse =                vcdrom_parse,
586         .exec =                 vcdrom_exec,
587         .task_mgmt_fn =         vdisk_task_mgmt_fn,
588 #ifdef CONFIG_SCST_PROC
589         .read_proc =            vcdrom_read_proc,
590         .write_proc =           vcdrom_write_proc,
591 #else
592         .devt_attrs =           vdisk_attrs,
593         .dev_attrs =            vcdrom_attrs,
594 #endif
595 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
596         .default_trace_flags =  SCST_DEFAULT_DEV_LOG_FLAGS,
597         .trace_flags =          &trace_flag,
598         .trace_tbl =            vdisk_local_trace_tbl,
599         .trace_tbl_help =       VDISK_TRACE_TLB_HELP,
600 #endif
601 };
602
603 static struct scst_vdisk_thr nullio_thr_data;
604
605 #ifdef CONFIG_SCST_PROC
606 static char *vdisk_proc_help_string =
607         "echo \"open|close|resync_size NAME [FILE_NAME [BLOCK_SIZE] "
608         "[WRITE_THROUGH READ_ONLY O_DIRECT NULLIO NV_CACHE BLOCKIO]]\" "
609         ">/proc/scsi_tgt/vdisk/vdisk\n";
610
611 static char *vcdrom_proc_help_string =
612         "echo \"open|change|close NAME [FILE_NAME]\" "
613         ">/proc/scsi_tgt/vcdrom/vcdrom\n";
614 #endif
615
616 static int scst_vdisk_ID;
617
618 module_param_named(scst_vdisk_ID, scst_vdisk_ID, int, S_IRUGO);
619 MODULE_PARM_DESC(scst_vdisk_ID, "SCST virtual disk subsystem ID");
620
621 /**************************************************************
622  *  Function:  vdev_open_fd
623  *
624  *  Argument:
625  *
626  *  Returns :  fd, use IS_ERR(fd) to get error status
627  *
628  *  Description:
629  *************************************************************/
630 static struct file *vdev_open_fd(const struct scst_vdisk_dev *virt_dev)
631 {
632         int open_flags = 0;
633         struct file *fd;
634
635         TRACE_ENTRY();
636
637         if (virt_dev->dev->rd_only)
638                 open_flags |= O_RDONLY;
639         else
640                 open_flags |= O_RDWR;
641         if (virt_dev->o_direct_flag)
642                 open_flags |= O_DIRECT;
643         if (virt_dev->wt_flag && !virt_dev->nv_cache)
644                 open_flags |= O_SYNC;
645         TRACE_DBG("Opening file %s, flags 0x%x",
646                   virt_dev->file_name, open_flags);
647         fd = filp_open(virt_dev->file_name, O_LARGEFILE | open_flags, 0600);
648
649         TRACE_EXIT();
650         return fd;
651 }
652
653 /**************************************************************
654  *  Function:  vdisk_get_file_size
655  *
656  *  Argument:
657  *
658  *  Returns :  0 on success and file size in *file_size,
659  *             error code otherwise
660  *
661  *  Description:
662  *************************************************************/
663 static int vdisk_get_file_size(const char *file_name, bool blockio,
664         loff_t *file_size)
665 {
666         struct inode *inode;
667         int res = 0;
668         struct file *fd;
669
670         TRACE_ENTRY();
671
672         *file_size = 0;
673
674         fd = filp_open(file_name, O_LARGEFILE | O_RDONLY, 0600);
675         if (IS_ERR(fd)) {
676                 res = PTR_ERR(fd);
677                 PRINT_ERROR("filp_open(%s) returned error %d", file_name, res);
678                 goto out;
679         }
680
681         inode = fd->f_dentry->d_inode;
682
683         if (blockio && !S_ISBLK(inode->i_mode)) {
684                 PRINT_ERROR("File %s is NOT a block device", file_name);
685                 res = -EINVAL;
686                 goto out_close;
687         }
688
689         if (S_ISREG(inode->i_mode))
690                 /* Nothing to do*/;
691         else if (S_ISBLK(inode->i_mode))
692                 inode = inode->i_bdev->bd_inode;
693         else {
694                 res = -EINVAL;
695                 goto out_close;
696         }
697
698         *file_size = inode->i_size;
699
700 out_close:
701         filp_close(fd, NULL);
702
703 out:
704         TRACE_EXIT_RES(res);
705         return res;
706 }
707
708 /**************************************************************
709  *  Function:  vdisk_attach
710  *
711  *  Argument:
712  *
713  *  Returns :  1 if attached, error code otherwise
714  *
715  *  Description:
716  *************************************************************/
717 static int vdisk_attach(struct scst_device *dev)
718 {
719         int res = 0;
720         loff_t err;
721         struct scst_vdisk_dev *virt_dev = NULL, *vv;
722         struct list_head *vd;
723
724         TRACE_ENTRY();
725
726         TRACE_DBG("virt_id %d (%s)", dev->virt_id, dev->virt_name);
727
728         if (dev->virt_id == 0) {
729                 PRINT_ERROR("%s", "Not a virtual device");
730                 res = -EINVAL;
731                 goto out;
732         }
733
734         vd = (dev->type == TYPE_DISK) ?
735                                 &vdisk_dev_list :
736                                 &vcdrom_dev_list;
737
738         /*
739          * scst_vdisk_mutex must be already taken before
740          * scst_register_virtual_device()
741          */
742         list_for_each_entry(vv, vd, vdisk_dev_list_entry) {
743                 if (strcmp(vv->name, dev->virt_name) == 0) {
744                         virt_dev = vv;
745                         break;
746                 }
747         }
748
749         if (virt_dev == NULL) {
750                 PRINT_ERROR("Device %s not found", dev->virt_name);
751                 res = -EINVAL;
752                 goto out;
753         }
754
755         virt_dev->dev = dev;
756
757         dev->rd_only = virt_dev->rd_only;
758         if (dev->type == TYPE_ROM)
759                 dev->rd_only = 1;
760
761         if (!virt_dev->cdrom_empty) {
762                 if (virt_dev->nullio)
763                         err = VDISK_NULLIO_SIZE;
764                 else {
765                         res = vdisk_get_file_size(virt_dev->file_name,
766                                 virt_dev->blockio, &err);
767                         if (res != 0)
768                                 goto out;
769                 }
770                 virt_dev->file_size = err;
771                 TRACE_DBG("size of file: %lld", (long long unsigned int)err);
772         } else
773                 virt_dev->file_size = 0;
774
775         virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift;
776
777         if (!virt_dev->cdrom_empty) {
778                 PRINT_INFO("Attached SCSI target virtual %s %s "
779                       "(file=\"%s\", fs=%lldMB, bs=%d, nblocks=%lld,"
780                       " cyln=%lld%s)",
781                       (dev->type == TYPE_DISK) ? "disk" : "cdrom",
782                       virt_dev->name, virt_dev->file_name,
783                       virt_dev->file_size >> 20, virt_dev->block_size,
784                       (long long unsigned int)virt_dev->nblocks,
785                       (long long unsigned int)virt_dev->nblocks/64/32,
786                       virt_dev->nblocks < 64*32
787                       ? " !WARNING! cyln less than 1" : "");
788         } else {
789                 PRINT_INFO("Attached empty SCSI target virtual cdrom %s",
790                         virt_dev->name);
791         }
792
793         dev->dh_priv = virt_dev;
794
795         dev->tst = DEF_TST;
796         dev->d_sense = DEF_DSENSE;
797         if (virt_dev->wt_flag && !virt_dev->nv_cache)
798                 dev->queue_alg = DEF_QUEUE_ALG_WT;
799         else
800                 dev->queue_alg = DEF_QUEUE_ALG;
801         dev->swp = DEF_SWP;
802         dev->tas = DEF_TAS;
803
804 out:
805         TRACE_EXIT();
806         return res;
807 }
808
809 /************************************************************
810  *  Function:  vdisk_detach
811  *
812  *  Argument:
813  *
814  *  Returns :  None
815  *
816  *  Description:  Called to detach this device type driver
817  ************************************************************/
818 static void vdisk_detach(struct scst_device *dev)
819 {
820         struct scst_vdisk_dev *virt_dev =
821             (struct scst_vdisk_dev *)dev->dh_priv;
822
823         TRACE_ENTRY();
824
825         TRACE_DBG("virt_id %d", dev->virt_id);
826
827         PRINT_INFO("Detached SCSI target virtual device %s (\"%s\")",
828                       virt_dev->name, virt_dev->file_name);
829
830         /* virt_dev will be freed by the caller */
831         dev->dh_priv = NULL;
832
833         TRACE_EXIT();
834         return;
835 }
836
837 static void vdisk_free_thr_data(struct scst_thr_data_hdr *d)
838 {
839         struct scst_vdisk_thr *thr =
840                 container_of(d, struct scst_vdisk_thr, hdr);
841
842         TRACE_ENTRY();
843
844         if (thr->fd)
845                 filp_close(thr->fd, NULL);
846
847         kfree(thr->iv);
848
849         kmem_cache_free(vdisk_thr_cachep, thr);
850
851         TRACE_EXIT();
852         return;
853 }
854
855 static struct scst_vdisk_thr *vdisk_init_thr_data(
856         struct scst_tgt_dev *tgt_dev)
857 {
858         struct scst_vdisk_thr *res;
859         struct scst_vdisk_dev *virt_dev =
860             (struct scst_vdisk_dev *)tgt_dev->dev->dh_priv;
861
862         TRACE_ENTRY();
863
864         EXTRACHECKS_BUG_ON(virt_dev->nullio);
865
866 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17)
867         res = kmem_cache_alloc(vdisk_thr_cachep, GFP_KERNEL);
868         if (res != NULL)
869                 memset(res, 0, sizeof(*res));
870 #else
871         res = kmem_cache_zalloc(vdisk_thr_cachep, GFP_KERNEL);
872 #endif
873         if (res == NULL) {
874                 TRACE(TRACE_OUT_OF_MEM, "%s", "Unable to allocate struct "
875                         "scst_vdisk_thr");
876                 goto out;
877         }
878
879         if (!virt_dev->cdrom_empty) {
880                 res->fd = vdev_open_fd(virt_dev);
881                 if (IS_ERR(res->fd)) {
882                         PRINT_ERROR("filp_open(%s) returned an error %ld",
883                                 virt_dev->file_name, PTR_ERR(res->fd));
884                         goto out_free;
885                 }
886                 if (virt_dev->blockio)
887                         res->bdev = res->fd->f_dentry->d_inode->i_bdev;
888                 else
889                         res->bdev = NULL;
890         } else
891                 res->fd = NULL;
892
893         scst_add_thr_data(tgt_dev, &res->hdr, vdisk_free_thr_data);
894
895 out:
896         TRACE_EXIT_HRES((unsigned long)res);
897         return res;
898
899 out_free:
900         kmem_cache_free(vdisk_thr_cachep, res);
901         res = NULL;
902         goto out;
903 }
904
905 static int vdisk_attach_tgt(struct scst_tgt_dev *tgt_dev)
906 {
907         struct scst_vdisk_tgt_dev *ftgt_dev;
908         int res = 0;
909
910         TRACE_ENTRY();
911
912         ftgt_dev = kzalloc(sizeof(*ftgt_dev), GFP_KERNEL);
913         if (ftgt_dev == NULL) {
914                 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of per-session "
915                         "virtual device failed");
916                 res = -ENOMEM;
917                 goto out;
918         }
919
920         tgt_dev->dh_priv = ftgt_dev;
921
922 out:
923         TRACE_EXIT_RES(res);
924         return res;
925 }
926
927 static void vdisk_detach_tgt(struct scst_tgt_dev *tgt_dev)
928 {
929         struct scst_vdisk_tgt_dev *ftgt_dev =
930                 (struct scst_vdisk_tgt_dev *)tgt_dev->dh_priv;
931
932         TRACE_ENTRY();
933
934         scst_del_all_thr_data(tgt_dev);
935
936         kfree(ftgt_dev);
937         tgt_dev->dh_priv = NULL;
938
939         TRACE_EXIT();
940         return;
941 }
942
943 static inline int vdisk_sync_queue_type(enum scst_cmd_queue_type qt)
944 {
945         switch (qt) {
946         case SCST_CMD_QUEUE_ORDERED:
947         case SCST_CMD_QUEUE_HEAD_OF_QUEUE:
948                 return 1;
949         default:
950                 return 0;
951         }
952 }
953
954 static inline int vdisk_need_pre_sync(enum scst_cmd_queue_type cur,
955         enum scst_cmd_queue_type last)
956 {
957         if (vdisk_sync_queue_type(cur))
958                 if (!vdisk_sync_queue_type(last))
959                         return 1;
960         return 0;
961 }
962
963 static int vdisk_do_job(struct scst_cmd *cmd)
964 {
965         int rc, res;
966         uint64_t lba_start = 0;
967         loff_t data_len = 0;
968         uint8_t *cdb = cmd->cdb;
969         int opcode = cdb[0];
970         loff_t loff;
971         struct scst_device *dev = cmd->dev;
972         struct scst_tgt_dev *tgt_dev = cmd->tgt_dev;
973         struct scst_vdisk_dev *virt_dev =
974                 (struct scst_vdisk_dev *)dev->dh_priv;
975         struct scst_thr_data_hdr *d;
976         struct scst_vdisk_thr *thr = NULL;
977         int fua = 0;
978
979         TRACE_ENTRY();
980
981         switch (cmd->queue_type) {
982         case SCST_CMD_QUEUE_ORDERED:
983                 TRACE(TRACE_ORDER, "ORDERED cmd %p (op %x)", cmd, cmd->cdb[0]);
984                 break;
985         case SCST_CMD_QUEUE_HEAD_OF_QUEUE:
986                 TRACE(TRACE_ORDER, "HQ cmd %p (op %x)", cmd, cmd->cdb[0]);
987                 break;
988         default:
989                 break;
990         }
991
992         rc = scst_check_local_events(cmd);
993         if (unlikely(rc != 0))
994                 goto out_done;
995
996         cmd->status = 0;
997         cmd->msg_status = 0;
998         cmd->host_status = DID_OK;
999         cmd->driver_status = 0;
1000
1001         if (!virt_dev->nullio) {
1002                 d = scst_find_thr_data(tgt_dev);
1003                 if (unlikely(d == NULL)) {
1004                         thr = vdisk_init_thr_data(tgt_dev);
1005                         if (thr == NULL) {
1006                                 scst_set_busy(cmd);
1007                                 goto out_compl;
1008                         }
1009                         scst_thr_data_get(&thr->hdr);
1010                 } else
1011                         thr = container_of(d, struct scst_vdisk_thr, hdr);
1012         } else {
1013                 thr = &nullio_thr_data;
1014                 scst_thr_data_get(&thr->hdr);
1015         }
1016
1017         switch (opcode) {
1018         case READ_6:
1019         case WRITE_6:
1020         case VERIFY_6:
1021                 lba_start = (((cdb[1] & 0x1f) << (BYTE * 2)) +
1022                              (cdb[2] << (BYTE * 1)) +
1023                              (cdb[3] << (BYTE * 0)));
1024                 data_len = cmd->bufflen;
1025                 break;
1026         case READ_10:
1027         case READ_12:
1028         case WRITE_10:
1029         case WRITE_12:
1030         case VERIFY:
1031         case WRITE_VERIFY:
1032         case WRITE_VERIFY_12:
1033         case VERIFY_12:
1034                 lba_start |= ((u64)cdb[2]) << 24;
1035                 lba_start |= ((u64)cdb[3]) << 16;
1036                 lba_start |= ((u64)cdb[4]) << 8;
1037                 lba_start |= ((u64)cdb[5]);
1038                 data_len = cmd->bufflen;
1039                 break;
1040         case READ_16:
1041         case WRITE_16:
1042         case WRITE_VERIFY_16:
1043         case VERIFY_16:
1044                 lba_start |= ((u64)cdb[2]) << 56;
1045                 lba_start |= ((u64)cdb[3]) << 48;
1046                 lba_start |= ((u64)cdb[4]) << 40;
1047                 lba_start |= ((u64)cdb[5]) << 32;
1048                 lba_start |= ((u64)cdb[6]) << 24;
1049                 lba_start |= ((u64)cdb[7]) << 16;
1050                 lba_start |= ((u64)cdb[8]) << 8;
1051                 lba_start |= ((u64)cdb[9]);
1052                 data_len = cmd->bufflen;
1053                 break;
1054         case SYNCHRONIZE_CACHE:
1055                 lba_start |= ((u64)cdb[2]) << 24;
1056                 lba_start |= ((u64)cdb[3]) << 16;
1057                 lba_start |= ((u64)cdb[4]) << 8;
1058                 lba_start |= ((u64)cdb[5]);
1059                 data_len = ((cdb[7] << (BYTE * 1)) + (cdb[8] << (BYTE * 0)))
1060                                 << virt_dev->block_shift;
1061                 if (data_len == 0)
1062                         data_len = virt_dev->file_size -
1063                                 ((loff_t)lba_start << virt_dev->block_shift);
1064                 break;
1065         }
1066
1067         loff = (loff_t)lba_start << virt_dev->block_shift;
1068         TRACE_DBG("cmd %p, lba_start %lld, loff %lld, data_len %lld", cmd,
1069                   (long long unsigned int)lba_start,
1070                   (long long unsigned int)loff,
1071                   (long long unsigned int)data_len);
1072         if (unlikely(loff < 0) || unlikely(data_len < 0) ||
1073             unlikely((loff + data_len) > virt_dev->file_size)) {
1074                 PRINT_INFO("Access beyond the end of the device "
1075                         "(%lld of %lld, len %lld)",
1076                            (long long unsigned int)loff,
1077                            (long long unsigned int)virt_dev->file_size,
1078                            (long long unsigned int)data_len);
1079                 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1080                                         scst_sense_block_out_range_error));
1081                 goto out_compl;
1082         }
1083
1084         switch (opcode) {
1085         case WRITE_10:
1086         case WRITE_12:
1087         case WRITE_16:
1088                 fua = (cdb[1] & 0x8);
1089                 if (fua) {
1090                         TRACE(TRACE_ORDER, "FUA: loff=%lld, "
1091                                 "data_len=%lld", (long long unsigned int)loff,
1092                                 (long long unsigned int)data_len);
1093                 }
1094                 break;
1095         }
1096
1097         switch (opcode) {
1098         case READ_6:
1099         case READ_10:
1100         case READ_12:
1101         case READ_16:
1102                 if (virt_dev->blockio) {
1103                         blockio_exec_rw(cmd, thr, lba_start, 0);
1104                         goto out_thr;
1105                 } else
1106                         vdisk_exec_read(cmd, thr, loff);
1107                 break;
1108         case WRITE_6:
1109         case WRITE_10:
1110         case WRITE_12:
1111         case WRITE_16:
1112         {
1113                 int do_fsync = vdisk_sync_queue_type(cmd->queue_type);
1114                 struct scst_vdisk_tgt_dev *ftgt_dev =
1115                         (struct scst_vdisk_tgt_dev *)tgt_dev->dh_priv;
1116                 enum scst_cmd_queue_type last_queue_type =
1117                         ftgt_dev->last_write_cmd_queue_type;
1118                 ftgt_dev->last_write_cmd_queue_type = cmd->queue_type;
1119                 if (vdisk_need_pre_sync(cmd->queue_type, last_queue_type)) {
1120                         TRACE(TRACE_ORDER, "ORDERED WRITE(%d): loff=%lld, "
1121                                 "data_len=%lld", cmd->queue_type,
1122                               (long long unsigned int)loff,
1123                               (long long unsigned int)data_len);
1124                         do_fsync = 1;
1125                         if (vdisk_fsync(thr, 0, 0, cmd, dev) != 0)
1126                                 goto out_compl;
1127                 }
1128                 if (virt_dev->blockio) {
1129                         blockio_exec_rw(cmd, thr, lba_start, 1);
1130                         goto out_thr;
1131                 } else
1132                         vdisk_exec_write(cmd, thr, loff);
1133                 /* O_SYNC flag is used for WT devices */
1134                 if (do_fsync || fua)
1135                         vdisk_fsync(thr, loff, data_len, cmd, dev);
1136                 break;
1137         }
1138         case WRITE_VERIFY:
1139         case WRITE_VERIFY_12:
1140         case WRITE_VERIFY_16:
1141         {
1142                 int do_fsync = vdisk_sync_queue_type(cmd->queue_type);
1143                 struct scst_vdisk_tgt_dev *ftgt_dev =
1144                         (struct scst_vdisk_tgt_dev *) tgt_dev->dh_priv;
1145                 enum scst_cmd_queue_type last_queue_type =
1146                         ftgt_dev->last_write_cmd_queue_type;
1147                 ftgt_dev->last_write_cmd_queue_type = cmd->queue_type;
1148                 if (vdisk_need_pre_sync(cmd->queue_type, last_queue_type)) {
1149                         TRACE(TRACE_ORDER, "ORDERED "
1150                               "WRITE_VERIFY(%d): loff=%lld,"
1151                               " data_len=%lld", cmd->queue_type,
1152                               (long long unsigned int)loff,
1153                               (long long unsigned int)data_len);
1154                         do_fsync = 1;
1155                         if (vdisk_fsync(thr, 0, 0, cmd, dev) != 0)
1156                                 goto out_compl;
1157                 }
1158                 /* ToDo: BLOCKIO VERIFY */
1159                 vdisk_exec_write(cmd, thr, loff);
1160                 /* O_SYNC flag is used for WT devices */
1161                 if (scsi_status_is_good(cmd->status))
1162                         vdisk_exec_verify(cmd, thr, loff);
1163                 else if (do_fsync)
1164                         vdisk_fsync(thr, loff, data_len, cmd, dev);
1165                 break;
1166         }
1167         case SYNCHRONIZE_CACHE:
1168         {
1169                 int immed = cdb[1] & 0x2;
1170                 TRACE(TRACE_ORDER, "SYNCHRONIZE_CACHE: "
1171                         "loff=%lld, data_len=%lld, immed=%d",
1172                         (long long unsigned int)loff,
1173                         (long long unsigned int)data_len, immed);
1174                 if (immed) {
1175                         scst_cmd_get(cmd); /* to protect dev */
1176                         cmd->completed = 1;
1177                         cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT,
1178                                 SCST_CONTEXT_SAME);
1179                         vdisk_fsync(thr, loff, data_len, NULL, dev);
1180                         /* ToDo: vdisk_fsync() error processing */
1181                         scst_cmd_put(cmd);
1182                         goto out_thr;
1183                 } else {
1184                         vdisk_fsync(thr, loff, data_len, cmd, dev);
1185                         break;
1186                 }
1187         }
1188         case VERIFY_6:
1189         case VERIFY:
1190         case VERIFY_12:
1191         case VERIFY_16:
1192                 vdisk_exec_verify(cmd, thr, loff);
1193                 break;
1194         case MODE_SENSE:
1195         case MODE_SENSE_10:
1196                 vdisk_exec_mode_sense(cmd);
1197                 break;
1198         case MODE_SELECT:
1199         case MODE_SELECT_10:
1200                 vdisk_exec_mode_select(cmd);
1201                 break;
1202         case LOG_SELECT:
1203         case LOG_SENSE:
1204                 vdisk_exec_log(cmd);
1205                 break;
1206         case ALLOW_MEDIUM_REMOVAL:
1207                 vdisk_exec_prevent_allow_medium_removal(cmd);
1208                 break;
1209         case READ_TOC:
1210                 vdisk_exec_read_toc(cmd);
1211                 break;
1212         case START_STOP:
1213                 vdisk_fsync(thr, 0, virt_dev->file_size, cmd, dev);
1214                 break;
1215         case RESERVE:
1216         case RESERVE_10:
1217         case RELEASE:
1218         case RELEASE_10:
1219         case TEST_UNIT_READY:
1220                 break;
1221         case INQUIRY:
1222                 vdisk_exec_inquiry(cmd);
1223                 break;
1224         case REQUEST_SENSE:
1225                 vdisk_exec_request_sense(cmd);
1226                 break;
1227         case READ_CAPACITY:
1228                 vdisk_exec_read_capacity(cmd);
1229                 break;
1230         case SERVICE_ACTION_IN:
1231                 if ((cmd->cdb[1] & 0x1f) == SAI_READ_CAPACITY_16) {
1232                         vdisk_exec_read_capacity16(cmd);
1233                         break;
1234                 }
1235                 /* else go through */
1236         case REPORT_LUNS:
1237         default:
1238                 TRACE_DBG("Invalid opcode %d", opcode);
1239                 scst_set_cmd_error(cmd,
1240                     SCST_LOAD_SENSE(scst_sense_invalid_opcode));
1241         }
1242
1243 out_compl:
1244         cmd->completed = 1;
1245
1246 out_done:
1247         cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
1248
1249 out_thr:
1250         if (likely(thr != NULL))
1251                 scst_thr_data_put(&thr->hdr);
1252
1253         res = SCST_EXEC_COMPLETED;
1254
1255         TRACE_EXIT_RES(res);
1256         return res;
1257 }
1258
1259 static int vdisk_get_block_shift(struct scst_cmd *cmd)
1260 {
1261         struct scst_vdisk_dev *virt_dev =
1262             (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1263         return virt_dev->block_shift;
1264 }
1265
1266 /********************************************************************
1267  *  Function:  vdisk_parse
1268  *
1269  *  Argument:
1270  *
1271  *  Returns :  The state of the command
1272  *
1273  *  Description:  This does the parsing of the command
1274  *
1275  *  Note:  Not all states are allowed on return
1276  ********************************************************************/
1277 static int vdisk_parse(struct scst_cmd *cmd)
1278 {
1279         scst_sbc_generic_parse(cmd, vdisk_get_block_shift);
1280         return SCST_CMD_STATE_DEFAULT;
1281 }
1282
1283 /********************************************************************
1284  *  Function:  vcdrom_parse
1285  *
1286  *  Argument:
1287  *
1288  *  Returns :  The state of the command
1289  *
1290  *  Description:  This does the parsing of the command
1291  *
1292  *  Note:  Not all states are allowed on return
1293  ********************************************************************/
1294 static int vcdrom_parse(struct scst_cmd *cmd)
1295 {
1296         scst_cdrom_generic_parse(cmd, vdisk_get_block_shift);
1297         return SCST_CMD_STATE_DEFAULT;
1298 }
1299
1300 /********************************************************************
1301  *  Function:  vcdrom_exec
1302  *
1303  *  Argument:
1304  *
1305  *  Returns :
1306  *
1307  *  Description:
1308  ********************************************************************/
1309 static int vcdrom_exec(struct scst_cmd *cmd)
1310 {
1311         int res = SCST_EXEC_COMPLETED;
1312         int opcode = cmd->cdb[0];
1313         struct scst_vdisk_dev *virt_dev =
1314             (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1315
1316         TRACE_ENTRY();
1317
1318         cmd->status = 0;
1319         cmd->msg_status = 0;
1320         cmd->host_status = DID_OK;
1321         cmd->driver_status = 0;
1322
1323         if (virt_dev->cdrom_empty && (opcode != INQUIRY)) {
1324                 TRACE_DBG("%s", "CDROM empty");
1325                 scst_set_cmd_error(cmd,
1326                         SCST_LOAD_SENSE(scst_sense_not_ready));
1327                 goto out_done;
1328         }
1329
1330         if (virt_dev->media_changed && scst_is_ua_command(cmd)) {
1331                 spin_lock(&virt_dev->flags_lock);
1332                 if (virt_dev->media_changed) {
1333                         virt_dev->media_changed = 0;
1334                         TRACE_DBG("%s", "Reporting media changed");
1335                         scst_set_cmd_error(cmd,
1336                                 SCST_LOAD_SENSE(scst_sense_medium_changed_UA));
1337                         spin_unlock(&virt_dev->flags_lock);
1338                         goto out_done;
1339                 }
1340                 spin_unlock(&virt_dev->flags_lock);
1341         }
1342
1343         res = vdisk_do_job(cmd);
1344
1345 out:
1346         TRACE_EXIT_RES(res);
1347         return res;
1348
1349 out_done:
1350         cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
1351         goto out;
1352 }
1353
1354 static uint64_t vdisk_gen_dev_id_num(struct scst_vdisk_dev *virt_dev)
1355 {
1356         unsigned int dev_id_num, i;
1357
1358         for (dev_id_num = 0, i = 0; i < strlen(virt_dev->name); i++) {
1359                 unsigned int rv = random_values[(int)(virt_dev->name[i])];
1360                 /* Do some rotating of the bits */
1361                 dev_id_num ^= ((rv << i) | (rv >> (32 - i)));
1362         }
1363
1364         return ((uint64_t)scst_vdisk_ID << 32) | dev_id_num;
1365 }
1366
1367 static void vdisk_exec_inquiry(struct scst_cmd *cmd)
1368 {
1369         int32_t length, i, resp_len = 0;
1370         uint8_t *address;
1371         uint8_t *buf;
1372         struct scst_vdisk_dev *virt_dev =
1373             (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1374
1375         /* ToDo: Performance Boost:
1376          * 1. remove kzalloc, buf
1377          * 2. do all checks before touching *address
1378          * 3. zero *address
1379          * 4. write directly to *address
1380          */
1381
1382         TRACE_ENTRY();
1383
1384         buf = kzalloc(INQ_BUF_SZ,
1385                 scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL);
1386         if (buf == NULL) {
1387                 scst_set_busy(cmd);
1388                 goto out;
1389         }
1390
1391         length = scst_get_buf_first(cmd, &address);
1392         TRACE_DBG("length %d", length);
1393         if (unlikely(length <= 0)) {
1394                 if (length < 0) {
1395                         PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1396                         scst_set_cmd_error(cmd,
1397                                 SCST_LOAD_SENSE(scst_sense_hardw_error));
1398                 }
1399                 goto out_free;
1400         }
1401
1402         if (cmd->cdb[1] & CMDDT) {
1403                 TRACE_DBG("%s", "INQUIRY: CMDDT is unsupported");
1404                 scst_set_cmd_error(cmd,
1405                     SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1406                 goto out_put;
1407         }
1408
1409         buf[0] = cmd->dev->type;      /* type dev */
1410         if (virt_dev->removable)
1411                 buf[1] = 0x80;      /* removable */
1412         /* Vital Product */
1413         if (cmd->cdb[1] & EVPD) {
1414                 uint64_t dev_id_num;
1415                 int dev_id_len;
1416                 char dev_id_str[17];
1417
1418                 dev_id_num = vdisk_gen_dev_id_num(virt_dev);
1419                 dev_id_len = scnprintf(dev_id_str, sizeof(dev_id_str), "%llx",
1420                                         dev_id_num);
1421                 TRACE_DBG("dev_id num %lld, str %s, len %d", dev_id_num,
1422                         dev_id_str, dev_id_len);
1423                 if (0 == cmd->cdb[2]) {
1424                         /* supported vital product data pages */
1425                         buf[3] = 3;
1426                         buf[4] = 0x0; /* this page */
1427                         buf[5] = 0x80; /* unit serial number */
1428                         buf[6] = 0x83; /* device identification */
1429                         resp_len = buf[3] + 4;
1430                 } else if (0x80 == cmd->cdb[2]) {
1431                         /* unit serial number */
1432                         int usn_len = strlen(virt_dev->usn);
1433                         buf[1] = 0x80;
1434                         buf[3] = usn_len;
1435                         strncpy(&buf[4], virt_dev->usn, usn_len);
1436                         resp_len = buf[3] + 4;
1437                 } else if (0x83 == cmd->cdb[2]) {
1438                         /* device identification */
1439                         int num = 4;
1440
1441                         buf[1] = 0x83;
1442                         /* T10 vendor identifier field format (faked) */
1443                         buf[num + 0] = 0x2;     /* ASCII */
1444                         buf[num + 1] = 0x1;     /* Vendor ID */
1445                         if (virt_dev->blockio)
1446                                 memcpy(&buf[num + 4], SCST_BIO_VENDOR, 8);
1447                         else
1448                                 memcpy(&buf[num + 4], SCST_FIO_VENDOR, 8);
1449
1450                         i = strlen(virt_dev->name) + 1; /* for ' ' */
1451                         memset(&buf[num + 12], ' ', i + dev_id_len);
1452                         memcpy(&buf[num + 12], virt_dev->name, i-1);
1453                         memcpy(&buf[num + 12 + i], dev_id_str, dev_id_len);
1454                         buf[num + 3] = 8 + i + dev_id_len;
1455                         num += buf[num + 3];
1456
1457 #if 0 /* This isn't required and can be misleading, so let's disable it */
1458                         num += 4;
1459
1460                         /* NAA IEEE registered identifier (faked) */
1461                         buf[num] = 0x1; /* binary */
1462                         buf[num + 1] = 0x3;
1463                         buf[num + 2] = 0x0;
1464                         buf[num + 3] = 0x8;
1465                         buf[num + 4] = 0x51; /* IEEE OUI=0x123456 (faked) */
1466                         buf[num + 5] = 0x23;
1467                         buf[num + 6] = 0x45;
1468                         buf[num + 7] = 0x60;
1469                         buf[num + 8] = (dev_id_num >> 24);
1470                         buf[num + 9] = (dev_id_num >> 16) & 0xff;
1471                         buf[num + 10] = (dev_id_num >> 8) & 0xff;
1472                         buf[num + 11] = dev_id_num & 0xff;
1473                         num = num + 12 - 4;
1474 #endif
1475
1476                         resp_len = num;
1477                         buf[2] = (resp_len >> 8) & 0xFF;
1478                         buf[3] = resp_len & 0xFF;
1479                         resp_len += 4;
1480                 } else {
1481                         TRACE_DBG("INQUIRY: Unsupported EVPD page %x",
1482                                 cmd->cdb[2]);
1483                         scst_set_cmd_error(cmd,
1484                             SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1485                         goto out_put;
1486                 }
1487         } else {
1488                 int len;
1489
1490                 if (cmd->cdb[2] != 0) {
1491                         TRACE_DBG("INQUIRY: Unsupported page %x", cmd->cdb[2]);
1492                         scst_set_cmd_error(cmd,
1493                             SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1494                         goto out_put;
1495                 }
1496
1497                 buf[2] = 5; /* Device complies to SPC-3 */
1498                 buf[3] = 0x12;  /* HiSup + data in format specified in SPC */
1499                 buf[4] = 31;/* n - 4 = 35 - 4 = 31 for full 36 byte data */
1500                 buf[6] = 1; /* MultiP 1 */
1501                 buf[7] = 2; /* CMDQUE 1, BQue 0 => commands queuing supported */
1502
1503                 /*
1504                  * 8 byte ASCII Vendor Identification of the target
1505                  * - left aligned.
1506                  */
1507                 if (virt_dev->blockio)
1508                         memcpy(&buf[8], SCST_BIO_VENDOR, 8);
1509                 else
1510                         memcpy(&buf[8], SCST_FIO_VENDOR, 8);
1511
1512                 /*
1513                  * 16 byte ASCII Product Identification of the target - left
1514                  * aligned.
1515                  */
1516                 memset(&buf[16], ' ', 16);
1517                 len = min(strlen(virt_dev->name), (size_t)16);
1518                 memcpy(&buf[16], virt_dev->name, len);
1519
1520                 /*
1521                  * 4 byte ASCII Product Revision Level of the target - left
1522                  * aligned.
1523                  */
1524                 memcpy(&buf[32], SCST_FIO_REV, 4);
1525                 resp_len = buf[4] + 5;
1526         }
1527
1528         sBUG_ON(resp_len >= INQ_BUF_SZ);
1529         if (length > resp_len)
1530                 length = resp_len;
1531         memcpy(address, buf, length);
1532
1533 out_put:
1534         scst_put_buf(cmd, address);
1535         if (length < cmd->resp_data_len)
1536                 scst_set_resp_data_len(cmd, length);
1537
1538 out_free:
1539         kfree(buf);
1540
1541 out:
1542         TRACE_EXIT();
1543         return;
1544 }
1545
1546 static void vdisk_exec_request_sense(struct scst_cmd *cmd)
1547 {
1548         int32_t length, sl;
1549         uint8_t *address;
1550         uint8_t b[SCST_STANDARD_SENSE_LEN];
1551
1552         TRACE_ENTRY();
1553
1554         sl = scst_set_sense(b, sizeof(b), cmd->dev->d_sense,
1555                 SCST_LOAD_SENSE(scst_sense_no_sense));
1556
1557         length = scst_get_buf_first(cmd, &address);
1558         TRACE_DBG("length %d", length);
1559         if (length < 0) {
1560                 PRINT_ERROR("scst_get_buf_first() failed: %d)", length);
1561                 scst_set_cmd_error(cmd,
1562                         SCST_LOAD_SENSE(scst_sense_hardw_error));
1563                 goto out;
1564         }
1565
1566         length = min(sl, length);
1567         memcpy(address, b, length);
1568         scst_set_resp_data_len(cmd, length);
1569
1570         scst_put_buf(cmd, address);
1571
1572 out:
1573         TRACE_EXIT();
1574         return;
1575 }
1576
1577 /*
1578  * <<Following mode pages info copied from ST318451LW with some corrections>>
1579  *
1580  * ToDo: revise them
1581  */
1582 static int vdisk_err_recov_pg(unsigned char *p, int pcontrol,
1583                                struct scst_vdisk_dev *virt_dev)
1584 {       /* Read-Write Error Recovery page for mode_sense */
1585         const unsigned char err_recov_pg[] = {0x1, 0xa, 0xc0, 11, 240, 0, 0, 0,
1586                                               5, 0, 0xff, 0xff};
1587
1588         memcpy(p, err_recov_pg, sizeof(err_recov_pg));
1589         if (1 == pcontrol)
1590                 memset(p + 2, 0, sizeof(err_recov_pg) - 2);
1591         return sizeof(err_recov_pg);
1592 }
1593
1594 static int vdisk_disconnect_pg(unsigned char *p, int pcontrol,
1595                                 struct scst_vdisk_dev *virt_dev)
1596 {       /* Disconnect-Reconnect page for mode_sense */
1597         const unsigned char disconnect_pg[] = {0x2, 0xe, 128, 128, 0, 10, 0, 0,
1598                                                0, 0, 0, 0, 0, 0, 0, 0};
1599
1600         memcpy(p, disconnect_pg, sizeof(disconnect_pg));
1601         if (1 == pcontrol)
1602                 memset(p + 2, 0, sizeof(disconnect_pg) - 2);
1603         return sizeof(disconnect_pg);
1604 }
1605
1606 static int vdisk_rigid_geo_pg(unsigned char *p, int pcontrol,
1607         struct scst_vdisk_dev *virt_dev)
1608 {
1609         unsigned char geo_m_pg[] = {0x04, 0x16, 0, 0, 0, DEF_HEADS, 0, 0,
1610                                     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1611                                     0x3a, 0x98/* 15K RPM */, 0, 0};
1612         int32_t ncyl, n, rem;
1613         uint64_t dividend;
1614
1615         memcpy(p, geo_m_pg, sizeof(geo_m_pg));
1616         /*
1617          * Divide virt_dev->nblocks by (DEF_HEADS * DEF_SECTORS) and store
1618          * the quotient in ncyl and the remainder in rem.
1619          */
1620         dividend = virt_dev->nblocks;
1621         rem = do_div(dividend, DEF_HEADS * DEF_SECTORS);
1622         ncyl = dividend;
1623         if (rem != 0)
1624                 ncyl++;
1625         memcpy(&n, p + 2, sizeof(u32));
1626         n = n | (cpu_to_be32(ncyl) >> 8);
1627         memcpy(p + 2, &n, sizeof(u32));
1628         if (1 == pcontrol)
1629                 memset(p + 2, 0, sizeof(geo_m_pg) - 2);
1630         return sizeof(geo_m_pg);
1631 }
1632
1633 static int vdisk_format_pg(unsigned char *p, int pcontrol,
1634                             struct scst_vdisk_dev *virt_dev)
1635 {       /* Format device page for mode_sense */
1636         const unsigned char format_pg[] = {0x3, 0x16, 0, 0, 0, 0, 0, 0,
1637                                            0, 0, 0, 0, 0, 0, 0, 0,
1638                                            0, 0, 0, 0, 0x40, 0, 0, 0};
1639
1640         memcpy(p, format_pg, sizeof(format_pg));
1641         p[10] = (DEF_SECTORS >> 8) & 0xff;
1642         p[11] = DEF_SECTORS & 0xff;
1643         p[12] = (virt_dev->block_size >> 8) & 0xff;
1644         p[13] = virt_dev->block_size & 0xff;
1645         if (1 == pcontrol)
1646                 memset(p + 2, 0, sizeof(format_pg) - 2);
1647         return sizeof(format_pg);
1648 }
1649
1650 static int vdisk_caching_pg(unsigned char *p, int pcontrol,
1651                              struct scst_vdisk_dev *virt_dev)
1652 {       /* Caching page for mode_sense */
1653         const unsigned char caching_pg[] = {0x8, 18, 0x10, 0, 0xff, 0xff, 0, 0,
1654                 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0, 0, 0, 0, 0};
1655
1656         memcpy(p, caching_pg, sizeof(caching_pg));
1657         p[2] |= !(virt_dev->wt_flag || virt_dev->nv_cache) ? WCE : 0;
1658         if (1 == pcontrol)
1659                 memset(p + 2, 0, sizeof(caching_pg) - 2);
1660         return sizeof(caching_pg);
1661 }
1662
1663 static int vdisk_ctrl_m_pg(unsigned char *p, int pcontrol,
1664                             struct scst_vdisk_dev *virt_dev)
1665 {       /* Control mode page for mode_sense */
1666         const unsigned char ctrl_m_pg[] = {0xa, 0xa, 0, 0, 0, 0, 0, 0,
1667                                            0, 0, 0x2, 0x4b};
1668
1669         memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg));
1670         switch (pcontrol) {
1671         case 0:
1672                 p[2] |= virt_dev->dev->tst << 5;
1673                 p[2] |= virt_dev->dev->d_sense << 2;
1674                 p[3] |= virt_dev->dev->queue_alg << 4;
1675                 p[4] |= virt_dev->dev->swp << 3;
1676                 p[5] |= virt_dev->dev->tas << 6;
1677                 break;
1678         case 1:
1679                 memset(p + 2, 0, sizeof(ctrl_m_pg) - 2);
1680 #if 0   /*
1681          * It's too early to implement it, since we can't control the
1682          * backstorage device parameters. ToDo
1683          */
1684                 p[2] |= 7 << 5;         /* TST */
1685                 p[3] |= 0xF << 4;       /* QUEUE ALGORITHM MODIFIER */
1686 #endif
1687                 p[2] |= 1 << 2;         /* D_SENSE */
1688                 p[4] |= 1 << 3;         /* SWP */
1689                 p[5] |= 1 << 6;         /* TAS */
1690                 break;
1691         case 2:
1692                 p[2] |= DEF_TST << 5;
1693                 p[2] |= DEF_DSENSE << 2;
1694                 if (virt_dev->wt_flag || virt_dev->nv_cache)
1695                         p[3] |= DEF_QUEUE_ALG_WT << 4;
1696                 else
1697                         p[3] |= DEF_QUEUE_ALG << 4;
1698                 p[4] |= DEF_SWP << 3;
1699                 p[5] |= DEF_TAS << 6;
1700                 break;
1701         default:
1702                 sBUG();
1703         }
1704         return sizeof(ctrl_m_pg);
1705 }
1706
1707 static int vdisk_iec_m_pg(unsigned char *p, int pcontrol,
1708                            struct scst_vdisk_dev *virt_dev)
1709 {       /* Informational Exceptions control mode page for mode_sense */
1710         const unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0,
1711                                           0, 0, 0x0, 0x0};
1712         memcpy(p, iec_m_pg, sizeof(iec_m_pg));
1713         if (1 == pcontrol)
1714                 memset(p + 2, 0, sizeof(iec_m_pg) - 2);
1715         return sizeof(iec_m_pg);
1716 }
1717
1718 static void vdisk_exec_mode_sense(struct scst_cmd *cmd)
1719 {
1720         int32_t length;
1721         uint8_t *address;
1722         uint8_t *buf;
1723         struct scst_vdisk_dev *virt_dev;
1724         uint32_t blocksize;
1725         uint64_t nblocks;
1726         unsigned char dbd, type;
1727         int pcontrol, pcode, subpcode;
1728         unsigned char dev_spec;
1729         int msense_6, offset = 0, len;
1730         unsigned char *bp;
1731
1732         TRACE_ENTRY();
1733
1734         buf = kzalloc(MSENSE_BUF_SZ,
1735                 scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL);
1736         if (buf == NULL) {
1737                 scst_set_busy(cmd);
1738                 goto out;
1739         }
1740
1741         virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1742         blocksize = virt_dev->block_size;
1743         nblocks = virt_dev->nblocks;
1744
1745         type = cmd->dev->type;    /* type dev */
1746         dbd = cmd->cdb[1] & DBD;
1747         pcontrol = (cmd->cdb[2] & 0xc0) >> 6;
1748         pcode = cmd->cdb[2] & 0x3f;
1749         subpcode = cmd->cdb[3];
1750         msense_6 = (MODE_SENSE == cmd->cdb[0]);
1751         dev_spec = (virt_dev->dev->rd_only ? WP : 0) | DPOFUA;
1752
1753         length = scst_get_buf_first(cmd, &address);
1754         if (unlikely(length <= 0)) {
1755                 if (length < 0) {
1756                         PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1757                         scst_set_cmd_error(cmd,
1758                                 SCST_LOAD_SENSE(scst_sense_hardw_error));
1759                 }
1760                 goto out_free;
1761         }
1762
1763         if (0x3 == pcontrol) {
1764                 TRACE_DBG("%s", "MODE SENSE: Saving values not supported");
1765                 scst_set_cmd_error(cmd,
1766                     SCST_LOAD_SENSE(scst_sense_saving_params_unsup));
1767                 goto out_put;
1768         }
1769
1770         if (msense_6) {
1771                 buf[1] = type;
1772                 buf[2] = dev_spec;
1773                 offset = 4;
1774         } else {
1775                 buf[2] = type;
1776                 buf[3] = dev_spec;
1777                 offset = 8;
1778         }
1779
1780         if (0 != subpcode) {
1781                 /* TODO: Control Extension page */
1782                 TRACE_DBG("%s", "MODE SENSE: Only subpage 0 is supported");
1783                 scst_set_cmd_error(cmd,
1784                     SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1785                 goto out_put;
1786         }
1787
1788         if (!dbd) {
1789                 /* Create block descriptor */
1790                 buf[offset - 1] = 0x08;         /* block descriptor length */
1791                 if (nblocks >> 32) {
1792                         buf[offset + 0] = 0xFF;
1793                         buf[offset + 1] = 0xFF;
1794                         buf[offset + 2] = 0xFF;
1795                         buf[offset + 3] = 0xFF;
1796                 } else {
1797                         /* num blks */
1798                         buf[offset + 0] = (nblocks >> (BYTE * 3)) & 0xFF;
1799                         buf[offset + 1] = (nblocks >> (BYTE * 2)) & 0xFF;
1800                         buf[offset + 2] = (nblocks >> (BYTE * 1)) & 0xFF;
1801                         buf[offset + 3] = (nblocks >> (BYTE * 0)) & 0xFF;
1802                 }
1803                 buf[offset + 4] = 0;                    /* density code */
1804                 buf[offset + 5] = (blocksize >> (BYTE * 2)) & 0xFF;/* blklen */
1805                 buf[offset + 6] = (blocksize >> (BYTE * 1)) & 0xFF;
1806                 buf[offset + 7] = (blocksize >> (BYTE * 0)) & 0xFF;
1807
1808                 offset += 8;                    /* increment offset */
1809         }
1810
1811         bp = buf + offset;
1812
1813         switch (pcode) {
1814         case 0x1:       /* Read-Write error recovery page, direct access */
1815                 len = vdisk_err_recov_pg(bp, pcontrol, virt_dev);
1816                 break;
1817         case 0x2:       /* Disconnect-Reconnect page, all devices */
1818                 len = vdisk_disconnect_pg(bp, pcontrol, virt_dev);
1819                 break;
1820         case 0x3:       /* Format device page, direct access */
1821                 len = vdisk_format_pg(bp, pcontrol, virt_dev);
1822                 break;
1823         case 0x4:       /* Rigid disk geometry */
1824                 len = vdisk_rigid_geo_pg(bp, pcontrol, virt_dev);
1825                 break;
1826         case 0x8:       /* Caching page, direct access */
1827                 len = vdisk_caching_pg(bp, pcontrol, virt_dev);
1828                 break;
1829         case 0xa:       /* Control Mode page, all devices */
1830                 len = vdisk_ctrl_m_pg(bp, pcontrol, virt_dev);
1831                 break;
1832         case 0x1c:      /* Informational Exceptions Mode page, all devices */
1833                 len = vdisk_iec_m_pg(bp, pcontrol, virt_dev);
1834                 break;
1835         case 0x3f:      /* Read all Mode pages */
1836                 len = vdisk_err_recov_pg(bp, pcontrol, virt_dev);
1837                 len += vdisk_disconnect_pg(bp + len, pcontrol, virt_dev);
1838                 len += vdisk_format_pg(bp + len, pcontrol, virt_dev);
1839                 len += vdisk_caching_pg(bp + len, pcontrol, virt_dev);
1840                 len += vdisk_ctrl_m_pg(bp + len, pcontrol, virt_dev);
1841                 len += vdisk_iec_m_pg(bp + len, pcontrol, virt_dev);
1842                 len += vdisk_rigid_geo_pg(bp + len, pcontrol, virt_dev);
1843                 break;
1844         default:
1845                 TRACE_DBG("MODE SENSE: Unsupported page %x", pcode);
1846                 scst_set_cmd_error(cmd,
1847                     SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1848                 goto out_put;
1849         }
1850
1851         offset += len;
1852
1853         if (msense_6)
1854                 buf[0] = offset - 1;
1855         else {
1856                 buf[0] = ((offset - 2) >> 8) & 0xff;
1857                 buf[1] = (offset - 2) & 0xff;
1858         }
1859
1860         if (offset > length)
1861                 offset = length;
1862         memcpy(address, buf, offset);
1863
1864 out_put:
1865         scst_put_buf(cmd, address);
1866         if (offset < cmd->resp_data_len)
1867                 scst_set_resp_data_len(cmd, offset);
1868
1869 out_free:
1870         kfree(buf);
1871
1872 out:
1873         TRACE_EXIT();
1874         return;
1875 }
1876
1877 static int vdisk_set_wt(struct scst_vdisk_dev *virt_dev, int wt)
1878 {
1879         int res = 0;
1880
1881         TRACE_ENTRY();
1882
1883         if ((virt_dev->wt_flag == wt) || virt_dev->nullio || virt_dev->nv_cache)
1884                 goto out;
1885
1886         spin_lock(&virt_dev->flags_lock);
1887         virt_dev->wt_flag = wt;
1888         spin_unlock(&virt_dev->flags_lock);
1889
1890         scst_dev_del_all_thr_data(virt_dev->dev);
1891
1892 out:
1893         TRACE_EXIT_RES(res);
1894         return res;
1895 }
1896
1897 static void vdisk_ctrl_m_pg_select(unsigned char *p,
1898         struct scst_vdisk_dev *virt_dev)
1899 {
1900         struct scst_device *dev = virt_dev->dev;
1901         int old_swp = dev->swp, old_tas = dev->tas, old_dsense = dev->d_sense;
1902
1903 #if 0
1904         /* Not implemented yet, see comment in vdisk_ctrl_m_pg() */
1905         dev->tst = p[2] >> 5;
1906         dev->queue_alg = p[3] >> 4;
1907 #endif
1908         dev->swp = (p[4] & 0x8) >> 3;
1909         dev->tas = (p[5] & 0x40) >> 6;
1910         dev->d_sense = (p[2] & 0x4) >> 2;
1911
1912         PRINT_INFO("Device %s: new control mode page parameters: SWP %x "
1913                 "(was %x), TAS %x (was %x), D_SENSE %d (was %d)",
1914                 virt_dev->name, dev->swp, old_swp, dev->tas, old_tas,
1915                 dev->d_sense, old_dsense);
1916         return;
1917 }
1918
1919 static void vdisk_exec_mode_select(struct scst_cmd *cmd)
1920 {
1921         int32_t length;
1922         uint8_t *address;
1923         struct scst_vdisk_dev *virt_dev;
1924         int mselect_6, offset;
1925
1926         TRACE_ENTRY();
1927
1928         virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1929         mselect_6 = (MODE_SELECT == cmd->cdb[0]);
1930
1931         length = scst_get_buf_first(cmd, &address);
1932         if (unlikely(length <= 0)) {
1933                 if (length < 0) {
1934                         PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1935                         scst_set_cmd_error(cmd,
1936                                 SCST_LOAD_SENSE(scst_sense_hardw_error));
1937                 }
1938                 goto out;
1939         }
1940
1941         if (!(cmd->cdb[1] & PF) || (cmd->cdb[1] & SP)) {
1942                 TRACE(TRACE_MINOR|TRACE_SCSI, "MODE SELECT: Unsupported "
1943                         "value(s) of PF and/or SP bits (cdb[1]=%x)",
1944                         cmd->cdb[1]);
1945                 scst_set_cmd_error(cmd,
1946                     SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1947                 goto out_put;
1948         }
1949
1950         if (mselect_6)
1951                 offset = 4;
1952         else
1953                 offset = 8;
1954
1955         if (address[offset - 1] == 8) {
1956                 offset += 8;
1957         } else if (address[offset - 1] != 0) {
1958                 PRINT_ERROR("%s", "MODE SELECT: Wrong parameters list "
1959                         "lenght");
1960                 scst_set_cmd_error(cmd,
1961                     SCST_LOAD_SENSE(scst_sense_invalid_field_in_parm_list));
1962                 goto out_put;
1963         }
1964
1965         while (length > offset + 2) {
1966                 if (address[offset] & PS) {
1967                         PRINT_ERROR("%s", "MODE SELECT: Illegal PS bit");
1968                         scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1969                                 scst_sense_invalid_field_in_parm_list));
1970                         goto out_put;
1971                 }
1972                 if ((address[offset] & 0x3f) == 0x8) {
1973                         /* Caching page */
1974                         if (address[offset + 1] != 18) {
1975                                 PRINT_ERROR("%s", "MODE SELECT: Invalid "
1976                                         "caching page request");
1977                                 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1978                                     scst_sense_invalid_field_in_parm_list));
1979                                 goto out_put;
1980                         }
1981                         if (vdisk_set_wt(virt_dev,
1982                               (address[offset + 2] & WCE) ? 0 : 1) != 0) {
1983                                 scst_set_cmd_error(cmd,
1984                                     SCST_LOAD_SENSE(scst_sense_hardw_error));
1985                                 goto out_put;
1986                         }
1987                         break;
1988                 } else if ((address[offset] & 0x3f) == 0xA) {
1989                         /* Control page */
1990                         if (address[offset + 1] != 0xA) {
1991                                 PRINT_ERROR("%s", "MODE SELECT: Invalid "
1992                                         "control page request");
1993                                 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1994                                     scst_sense_invalid_field_in_parm_list));
1995                                 goto out_put;
1996                         }
1997                         vdisk_ctrl_m_pg_select(&address[offset], virt_dev);
1998                 } else {
1999                         PRINT_ERROR("MODE SELECT: Invalid request %x",
2000                                 address[offset] & 0x3f);
2001                         scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
2002                             scst_sense_invalid_field_in_parm_list));
2003                         goto out_put;
2004                 }
2005                 offset += address[offset + 1];
2006         }
2007
2008 out_put:
2009         scst_put_buf(cmd, address);
2010
2011 out:
2012         TRACE_EXIT();
2013         return;
2014 }
2015
2016 static void vdisk_exec_log(struct scst_cmd *cmd)
2017 {
2018         TRACE_ENTRY();
2019
2020         /* No log pages are supported */
2021         scst_set_cmd_error(cmd,
2022                 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
2023
2024         TRACE_EXIT();
2025         return;
2026 }
2027
2028 static void vdisk_exec_read_capacity(struct scst_cmd *cmd)
2029 {
2030         int32_t length;
2031         uint8_t *address;
2032         struct scst_vdisk_dev *virt_dev;
2033         uint32_t blocksize;
2034         uint64_t nblocks;
2035         uint8_t buffer[READ_CAP_LEN];
2036
2037         TRACE_ENTRY();
2038
2039         virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2040         blocksize = virt_dev->block_size;
2041         nblocks = virt_dev->nblocks;
2042
2043         /* last block on the virt_dev is (nblocks-1) */
2044         memset(buffer, 0, sizeof(buffer));
2045         if (nblocks >> 32) {
2046                 buffer[0] = 0xFF;
2047                 buffer[1] = 0xFF;
2048                 buffer[2] = 0xFF;
2049                 buffer[3] = 0xFF;
2050         } else {
2051                 buffer[0] = ((nblocks - 1) >> (BYTE * 3)) & 0xFF;
2052                 buffer[1] = ((nblocks - 1) >> (BYTE * 2)) & 0xFF;
2053                 buffer[2] = ((nblocks - 1) >> (BYTE * 1)) & 0xFF;
2054                 buffer[3] = ((nblocks - 1) >> (BYTE * 0)) & 0xFF;
2055         }
2056         buffer[4] = (blocksize >> (BYTE * 3)) & 0xFF;
2057         buffer[5] = (blocksize >> (BYTE * 2)) & 0xFF;
2058         buffer[6] = (blocksize >> (BYTE * 1)) & 0xFF;
2059         buffer[7] = (blocksize >> (BYTE * 0)) & 0xFF;
2060
2061         length = scst_get_buf_first(cmd, &address);
2062         if (unlikely(length <= 0)) {
2063                 if (length < 0) {
2064                         PRINT_ERROR("scst_get_buf_first() failed: %d", length);
2065                         scst_set_cmd_error(cmd,
2066                                 SCST_LOAD_SENSE(scst_sense_hardw_error));
2067                 }
2068                 goto out;
2069         }
2070
2071         if (length > READ_CAP_LEN)
2072                 length = READ_CAP_LEN;
2073         memcpy(address, buffer, length);
2074
2075         scst_put_buf(cmd, address);
2076
2077         if (length < cmd->resp_data_len)
2078                 scst_set_resp_data_len(cmd, length);
2079
2080 out:
2081         TRACE_EXIT();
2082         return;
2083 }
2084
2085 static void vdisk_exec_read_capacity16(struct scst_cmd *cmd)
2086 {
2087         int32_t length;
2088         uint8_t *address;
2089         struct scst_vdisk_dev *virt_dev;
2090         uint32_t blocksize;
2091         uint64_t nblocks;
2092         uint8_t buffer[READ_CAP16_LEN];
2093
2094         TRACE_ENTRY();
2095
2096         virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2097         blocksize = virt_dev->block_size;
2098         nblocks = virt_dev->nblocks - 1;
2099
2100         memset(buffer, 0, sizeof(buffer));
2101
2102         buffer[0] = nblocks >> 56;
2103         buffer[1] = (nblocks >> 48) & 0xFF;
2104         buffer[2] = (nblocks >> 40) & 0xFF;
2105         buffer[3] = (nblocks >> 32) & 0xFF;
2106         buffer[4] = (nblocks >> 24) & 0xFF;
2107         buffer[5] = (nblocks >> 16) & 0xFF;
2108         buffer[6] = (nblocks >> 8) & 0xFF;
2109         buffer[7] = nblocks & 0xFF;
2110
2111         buffer[8] = (blocksize >> (BYTE * 3)) & 0xFF;
2112         buffer[9] = (blocksize >> (BYTE * 2)) & 0xFF;
2113         buffer[10] = (blocksize >> (BYTE * 1)) & 0xFF;
2114         buffer[11] = (blocksize >> (BYTE * 0)) & 0xFF;
2115
2116         switch (blocksize) {
2117         case 512:
2118                 buffer[13] = 3;
2119                 break;
2120         case 1024:
2121                 buffer[13] = 2;
2122                 break;
2123         case 2048:
2124                 buffer[13] = 1;
2125                 break;
2126         default:
2127                 PRINT_ERROR("%s: Unexpected block size %d",
2128                         cmd->op_name, blocksize);
2129                 /* go through */
2130         case 4096:
2131                 buffer[13] = 0;
2132                 break;
2133         }
2134
2135         length = scst_get_buf_first(cmd, &address);
2136         if (unlikely(length <= 0)) {
2137                 if (length < 0) {
2138                         PRINT_ERROR("scst_get_buf_first() failed: %d", length);
2139                         scst_set_cmd_error(cmd,
2140                                 SCST_LOAD_SENSE(scst_sense_hardw_error));
2141                         }
2142                 goto out;
2143         }
2144
2145         /*
2146          * Some versions of Windows have a bug, which makes them consider
2147          * response of READ CAPACITY(16) longer than 12 bytes as a faulty one.
2148          * As the result, such Windows'es refuse to see SCST exported
2149          * devices >2TB in size. This is fixed by MS in latter Windows
2150          * versions, probably, by some hotfix.
2151          *
2152          * But if you're using such buggy Windows and experience this problem,
2153          * change this '1' to '0'.
2154          */
2155 #if 1
2156         if (length > READ_CAP16_LEN)
2157                 length = READ_CAP16_LEN;
2158 #else
2159         if (length > 12)
2160                 length = 12;
2161 #endif
2162         memcpy(address, buffer, length);
2163
2164         scst_put_buf(cmd, address);
2165
2166         if (length < cmd->resp_data_len)
2167                 scst_set_resp_data_len(cmd, length);
2168
2169 out:
2170         TRACE_EXIT();
2171         return;
2172 }
2173
2174 static void vdisk_exec_read_toc(struct scst_cmd *cmd)
2175 {
2176         int32_t length, off = 0;
2177         uint8_t *address;
2178         struct scst_vdisk_dev *virt_dev;
2179         uint32_t nblocks;
2180         uint8_t buffer[4+8+8] = { 0x00, 0x0a, 0x01, 0x01, 0x00, 0x14,
2181                                   0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
2182
2183         TRACE_ENTRY();
2184
2185         if (cmd->dev->type != TYPE_ROM) {
2186                 PRINT_ERROR("%s", "READ TOC for non-CDROM device");
2187                 scst_set_cmd_error(cmd,
2188                         SCST_LOAD_SENSE(scst_sense_invalid_opcode));
2189                 goto out;
2190         }
2191
2192         if (cmd->cdb[2] & 0x0e/*Format*/) {
2193                 PRINT_ERROR("%s", "READ TOC: invalid requested data format");
2194                 scst_set_cmd_error(cmd,
2195                         SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
2196                 goto out;
2197         }
2198
2199         if ((cmd->cdb[6] != 0 && (cmd->cdb[2] & 0x01)) ||
2200             (cmd->cdb[6] > 1 && cmd->cdb[6] != 0xAA)) {
2201                 PRINT_ERROR("READ TOC: invalid requested track number %x",
2202                         cmd->cdb[6]);
2203                 scst_set_cmd_error(cmd,
2204                         SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
2205                 goto out;
2206         }
2207
2208         length = scst_get_buf_first(cmd, &address);
2209         if (unlikely(length <= 0)) {
2210                 if (length < 0) {
2211                         PRINT_ERROR("scst_get_buf_first() failed: %d", length);
2212                         scst_set_cmd_error(cmd,
2213                                 SCST_LOAD_SENSE(scst_sense_hardw_error));
2214                 }
2215                 goto out;
2216         }
2217
2218         virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2219         /* ToDo when you have > 8TB ROM device. */
2220         nblocks = (uint32_t)virt_dev->nblocks;
2221
2222         /* Header */
2223         memset(buffer, 0, sizeof(buffer));
2224         buffer[2] = 0x01;    /* First Track/Session */
2225         buffer[3] = 0x01;    /* Last Track/Session */
2226         off = 4;
2227         if (cmd->cdb[6] <= 1) {
2228                 /* Fistr TOC Track Descriptor */
2229                 /* ADDR    0x10 - Q Sub-channel encodes current position data
2230                    CONTROL 0x04 - Data track, recoreded uninterrupted */
2231                 buffer[off+1] = 0x14;
2232                 /* Track Number */
2233                 buffer[off+2] = 0x01;
2234                 off += 8;
2235         }
2236         if (!(cmd->cdb[2] & 0x01)) {
2237                 /* Lead-out area TOC Track Descriptor */
2238                 buffer[off+1] = 0x14;
2239                 /* Track Number */
2240                 buffer[off+2] = 0xAA;
2241                 /* Track Start Address */
2242                 buffer[off+4] = (nblocks >> (BYTE * 3)) & 0xFF;
2243                 buffer[off+5] = (nblocks >> (BYTE * 2)) & 0xFF;
2244                 buffer[off+6] = (nblocks >> (BYTE * 1)) & 0xFF;
2245                 buffer[off+7] = (nblocks >> (BYTE * 0)) & 0xFF;
2246                 off += 8;
2247         }
2248
2249         buffer[1] = off - 2;    /* Data  Length */
2250
2251         if (off > length)
2252                 off = length;
2253         memcpy(address, buffer, off);
2254
2255         scst_put_buf(cmd, address);
2256
2257         if (off < cmd->resp_data_len)
2258                 scst_set_resp_data_len(cmd, off);
2259
2260 out:
2261         TRACE_EXIT();
2262         return;
2263 }
2264
2265 static void vdisk_exec_prevent_allow_medium_removal(struct scst_cmd *cmd)
2266 {
2267         struct scst_vdisk_dev *virt_dev =
2268                 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2269
2270         TRACE_DBG("PERSIST/PREVENT 0x%02x", cmd->cdb[4]);
2271
2272         if (cmd->dev->type == TYPE_ROM) {
2273                 spin_lock(&virt_dev->flags_lock);
2274                 virt_dev->prevent_allow_medium_removal =
2275                         cmd->cdb[4] & 0x01 ? 1 : 0;
2276                 spin_unlock(&virt_dev->flags_lock);
2277         }
2278
2279         return;
2280 }
2281
2282 static int vdisk_fsync(struct scst_vdisk_thr *thr, loff_t loff,
2283         loff_t len, struct scst_cmd *cmd, struct scst_device *dev)
2284 {
2285         int res = 0;
2286         struct scst_vdisk_dev *virt_dev =
2287                 (struct scst_vdisk_dev *)dev->dh_priv;
2288         struct file *file = thr->fd;
2289         struct inode *inode;
2290         struct address_space *mapping;
2291
2292         TRACE_ENTRY();
2293
2294         /* Hopefully, the compiler will generate the single comparison */
2295         if (virt_dev->nv_cache || virt_dev->blockio || virt_dev->wt_flag ||
2296             virt_dev->o_direct_flag || virt_dev->nullio)
2297                 goto out;
2298
2299         inode = file->f_dentry->d_inode;
2300         mapping = file->f_mapping;
2301
2302         res = sync_page_range(inode, mapping, loff, len);
2303         if (unlikely(res != 0)) {
2304                 PRINT_ERROR("sync_page_range() failed (%d)", res);
2305                 if (cmd != NULL) {
2306                         scst_set_cmd_error(cmd,
2307                                 SCST_LOAD_SENSE(scst_sense_write_error));
2308                 }
2309         }
2310
2311         /* ToDo: flush the device cache, if needed */
2312
2313 out:
2314         TRACE_EXIT_RES(res);
2315         return res;
2316 }
2317
2318 static struct iovec *vdisk_alloc_iv(struct scst_cmd *cmd,
2319         struct scst_vdisk_thr *thr)
2320 {
2321         int iv_count;
2322
2323         iv_count = scst_get_buf_count(cmd);
2324         if (iv_count > thr->iv_count) {
2325                 kfree(thr->iv);
2326                 /* It can't be called in atomic context */
2327                 thr->iv = kmalloc(sizeof(*thr->iv) * iv_count, GFP_KERNEL);
2328                 if (thr->iv == NULL) {
2329                         PRINT_ERROR("Unable to allocate iv (%d)", iv_count);
2330                         scst_set_busy(cmd);
2331                         goto out;
2332                 }
2333                 thr->iv_count = iv_count;
2334         }
2335
2336 out:
2337         return thr->iv;
2338 }
2339
2340 static void vdisk_exec_read(struct scst_cmd *cmd,
2341         struct scst_vdisk_thr *thr, loff_t loff)
2342 {
2343         mm_segment_t old_fs;
2344         loff_t err;
2345         ssize_t length, full_len;
2346         uint8_t __user *address;
2347         struct scst_vdisk_dev *virt_dev =
2348             (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2349         struct file *fd = thr->fd;
2350         struct iovec *iv;
2351         int iv_count, i;
2352
2353         TRACE_ENTRY();
2354
2355         if (virt_dev->nullio)
2356                 goto out;
2357
2358         iv = vdisk_alloc_iv(cmd, thr);
2359         if (iv == NULL)
2360                 goto out;
2361
2362         iv_count = 0;
2363         full_len = 0;
2364         i = -1;
2365         length = scst_get_buf_first(cmd, (uint8_t __force **)&address);
2366         while (length > 0) {
2367                 full_len += length;
2368                 i++;
2369                 iv_count++;
2370                 iv[i].iov_base = address;
2371                 iv[i].iov_len = length;
2372                 length = scst_get_buf_next(cmd, (uint8_t __force **)&address);
2373         }
2374         if (unlikely(length < 0)) {
2375                 PRINT_ERROR("scst_get_buf_() failed: %zd", length);
2376                 scst_set_cmd_error(cmd,
2377                     SCST_LOAD_SENSE(scst_sense_hardw_error));
2378                 goto out_put;
2379         }
2380
2381         old_fs = get_fs();
2382         set_fs(get_ds());
2383
2384         TRACE_DBG("reading(iv_count %d, full_len %zd)", iv_count, full_len);
2385         /* SEEK */
2386         if (fd->f_op->llseek)
2387                 err = fd->f_op->llseek(fd, loff, 0/*SEEK_SET*/);
2388         else
2389                 err = default_llseek(fd, loff, 0/*SEEK_SET*/);
2390         if (err != loff) {
2391                 PRINT_ERROR("lseek trouble %lld != %lld",
2392                             (long long unsigned int)err,
2393                             (long long unsigned int)loff);
2394                 scst_set_cmd_error(cmd,
2395                         SCST_LOAD_SENSE(scst_sense_hardw_error));
2396                 goto out_set_fs;
2397         }
2398
2399         /* READ */
2400         err = vfs_readv(fd, iv, iv_count, &fd->f_pos);
2401
2402         if ((err < 0) || (err < full_len)) {
2403                 PRINT_ERROR("readv() returned %lld from %zd",
2404                             (long long unsigned int)err,
2405                             full_len);
2406                 if (err == -EAGAIN)
2407                         scst_set_busy(cmd);
2408                 else {
2409                         scst_set_cmd_error(cmd,
2410                             SCST_LOAD_SENSE(scst_sense_read_error));
2411                 }
2412                 goto out_set_fs;
2413         }
2414
2415 out_set_fs:
2416         set_fs(old_fs);
2417
2418 out_put:
2419         for (; i >= 0; i--)
2420                 scst_put_buf(cmd, (void __force *)(iv[i].iov_base));
2421
2422 out:
2423         TRACE_EXIT();
2424         return;
2425 }
2426
2427 static void vdisk_exec_write(struct scst_cmd *cmd,
2428         struct scst_vdisk_thr *thr, loff_t loff)
2429 {
2430         mm_segment_t old_fs;
2431         loff_t err;
2432         ssize_t length, full_len;
2433         uint8_t __user *address;
2434         struct scst_vdisk_dev *virt_dev =
2435             (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2436         struct file *fd = thr->fd;
2437         struct iovec *iv, *eiv;
2438         int iv_count, eiv_count;
2439
2440         TRACE_ENTRY();
2441
2442         if (virt_dev->nullio)
2443                 goto out;
2444
2445         iv = vdisk_alloc_iv(cmd, thr);
2446         if (iv == NULL)
2447                 goto out;
2448
2449         iv_count = 0;
2450         full_len = 0;
2451         length = scst_get_buf_first(cmd, (uint8_t __force **)&address);
2452         while (length > 0) {
2453                 full_len += length;
2454                 iv[iv_count].iov_base = address;
2455                 iv[iv_count].iov_len = length;
2456                 iv_count++;
2457                 length = scst_get_buf_next(cmd, (uint8_t __force **)&address);
2458         }
2459         if (unlikely(length < 0)) {
2460                 PRINT_ERROR("scst_get_buf_() failed: %zd", length);
2461                 scst_set_cmd_error(cmd,
2462                     SCST_LOAD_SENSE(scst_sense_hardw_error));
2463                 goto out_put;
2464         }
2465
2466         old_fs = get_fs();
2467         set_fs(get_ds());
2468
2469         eiv = iv;
2470         eiv_count = iv_count;
2471 restart:
2472         TRACE_DBG("writing(eiv_count %d, full_len %zd)", eiv_count, full_len);
2473
2474         /* SEEK */
2475         if (fd->f_op->llseek)
2476                 err = fd->f_op->llseek(fd, loff, 0 /*SEEK_SET */);
2477         else
2478                 err = default_llseek(fd, loff, 0 /*SEEK_SET */);
2479         if (err != loff) {
2480                 PRINT_ERROR("lseek trouble %lld != %lld",
2481                             (long long unsigned int)err,
2482                             (long long unsigned int)loff);
2483                 scst_set_cmd_error(cmd,
2484                                    SCST_LOAD_SENSE(scst_sense_hardw_error));
2485                 goto out_set_fs;
2486         }
2487
2488         /* WRITE */
2489         err = vfs_writev(fd, eiv, eiv_count, &fd->f_pos);
2490
2491         if (err < 0) {
2492                 PRINT_ERROR("write() returned %lld from %zd",
2493                             (long long unsigned int)err,
2494                             full_len);
2495                 if (err == -EAGAIN)
2496                         scst_set_busy(cmd);
2497                 else {
2498                         scst_set_cmd_error(cmd,
2499                             SCST_LOAD_SENSE(scst_sense_write_error));
2500                 }
2501                 goto out_set_fs;
2502         } else if (err < full_len) {
2503                 /*
2504                  * Probably that's wrong, but sometimes write() returns
2505                  * value less, than requested. Let's restart.
2506                  */
2507                 int i, e = eiv_count;
2508                 TRACE_MGMT_DBG("write() returned %d from %zd "
2509                         "(iv_count=%d)", (int)err, full_len,
2510                         eiv_count);
2511                 if (err == 0) {
2512                         PRINT_INFO("Suspicious: write() returned 0 from "
2513                                 "%zd (iv_count=%d)", full_len, eiv_count);
2514                 }
2515                 full_len -= err;
2516                 for (i = 0; i < e; i++) {
2517                         if ((long long)eiv->iov_len < err) {
2518                                 err -= eiv->iov_len;
2519                                 eiv++;
2520                                 eiv_count--;
2521                         } else {
2522                                 eiv->iov_base =
2523                                         (uint8_t __force __user *)eiv->iov_base +
2524                                         err;
2525                                 eiv->iov_len -= err;
2526                                 break;
2527                         }
2528                 }
2529                 goto restart;
2530         }
2531
2532 out_set_fs:
2533         set_fs(old_fs);
2534
2535 out_put:
2536         while (iv_count > 0) {
2537                 scst_put_buf(cmd, (void __force *)(iv[iv_count-1].iov_base));
2538                 iv_count--;
2539         }
2540
2541 out:
2542         TRACE_EXIT();
2543         return;
2544 }
2545
2546 struct scst_blockio_work {
2547         atomic_t bios_inflight;
2548         struct scst_cmd *cmd;
2549 };
2550
2551 static inline void blockio_check_finish(struct scst_blockio_work *blockio_work)
2552 {
2553         /* Decrement the bios in processing, and if zero signal completion */
2554         if (atomic_dec_and_test(&blockio_work->bios_inflight)) {
2555                 blockio_work->cmd->completed = 1;
2556                 blockio_work->cmd->scst_cmd_done(blockio_work->cmd,
2557                         SCST_CMD_STATE_DEFAULT, scst_estimate_context());
2558                 kmem_cache_free(blockio_work_cachep, blockio_work);
2559         }
2560         return;
2561 }
2562
2563 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
2564 static int blockio_endio(struct bio *bio, unsigned int bytes_done, int error)
2565 #else
2566 static void blockio_endio(struct bio *bio, int error)
2567 #endif
2568 {
2569         struct scst_blockio_work *blockio_work = bio->bi_private;
2570
2571 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
2572         if (bio->bi_size)
2573                 return 1;
2574 #endif
2575
2576         error = test_bit(BIO_UPTODATE, &bio->bi_flags) ? error : -EIO;
2577
2578         if (unlikely(error != 0)) {
2579                 PRINT_ERROR("cmd %p returned error %d", blockio_work->cmd,
2580                         error);
2581                 /*
2582                  * The race with other such bio's doesn't matter, since all
2583                  * scst_set_cmd_error() calls do the same local to this cmd
2584                  * operations.
2585                  */
2586                 if (bio->bi_rw & WRITE)
2587                         scst_set_cmd_error(blockio_work->cmd,
2588                                 SCST_LOAD_SENSE(scst_sense_write_error));
2589                 else
2590                         scst_set_cmd_error(blockio_work->cmd,
2591                                 SCST_LOAD_SENSE(scst_sense_read_error));
2592         }
2593
2594         blockio_check_finish(blockio_work);
2595
2596         bio_put(bio);
2597 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
2598         return 0;
2599 #else
2600         return;
2601 #endif
2602 }
2603
2604 static void blockio_exec_rw(struct scst_cmd *cmd, struct scst_vdisk_thr *thr,
2605         u64 lba_start, int write)
2606 {
2607         struct scst_vdisk_dev *virt_dev =
2608                 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2609         struct block_device *bdev = thr->bdev;
2610         struct request_queue *q = bdev_get_queue(bdev);
2611         int length, max_nr_vecs = 0;
2612         uint8_t *address;
2613         struct bio *bio = NULL, *hbio = NULL, *tbio = NULL;
2614         int need_new_bio;
2615         struct scst_blockio_work *blockio_work;
2616         int bios = 0;
2617
2618         TRACE_ENTRY();
2619
2620         if (virt_dev->nullio)
2621                 goto out;
2622
2623         /* Allocate and initialize blockio_work struct */
2624         blockio_work = kmem_cache_alloc(blockio_work_cachep, GFP_KERNEL);
2625         if (blockio_work == NULL)
2626                 goto out_no_mem;
2627
2628         blockio_work->cmd = cmd;
2629
2630         if (q)
2631                 max_nr_vecs = min(bio_get_nr_vecs(bdev), BIO_MAX_PAGES);
2632         else
2633                 max_nr_vecs = 1;
2634
2635         need_new_bio = 1;
2636
2637         length = scst_get_buf_first(cmd, &address);
2638         while (length > 0) {
2639                 int len, bytes, off, thislen;
2640                 uint8_t *addr;
2641                 u64 lba_start0;
2642
2643                 addr = address;
2644                 off = offset_in_page(addr);
2645                 len = length;
2646                 thislen = 0;
2647                 lba_start0 = lba_start;
2648
2649                 while (len > 0) {
2650                         int rc;
2651                         struct page *page = virt_to_page(addr);
2652
2653                         if (need_new_bio) {
2654 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
2655                                 bio = bio_kmalloc(GFP_KERNEL, max_nr_vecs);
2656 #else
2657                                 bio = bio_alloc(GFP_KERNEL, max_nr_vecs);
2658 #endif
2659                                 if (!bio) {
2660                                         PRINT_ERROR("Failed to create bio "
2661                                                 "for data segment %d (cmd %p)",
2662                                                 cmd->get_sg_buf_entry_num, cmd);
2663                                         goto out_no_bio;
2664                                 }
2665
2666                                 bios++;
2667                                 need_new_bio = 0;
2668                                 bio->bi_end_io = blockio_endio;
2669                                 bio->bi_sector = lba_start0 <<
2670                                         (virt_dev->block_shift - 9);
2671                                 bio->bi_bdev = bdev;
2672                                 bio->bi_private = blockio_work;
2673 #if 0 /* It could be win, but could be not, so a performance study is needed */
2674                                 bio->bi_rw |= 1 << BIO_RW_SYNC;
2675 #endif
2676                                 if (!hbio)
2677                                         hbio = tbio = bio;
2678                                 else
2679                                         tbio = tbio->bi_next = bio;
2680                         }
2681
2682                         bytes = min_t(unsigned int, len, PAGE_SIZE - off);
2683
2684                         rc = bio_add_page(bio, page, bytes, off);
2685                         if (rc < bytes) {
2686                                 sBUG_ON(rc != 0);
2687                                 need_new_bio = 1;
2688                                 lba_start0 += thislen >> virt_dev->block_shift;
2689                                 thislen = 0;
2690                                 continue;
2691                         }
2692
2693                         addr += PAGE_SIZE;
2694                         thislen += bytes;
2695                         len -= bytes;
2696                         off = 0;
2697                 }
2698
2699                 lba_start += length >> virt_dev->block_shift;
2700
2701                 scst_put_buf(cmd, address);
2702                 length = scst_get_buf_next(cmd, &address);
2703         }
2704
2705         /* +1 to prevent erroneous too early command completion */
2706         atomic_set(&blockio_work->bios_inflight, bios+1);
2707
2708         while (hbio) {
2709                 bio = hbio;
2710                 hbio = hbio->bi_next;
2711                 bio->bi_next = NULL;
2712                 submit_bio(write, bio);
2713         }
2714
2715         if (q && q->unplug_fn)
2716                 q->unplug_fn(q);
2717
2718         blockio_check_finish(blockio_work);
2719
2720 out:
2721         TRACE_EXIT();
2722         return;
2723
2724 out_no_bio:
2725         while (hbio) {
2726                 bio = hbio;
2727                 hbio = hbio->bi_next;
2728                 bio_put(bio);
2729         }
2730         kmem_cache_free(blockio_work_cachep, blockio_work);
2731
2732 out_no_mem:
2733         scst_set_busy(cmd);
2734         goto out;
2735 }
2736
2737 static void vdisk_exec_verify(struct scst_cmd *cmd,
2738         struct scst_vdisk_thr *thr, loff_t loff)
2739 {
2740         mm_segment_t old_fs;
2741         loff_t err;
2742         ssize_t length, len_mem = 0;
2743         uint8_t *address_sav, *address;
2744         int compare;
2745         struct scst_vdisk_dev *virt_dev =
2746             (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2747         struct file *fd = thr->fd;
2748         uint8_t *mem_verify = NULL;
2749
2750         TRACE_ENTRY();
2751
2752         if (vdisk_fsync(thr, loff, cmd->bufflen, cmd, cmd->dev) != 0)
2753                 goto out;
2754
2755         /*
2756          * Until the cache is cleared prior the verifying, there is not
2757          * much point in this code. ToDo.
2758          *
2759          * Nevertherless, this code is valuable if the data have not read
2760          * from the file/disk yet.
2761          */
2762
2763         /* SEEK */
2764         old_fs = get_fs();
2765         set_fs(get_ds());
2766
2767         if (!virt_dev->nullio) {
2768                 if (fd->f_op->llseek)
2769                         err = fd->f_op->llseek(fd, loff, 0/*SEEK_SET*/);
2770                 else
2771                         err = default_llseek(fd, loff, 0/*SEEK_SET*/);
2772                 if (err != loff) {
2773                         PRINT_ERROR("lseek trouble %lld != %lld",
2774                                     (long long unsigned int)err,
2775                                     (long long unsigned int)loff);
2776                         scst_set_cmd_error(cmd,
2777                                 SCST_LOAD_SENSE(scst_sense_hardw_error));
2778                         goto out_set_fs;
2779                 }
2780         }
2781
2782         mem_verify = vmalloc(LEN_MEM);
2783         if (mem_verify == NULL) {
2784                 PRINT_ERROR("Unable to allocate memory %d for verify",
2785                                LEN_MEM);
2786                 scst_set_cmd_error(cmd,
2787                                    SCST_LOAD_SENSE(scst_sense_hardw_error));
2788                 goto out_set_fs;
2789         }
2790
2791         length = scst_get_buf_first(cmd, &address);
2792         address_sav = address;
2793         if (!length && cmd->data_len) {
2794                 length = cmd->data_len;
2795                 compare = 0;
2796         } else
2797                 compare = 1;
2798
2799         while (length > 0) {
2800                 len_mem = (length > LEN_MEM) ? LEN_MEM : length;
2801                 TRACE_DBG("Verify: length %zd - len_mem %zd", length, len_mem);
2802
2803                 if (!virt_dev->nullio)
2804                         err = vfs_read(fd, (char __force __user *)mem_verify,
2805                                 len_mem, &fd->f_pos);
2806                 else
2807                         err = len_mem;
2808                 if ((err < 0) || (err < len_mem)) {
2809                         PRINT_ERROR("verify() returned %lld from %zd",
2810                                     (long long unsigned int)err, len_mem);
2811                         if (err == -EAGAIN)
2812                                 scst_set_busy(cmd);
2813                         else {
2814                                 scst_set_cmd_error(cmd,
2815                                     SCST_LOAD_SENSE(scst_sense_read_error));
2816                         }
2817                         if (compare)
2818                                 scst_put_buf(cmd, address_sav);
2819                         goto out_set_fs;
2820                 }
2821                 if (compare && memcmp(address, mem_verify, len_mem) != 0) {
2822                         TRACE_DBG("Verify: error memcmp length %zd", length);
2823                         scst_set_cmd_error(cmd,
2824                             SCST_LOAD_SENSE(scst_sense_miscompare_error));
2825                         scst_put_buf(cmd, address_sav);
2826                         goto out_set_fs;
2827                 }
2828                 length -= len_mem;
2829                 address += len_mem;
2830                 if (compare && length <= 0) {
2831                         scst_put_buf(cmd, address_sav);
2832                         length = scst_get_buf_next(cmd, &address);
2833                         address_sav = address;
2834                 }
2835         }
2836
2837         if (length < 0) {
2838                 PRINT_ERROR("scst_get_buf_() failed: %zd", length);
2839                 scst_set_cmd_error(cmd,
2840                     SCST_LOAD_SENSE(scst_sense_hardw_error));
2841         }
2842
2843 out_set_fs:
2844         set_fs(old_fs);
2845         if (mem_verify)
2846                 vfree(mem_verify);
2847
2848 out:
2849         TRACE_EXIT();
2850         return;
2851 }
2852
2853 static int vdisk_task_mgmt_fn(struct scst_mgmt_cmd *mcmd,
2854         struct scst_tgt_dev *tgt_dev)
2855 {
2856         TRACE_ENTRY();
2857
2858         if ((mcmd->fn == SCST_LUN_RESET) || (mcmd->fn == SCST_TARGET_RESET)) {
2859                 /* Restore default values */
2860                 struct scst_device *dev = tgt_dev->dev;
2861                 struct scst_vdisk_dev *virt_dev =
2862                         (struct scst_vdisk_dev *)dev->dh_priv;
2863
2864                 dev->tst = DEF_TST;
2865                 dev->d_sense = DEF_DSENSE;
2866                 if (virt_dev->wt_flag && !virt_dev->nv_cache)
2867                         dev->queue_alg = DEF_QUEUE_ALG_WT;
2868                 else
2869                         dev->queue_alg = DEF_QUEUE_ALG;
2870                 dev->swp = DEF_SWP;
2871                 dev->tas = DEF_TAS;
2872
2873                 virt_dev->prevent_allow_medium_removal = 0;
2874         }
2875
2876         TRACE_EXIT();
2877         return SCST_DEV_TM_NOT_COMPLETED;
2878 }
2879
2880 static void vdisk_report_registering(const struct scst_vdisk_dev *virt_dev)
2881 {
2882         char buf[128];
2883         int i, j;
2884
2885         i = snprintf(buf, sizeof(buf), "Registering virtual %s device %s ",
2886                 virt_dev->vdt->vdt_name, virt_dev->name);
2887         j = i;
2888
2889         if (virt_dev->wt_flag)
2890                 i += snprintf(&buf[i], sizeof(buf) - i, "(WRITE_THROUGH");
2891
2892         if (virt_dev->nv_cache)
2893                 i += snprintf(&buf[i], sizeof(buf) - i, "%sNV_CACHE",
2894                         (j == i) ? "(" : ", ");
2895
2896         if (virt_dev->rd_only)
2897                 i += snprintf(&buf[i], sizeof(buf) - i, "%sREAD_ONLY",
2898                         (j == i) ? "(" : ", ");
2899
2900         if (virt_dev->o_direct_flag)
2901                 i += snprintf(&buf[i], sizeof(buf) - i, "%sO_DIRECT",
2902                         (j == i) ? "(" : ", ");
2903
2904         if (virt_dev->nullio)
2905                 i += snprintf(&buf[i], sizeof(buf) - i, "%sNULLIO",
2906                         (j == i) ? "(" : ", ");
2907
2908         if (virt_dev->blockio)
2909                 i += snprintf(&buf[i], sizeof(buf) - i, "%sBLOCKIO",
2910                         (j == i) ? "(" : ", ");
2911
2912         if (virt_dev->removable)
2913                 i += snprintf(&buf[i], sizeof(buf) - i, "%sREMOVABLE",
2914                         (j == i) ? "(" : ", ");
2915
2916         if (j == i)
2917                 PRINT_INFO("%s", buf);
2918         else
2919                 PRINT_INFO("%s)", buf);
2920
2921         return;
2922 }
2923
2924 /* scst_vdisk_mutex supposed to be held */
2925 static int __vdisk_resync_size(struct scst_vdisk_dev *virt_dev)
2926 {
2927         loff_t file_size;
2928         int res = 0;
2929
2930         if (!virt_dev->nullio) {
2931                 res = vdisk_get_file_size(virt_dev->file_name,
2932                                 virt_dev->blockio, &file_size);
2933                 if (res != 0)
2934                         goto out;
2935         } else
2936                 file_size = VDISK_NULLIO_SIZE;
2937
2938         if (file_size == virt_dev->file_size) {
2939                 PRINT_INFO("Size of virtual disk %s remained the same",
2940                         virt_dev->name);
2941                 goto out;
2942         }
2943
2944         res = scst_suspend_activity(true);
2945         if (res != 0)
2946                 goto out;
2947
2948         virt_dev->file_size = file_size;
2949         virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift;
2950
2951         scst_dev_del_all_thr_data(virt_dev->dev);
2952
2953         PRINT_INFO("New size of SCSI target virtual disk %s "
2954                 "(fs=%lldMB, bs=%d, nblocks=%lld, cyln=%lld%s)",
2955                 virt_dev->name, virt_dev->file_size >> 20,
2956                 virt_dev->block_size,
2957                 (long long unsigned int)virt_dev->nblocks,
2958                 (long long unsigned int)virt_dev->nblocks/64/32,
2959                 virt_dev->nblocks < 64*32 ? " !WARNING! cyln less "
2960                                                 "than 1" : "");
2961
2962         scst_capacity_data_changed(virt_dev->dev);
2963
2964         scst_resume_activity();
2965
2966 out:
2967         return res;
2968 }
2969
2970 /* scst_vdisk_mutex supposed to be held */
2971 static int vdisk_resync_size(struct vdev_type *vdt, char *p, const char *name)
2972 {
2973         struct scst_vdisk_dev *virt_dev;
2974         int res;
2975
2976         virt_dev = vdt->vfns.vdev_find(name);
2977         if (virt_dev == NULL) {
2978                 PRINT_ERROR("Device %s not found", name);
2979                 res = -EINVAL;
2980                 goto out;
2981         }
2982
2983         res = __vdisk_resync_size(virt_dev);
2984
2985 out:
2986         TRACE_EXIT_RES(res);
2987         return res;
2988 }
2989
2990 static void vdev_init(struct vdev_type *vdt, struct scst_vdisk_dev *virt_dev)
2991 {
2992         memset(virt_dev, 0, sizeof(*virt_dev));
2993         spin_lock_init(&virt_dev->flags_lock);
2994         virt_dev->vdt = vdt;
2995
2996         virt_dev->block_size = DEF_DISK_BLOCKSIZE;
2997         virt_dev->block_shift = DEF_DISK_BLOCKSIZE_SHIFT;
2998
2999         return;
3000 }
3001
3002 static struct scst_vdisk_dev *vdev_create(struct vdev_type *vdt)
3003 {
3004         struct scst_vdisk_dev *virt_dev;
3005
3006         virt_dev = kmalloc(sizeof(*virt_dev), GFP_KERNEL);
3007         if (virt_dev == NULL) {
3008                 PRINT_ERROR("Allocation of virtual device %s failed",
3009                         vdt->vdt_name);
3010                 goto out;
3011         }
3012
3013         vdt->vfns.vdev_init(vdt, virt_dev);
3014
3015 out:
3016         return virt_dev;
3017 }
3018
3019 static void vdev_deinit(struct scst_vdisk_dev *virt_dev)
3020 {
3021         kfree(virt_dev->file_name);
3022         return;
3023 }
3024
3025 static void vdev_destroy(struct scst_vdisk_dev *virt_dev)
3026 {
3027         virt_dev->vdt->vfns.vdev_deinit(virt_dev);
3028         kfree(virt_dev);
3029         return;
3030 }
3031
3032 static int vdisk_fileio_pre_register(struct scst_vdisk_dev *virt_dev)
3033 {
3034         int res = 0;
3035
3036         if ((virt_dev->file_name == NULL) ||
3037             (strcmp(virt_dev->file_name, VDEV_NONE_FILENAME) == 0)) {
3038                 PRINT_ERROR("%s", "File name required");
3039                 res = -EINVAL;
3040                 goto out;
3041         }
3042
3043         if (virt_dev->rd_only && (virt_dev->wt_flag || virt_dev->nv_cache)) {
3044                 PRINT_ERROR("Write options on read only device %s",
3045                         virt_dev->name);
3046                 res = -EINVAL;
3047                 goto out;
3048         }
3049
3050 out:
3051         return res;
3052 }
3053
3054 static int vdisk_blockio_pre_register(struct scst_vdisk_dev *virt_dev)
3055 {
3056         int res = 0;
3057
3058         if ((virt_dev->file_name == NULL) ||
3059             (strcmp(virt_dev->file_name, VDEV_NONE_FILENAME) == 0)) {
3060                 PRINT_ERROR("%s", "File name required");
3061                 res = -EINVAL;
3062                 goto out;
3063         }
3064
3065 out:
3066         return res;
3067 }
3068
3069 static void vdisk_blockio_init(struct vdev_type *vdt,
3070         struct scst_vdisk_dev *virt_dev)
3071 {
3072         struct vdisk_blockio_type *v;
3073
3074         v = container_of(vdt, struct vdisk_blockio_type, parent_vdt);
3075
3076         v->parent_vdt_vfns.vdev_init(vdt, virt_dev);
3077
3078         virt_dev->blockio = 1;
3079         return;
3080 }
3081
3082 static void vdisk_nullio_init(struct vdev_type *vdt,
3083         struct scst_vdisk_dev *virt_dev)
3084 {
3085         struct vdisk_nullio_type *v;
3086
3087         v = container_of(vdt, struct vdisk_nullio_type, parent_vdt);
3088
3089         v->parent_vdt_vfns.vdev_init(vdt, virt_dev);
3090
3091         virt_dev->nullio = 1;
3092         return;
3093 }
3094
3095 static int vdisk_parse_option(struct scst_vdisk_dev *virt_dev, char *p)
3096 {
3097         int res = -EINVAL;
3098
3099         TRACE_ENTRY();
3100
3101         if (!strncmp("READ_ONLY", p, 9)) {
3102                 res = 9;
3103                 virt_dev->rd_only = 1;
3104                 TRACE_DBG("%s", "READ_ONLY");
3105         } else if (!strncmp("REMOVABLE", p, 9)) {
3106                 res = 9;
3107                 virt_dev->removable = 1;
3108                 TRACE_DBG("%s", "REMOVABLE");
3109         }
3110
3111         TRACE_EXIT_RES(res);
3112         return res;
3113 }
3114
3115 static int vdisk_fileio_parse_option(struct scst_vdisk_dev *virt_dev, char *p)
3116 {
3117         int res;
3118
3119         TRACE_ENTRY();
3120
3121         res = vdisk_parse_option(virt_dev, p);
3122         if (res >= 0)
3123                 goto out;
3124
3125         if (!strncmp("WRITE_THROUGH", p, 13)) {
3126                 res = 13;
3127                 virt_dev->wt_flag = 1;
3128                 TRACE_DBG("%s", "WRITE_THROUGH");
3129         } else if (!strncmp("NV_CACHE", p, 8)) {
3130                 res = 8;
3131                 virt_dev->nv_cache = 1;
3132                 TRACE_DBG("%s", "NON-VOLATILE CACHE");
3133         } else if (!strncmp("O_DIRECT", p, 8)) {
3134                 res = 8;
3135 #if 0
3136                 virt_dev->o_direct_flag = 1;
3137                 TRACE_DBG("%s", "O_DIRECT");
3138 #else
3139                 PRINT_INFO("%s flag doesn't currently"
3140                         " work, ignoring it, use fileio_tgt "
3141                         "in O_DIRECT mode instead", "O_DIRECT");
3142 #endif
3143         }
3144
3145 out:
3146         TRACE_EXIT_RES(res);
3147         return res;
3148 }
3149
3150 /* scst_vdisk_mutex supposed to be held */
3151 static int vdev_open(struct vdev_type *vdt, char *p, const char *name)
3152 {
3153         int res = 0;
3154         char *file_name;
3155         struct scst_vdisk_dev *virt_dev;
3156         size_t len;
3157
3158         TRACE_ENTRY();
3159
3160         virt_dev = vdt->vfns.vdev_find(name);
3161         if (virt_dev != NULL) {
3162                 PRINT_ERROR("Virtual device with name %s already exist", name);
3163                 res = -EINVAL;
3164                 goto out;
3165         }
3166
3167         while (isspace(*p) && *p != '\0')
3168                 p++;
3169         file_name = p;
3170         if ((*file_name == '/') || (strcmp(file_name, VDEV_NONE_FILENAME) == 0)) {
3171                 while (!isspace(*p) && *p != '\0')
3172                         p++;
3173                 *p++ = '\0';
3174
3175                 TRACE_DBG("file name %s", file_name);
3176
3177                 while (isspace(*p) && *p != '\0')
3178                         p++;
3179         } else {
3180                 TRACE_DBG("file name %s", "not specified");
3181                 file_name = NULL;
3182         }
3183
3184         virt_dev = vdt->vfns.vdev_create(vdt);
3185         if (virt_dev == NULL) {
3186                 TRACE(TRACE_OUT_OF_MEM, "Creation of virt_dev %s failed", name);
3187                 res = -ENOMEM;
3188                 goto out;
3189         }
3190
3191         if (isdigit(*p)) {
3192                 uint32_t block_size;
3193                 int block_shift;
3194                 char *pp;
3195
3196                 block_size = simple_strtoul(p, &pp, 0);
3197                 p = pp;
3198                 if ((*p != '\0') && !isspace(*p)) {
3199                         PRINT_ERROR("Parse error: \"%s\"", p);
3200                         res = -EINVAL;
3201                         goto out_free_vdev;
3202                 }
3203                 while (isspace(*p) && *p != '\0')
3204                         p++;
3205
3206                 block_shift = scst_calc_block_shift(block_size);
3207                 if (block_shift < 9) {
3208                         res = -EINVAL;
3209                         goto out_free_vdev;
3210                 }
3211
3212                 TRACE_DBG("block_size %d, block_shift %d", block_size,
3213                         block_shift);
3214
3215                 virt_dev->block_size = block_size;
3216                 virt_dev->block_shift = block_shift;
3217         }
3218
3219         while (*p != '\0') {
3220                 while (isspace(*p) && *p != '\0')
3221                         p++;
3222
3223                 if (vdt->vfns.parse_option != NULL)
3224                         res = vdt->vfns.parse_option(virt_dev, p);
3225                 else
3226                         res = -EINVAL;
3227
3228                 if (res < 0) {
3229                         PRINT_ERROR("Unknown option \"%s\"", p);
3230                         goto out_free_vdev;
3231                 } else if (res == 0)
3232                         break;
3233
3234                 p += res;
3235
3236                 if (!isspace(*p) && (*p != '\0')) {
3237                         PRINT_ERROR("Syntax error on %s", p);
3238                         goto out_free_vdev;
3239                 }
3240         }
3241
3242         strcpy(virt_dev->name, name);
3243
3244         scnprintf(virt_dev->usn, sizeof(virt_dev->usn), "%llx",
3245                         vdisk_gen_dev_id_num(virt_dev));
3246         TRACE_DBG("usn %s", virt_dev->usn);
3247
3248         if (file_name != NULL) {
3249                 len = strlen(file_name) + 1;
3250                 virt_dev->file_name = kmalloc(len, GFP_KERNEL);
3251                 if (virt_dev->file_name == NULL) {
3252                         TRACE(TRACE_OUT_OF_MEM, "Allocation of file_name %s "
3253                                 "failed", file_name);
3254                         res = -ENOMEM;
3255                         goto out_free_vdev;
3256                 }
3257                 strncpy(virt_dev->file_name, file_name, len);
3258         }
3259
3260         if (vdt->vfns.pre_register != NULL) {
3261                 res = vdt->vfns.pre_register(virt_dev);
3262                 if (res != 0)
3263                         goto out_free_vpath;
3264         }
3265
3266         vdt->vfns.vdev_add(virt_dev);
3267
3268         vdisk_report_registering(virt_dev);
3269         virt_dev->virt_id = scst_register_virtual_device(vdt->vdt_devt,
3270                                                  virt_dev->name);
3271         if (virt_dev->virt_id < 0) {
3272                 res = virt_dev->virt_id;
3273                 goto out_del;
3274         }
3275
3276         TRACE_DBG("Added virt_dev (name %s, file name %s, id %d, block size "
3277                 "%d) to vdisk_dev_list", virt_dev->name, virt_dev->file_name,
3278                 virt_dev->virt_id, virt_dev->block_size);
3279
3280 out:
3281         TRACE_EXIT_RES(res);
3282         return res;
3283
3284 out_del:
3285         vdt->vfns.vdev_del(virt_dev);
3286
3287 out_free_vpath:
3288         kfree(virt_dev->file_name);
3289
3290 out_free_vdev:
3291         kfree(virt_dev);
3292         goto out;
3293 }
3294
3295 /* scst_vdisk_mutex supposed to be held */
3296 static int vdev_close(struct vdev_type *vdt, const char *name)
3297 {
3298         int res = 0;
3299         struct scst_vdisk_dev *virt_dev;
3300
3301         TRACE_ENTRY();
3302
3303         virt_dev = vdt->vfns.vdev_find(name);
3304         if (virt_dev == NULL) {
3305                 PRINT_ERROR("Device %s not found", name);
3306                 res = -EINVAL;
3307                 goto out;
3308         }
3309
3310         scst_unregister_virtual_device(virt_dev->virt_id);
3311
3312         PRINT_INFO("Virtual device %s unregistered", virt_dev->name);
3313         TRACE_DBG("virt_id %d unregister", virt_dev->virt_id);
3314
3315         vdt->vfns.vdev_del(virt_dev);
3316         vdt->vfns.vdev_destroy(virt_dev);
3317
3318 out:
3319         TRACE_EXIT_RES(res);
3320         return res;
3321 }
3322
3323 /* scst_vdisk_mutex supposed to be held */
3324 static void vdev_del(struct scst_vdisk_dev *virt_dev)
3325 {
3326         TRACE_ENTRY();
3327
3328         list_del(&virt_dev->vdisk_dev_list_entry);
3329
3330         TRACE_EXIT();
3331         return;
3332 }
3333
3334 /* scst_vdisk_mutex supposed to be held */
3335 static void vdisk_add(struct scst_vdisk_dev *virt_dev)
3336 {
3337         TRACE_ENTRY();
3338
3339         list_add_tail(&virt_dev->vdisk_dev_list_entry, &vdisk_dev_list);
3340
3341         TRACE_EXIT();
3342         return;
3343 }
3344
3345 /* scst_vdisk_mutex supposed to be held */
3346 static struct scst_vdisk_dev *vdisk_find(const char *name)
3347 {
3348         struct scst_vdisk_dev *res, *vv;
3349
3350         TRACE_ENTRY();
3351
3352         res = NULL;
3353         list_for_each_entry(vv, &vdisk_dev_list, vdisk_dev_list_entry) {
3354                 if (strcmp(vv->name, name) == 0) {
3355                         res = vv;
3356                         break;
3357                 }
3358         }
3359
3360         TRACE_EXIT_HRES((unsigned long)res);
3361         return res;
3362 }
3363
3364 /* scst_vdisk_mutex supposed to be held */
3365 static void vcdrom_add(struct scst_vdisk_dev *virt_dev)
3366 {
3367         TRACE_ENTRY();
3368
3369         list_add_tail(&virt_dev->vdisk_dev_list_entry, &vcdrom_dev_list);
3370
3371         TRACE_EXIT();
3372         return;
3373 }
3374
3375 /* scst_vdisk_mutex supposed to be held */
3376 static struct scst_vdisk_dev *vcdrom_find(const char *name)
3377 {
3378         struct scst_vdisk_dev *res, *vv;
3379
3380         TRACE_ENTRY();
3381
3382         res = NULL;
3383         list_for_each_entry(vv, &vcdrom_dev_list, vdisk_dev_list_entry) {
3384                 if (strcmp(vv->name, name) == 0) {
3385                         res = vv;
3386                         break;
3387                 }
3388         }
3389
3390         TRACE_EXIT_HRES((unsigned long)res);
3391         return res;
3392 }
3393
3394 static int vdisk_parse_cmd(struct vdev_type *vdt, char *p, int *action)
3395 {
3396         int res = -EINVAL;
3397
3398         TRACE_ENTRY();
3399
3400         if (!strncmp("resync_size", p, 11)) {
3401                 res = 11;
3402                 p += res;
3403                 *action = VDISK_ACTION_RESYNC_SIZE;
3404         }
3405
3406         TRACE_EXIT_RES(res);
3407         return res;
3408 }
3409
3410 /* scst_vdisk_mutex supposed to be held */
3411 static int vdisk_perform_cmd(struct vdev_type *vdt, int action, char *p,
3412         char *name)
3413 {
3414         int res = -EINVAL;
3415
3416         TRACE_ENTRY();
3417
3418         if (action == VDISK_ACTION_RESYNC_SIZE)
3419                 res = vdisk_resync_size(vdt, p, name);
3420
3421         TRACE_EXIT_RES(res);
3422         return res;
3423 }
3424
3425 static void vcdrom_init(struct vdev_type *vdt,
3426         struct scst_vdisk_dev *virt_dev)
3427 {
3428         struct vcdrom_type *vt;
3429
3430         vt = container_of(vdt, struct vcdrom_type, parent_vdt);
3431
3432         vt->parent_vdt_vfns.vdev_init(vdt, virt_dev);
3433
3434         virt_dev->rd_only = 1;
3435         virt_dev->removable = 1;
3436
3437         virt_dev->block_size = DEF_CDROM_BLOCKSIZE;
3438         virt_dev->block_shift = DEF_CDROM_BLOCKSIZE_SHIFT;
3439
3440         return;
3441 }
3442
3443 static int vcdrom_pre_register(struct scst_vdisk_dev *virt_dev)
3444 {
3445         int res = 0;
3446
3447         if ((virt_dev->file_name == NULL) ||
3448             (strcmp(virt_dev->file_name, VDEV_NONE_FILENAME) == 0))
3449                 virt_dev->cdrom_empty = 1;
3450
3451         if (virt_dev->block_size != DEF_CDROM_BLOCKSIZE) {
3452                 PRINT_WARNING("Block size %d for vortual device %s ignored",
3453                         virt_dev->block_size, virt_dev->name);
3454                 virt_dev->block_size = DEF_CDROM_BLOCKSIZE;
3455                 virt_dev->block_shift = DEF_CDROM_BLOCKSIZE_SHIFT;
3456         }
3457
3458         return res;
3459 }
3460
3461 /* scst_vdisk_mutex supposed to be held */
3462 static int vcdrom_change(struct vdev_type *vdt, char *p, const char *name)
3463 {
3464         loff_t err;
3465         struct scst_vdisk_dev *virt_dev;
3466         char *file_name, *fn = NULL, *old_fn;
3467         int len;
3468         int res = 0;
3469
3470         virt_dev = vdt->vfns.vdev_find(name);
3471         if (virt_dev == NULL) {
3472                 PRINT_ERROR("Virtual device with name "
3473                        "%s not found", name);
3474                 res = -EINVAL;
3475                 goto out;
3476         }
3477
3478         while (isspace(*p) && *p != '\0')
3479                 p++;
3480         file_name = p;
3481         while (!isspace(*p) && *p != '\0')
3482                 p++;
3483         *p++ = '\0';
3484         if (*file_name == '\0') {
3485                 virt_dev->cdrom_empty = 1;
3486                 TRACE_DBG("%s", "No media");
3487         } else if (*file_name != '/') {
3488                 PRINT_ERROR("File path \"%s\" is not "
3489                         "absolute", file_name);
3490                 res = -EINVAL;
3491                 goto out;
3492         } else
3493                 virt_dev->cdrom_empty = 0;
3494
3495         old_fn = virt_dev->file_name;
3496
3497         if (!virt_dev->cdrom_empty) {
3498                 len = strlen(file_name) + 1;
3499                 fn = kmalloc(len, GFP_KERNEL);
3500                 if (fn == NULL) {
3501                         TRACE(TRACE_OUT_OF_MEM, "%s",
3502                                 "Allocation of file_name failed");
3503                         res = -ENOMEM;
3504                         goto out;
3505                 }
3506
3507                 strncpy(fn, file_name, len);
3508                 virt_dev->file_name = fn;
3509
3510                 res = vdisk_get_file_size(virt_dev->file_name,
3511                                 virt_dev->blockio, &err);
3512                 if (res != 0)
3513                         goto out_free;
3514         } else {
3515                 err = 0;
3516                 virt_dev->file_name = NULL;
3517         }
3518
3519         res = scst_suspend_activity(true);
3520         if (res != 0)
3521                 goto out_free;
3522
3523         if (virt_dev->prevent_allow_medium_removal) {
3524                 PRINT_ERROR("Prevent medium removal for "
3525                         "virtual device with name %s", name);
3526                 res = -EINVAL;
3527                 goto out_free_resume;
3528         }
3529
3530         virt_dev->file_size = err;
3531         virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift;
3532         if (!virt_dev->cdrom_empty)
3533                 virt_dev->media_changed = 1;
3534
3535         scst_dev_del_all_thr_data(virt_dev->dev);
3536
3537         if (!virt_dev->cdrom_empty) {
3538                 PRINT_INFO("Changed SCSI target virtual cdrom %s "
3539                         "(file=\"%s\", fs=%lldMB, bs=%d, nblocks=%lld,"
3540                         " cyln=%lld%s)", virt_dev->name, virt_dev->file_name,
3541                         virt_dev->file_size >> 20, virt_dev->block_size,
3542                         (long long unsigned int)virt_dev->nblocks,
3543                         (long long unsigned int)virt_dev->nblocks/64/32,
3544                         virt_dev->nblocks < 64*32 ? " !WARNING! cyln less "
3545                                                         "than 1" : "");
3546         } else {
3547                 PRINT_INFO("Removed media from SCSI target virtual cdrom %s",
3548                         virt_dev->name);
3549         }
3550
3551         kfree(old_fn);
3552
3553 out_resume:
3554         scst_resume_activity();
3555
3556 out:
3557         return res;
3558
3559 out_free:
3560         virt_dev->file_name = old_fn;
3561 &nb