Set max_cmd_len correcty.
[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 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
682         if ((fd->f_op == NULL) ||
683             (fd->f_op->readv == NULL) ||
684             (fd->f_op->writev == NULL)) {
685 #else
686         if ((fd->f_op == NULL) ||
687             (fd->f_op->aio_read == NULL) ||
688             (fd->f_op->aio_write == NULL)) {
689 #endif
690                 PRINT_ERROR("%s", "Wrong f_op or FS doesn't have required "
691                         "capabilities");
692                 res = -EINVAL;
693                 goto out_close;
694         }
695
696         inode = fd->f_dentry->d_inode;
697
698         if (blockio && !S_ISBLK(inode->i_mode)) {
699                 PRINT_ERROR("File %s is NOT a block device", file_name);
700                 res = -EINVAL;
701                 goto out_close;
702         }
703
704         if (S_ISREG(inode->i_mode))
705                 /* Nothing to do*/;
706         else if (S_ISBLK(inode->i_mode))
707                 inode = inode->i_bdev->bd_inode;
708         else {
709                 res = -EINVAL;
710                 goto out_close;
711         }
712
713         *file_size = inode->i_size;
714
715 out_close:
716         filp_close(fd, NULL);
717
718 out:
719         TRACE_EXIT_RES(res);
720         return res;
721 }
722
723 /**************************************************************
724  *  Function:  vdisk_attach
725  *
726  *  Argument:
727  *
728  *  Returns :  1 if attached, error code otherwise
729  *
730  *  Description:
731  *************************************************************/
732 static int vdisk_attach(struct scst_device *dev)
733 {
734         int res = 0;
735         loff_t err;
736         struct scst_vdisk_dev *virt_dev = NULL, *vv;
737         struct list_head *vd;
738
739         TRACE_ENTRY();
740
741         TRACE_DBG("virt_id %d (%s)", dev->virt_id, dev->virt_name);
742
743         if (dev->virt_id == 0) {
744                 PRINT_ERROR("%s", "Not a virtual device");
745                 res = -EINVAL;
746                 goto out;
747         }
748
749         vd = (dev->type == TYPE_DISK) ?
750                                 &vdisk_dev_list :
751                                 &vcdrom_dev_list;
752
753         /*
754          * scst_vdisk_mutex must be already taken before
755          * scst_register_virtual_device()
756          */
757         list_for_each_entry(vv, vd, vdisk_dev_list_entry) {
758                 if (strcmp(vv->name, dev->virt_name) == 0) {
759                         virt_dev = vv;
760                         break;
761                 }
762         }
763
764         if (virt_dev == NULL) {
765                 PRINT_ERROR("Device %s not found", dev->virt_name);
766                 res = -EINVAL;
767                 goto out;
768         }
769
770         virt_dev->dev = dev;
771
772         dev->rd_only = virt_dev->rd_only;
773         if (dev->type == TYPE_ROM)
774                 dev->rd_only = 1;
775
776         if (!virt_dev->cdrom_empty) {
777                 if (virt_dev->nullio)
778                         err = VDISK_NULLIO_SIZE;
779                 else {
780                         res = vdisk_get_file_size(virt_dev->file_name,
781                                 virt_dev->blockio, &err);
782                         if (res != 0)
783                                 goto out;
784                 }
785                 virt_dev->file_size = err;
786                 TRACE_DBG("size of file: %lld", (long long unsigned int)err);
787         } else
788                 virt_dev->file_size = 0;
789
790         virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift;
791
792         if (!virt_dev->cdrom_empty) {
793                 PRINT_INFO("Attached SCSI target virtual %s %s "
794                       "(file=\"%s\", fs=%lldMB, bs=%d, nblocks=%lld,"
795                       " cyln=%lld%s)",
796                       (dev->type == TYPE_DISK) ? "disk" : "cdrom",
797                       virt_dev->name, virt_dev->file_name,
798                       virt_dev->file_size >> 20, virt_dev->block_size,
799                       (long long unsigned int)virt_dev->nblocks,
800                       (long long unsigned int)virt_dev->nblocks/64/32,
801                       virt_dev->nblocks < 64*32
802                       ? " !WARNING! cyln less than 1" : "");
803         } else {
804                 PRINT_INFO("Attached empty SCSI target virtual cdrom %s",
805                         virt_dev->name);
806         }
807
808         dev->dh_priv = virt_dev;
809
810         dev->tst = DEF_TST;
811         dev->d_sense = DEF_DSENSE;
812         if (virt_dev->wt_flag && !virt_dev->nv_cache)
813                 dev->queue_alg = DEF_QUEUE_ALG_WT;
814         else
815                 dev->queue_alg = DEF_QUEUE_ALG;
816         dev->swp = DEF_SWP;
817         dev->tas = DEF_TAS;
818
819 out:
820         TRACE_EXIT();
821         return res;
822 }
823
824 /************************************************************
825  *  Function:  vdisk_detach
826  *
827  *  Argument:
828  *
829  *  Returns :  None
830  *
831  *  Description:  Called to detach this device type driver
832  ************************************************************/
833 static void vdisk_detach(struct scst_device *dev)
834 {
835         struct scst_vdisk_dev *virt_dev =
836             (struct scst_vdisk_dev *)dev->dh_priv;
837
838         TRACE_ENTRY();
839
840         TRACE_DBG("virt_id %d", dev->virt_id);
841
842         PRINT_INFO("Detached SCSI target virtual device %s (\"%s\")",
843                       virt_dev->name, virt_dev->file_name);
844
845         /* virt_dev will be freed by the caller */
846         dev->dh_priv = NULL;
847
848         TRACE_EXIT();
849         return;
850 }
851
852 static void vdisk_free_thr_data(struct scst_thr_data_hdr *d)
853 {
854         struct scst_vdisk_thr *thr =
855                 container_of(d, struct scst_vdisk_thr, hdr);
856
857         TRACE_ENTRY();
858
859         if (thr->fd)
860                 filp_close(thr->fd, NULL);
861
862         kfree(thr->iv);
863
864         kmem_cache_free(vdisk_thr_cachep, thr);
865
866         TRACE_EXIT();
867         return;
868 }
869
870 static struct scst_vdisk_thr *vdisk_init_thr_data(
871         struct scst_tgt_dev *tgt_dev)
872 {
873         struct scst_vdisk_thr *res;
874         struct scst_vdisk_dev *virt_dev =
875             (struct scst_vdisk_dev *)tgt_dev->dev->dh_priv;
876
877         TRACE_ENTRY();
878
879         EXTRACHECKS_BUG_ON(virt_dev->nullio);
880
881 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17)
882         res = kmem_cache_alloc(vdisk_thr_cachep, GFP_KERNEL);
883         if (res != NULL)
884                 memset(res, 0, sizeof(*res));
885 #else
886         res = kmem_cache_zalloc(vdisk_thr_cachep, GFP_KERNEL);
887 #endif
888         if (res == NULL) {
889                 TRACE(TRACE_OUT_OF_MEM, "%s", "Unable to allocate struct "
890                         "scst_vdisk_thr");
891                 goto out;
892         }
893
894         if (!virt_dev->cdrom_empty) {
895                 res->fd = vdev_open_fd(virt_dev);
896                 if (IS_ERR(res->fd)) {
897                         PRINT_ERROR("filp_open(%s) returned an error %ld",
898                                 virt_dev->file_name, PTR_ERR(res->fd));
899                         goto out_free;
900                 }
901                 if (virt_dev->blockio)
902                         res->bdev = res->fd->f_dentry->d_inode->i_bdev;
903                 else
904                         res->bdev = NULL;
905         } else
906                 res->fd = NULL;
907
908         scst_add_thr_data(tgt_dev, &res->hdr, vdisk_free_thr_data);
909
910 out:
911         TRACE_EXIT_HRES((unsigned long)res);
912         return res;
913
914 out_free:
915         kmem_cache_free(vdisk_thr_cachep, res);
916         res = NULL;
917         goto out;
918 }
919
920 static int vdisk_attach_tgt(struct scst_tgt_dev *tgt_dev)
921 {
922         struct scst_vdisk_tgt_dev *ftgt_dev;
923         int res = 0;
924
925         TRACE_ENTRY();
926
927         ftgt_dev = kzalloc(sizeof(*ftgt_dev), GFP_KERNEL);
928         if (ftgt_dev == NULL) {
929                 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of per-session "
930                         "virtual device failed");
931                 res = -ENOMEM;
932                 goto out;
933         }
934
935         tgt_dev->dh_priv = ftgt_dev;
936
937 out:
938         TRACE_EXIT_RES(res);
939         return res;
940 }
941
942 static void vdisk_detach_tgt(struct scst_tgt_dev *tgt_dev)
943 {
944         struct scst_vdisk_tgt_dev *ftgt_dev =
945                 (struct scst_vdisk_tgt_dev *)tgt_dev->dh_priv;
946
947         TRACE_ENTRY();
948
949         scst_del_all_thr_data(tgt_dev);
950
951         kfree(ftgt_dev);
952         tgt_dev->dh_priv = NULL;
953
954         TRACE_EXIT();
955         return;
956 }
957
958 static inline int vdisk_sync_queue_type(enum scst_cmd_queue_type qt)
959 {
960         switch (qt) {
961         case SCST_CMD_QUEUE_ORDERED:
962         case SCST_CMD_QUEUE_HEAD_OF_QUEUE:
963                 return 1;
964         default:
965                 return 0;
966         }
967 }
968
969 static inline int vdisk_need_pre_sync(enum scst_cmd_queue_type cur,
970         enum scst_cmd_queue_type last)
971 {
972         if (vdisk_sync_queue_type(cur))
973                 if (!vdisk_sync_queue_type(last))
974                         return 1;
975         return 0;
976 }
977
978 static int vdisk_do_job(struct scst_cmd *cmd)
979 {
980         int rc, res;
981         uint64_t lba_start = 0;
982         loff_t data_len = 0;
983         uint8_t *cdb = cmd->cdb;
984         int opcode = cdb[0];
985         loff_t loff;
986         struct scst_device *dev = cmd->dev;
987         struct scst_tgt_dev *tgt_dev = cmd->tgt_dev;
988         struct scst_vdisk_dev *virt_dev =
989                 (struct scst_vdisk_dev *)dev->dh_priv;
990         struct scst_thr_data_hdr *d;
991         struct scst_vdisk_thr *thr = NULL;
992         int fua = 0;
993
994         TRACE_ENTRY();
995
996         switch (cmd->queue_type) {
997         case SCST_CMD_QUEUE_ORDERED:
998                 TRACE(TRACE_ORDER, "ORDERED cmd %p (op %x)", cmd, cmd->cdb[0]);
999                 break;
1000         case SCST_CMD_QUEUE_HEAD_OF_QUEUE:
1001                 TRACE(TRACE_ORDER, "HQ cmd %p (op %x)", cmd, cmd->cdb[0]);
1002                 break;
1003         default:
1004                 break;
1005         }
1006
1007         rc = scst_check_local_events(cmd);
1008         if (unlikely(rc != 0))
1009                 goto out_done;
1010
1011         cmd->status = 0;
1012         cmd->msg_status = 0;
1013         cmd->host_status = DID_OK;
1014         cmd->driver_status = 0;
1015
1016         if (!virt_dev->nullio) {
1017                 d = scst_find_thr_data(tgt_dev);
1018                 if (unlikely(d == NULL)) {
1019                         thr = vdisk_init_thr_data(tgt_dev);
1020                         if (thr == NULL) {
1021                                 scst_set_busy(cmd);
1022                                 goto out_compl;
1023                         }
1024                         scst_thr_data_get(&thr->hdr);
1025                 } else
1026                         thr = container_of(d, struct scst_vdisk_thr, hdr);
1027         } else {
1028                 thr = &nullio_thr_data;
1029                 scst_thr_data_get(&thr->hdr);
1030         }
1031
1032         switch (opcode) {
1033         case READ_6:
1034         case WRITE_6:
1035         case VERIFY_6:
1036                 lba_start = (((cdb[1] & 0x1f) << (BYTE * 2)) +
1037                              (cdb[2] << (BYTE * 1)) +
1038                              (cdb[3] << (BYTE * 0)));
1039                 data_len = cmd->bufflen;
1040                 break;
1041         case READ_10:
1042         case READ_12:
1043         case WRITE_10:
1044         case WRITE_12:
1045         case VERIFY:
1046         case WRITE_VERIFY:
1047         case WRITE_VERIFY_12:
1048         case VERIFY_12:
1049                 lba_start |= ((u64)cdb[2]) << 24;
1050                 lba_start |= ((u64)cdb[3]) << 16;
1051                 lba_start |= ((u64)cdb[4]) << 8;
1052                 lba_start |= ((u64)cdb[5]);
1053                 data_len = cmd->bufflen;
1054                 break;
1055         case READ_16:
1056         case WRITE_16:
1057         case WRITE_VERIFY_16:
1058         case VERIFY_16:
1059                 lba_start |= ((u64)cdb[2]) << 56;
1060                 lba_start |= ((u64)cdb[3]) << 48;
1061                 lba_start |= ((u64)cdb[4]) << 40;
1062                 lba_start |= ((u64)cdb[5]) << 32;
1063                 lba_start |= ((u64)cdb[6]) << 24;
1064                 lba_start |= ((u64)cdb[7]) << 16;
1065                 lba_start |= ((u64)cdb[8]) << 8;
1066                 lba_start |= ((u64)cdb[9]);
1067                 data_len = cmd->bufflen;
1068                 break;
1069         case SYNCHRONIZE_CACHE:
1070                 lba_start |= ((u64)cdb[2]) << 24;
1071                 lba_start |= ((u64)cdb[3]) << 16;
1072                 lba_start |= ((u64)cdb[4]) << 8;
1073                 lba_start |= ((u64)cdb[5]);
1074                 data_len = ((cdb[7] << (BYTE * 1)) + (cdb[8] << (BYTE * 0)))
1075                                 << virt_dev->block_shift;
1076                 if (data_len == 0)
1077                         data_len = virt_dev->file_size -
1078                                 ((loff_t)lba_start << virt_dev->block_shift);
1079                 break;
1080         }
1081
1082         loff = (loff_t)lba_start << virt_dev->block_shift;
1083         TRACE_DBG("cmd %p, lba_start %lld, loff %lld, data_len %lld", cmd,
1084                   (long long unsigned int)lba_start,
1085                   (long long unsigned int)loff,
1086                   (long long unsigned int)data_len);
1087         if (unlikely(loff < 0) || unlikely(data_len < 0) ||
1088             unlikely((loff + data_len) > virt_dev->file_size)) {
1089                 PRINT_INFO("Access beyond the end of the device "
1090                         "(%lld of %lld, len %lld)",
1091                            (long long unsigned int)loff,
1092                            (long long unsigned int)virt_dev->file_size,
1093                            (long long unsigned int)data_len);
1094                 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1095                                         scst_sense_block_out_range_error));
1096                 goto out_compl;
1097         }
1098
1099         switch (opcode) {
1100         case WRITE_10:
1101         case WRITE_12:
1102         case WRITE_16:
1103                 fua = (cdb[1] & 0x8);
1104                 if (fua) {
1105                         TRACE(TRACE_ORDER, "FUA: loff=%lld, "
1106                                 "data_len=%lld", (long long unsigned int)loff,
1107                                 (long long unsigned int)data_len);
1108                 }
1109                 break;
1110         }
1111
1112         switch (opcode) {
1113         case READ_6:
1114         case READ_10:
1115         case READ_12:
1116         case READ_16:
1117                 if (virt_dev->blockio) {
1118                         blockio_exec_rw(cmd, thr, lba_start, 0);
1119                         goto out_thr;
1120                 } else
1121                         vdisk_exec_read(cmd, thr, loff);
1122                 break;
1123         case WRITE_6:
1124         case WRITE_10:
1125         case WRITE_12:
1126         case WRITE_16:
1127         {
1128                 int do_fsync = vdisk_sync_queue_type(cmd->queue_type);
1129                 struct scst_vdisk_tgt_dev *ftgt_dev =
1130                         (struct scst_vdisk_tgt_dev *)tgt_dev->dh_priv;
1131                 enum scst_cmd_queue_type last_queue_type =
1132                         ftgt_dev->last_write_cmd_queue_type;
1133                 ftgt_dev->last_write_cmd_queue_type = cmd->queue_type;
1134                 if (vdisk_need_pre_sync(cmd->queue_type, last_queue_type)) {
1135                         TRACE(TRACE_ORDER, "ORDERED WRITE(%d): loff=%lld, "
1136                                 "data_len=%lld", cmd->queue_type,
1137                               (long long unsigned int)loff,
1138                               (long long unsigned int)data_len);
1139                         do_fsync = 1;
1140                         if (vdisk_fsync(thr, 0, 0, cmd, dev) != 0)
1141                                 goto out_compl;
1142                 }
1143                 if (virt_dev->blockio) {
1144                         blockio_exec_rw(cmd, thr, lba_start, 1);
1145                         goto out_thr;
1146                 } else
1147                         vdisk_exec_write(cmd, thr, loff);
1148                 /* O_SYNC flag is used for WT devices */
1149                 if (do_fsync || fua)
1150                         vdisk_fsync(thr, loff, data_len, cmd, dev);
1151                 break;
1152         }
1153         case WRITE_VERIFY:
1154         case WRITE_VERIFY_12:
1155         case WRITE_VERIFY_16:
1156         {
1157                 int do_fsync = vdisk_sync_queue_type(cmd->queue_type);
1158                 struct scst_vdisk_tgt_dev *ftgt_dev =
1159                         (struct scst_vdisk_tgt_dev *) tgt_dev->dh_priv;
1160                 enum scst_cmd_queue_type last_queue_type =
1161                         ftgt_dev->last_write_cmd_queue_type;
1162                 ftgt_dev->last_write_cmd_queue_type = cmd->queue_type;
1163                 if (vdisk_need_pre_sync(cmd->queue_type, last_queue_type)) {
1164                         TRACE(TRACE_ORDER, "ORDERED "
1165                               "WRITE_VERIFY(%d): loff=%lld,"
1166                               " data_len=%lld", cmd->queue_type,
1167                               (long long unsigned int)loff,
1168                               (long long unsigned int)data_len);
1169                         do_fsync = 1;
1170                         if (vdisk_fsync(thr, 0, 0, cmd, dev) != 0)
1171                                 goto out_compl;
1172                 }
1173                 /* ToDo: BLOCKIO VERIFY */
1174                 vdisk_exec_write(cmd, thr, loff);
1175                 /* O_SYNC flag is used for WT devices */
1176                 if (scsi_status_is_good(cmd->status))
1177                         vdisk_exec_verify(cmd, thr, loff);
1178                 else if (do_fsync)
1179                         vdisk_fsync(thr, loff, data_len, cmd, dev);
1180                 break;
1181         }
1182         case SYNCHRONIZE_CACHE:
1183         {
1184                 int immed = cdb[1] & 0x2;
1185                 TRACE(TRACE_ORDER, "SYNCHRONIZE_CACHE: "
1186                         "loff=%lld, data_len=%lld, immed=%d",
1187                         (long long unsigned int)loff,
1188                         (long long unsigned int)data_len, immed);
1189                 if (immed) {
1190                         scst_cmd_get(cmd); /* to protect dev */
1191                         cmd->completed = 1;
1192                         cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT,
1193                                 SCST_CONTEXT_SAME);
1194                         vdisk_fsync(thr, loff, data_len, NULL, dev);
1195                         /* ToDo: vdisk_fsync() error processing */
1196                         scst_cmd_put(cmd);
1197                         goto out_thr;
1198                 } else {
1199                         vdisk_fsync(thr, loff, data_len, cmd, dev);
1200                         break;
1201                 }
1202         }
1203         case VERIFY_6:
1204         case VERIFY:
1205         case VERIFY_12:
1206         case VERIFY_16:
1207                 vdisk_exec_verify(cmd, thr, loff);
1208                 break;
1209         case MODE_SENSE:
1210         case MODE_SENSE_10:
1211                 vdisk_exec_mode_sense(cmd);
1212                 break;
1213         case MODE_SELECT:
1214         case MODE_SELECT_10:
1215                 vdisk_exec_mode_select(cmd);
1216                 break;
1217         case LOG_SELECT:
1218         case LOG_SENSE:
1219                 vdisk_exec_log(cmd);
1220                 break;
1221         case ALLOW_MEDIUM_REMOVAL:
1222                 vdisk_exec_prevent_allow_medium_removal(cmd);
1223                 break;
1224         case READ_TOC:
1225                 vdisk_exec_read_toc(cmd);
1226                 break;
1227         case START_STOP:
1228                 vdisk_fsync(thr, 0, virt_dev->file_size, cmd, dev);
1229                 break;
1230         case RESERVE:
1231         case RESERVE_10:
1232         case RELEASE:
1233         case RELEASE_10:
1234         case TEST_UNIT_READY:
1235                 break;
1236         case INQUIRY:
1237                 vdisk_exec_inquiry(cmd);
1238                 break;
1239         case REQUEST_SENSE:
1240                 vdisk_exec_request_sense(cmd);
1241                 break;
1242         case READ_CAPACITY:
1243                 vdisk_exec_read_capacity(cmd);
1244                 break;
1245         case SERVICE_ACTION_IN:
1246                 if ((cmd->cdb[1] & 0x1f) == SAI_READ_CAPACITY_16) {
1247                         vdisk_exec_read_capacity16(cmd);
1248                         break;
1249                 }
1250                 /* else go through */
1251         case REPORT_LUNS:
1252         default:
1253                 TRACE_DBG("Invalid opcode %d", opcode);
1254                 scst_set_cmd_error(cmd,
1255                     SCST_LOAD_SENSE(scst_sense_invalid_opcode));
1256         }
1257
1258 out_compl:
1259         cmd->completed = 1;
1260
1261 out_done:
1262         cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
1263
1264 out_thr:
1265         if (likely(thr != NULL))
1266                 scst_thr_data_put(&thr->hdr);
1267
1268         res = SCST_EXEC_COMPLETED;
1269
1270         TRACE_EXIT_RES(res);
1271         return res;
1272 }
1273
1274 static int vdisk_get_block_shift(struct scst_cmd *cmd)
1275 {
1276         struct scst_vdisk_dev *virt_dev =
1277             (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1278         return virt_dev->block_shift;
1279 }
1280
1281 /********************************************************************
1282  *  Function:  vdisk_parse
1283  *
1284  *  Argument:
1285  *
1286  *  Returns :  The state of the command
1287  *
1288  *  Description:  This does the parsing of the command
1289  *
1290  *  Note:  Not all states are allowed on return
1291  ********************************************************************/
1292 static int vdisk_parse(struct scst_cmd *cmd)
1293 {
1294         scst_sbc_generic_parse(cmd, vdisk_get_block_shift);
1295         return SCST_CMD_STATE_DEFAULT;
1296 }
1297
1298 /********************************************************************
1299  *  Function:  vcdrom_parse
1300  *
1301  *  Argument:
1302  *
1303  *  Returns :  The state of the command
1304  *
1305  *  Description:  This does the parsing of the command
1306  *
1307  *  Note:  Not all states are allowed on return
1308  ********************************************************************/
1309 static int vcdrom_parse(struct scst_cmd *cmd)
1310 {
1311         scst_cdrom_generic_parse(cmd, vdisk_get_block_shift);
1312         return SCST_CMD_STATE_DEFAULT;
1313 }
1314
1315 /********************************************************************
1316  *  Function:  vcdrom_exec
1317  *
1318  *  Argument:
1319  *
1320  *  Returns :
1321  *
1322  *  Description:
1323  ********************************************************************/
1324 static int vcdrom_exec(struct scst_cmd *cmd)
1325 {
1326         int res = SCST_EXEC_COMPLETED;
1327         int opcode = cmd->cdb[0];
1328         struct scst_vdisk_dev *virt_dev =
1329             (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1330
1331         TRACE_ENTRY();
1332
1333         cmd->status = 0;
1334         cmd->msg_status = 0;
1335         cmd->host_status = DID_OK;
1336         cmd->driver_status = 0;
1337
1338         if (virt_dev->cdrom_empty && (opcode != INQUIRY)) {
1339                 TRACE_DBG("%s", "CDROM empty");
1340                 scst_set_cmd_error(cmd,
1341                         SCST_LOAD_SENSE(scst_sense_not_ready));
1342                 goto out_done;
1343         }
1344
1345         if (virt_dev->media_changed && scst_is_ua_command(cmd)) {
1346                 spin_lock(&virt_dev->flags_lock);
1347                 if (virt_dev->media_changed) {
1348                         virt_dev->media_changed = 0;
1349                         TRACE_DBG("%s", "Reporting media changed");
1350                         scst_set_cmd_error(cmd,
1351                                 SCST_LOAD_SENSE(scst_sense_medium_changed_UA));
1352                         spin_unlock(&virt_dev->flags_lock);
1353                         goto out_done;
1354                 }
1355                 spin_unlock(&virt_dev->flags_lock);
1356         }
1357
1358         res = vdisk_do_job(cmd);
1359
1360 out:
1361         TRACE_EXIT_RES(res);
1362         return res;
1363
1364 out_done:
1365         cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
1366         goto out;
1367 }
1368
1369 static uint64_t vdisk_gen_dev_id_num(struct scst_vdisk_dev *virt_dev)
1370 {
1371         unsigned int dev_id_num, i;
1372
1373         for (dev_id_num = 0, i = 0; i < strlen(virt_dev->name); i++) {
1374                 unsigned int rv = random_values[(int)(virt_dev->name[i])];
1375                 /* Do some rotating of the bits */
1376                 dev_id_num ^= ((rv << i) | (rv >> (32 - i)));
1377         }
1378
1379         return ((uint64_t)scst_vdisk_ID << 32) | dev_id_num;
1380 }
1381
1382 static void vdisk_exec_inquiry(struct scst_cmd *cmd)
1383 {
1384         int32_t length, i, resp_len = 0;
1385         uint8_t *address;
1386         uint8_t *buf;
1387         struct scst_vdisk_dev *virt_dev =
1388             (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1389
1390         /* ToDo: Performance Boost:
1391          * 1. remove kzalloc, buf
1392          * 2. do all checks before touching *address
1393          * 3. zero *address
1394          * 4. write directly to *address
1395          */
1396
1397         TRACE_ENTRY();
1398
1399         buf = kzalloc(INQ_BUF_SZ,
1400                 scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL);
1401         if (buf == NULL) {
1402                 scst_set_busy(cmd);
1403                 goto out;
1404         }
1405
1406         length = scst_get_buf_first(cmd, &address);
1407         TRACE_DBG("length %d", length);
1408         if (unlikely(length <= 0)) {
1409                 if (length < 0) {
1410                         PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1411                         scst_set_cmd_error(cmd,
1412                                 SCST_LOAD_SENSE(scst_sense_hardw_error));
1413                 }
1414                 goto out_free;
1415         }
1416
1417         if (cmd->cdb[1] & CMDDT) {
1418                 TRACE_DBG("%s", "INQUIRY: CMDDT is unsupported");
1419                 scst_set_cmd_error(cmd,
1420                     SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1421                 goto out_put;
1422         }
1423
1424         buf[0] = cmd->dev->type;      /* type dev */
1425         if (virt_dev->removable)
1426                 buf[1] = 0x80;      /* removable */
1427         /* Vital Product */
1428         if (cmd->cdb[1] & EVPD) {
1429                 uint64_t dev_id_num;
1430                 int dev_id_len;
1431                 char dev_id_str[17];
1432
1433                 dev_id_num = vdisk_gen_dev_id_num(virt_dev);
1434                 dev_id_len = scnprintf(dev_id_str, sizeof(dev_id_str), "%llx",
1435                                         dev_id_num);
1436                 TRACE_DBG("dev_id num %lld, str %s, len %d", dev_id_num,
1437                         dev_id_str, dev_id_len);
1438                 if (0 == cmd->cdb[2]) {
1439                         /* supported vital product data pages */
1440                         buf[3] = 3;
1441                         buf[4] = 0x0; /* this page */
1442                         buf[5] = 0x80; /* unit serial number */
1443                         buf[6] = 0x83; /* device identification */
1444                         resp_len = buf[3] + 4;
1445                 } else if (0x80 == cmd->cdb[2]) {
1446                         /* unit serial number */
1447                         int usn_len = strlen(virt_dev->usn);
1448                         buf[1] = 0x80;
1449                         buf[3] = usn_len;
1450                         strncpy(&buf[4], virt_dev->usn, usn_len);
1451                         resp_len = buf[3] + 4;
1452                 } else if (0x83 == cmd->cdb[2]) {
1453                         /* device identification */
1454                         int num = 4;
1455
1456                         buf[1] = 0x83;
1457                         /* T10 vendor identifier field format (faked) */
1458                         buf[num + 0] = 0x2;     /* ASCII */
1459                         buf[num + 1] = 0x1;     /* Vendor ID */
1460                         if (virt_dev->blockio)
1461                                 memcpy(&buf[num + 4], SCST_BIO_VENDOR, 8);
1462                         else
1463                                 memcpy(&buf[num + 4], SCST_FIO_VENDOR, 8);
1464
1465                         i = strlen(virt_dev->name) + 1; /* for ' ' */
1466                         memset(&buf[num + 12], ' ', i + dev_id_len);
1467                         memcpy(&buf[num + 12], virt_dev->name, i-1);
1468                         memcpy(&buf[num + 12 + i], dev_id_str, dev_id_len);
1469                         buf[num + 3] = 8 + i + dev_id_len;
1470                         num += buf[num + 3];
1471
1472 #if 0 /* This isn't required and can be misleading, so let's disable it */
1473                         num += 4;
1474
1475                         /* NAA IEEE registered identifier (faked) */
1476                         buf[num] = 0x1; /* binary */
1477                         buf[num + 1] = 0x3;
1478                         buf[num + 2] = 0x0;
1479                         buf[num + 3] = 0x8;
1480                         buf[num + 4] = 0x51; /* IEEE OUI=0x123456 (faked) */
1481                         buf[num + 5] = 0x23;
1482                         buf[num + 6] = 0x45;
1483                         buf[num + 7] = 0x60;
1484                         buf[num + 8] = (dev_id_num >> 24);
1485                         buf[num + 9] = (dev_id_num >> 16) & 0xff;
1486                         buf[num + 10] = (dev_id_num >> 8) & 0xff;
1487                         buf[num + 11] = dev_id_num & 0xff;
1488                         num = num + 12 - 4;
1489 #endif
1490
1491                         resp_len = num;
1492                         buf[2] = (resp_len >> 8) & 0xFF;
1493                         buf[3] = resp_len & 0xFF;
1494                         resp_len += 4;
1495                 } else {
1496                         TRACE_DBG("INQUIRY: Unsupported EVPD page %x",
1497                                 cmd->cdb[2]);
1498                         scst_set_cmd_error(cmd,
1499                             SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1500                         goto out_put;
1501                 }
1502         } else {
1503                 int len;
1504
1505                 if (cmd->cdb[2] != 0) {
1506                         TRACE_DBG("INQUIRY: Unsupported page %x", cmd->cdb[2]);
1507                         scst_set_cmd_error(cmd,
1508                             SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1509                         goto out_put;
1510                 }
1511
1512                 buf[2] = 5; /* Device complies to SPC-3 */
1513                 buf[3] = 0x12;  /* HiSup + data in format specified in SPC */
1514                 buf[4] = 31;/* n - 4 = 35 - 4 = 31 for full 36 byte data */
1515                 buf[6] = 1; /* MultiP 1 */
1516                 buf[7] = 2; /* CMDQUE 1, BQue 0 => commands queuing supported */
1517
1518                 /*
1519                  * 8 byte ASCII Vendor Identification of the target
1520                  * - left aligned.
1521                  */
1522                 if (virt_dev->blockio)
1523                         memcpy(&buf[8], SCST_BIO_VENDOR, 8);
1524                 else
1525                         memcpy(&buf[8], SCST_FIO_VENDOR, 8);
1526
1527                 /*
1528                  * 16 byte ASCII Product Identification of the target - left
1529                  * aligned.
1530                  */
1531                 memset(&buf[16], ' ', 16);
1532                 len = min(strlen(virt_dev->name), (size_t)16);
1533                 memcpy(&buf[16], virt_dev->name, len);
1534
1535                 /*
1536                  * 4 byte ASCII Product Revision Level of the target - left
1537                  * aligned.
1538                  */
1539                 memcpy(&buf[32], SCST_FIO_REV, 4);
1540                 resp_len = buf[4] + 5;
1541         }
1542
1543         sBUG_ON(resp_len >= INQ_BUF_SZ);
1544         if (length > resp_len)
1545                 length = resp_len;
1546         memcpy(address, buf, length);
1547
1548 out_put:
1549         scst_put_buf(cmd, address);
1550         if (length < cmd->resp_data_len)
1551                 scst_set_resp_data_len(cmd, length);
1552
1553 out_free:
1554         kfree(buf);
1555
1556 out:
1557         TRACE_EXIT();
1558         return;
1559 }
1560
1561 static void vdisk_exec_request_sense(struct scst_cmd *cmd)
1562 {
1563         int32_t length, sl;
1564         uint8_t *address;
1565         uint8_t b[SCST_STANDARD_SENSE_LEN];
1566
1567         TRACE_ENTRY();
1568
1569         sl = scst_set_sense(b, sizeof(b), cmd->dev->d_sense,
1570                 SCST_LOAD_SENSE(scst_sense_no_sense));
1571
1572         length = scst_get_buf_first(cmd, &address);
1573         TRACE_DBG("length %d", length);
1574         if (length < 0) {
1575                 PRINT_ERROR("scst_get_buf_first() failed: %d)", length);
1576                 scst_set_cmd_error(cmd,
1577                         SCST_LOAD_SENSE(scst_sense_hardw_error));
1578                 goto out;
1579         }
1580
1581         length = min(sl, length);
1582         memcpy(address, b, length);
1583         scst_set_resp_data_len(cmd, length);
1584
1585         scst_put_buf(cmd, address);
1586
1587 out:
1588         TRACE_EXIT();
1589         return;
1590 }
1591
1592 /*
1593  * <<Following mode pages info copied from ST318451LW with some corrections>>
1594  *
1595  * ToDo: revise them
1596  */
1597 static int vdisk_err_recov_pg(unsigned char *p, int pcontrol,
1598                                struct scst_vdisk_dev *virt_dev)
1599 {       /* Read-Write Error Recovery page for mode_sense */
1600         const unsigned char err_recov_pg[] = {0x1, 0xa, 0xc0, 11, 240, 0, 0, 0,
1601                                               5, 0, 0xff, 0xff};
1602
1603         memcpy(p, err_recov_pg, sizeof(err_recov_pg));
1604         if (1 == pcontrol)
1605                 memset(p + 2, 0, sizeof(err_recov_pg) - 2);
1606         return sizeof(err_recov_pg);
1607 }
1608
1609 static int vdisk_disconnect_pg(unsigned char *p, int pcontrol,
1610                                 struct scst_vdisk_dev *virt_dev)
1611 {       /* Disconnect-Reconnect page for mode_sense */
1612         const unsigned char disconnect_pg[] = {0x2, 0xe, 128, 128, 0, 10, 0, 0,
1613                                                0, 0, 0, 0, 0, 0, 0, 0};
1614
1615         memcpy(p, disconnect_pg, sizeof(disconnect_pg));
1616         if (1 == pcontrol)
1617                 memset(p + 2, 0, sizeof(disconnect_pg) - 2);
1618         return sizeof(disconnect_pg);
1619 }
1620
1621 static int vdisk_rigid_geo_pg(unsigned char *p, int pcontrol,
1622         struct scst_vdisk_dev *virt_dev)
1623 {
1624         unsigned char geo_m_pg[] = {0x04, 0x16, 0, 0, 0, DEF_HEADS, 0, 0,
1625                                     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1626                                     0x3a, 0x98/* 15K RPM */, 0, 0};
1627         int32_t ncyl, n, rem;
1628         uint64_t dividend;
1629
1630         memcpy(p, geo_m_pg, sizeof(geo_m_pg));
1631         /*
1632          * Divide virt_dev->nblocks by (DEF_HEADS * DEF_SECTORS) and store
1633          * the quotient in ncyl and the remainder in rem.
1634          */
1635         dividend = virt_dev->nblocks;
1636         rem = do_div(dividend, DEF_HEADS * DEF_SECTORS);
1637         ncyl = dividend;
1638         if (rem != 0)
1639                 ncyl++;
1640         memcpy(&n, p + 2, sizeof(u32));
1641         n = n | (cpu_to_be32(ncyl) >> 8);
1642         memcpy(p + 2, &n, sizeof(u32));
1643         if (1 == pcontrol)
1644                 memset(p + 2, 0, sizeof(geo_m_pg) - 2);
1645         return sizeof(geo_m_pg);
1646 }
1647
1648 static int vdisk_format_pg(unsigned char *p, int pcontrol,
1649                             struct scst_vdisk_dev *virt_dev)
1650 {       /* Format device page for mode_sense */
1651         const unsigned char format_pg[] = {0x3, 0x16, 0, 0, 0, 0, 0, 0,
1652                                            0, 0, 0, 0, 0, 0, 0, 0,
1653                                            0, 0, 0, 0, 0x40, 0, 0, 0};
1654
1655         memcpy(p, format_pg, sizeof(format_pg));
1656         p[10] = (DEF_SECTORS >> 8) & 0xff;
1657         p[11] = DEF_SECTORS & 0xff;
1658         p[12] = (virt_dev->block_size >> 8) & 0xff;
1659         p[13] = virt_dev->block_size & 0xff;
1660         if (1 == pcontrol)
1661                 memset(p + 2, 0, sizeof(format_pg) - 2);
1662         return sizeof(format_pg);
1663 }
1664
1665 static int vdisk_caching_pg(unsigned char *p, int pcontrol,
1666                              struct scst_vdisk_dev *virt_dev)
1667 {       /* Caching page for mode_sense */
1668         const unsigned char caching_pg[] = {0x8, 18, 0x10, 0, 0xff, 0xff, 0, 0,
1669                 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0, 0, 0, 0, 0};
1670
1671         memcpy(p, caching_pg, sizeof(caching_pg));
1672         p[2] |= !(virt_dev->wt_flag || virt_dev->nv_cache) ? WCE : 0;
1673         if (1 == pcontrol)
1674                 memset(p + 2, 0, sizeof(caching_pg) - 2);
1675         return sizeof(caching_pg);
1676 }
1677
1678 static int vdisk_ctrl_m_pg(unsigned char *p, int pcontrol,
1679                             struct scst_vdisk_dev *virt_dev)
1680 {       /* Control mode page for mode_sense */
1681         const unsigned char ctrl_m_pg[] = {0xa, 0xa, 0, 0, 0, 0, 0, 0,
1682                                            0, 0, 0x2, 0x4b};
1683
1684         memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg));
1685         switch (pcontrol) {
1686         case 0:
1687                 p[2] |= virt_dev->dev->tst << 5;
1688                 p[2] |= virt_dev->dev->d_sense << 2;
1689                 p[3] |= virt_dev->dev->queue_alg << 4;
1690                 p[4] |= virt_dev->dev->swp << 3;
1691                 p[5] |= virt_dev->dev->tas << 6;
1692                 break;
1693         case 1:
1694                 memset(p + 2, 0, sizeof(ctrl_m_pg) - 2);
1695 #if 0   /*
1696          * It's too early to implement it, since we can't control the
1697          * backstorage device parameters. ToDo
1698          */
1699                 p[2] |= 7 << 5;         /* TST */
1700                 p[3] |= 0xF << 4;       /* QUEUE ALGORITHM MODIFIER */
1701 #endif
1702                 p[2] |= 1 << 2;         /* D_SENSE */
1703                 p[4] |= 1 << 3;         /* SWP */
1704                 p[5] |= 1 << 6;         /* TAS */
1705                 break;
1706         case 2:
1707                 p[2] |= DEF_TST << 5;
1708                 p[2] |= DEF_DSENSE << 2;
1709                 if (virt_dev->wt_flag || virt_dev->nv_cache)
1710                         p[3] |= DEF_QUEUE_ALG_WT << 4;
1711                 else
1712                         p[3] |= DEF_QUEUE_ALG << 4;
1713                 p[4] |= DEF_SWP << 3;
1714                 p[5] |= DEF_TAS << 6;
1715                 break;
1716         default:
1717                 sBUG();
1718         }
1719         return sizeof(ctrl_m_pg);
1720 }
1721
1722 static int vdisk_iec_m_pg(unsigned char *p, int pcontrol,
1723                            struct scst_vdisk_dev *virt_dev)
1724 {       /* Informational Exceptions control mode page for mode_sense */
1725         const unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0,
1726                                           0, 0, 0x0, 0x0};
1727         memcpy(p, iec_m_pg, sizeof(iec_m_pg));
1728         if (1 == pcontrol)
1729                 memset(p + 2, 0, sizeof(iec_m_pg) - 2);
1730         return sizeof(iec_m_pg);
1731 }
1732
1733 static void vdisk_exec_mode_sense(struct scst_cmd *cmd)
1734 {
1735         int32_t length;
1736         uint8_t *address;
1737         uint8_t *buf;
1738         struct scst_vdisk_dev *virt_dev;
1739         uint32_t blocksize;
1740         uint64_t nblocks;
1741         unsigned char dbd, type;
1742         int pcontrol, pcode, subpcode;
1743         unsigned char dev_spec;
1744         int msense_6, offset = 0, len;
1745         unsigned char *bp;
1746
1747         TRACE_ENTRY();
1748
1749         buf = kzalloc(MSENSE_BUF_SZ,
1750                 scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL);
1751         if (buf == NULL) {
1752                 scst_set_busy(cmd);
1753                 goto out;
1754         }
1755
1756         virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1757         blocksize = virt_dev->block_size;
1758         nblocks = virt_dev->nblocks;
1759
1760         type = cmd->dev->type;    /* type dev */
1761         dbd = cmd->cdb[1] & DBD;
1762         pcontrol = (cmd->cdb[2] & 0xc0) >> 6;
1763         pcode = cmd->cdb[2] & 0x3f;
1764         subpcode = cmd->cdb[3];
1765         msense_6 = (MODE_SENSE == cmd->cdb[0]);
1766         dev_spec = (virt_dev->dev->rd_only ? WP : 0) | DPOFUA;
1767
1768         length = scst_get_buf_first(cmd, &address);
1769         if (unlikely(length <= 0)) {
1770                 if (length < 0) {
1771                         PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1772                         scst_set_cmd_error(cmd,
1773                                 SCST_LOAD_SENSE(scst_sense_hardw_error));
1774                 }
1775                 goto out_free;
1776         }
1777
1778         if (0x3 == pcontrol) {
1779                 TRACE_DBG("%s", "MODE SENSE: Saving values not supported");
1780                 scst_set_cmd_error(cmd,
1781                     SCST_LOAD_SENSE(scst_sense_saving_params_unsup));
1782                 goto out_put;
1783         }
1784
1785         if (msense_6) {
1786                 buf[1] = type;
1787                 buf[2] = dev_spec;
1788                 offset = 4;
1789         } else {
1790                 buf[2] = type;
1791                 buf[3] = dev_spec;
1792                 offset = 8;
1793         }
1794
1795         if (0 != subpcode) {
1796                 /* TODO: Control Extension page */
1797                 TRACE_DBG("%s", "MODE SENSE: Only subpage 0 is supported");
1798                 scst_set_cmd_error(cmd,
1799                     SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1800                 goto out_put;
1801         }
1802
1803         if (!dbd) {
1804                 /* Create block descriptor */
1805                 buf[offset - 1] = 0x08;         /* block descriptor length */
1806                 if (nblocks >> 32) {
1807                         buf[offset + 0] = 0xFF;
1808                         buf[offset + 1] = 0xFF;
1809                         buf[offset + 2] = 0xFF;
1810                         buf[offset + 3] = 0xFF;
1811                 } else {
1812                         /* num blks */
1813                         buf[offset + 0] = (nblocks >> (BYTE * 3)) & 0xFF;
1814                         buf[offset + 1] = (nblocks >> (BYTE * 2)) & 0xFF;
1815                         buf[offset + 2] = (nblocks >> (BYTE * 1)) & 0xFF;
1816                         buf[offset + 3] = (nblocks >> (BYTE * 0)) & 0xFF;
1817                 }
1818                 buf[offset + 4] = 0;                    /* density code */
1819                 buf[offset + 5] = (blocksize >> (BYTE * 2)) & 0xFF;/* blklen */
1820                 buf[offset + 6] = (blocksize >> (BYTE * 1)) & 0xFF;
1821                 buf[offset + 7] = (blocksize >> (BYTE * 0)) & 0xFF;
1822
1823                 offset += 8;                    /* increment offset */
1824         }
1825
1826         bp = buf + offset;
1827
1828         switch (pcode) {
1829         case 0x1:       /* Read-Write error recovery page, direct access */
1830                 len = vdisk_err_recov_pg(bp, pcontrol, virt_dev);
1831                 break;
1832         case 0x2:       /* Disconnect-Reconnect page, all devices */
1833                 len = vdisk_disconnect_pg(bp, pcontrol, virt_dev);
1834                 break;
1835         case 0x3:       /* Format device page, direct access */
1836                 len = vdisk_format_pg(bp, pcontrol, virt_dev);
1837                 break;
1838         case 0x4:       /* Rigid disk geometry */
1839                 len = vdisk_rigid_geo_pg(bp, pcontrol, virt_dev);
1840                 break;
1841         case 0x8:       /* Caching page, direct access */
1842                 len = vdisk_caching_pg(bp, pcontrol, virt_dev);
1843                 break;
1844         case 0xa:       /* Control Mode page, all devices */
1845                 len = vdisk_ctrl_m_pg(bp, pcontrol, virt_dev);
1846                 break;
1847         case 0x1c:      /* Informational Exceptions Mode page, all devices */
1848                 len = vdisk_iec_m_pg(bp, pcontrol, virt_dev);
1849                 break;
1850         case 0x3f:      /* Read all Mode pages */
1851                 len = vdisk_err_recov_pg(bp, pcontrol, virt_dev);
1852                 len += vdisk_disconnect_pg(bp + len, pcontrol, virt_dev);
1853                 len += vdisk_format_pg(bp + len, pcontrol, virt_dev);
1854                 len += vdisk_caching_pg(bp + len, pcontrol, virt_dev);
1855                 len += vdisk_ctrl_m_pg(bp + len, pcontrol, virt_dev);
1856                 len += vdisk_iec_m_pg(bp + len, pcontrol, virt_dev);
1857                 len += vdisk_rigid_geo_pg(bp + len, pcontrol, virt_dev);
1858                 break;
1859         default:
1860                 TRACE_DBG("MODE SENSE: Unsupported page %x", pcode);
1861                 scst_set_cmd_error(cmd,
1862                     SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1863                 goto out_put;
1864         }
1865
1866         offset += len;
1867
1868         if (msense_6)
1869                 buf[0] = offset - 1;
1870         else {
1871                 buf[0] = ((offset - 2) >> 8) & 0xff;
1872                 buf[1] = (offset - 2) & 0xff;
1873         }
1874
1875         if (offset > length)
1876                 offset = length;
1877         memcpy(address, buf, offset);
1878
1879 out_put:
1880         scst_put_buf(cmd, address);
1881         if (offset < cmd->resp_data_len)
1882                 scst_set_resp_data_len(cmd, offset);
1883
1884 out_free:
1885         kfree(buf);
1886
1887 out:
1888         TRACE_EXIT();
1889         return;
1890 }
1891
1892 static int vdisk_set_wt(struct scst_vdisk_dev *virt_dev, int wt)
1893 {
1894         int res = 0;
1895
1896         TRACE_ENTRY();
1897
1898         if ((virt_dev->wt_flag == wt) || virt_dev->nullio || virt_dev->nv_cache)
1899                 goto out;
1900
1901         spin_lock(&virt_dev->flags_lock);
1902         virt_dev->wt_flag = wt;
1903         spin_unlock(&virt_dev->flags_lock);
1904
1905         scst_dev_del_all_thr_data(virt_dev->dev);
1906
1907 out:
1908         TRACE_EXIT_RES(res);
1909         return res;
1910 }
1911
1912 static void vdisk_ctrl_m_pg_select(unsigned char *p,
1913         struct scst_vdisk_dev *virt_dev)
1914 {
1915         struct scst_device *dev = virt_dev->dev;
1916         int old_swp = dev->swp, old_tas = dev->tas, old_dsense = dev->d_sense;
1917
1918 #if 0
1919         /* Not implemented yet, see comment in vdisk_ctrl_m_pg() */
1920         dev->tst = p[2] >> 5;
1921         dev->queue_alg = p[3] >> 4;
1922 #endif
1923         dev->swp = (p[4] & 0x8) >> 3;
1924         dev->tas = (p[5] & 0x40) >> 6;
1925         dev->d_sense = (p[2] & 0x4) >> 2;
1926
1927         PRINT_INFO("Device %s: new control mode page parameters: SWP %x "
1928                 "(was %x), TAS %x (was %x), D_SENSE %d (was %d)",
1929                 virt_dev->name, dev->swp, old_swp, dev->tas, old_tas,
1930                 dev->d_sense, old_dsense);
1931         return;
1932 }
1933
1934 static void vdisk_exec_mode_select(struct scst_cmd *cmd)
1935 {
1936         int32_t length;
1937         uint8_t *address;
1938         struct scst_vdisk_dev *virt_dev;
1939         int mselect_6, offset;
1940
1941         TRACE_ENTRY();
1942
1943         virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1944         mselect_6 = (MODE_SELECT == cmd->cdb[0]);
1945
1946         length = scst_get_buf_first(cmd, &address);
1947         if (unlikely(length <= 0)) {
1948                 if (length < 0) {
1949                         PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1950                         scst_set_cmd_error(cmd,
1951                                 SCST_LOAD_SENSE(scst_sense_hardw_error));
1952                 }
1953                 goto out;
1954         }
1955
1956         if (!(cmd->cdb[1] & PF) || (cmd->cdb[1] & SP)) {
1957                 TRACE(TRACE_MINOR|TRACE_SCSI, "MODE SELECT: Unsupported "
1958                         "value(s) of PF and/or SP bits (cdb[1]=%x)",
1959                         cmd->cdb[1]);
1960                 scst_set_cmd_error(cmd,
1961                     SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1962                 goto out_put;
1963         }
1964
1965         if (mselect_6)
1966                 offset = 4;
1967         else
1968                 offset = 8;
1969
1970         if (address[offset - 1] == 8) {
1971                 offset += 8;
1972         } else if (address[offset - 1] != 0) {
1973                 PRINT_ERROR("%s", "MODE SELECT: Wrong parameters list "
1974                         "lenght");
1975                 scst_set_cmd_error(cmd,
1976                     SCST_LOAD_SENSE(scst_sense_invalid_field_in_parm_list));
1977                 goto out_put;
1978         }
1979
1980         while (length > offset + 2) {
1981                 if (address[offset] & PS) {
1982                         PRINT_ERROR("%s", "MODE SELECT: Illegal PS bit");
1983                         scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1984                                 scst_sense_invalid_field_in_parm_list));
1985                         goto out_put;
1986                 }
1987                 if ((address[offset] & 0x3f) == 0x8) {
1988                         /* Caching page */
1989                         if (address[offset + 1] != 18) {
1990                                 PRINT_ERROR("%s", "MODE SELECT: Invalid "
1991                                         "caching page request");
1992                                 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1993                                     scst_sense_invalid_field_in_parm_list));
1994                                 goto out_put;
1995                         }
1996                         if (vdisk_set_wt(virt_dev,
1997                               (address[offset + 2] & WCE) ? 0 : 1) != 0) {
1998                                 scst_set_cmd_error(cmd,
1999                                     SCST_LOAD_SENSE(scst_sense_hardw_error));
2000                                 goto out_put;
2001                         }
2002                         break;
2003                 } else if ((address[offset] & 0x3f) == 0xA) {
2004                         /* Control page */
2005                         if (address[offset + 1] != 0xA) {
2006                                 PRINT_ERROR("%s", "MODE SELECT: Invalid "
2007                                         "control page request");
2008                                 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
2009                                     scst_sense_invalid_field_in_parm_list));
2010                                 goto out_put;
2011                         }
2012                         vdisk_ctrl_m_pg_select(&address[offset], virt_dev);
2013                 } else {
2014                         PRINT_ERROR("MODE SELECT: Invalid request %x",
2015                                 address[offset] & 0x3f);
2016                         scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
2017                             scst_sense_invalid_field_in_parm_list));
2018                         goto out_put;
2019                 }
2020                 offset += address[offset + 1];
2021         }
2022
2023 out_put:
2024         scst_put_buf(cmd, address);
2025
2026 out:
2027         TRACE_EXIT();
2028         return;
2029 }
2030
2031 static void vdisk_exec_log(struct scst_cmd *cmd)
2032 {
2033         TRACE_ENTRY();
2034
2035         /* No log pages are supported */
2036         scst_set_cmd_error(cmd,
2037                 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
2038
2039         TRACE_EXIT();
2040         return;
2041 }
2042
2043 static void vdisk_exec_read_capacity(struct scst_cmd *cmd)
2044 {
2045         int32_t length;
2046         uint8_t *address;
2047         struct scst_vdisk_dev *virt_dev;
2048         uint32_t blocksize;
2049         uint64_t nblocks;
2050         uint8_t buffer[READ_CAP_LEN];
2051
2052         TRACE_ENTRY();
2053
2054         virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2055         blocksize = virt_dev->block_size;
2056         nblocks = virt_dev->nblocks;
2057
2058         /* last block on the virt_dev is (nblocks-1) */
2059         memset(buffer, 0, sizeof(buffer));
2060         if (nblocks >> 32) {
2061                 buffer[0] = 0xFF;
2062                 buffer[1] = 0xFF;
2063                 buffer[2] = 0xFF;
2064                 buffer[3] = 0xFF;
2065         } else {
2066                 buffer[0] = ((nblocks - 1) >> (BYTE * 3)) & 0xFF;
2067                 buffer[1] = ((nblocks - 1) >> (BYTE * 2)) & 0xFF;
2068                 buffer[2] = ((nblocks - 1) >> (BYTE * 1)) & 0xFF;
2069                 buffer[3] = ((nblocks - 1) >> (BYTE * 0)) & 0xFF;
2070         }
2071         buffer[4] = (blocksize >> (BYTE * 3)) & 0xFF;
2072         buffer[5] = (blocksize >> (BYTE * 2)) & 0xFF;
2073         buffer[6] = (blocksize >> (BYTE * 1)) & 0xFF;
2074         buffer[7] = (blocksize >> (BYTE * 0)) & 0xFF;
2075
2076         length = scst_get_buf_first(cmd, &address);
2077         if (unlikely(length <= 0)) {
2078                 if (length < 0) {
2079                         PRINT_ERROR("scst_get_buf_first() failed: %d", length);
2080                         scst_set_cmd_error(cmd,
2081                                 SCST_LOAD_SENSE(scst_sense_hardw_error));
2082                 }
2083                 goto out;
2084         }
2085
2086         if (length > READ_CAP_LEN)
2087                 length = READ_CAP_LEN;
2088         memcpy(address, buffer, length);
2089
2090         scst_put_buf(cmd, address);
2091
2092         if (length < cmd->resp_data_len)
2093                 scst_set_resp_data_len(cmd, length);
2094
2095 out:
2096         TRACE_EXIT();
2097         return;
2098 }
2099
2100 static void vdisk_exec_read_capacity16(struct scst_cmd *cmd)
2101 {
2102         int32_t length;
2103         uint8_t *address;
2104         struct scst_vdisk_dev *virt_dev;
2105         uint32_t blocksize;
2106         uint64_t nblocks;
2107         uint8_t buffer[READ_CAP16_LEN];
2108
2109         TRACE_ENTRY();
2110
2111         virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2112         blocksize = virt_dev->block_size;
2113         nblocks = virt_dev->nblocks - 1;
2114
2115         memset(buffer, 0, sizeof(buffer));
2116
2117         buffer[0] = nblocks >> 56;
2118         buffer[1] = (nblocks >> 48) & 0xFF;
2119         buffer[2] = (nblocks >> 40) & 0xFF;
2120         buffer[3] = (nblocks >> 32) & 0xFF;
2121         buffer[4] = (nblocks >> 24) & 0xFF;
2122         buffer[5] = (nblocks >> 16) & 0xFF;
2123         buffer[6] = (nblocks >> 8) & 0xFF;
2124         buffer[7] = nblocks & 0xFF;
2125
2126         buffer[8] = (blocksize >> (BYTE * 3)) & 0xFF;
2127         buffer[9] = (blocksize >> (BYTE * 2)) & 0xFF;
2128         buffer[10] = (blocksize >> (BYTE * 1)) & 0xFF;
2129         buffer[11] = (blocksize >> (BYTE * 0)) & 0xFF;
2130
2131         switch (blocksize) {
2132         case 512:
2133                 buffer[13] = 3;
2134                 break;
2135         case 1024:
2136                 buffer[13] = 2;
2137                 break;
2138         case 2048:
2139                 buffer[13] = 1;
2140                 break;
2141         default:
2142                 PRINT_ERROR("%s: Unexpected block size %d",
2143                         cmd->op_name, blocksize);
2144                 /* go through */
2145         case 4096:
2146                 buffer[13] = 0;
2147                 break;
2148         }
2149
2150         length = scst_get_buf_first(cmd, &address);
2151         if (unlikely(length <= 0)) {
2152                 if (length < 0) {
2153                         PRINT_ERROR("scst_get_buf_first() failed: %d", length);
2154                         scst_set_cmd_error(cmd,
2155                                 SCST_LOAD_SENSE(scst_sense_hardw_error));
2156                         }
2157                 goto out;
2158         }
2159
2160         /*
2161          * Some versions of Windows have a bug, which makes them consider
2162          * response of READ CAPACITY(16) longer than 12 bytes as a faulty one.
2163          * As the result, such Windows'es refuse to see SCST exported
2164          * devices >2TB in size. This is fixed by MS in latter Windows
2165          * versions, probably, by some hotfix.
2166          *
2167          * But if you're using such buggy Windows and experience this problem,
2168          * change this '1' to '0'.
2169          */
2170 #if 1
2171         if (length > READ_CAP16_LEN)
2172                 length = READ_CAP16_LEN;
2173 #else
2174         if (length > 12)
2175                 length = 12;
2176 #endif
2177         memcpy(address, buffer, length);
2178
2179         scst_put_buf(cmd, address);
2180
2181         if (length < cmd->resp_data_len)
2182                 scst_set_resp_data_len(cmd, length);
2183
2184 out:
2185         TRACE_EXIT();
2186         return;
2187 }
2188
2189 static void vdisk_exec_read_toc(struct scst_cmd *cmd)
2190 {
2191         int32_t length, off = 0;
2192         uint8_t *address;
2193         struct scst_vdisk_dev *virt_dev;
2194         uint32_t nblocks;
2195         uint8_t buffer[4+8+8] = { 0x00, 0x0a, 0x01, 0x01, 0x00, 0x14,
2196                                   0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
2197
2198         TRACE_ENTRY();
2199
2200         if (cmd->dev->type != TYPE_ROM) {
2201                 PRINT_ERROR("%s", "READ TOC for non-CDROM device");
2202                 scst_set_cmd_error(cmd,
2203                         SCST_LOAD_SENSE(scst_sense_invalid_opcode));
2204                 goto out;
2205         }
2206
2207         if (cmd->cdb[2] & 0x0e/*Format*/) {
2208                 PRINT_ERROR("%s", "READ TOC: invalid requested data format");
2209                 scst_set_cmd_error(cmd,
2210                         SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
2211                 goto out;
2212         }
2213
2214         if ((cmd->cdb[6] != 0 && (cmd->cdb[2] & 0x01)) ||
2215             (cmd->cdb[6] > 1 && cmd->cdb[6] != 0xAA)) {
2216                 PRINT_ERROR("READ TOC: invalid requested track number %x",
2217                         cmd->cdb[6]);
2218                 scst_set_cmd_error(cmd,
2219                         SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
2220                 goto out;
2221         }
2222
2223         length = scst_get_buf_first(cmd, &address);
2224         if (unlikely(length <= 0)) {
2225                 if (length < 0) {
2226                         PRINT_ERROR("scst_get_buf_first() failed: %d", length);
2227                         scst_set_cmd_error(cmd,
2228                                 SCST_LOAD_SENSE(scst_sense_hardw_error));
2229                 }
2230                 goto out;
2231         }
2232
2233         virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2234         /* ToDo when you have > 8TB ROM device. */
2235         nblocks = (uint32_t)virt_dev->nblocks;
2236
2237         /* Header */
2238         memset(buffer, 0, sizeof(buffer));
2239         buffer[2] = 0x01;    /* First Track/Session */
2240         buffer[3] = 0x01;    /* Last Track/Session */
2241         off = 4;
2242         if (cmd->cdb[6] <= 1) {
2243                 /* Fistr TOC Track Descriptor */
2244                 /* ADDR    0x10 - Q Sub-channel encodes current position data
2245                    CONTROL 0x04 - Data track, recoreded uninterrupted */
2246                 buffer[off+1] = 0x14;
2247                 /* Track Number */
2248                 buffer[off+2] = 0x01;
2249                 off += 8;
2250         }
2251         if (!(cmd->cdb[2] & 0x01)) {
2252                 /* Lead-out area TOC Track Descriptor */
2253                 buffer[off+1] = 0x14;
2254                 /* Track Number */
2255                 buffer[off+2] = 0xAA;
2256                 /* Track Start Address */
2257                 buffer[off+4] = (nblocks >> (BYTE * 3)) & 0xFF;
2258                 buffer[off+5] = (nblocks >> (BYTE * 2)) & 0xFF;
2259                 buffer[off+6] = (nblocks >> (BYTE * 1)) & 0xFF;
2260                 buffer[off+7] = (nblocks >> (BYTE * 0)) & 0xFF;
2261                 off += 8;
2262         }
2263
2264         buffer[1] = off - 2;    /* Data  Length */
2265
2266         if (off > length)
2267                 off = length;
2268         memcpy(address, buffer, off);
2269
2270         scst_put_buf(cmd, address);
2271
2272         if (off < cmd->resp_data_len)
2273                 scst_set_resp_data_len(cmd, off);
2274
2275 out:
2276         TRACE_EXIT();
2277         return;
2278 }
2279
2280 static void vdisk_exec_prevent_allow_medium_removal(struct scst_cmd *cmd)
2281 {
2282         struct scst_vdisk_dev *virt_dev =
2283                 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2284
2285         TRACE_DBG("PERSIST/PREVENT 0x%02x", cmd->cdb[4]);
2286
2287         if (cmd->dev->type == TYPE_ROM) {
2288                 spin_lock(&virt_dev->flags_lock);
2289                 virt_dev->prevent_allow_medium_removal =
2290                         cmd->cdb[4] & 0x01 ? 1 : 0;
2291                 spin_unlock(&virt_dev->flags_lock);
2292         }
2293
2294         return;
2295 }
2296
2297 static int vdisk_fsync(struct scst_vdisk_thr *thr, loff_t loff,
2298         loff_t len, struct scst_cmd *cmd, struct scst_device *dev)
2299 {
2300         int res = 0;
2301         struct scst_vdisk_dev *virt_dev =
2302                 (struct scst_vdisk_dev *)dev->dh_priv;
2303         struct file *file = thr->fd;
2304         struct inode *inode;
2305         struct address_space *mapping;
2306
2307         TRACE_ENTRY();
2308
2309         /* Hopefully, the compiler will generate the single comparison */
2310         if (virt_dev->nv_cache || virt_dev->blockio || virt_dev->wt_flag ||
2311             virt_dev->o_direct_flag || virt_dev->nullio)
2312                 goto out;
2313
2314         inode = file->f_dentry->d_inode;
2315         mapping = file->f_mapping;
2316
2317         res = sync_page_range(inode, mapping, loff, len);
2318         if (unlikely(res != 0)) {
2319                 PRINT_ERROR("sync_page_range() failed (%d)", res);
2320                 if (cmd != NULL) {
2321                         scst_set_cmd_error(cmd,
2322                                 SCST_LOAD_SENSE(scst_sense_write_error));
2323                 }
2324         }
2325
2326         /* ToDo: flush the device cache, if needed */
2327
2328 out:
2329         TRACE_EXIT_RES(res);
2330         return res;
2331 }
2332
2333 static struct iovec *vdisk_alloc_iv(struct scst_cmd *cmd,
2334         struct scst_vdisk_thr *thr)
2335 {
2336         int iv_count;
2337
2338         iv_count = scst_get_buf_count(cmd);
2339         if (iv_count > thr->iv_count) {
2340                 kfree(thr->iv);
2341                 /* It can't be called in atomic context */
2342                 thr->iv = kmalloc(sizeof(*thr->iv) * iv_count, GFP_KERNEL);
2343                 if (thr->iv == NULL) {
2344                         PRINT_ERROR("Unable to allocate iv (%d)", iv_count);
2345                         scst_set_busy(cmd);
2346                         goto out;
2347                 }
2348                 thr->iv_count = iv_count;
2349         }
2350
2351 out:
2352         return thr->iv;
2353 }
2354
2355 /*
2356  * copied from <ksrc>/fs/read_write.*
2357  */
2358 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
2359 static void wait_on_retry_sync_kiocb(struct kiocb *iocb)
2360 {
2361         set_current_state(TASK_UNINTERRUPTIBLE);
2362         if (!kiocbIsKicked(iocb))
2363                 schedule();
2364         else
2365                 kiocbClearKicked(iocb);
2366         __set_current_state(TASK_RUNNING);
2367 }
2368
2369 typedef ssize_t (*iov_fn_t)(struct kiocb *, const struct iovec *,
2370                                 unsigned long, loff_t);
2371
2372 static ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
2373                 unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn)
2374 {
2375         struct kiocb kiocb;
2376         ssize_t ret;
2377
2378         init_sync_kiocb(&kiocb, filp);
2379         kiocb.ki_pos = *ppos;
2380         kiocb.ki_left = len;
2381         kiocb.ki_nbytes = len;
2382
2383         for (;;) {
2384                 ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos);
2385                 if (ret != -EIOCBRETRY)
2386                         break;
2387                 wait_on_retry_sync_kiocb(&kiocb);
2388         }
2389
2390         if (ret == -EIOCBQUEUED)
2391                 ret = wait_on_sync_kiocb(&kiocb);
2392         *ppos = kiocb.ki_pos;
2393         return ret;
2394 }
2395 #endif
2396
2397 static void vdisk_exec_read(struct scst_cmd *cmd,
2398         struct scst_vdisk_thr *thr, loff_t loff)
2399 {
2400         mm_segment_t old_fs;
2401         loff_t err;
2402         ssize_t length, full_len;
2403         uint8_t __user *address;
2404         struct scst_vdisk_dev *virt_dev =
2405             (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2406         struct file *fd = thr->fd;
2407         struct iovec *iv;
2408         int iv_count, i;
2409
2410         TRACE_ENTRY();
2411
2412         if (virt_dev->nullio)
2413                 goto out;
2414
2415         iv = vdisk_alloc_iv(cmd, thr);
2416         if (iv == NULL)
2417                 goto out;
2418
2419         iv_count = 0;
2420         full_len = 0;
2421         i = -1;
2422         length = scst_get_buf_first(cmd, (uint8_t __force **)&address);
2423         while (length > 0) {
2424                 full_len += length;
2425                 i++;
2426                 iv_count++;
2427                 iv[i].iov_base = address;
2428                 iv[i].iov_len = length;
2429                 length = scst_get_buf_next(cmd, (uint8_t __force **)&address);
2430         }
2431         if (unlikely(length < 0)) {
2432                 PRINT_ERROR("scst_get_buf_() failed: %zd", length);
2433                 scst_set_cmd_error(cmd,
2434                     SCST_LOAD_SENSE(scst_sense_hardw_error));
2435                 goto out_put;
2436         }
2437
2438         old_fs = get_fs();
2439         set_fs(get_ds());
2440
2441         TRACE_DBG("reading(iv_count %d, full_len %zd)", iv_count, full_len);
2442         /* SEEK */
2443         if (fd->f_op->llseek)
2444                 err = fd->f_op->llseek(fd, loff, 0/*SEEK_SET*/);
2445         else
2446                 err = default_llseek(fd, loff, 0/*SEEK_SET*/);
2447         if (err != loff) {
2448                 PRINT_ERROR("lseek trouble %lld != %lld",
2449                             (long long unsigned int)err,
2450                             (long long unsigned int)loff);
2451                 scst_set_cmd_error(cmd,
2452                         SCST_LOAD_SENSE(scst_sense_hardw_error));
2453                 goto out_set_fs;
2454         }
2455
2456         /* READ */
2457 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
2458         err = fd->f_op->readv(fd, iv, iv_count, &fd->f_pos);
2459 #else
2460         err = do_sync_readv_writev(fd, iv, iv_count, full_len,
2461                                    &fd->f_pos, fd->f_op->aio_read);
2462 #endif
2463
2464         if ((err < 0) || (err < full_len)) {
2465                 PRINT_ERROR("readv() returned %lld from %zd",
2466                             (long long unsigned int)err,
2467                             full_len);
2468                 if (err == -EAGAIN)
2469                         scst_set_busy(cmd);
2470                 else {
2471                         scst_set_cmd_error(cmd,
2472                             SCST_LOAD_SENSE(scst_sense_read_error));
2473                 }
2474                 goto out_set_fs;
2475         }
2476
2477 out_set_fs:
2478         set_fs(old_fs);
2479
2480 out_put:
2481         for (; i >= 0; i--)
2482                 scst_put_buf(cmd, (void __force *)(iv[i].iov_base));
2483
2484 out:
2485         TRACE_EXIT();
2486         return;
2487 }
2488
2489 static void vdisk_exec_write(struct scst_cmd *cmd,
2490         struct scst_vdisk_thr *thr, loff_t loff)
2491 {
2492         mm_segment_t old_fs;
2493         loff_t err;
2494         ssize_t length, full_len;
2495         uint8_t __user *address;
2496         struct scst_vdisk_dev *virt_dev =
2497             (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2498         struct file *fd = thr->fd;
2499         struct iovec *iv, *eiv;
2500         int iv_count, eiv_count;
2501
2502         TRACE_ENTRY();
2503
2504         if (virt_dev->nullio)
2505                 goto out;
2506
2507         iv = vdisk_alloc_iv(cmd, thr);
2508         if (iv == NULL)
2509                 goto out;
2510
2511         iv_count = 0;
2512         full_len = 0;
2513         length = scst_get_buf_first(cmd, (uint8_t __force **)&address);
2514         while (length > 0) {
2515                 full_len += length;
2516                 iv[iv_count].iov_base = address;
2517                 iv[iv_count].iov_len = length;
2518                 iv_count++;
2519                 length = scst_get_buf_next(cmd, (uint8_t __force **)&address);
2520         }
2521         if (unlikely(length < 0)) {
2522                 PRINT_ERROR("scst_get_buf_() failed: %zd", length);
2523                 scst_set_cmd_error(cmd,
2524                     SCST_LOAD_SENSE(scst_sense_hardw_error));
2525                 goto out_put;
2526         }
2527
2528         old_fs = get_fs();
2529         set_fs(get_ds());
2530
2531         eiv = iv;
2532         eiv_count = iv_count;
2533 restart:
2534         TRACE_DBG("writing(eiv_count %d, full_len %zd)", eiv_count, full_len);
2535
2536         /* SEEK */
2537         if (fd->f_op->llseek)
2538                 err = fd->f_op->llseek(fd, loff, 0 /*SEEK_SET */);
2539         else
2540                 err = default_llseek(fd, loff, 0 /*SEEK_SET */);
2541         if (err != loff) {
2542                 PRINT_ERROR("lseek trouble %lld != %lld",
2543                             (long long unsigned int)err,
2544                             (long long unsigned int)loff);
2545                 scst_set_cmd_error(cmd,
2546                                    SCST_LOAD_SENSE(scst_sense_hardw_error));
2547                 goto out_set_fs;
2548         }
2549
2550         /* WRITE */
2551 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
2552         err = fd->f_op->writev(fd, eiv, eiv_count, &fd->f_pos);
2553 #else
2554         err = do_sync_readv_writev(fd, iv, iv_count, full_len, &fd->f_pos,
2555                                         fd->f_op->aio_write);
2556 #endif
2557
2558         if (err < 0) {
2559                 PRINT_ERROR("write() returned %lld from %zd",
2560                             (long long unsigned int)err,
2561                             full_len);
2562                 if (err == -EAGAIN)
2563                         scst_set_busy(cmd);
2564                 else {
2565                         scst_set_cmd_error(cmd,
2566                             SCST_LOAD_SENSE(scst_sense_write_error));
2567                 }
2568                 goto out_set_fs;
2569         } else if (err < full_len) {
2570                 /*
2571                  * Probably that's wrong, but sometimes write() returns
2572                  * value less, than requested. Let's restart.
2573                  */
2574                 int i, e = eiv_count;
2575                 TRACE_MGMT_DBG("write() returned %d from %zd "
2576                         "(iv_count=%d)", (int)err, full_len,
2577                         eiv_count);
2578                 if (err == 0) {
2579                         PRINT_INFO("Suspicious: write() returned 0 from "
2580                                 "%zd (iv_count=%d)", full_len, eiv_count);
2581                 }
2582                 full_len -= err;
2583                 for (i = 0; i < e; i++) {
2584                         if ((long long)eiv->iov_len < err) {
2585                                 err -= eiv->iov_len;
2586                                 eiv++;
2587                                 eiv_count--;
2588                         } else {
2589                                 eiv->iov_base =
2590                                         (uint8_t __force __user *)eiv->iov_base +
2591                                         err;
2592                                 eiv->iov_len -= err;
2593                                 break;
2594                         }
2595                 }
2596                 goto restart;
2597         }
2598
2599 out_set_fs:
2600         set_fs(old_fs);
2601
2602 out_put:
2603         while (iv_count > 0) {
2604                 scst_put_buf(cmd, (void __force *)(iv[iv_count-1].iov_base));
2605                 iv_count--;
2606         }
2607
2608 out:
2609         TRACE_EXIT();
2610         return;
2611 }
2612
2613 struct scst_blockio_work {
2614         atomic_t bios_inflight;
2615         struct scst_cmd *cmd;
2616 };
2617
2618 static inline void blockio_check_finish(struct scst_blockio_work *blockio_work)
2619 {
2620         /* Decrement the bios in processing, and if zero signal completion */
2621         if (atomic_dec_and_test(&blockio_work->bios_inflight)) {
2622                 blockio_work->cmd->completed = 1;
2623                 blockio_work->cmd->scst_cmd_done(blockio_work->cmd,
2624                         SCST_CMD_STATE_DEFAULT, scst_estimate_context());
2625                 kmem_cache_free(blockio_work_cachep, blockio_work);
2626         }
2627         return;
2628 }
2629
2630 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
2631 static int blockio_endio(struct bio *bio, unsigned int bytes_done, int error)
2632 #else
2633 static void blockio_endio(struct bio *bio, int error)
2634 #endif
2635 {
2636         struct scst_blockio_work *blockio_work = bio->bi_private;
2637
2638 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
2639         if (bio->bi_size)
2640                 return 1;
2641 #endif
2642
2643         error = test_bit(BIO_UPTODATE, &bio->bi_flags) ? error : -EIO;
2644
2645         if (unlikely(error != 0)) {
2646                 PRINT_ERROR("cmd %p returned error %d", blockio_work->cmd,
2647                         error);
2648                 /*
2649                  * The race with other such bio's doesn't matter, since all
2650                  * scst_set_cmd_error() calls do the same local to this cmd
2651                  * operations.
2652                  */
2653                 if (bio->bi_rw & WRITE)
2654                         scst_set_cmd_error(blockio_work->cmd,
2655                                 SCST_LOAD_SENSE(scst_sense_write_error));
2656                 else
2657                         scst_set_cmd_error(blockio_work->cmd,
2658                                 SCST_LOAD_SENSE(scst_sense_read_error));
2659         }
2660
2661         blockio_check_finish(blockio_work);
2662
2663         bio_put(bio);
2664 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
2665         return 0;
2666 #else
2667         return;
2668 #endif
2669 }
2670
2671 static void blockio_exec_rw(struct scst_cmd *cmd, struct scst_vdisk_thr *thr,
2672         u64 lba_start, int write)
2673 {
2674         struct scst_vdisk_dev *virt_dev =
2675                 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2676         struct block_device *bdev = thr->bdev;
2677         struct request_queue *q = bdev_get_queue(bdev);
2678         int length, max_nr_vecs = 0;
2679         uint8_t *address;
2680         struct bio *bio = NULL, *hbio = NULL, *tbio = NULL;
2681         int need_new_bio;
2682         struct scst_blockio_work *blockio_work;
2683         int bios = 0;
2684
2685         TRACE_ENTRY();
2686
2687         if (virt_dev->nullio)
2688                 goto out;
2689
2690         /* Allocate and initialize blockio_work struct */
2691         blockio_work = kmem_cache_alloc(blockio_work_cachep, GFP_KERNEL);
2692         if (blockio_work == NULL)
2693                 goto out_no_mem;
2694
2695         blockio_work->cmd = cmd;
2696
2697         if (q)
2698                 max_nr_vecs = min(bio_get_nr_vecs(bdev), BIO_MAX_PAGES);
2699         else
2700                 max_nr_vecs = 1;
2701
2702         need_new_bio = 1;
2703
2704         length = scst_get_buf_first(cmd, &address);
2705         while (length > 0) {
2706                 int len, bytes, off, thislen;
2707                 uint8_t *addr;
2708                 u64 lba_start0;
2709
2710                 addr = address;
2711                 off = offset_in_page(addr);
2712                 len = length;
2713                 thislen = 0;
2714                 lba_start0 = lba_start;
2715
2716                 while (len > 0) {
2717                         int rc;
2718                         struct page *page = virt_to_page(addr);
2719
2720                         if (need_new_bio) {
2721 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
2722                                 bio = bio_kmalloc(GFP_KERNEL, max_nr_vecs);
2723 #else
2724                                 bio = bio_alloc(GFP_KERNEL, max_nr_vecs);
2725 #endif
2726                                 if (!bio) {
2727                                         PRINT_ERROR("Failed to create bio "
2728                                                 "for data segment %d (cmd %p)",
2729                                                 cmd->get_sg_buf_entry_num, cmd);
2730                                         goto out_no_bio;
2731                                 }
2732
2733                                 bios++;
2734                                 need_new_bio = 0;
2735                                 bio->bi_end_io = blockio_endio;
2736                                 bio->bi_sector = lba_start0 <<
2737                                         (virt_dev->block_shift - 9);
2738                                 bio->bi_bdev = bdev;
2739                                 bio->bi_private = blockio_work;
2740 #if 0 /* It could be win, but could be not, so a performance study is needed */
2741                                 bio->bi_rw |= 1 << BIO_RW_SYNC;
2742 #endif
2743                                 if (!hbio)
2744                                         hbio = tbio = bio;
2745                                 else
2746                                         tbio = tbio->bi_next = bio;
2747                         }
2748
2749                         bytes = min_t(unsigned int, len, PAGE_SIZE - off);
2750
2751                         rc = bio_add_page(bio, page, bytes, off);
2752                         if (rc < bytes) {
2753                                 sBUG_ON(rc != 0);
2754                                 need_new_bio = 1;
2755                                 lba_start0 += thislen >> virt_dev->block_shift;
2756                                 thislen = 0;
2757                                 continue;
2758                         }
2759
2760                         addr += PAGE_SIZE;
2761                         thislen += bytes;
2762                         len -= bytes;
2763                         off = 0;
2764                 }
2765
2766                 lba_start += length >> virt_dev->block_shift;
2767
2768                 scst_put_buf(cmd, address);
2769                 length = scst_get_buf_next(cmd, &address);
2770         }
2771
2772         /* +1 to prevent erroneous too early command completion */
2773         atomic_set(&blockio_work->bios_inflight, bios+1);
2774
2775         while (hbio) {
2776                 bio = hbio;
2777                 hbio = hbio->bi_next;
2778                 bio->bi_next = NULL;
2779                 submit_bio(write, bio);
2780         }
2781
2782         if (q && q->unplug_fn)
2783                 q->unplug_fn(q);
2784
2785         blockio_check_finish(blockio_work);
2786
2787 out:
2788         TRACE_EXIT();
2789         return;
2790
2791 out_no_bio:
2792         while (hbio) {
2793                 bio = hbio;
2794                 hbio = hbio->bi_next;
2795                 bio_put(bio);
2796         }
2797         kmem_cache_free(blockio_work_cachep, blockio_work);
2798
2799 out_no_mem:
2800         scst_set_busy(cmd);
2801         goto out;
2802 }
2803
2804 static void vdisk_exec_verify(struct scst_cmd *cmd,
2805         struct scst_vdisk_thr *thr, loff_t loff)
2806 {
2807         mm_segment_t old_fs;
2808         loff_t err;
2809         ssize_t length, len_mem = 0;
2810         uint8_t *address_sav, *address;
2811         int compare;
2812         struct scst_vdisk_dev *virt_dev =
2813             (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2814         struct file *fd = thr->fd;
2815         uint8_t *mem_verify = NULL;
2816
2817         TRACE_ENTRY();
2818
2819         if (vdisk_fsync(thr, loff, cmd->bufflen, cmd, cmd->dev) != 0)
2820                 goto out;
2821
2822         /*
2823          * Until the cache is cleared prior the verifying, there is not
2824          * much point in this code. ToDo.
2825          *
2826          * Nevertherless, this code is valuable if the data have not read
2827          * from the file/disk yet.
2828          */
2829
2830         /* SEEK */
2831         old_fs = get_fs();
2832         set_fs(get_ds());
2833
2834         if (!virt_dev->nullio) {
2835                 if (fd->f_op->llseek)
2836                         err = fd->f_op->llseek(fd, loff, 0/*SEEK_SET*/);
2837                 else
2838                         err = default_llseek(fd, loff, 0/*SEEK_SET*/);
2839                 if (err != loff) {
2840                         PRINT_ERROR("lseek trouble %lld != %lld",
2841                                     (long long unsigned int)err,
2842                                     (long long unsigned int)loff);
2843                         scst_set_cmd_error(cmd,
2844                                 SCST_LOAD_SENSE(scst_sense_hardw_error));
2845                         goto out_set_fs;
2846                 }
2847         }
2848
2849         mem_verify = vmalloc(LEN_MEM);
2850         if (mem_verify == NULL) {
2851                 PRINT_ERROR("Unable to allocate memory %d for verify",
2852                                LEN_MEM);
2853                 scst_set_cmd_error(cmd,
2854                                    SCST_LOAD_SENSE(scst_sense_hardw_error));
2855                 goto out_set_fs;
2856         }
2857
2858         length = scst_get_buf_first(cmd, &address);
2859         address_sav = address;
2860         if (!length && cmd->data_len) {
2861                 length = cmd->data_len;
2862                 compare = 0;
2863         } else
2864                 compare = 1;
2865
2866         while (length > 0) {
2867                 len_mem = (length > LEN_MEM) ? LEN_MEM : length;
2868                 TRACE_DBG("Verify: length %zd - len_mem %zd", length, len_mem);
2869
2870                 if (!virt_dev->nullio)
2871                         err = fd->f_op->read(fd,
2872                                 (char __force __user *)mem_verify, len_mem,
2873                                 &fd->f_pos);
2874                 else
2875                         err = len_mem;
2876                 if ((err < 0) || (err < len_mem)) {
2877                         PRINT_ERROR("verify() returned %lld from %zd",
2878                                     (long long unsigned int)err, len_mem);
2879                         if (err == -EAGAIN)
2880                                 scst_set_busy(cmd);
2881                         else {
2882                                 scst_set_cmd_error(cmd,
2883                                     SCST_LOAD_SENSE(scst_sense_read_error));
2884                         }
2885                         if (compare)
2886                                 scst_put_buf(cmd, address_sav);
2887                         goto out_set_fs;
2888                 }
2889                 if (compare && memcmp(address, mem_verify, len_mem) != 0) {
2890                         TRACE_DBG("Verify: error memcmp length %zd", length);
2891                         scst_set_cmd_error(cmd,
2892                             SCST_LOAD_SENSE(scst_sense_miscompare_error));
2893                         scst_put_buf(cmd, address_sav);
2894                         goto out_set_fs;
2895                 }
2896                 length -= len_mem;
2897                 address += len_mem;
2898                 if (compare && length <= 0) {
2899                         scst_put_buf(cmd, address_sav);
2900                         length = scst_get_buf_next(cmd, &address);
2901                         address_sav = address;
2902                 }
2903         }
2904
2905         if (length < 0) {
2906                 PRINT_ERROR("scst_get_buf_() failed: %zd", length);
2907                 scst_set_cmd_error(cmd,
2908                     SCST_LOAD_SENSE(scst_sense_hardw_error));
2909         }
2910
2911 out_set_fs:
2912         set_fs(old_fs);
2913         if (mem_verify)
2914                 vfree(mem_verify);
2915
2916 out:
2917         TRACE_EXIT();
2918         return;
2919 }
2920
2921 static int vdisk_task_mgmt_fn(struct scst_mgmt_cmd *mcmd,
2922         struct scst_tgt_dev *tgt_dev)
2923 {
2924         TRACE_ENTRY();
2925
2926         if ((mcmd->fn == SCST_LUN_RESET) || (mcmd->fn == SCST_TARGET_RESET)) {
2927                 /* Restore default values */
2928                 struct scst_device *dev = tgt_dev->dev;
2929                 struct scst_vdisk_dev *virt_dev =
2930                         (struct scst_vdisk_dev *)dev->dh_priv;
2931
2932                 dev->tst = DEF_TST;
2933                 dev->d_sense = DEF_DSENSE;
2934                 if (virt_dev->wt_flag && !virt_dev->nv_cache)
2935                         dev->queue_alg = DEF_QUEUE_ALG_WT;
2936                 else
2937                         dev->queue_alg = DEF_QUEUE_ALG;
2938                 dev->swp = DEF_SWP;
2939                 dev->tas = DEF_TAS;
2940
2941                 virt_dev->prevent_allow_medium_removal = 0;
2942         }
2943
2944         TRACE_EXIT();
2945         return SCST_DEV_TM_NOT_COMPLETED;
2946 }
2947
2948 static void vdisk_report_registering(const struct scst_vdisk_dev *virt_dev)
2949 {
2950         char buf[128];
2951         int i, j;
2952
2953         i = snprintf(buf, sizeof(buf), "Registering virtual %s device %s ",
2954                 virt_dev->vdt->vdt_name, virt_dev->name);
2955         j = i;
2956
2957         if (virt_dev->wt_flag)
2958                 i += snprintf(&buf[i], sizeof(buf) - i, "(WRITE_THROUGH");
2959
2960         if (virt_dev->nv_cache)
2961                 i += snprintf(&buf[i], sizeof(buf) - i, "%sNV_CACHE",
2962                         (j == i) ? "(" : ", ");
2963
2964         if (virt_dev->rd_only)
2965                 i += snprintf(&buf[i], sizeof(buf) - i, "%sREAD_ONLY",
2966                         (j == i) ? "(" : ", ");
2967
2968         if (virt_dev->o_direct_flag)
2969                 i += snprintf(&buf[i], sizeof(buf) - i, "%sO_DIRECT",
2970                         (j == i) ? "(" : ", ");
2971
2972         if (virt_dev->nullio)
2973                 i += snprintf(&buf[i], sizeof(buf) - i, "%sNULLIO",
2974                         (j == i) ? "(" : ", ");
2975
2976         if (virt_dev->blockio)
2977                 i += snprintf(&buf[i], sizeof(buf) - i, "%sBLOCKIO",
2978                         (j == i) ? "(" : ", ");
2979
2980         if (virt_dev->removable)
2981                 i += snprintf(&buf[i], sizeof(buf) - i, "%sREMOVABLE",
2982                         (j == i) ? "(" : ", ");
2983
2984         if (j == i)
2985                 PRINT_INFO("%s", buf);
2986         else
2987                 PRINT_INFO("%s)", buf);
2988
2989         return;
2990 }
2991
2992 /* scst_vdisk_mutex supposed to be held */
2993 static int __vdisk_resync_size(struct scst_vdisk_dev *virt_dev)
2994 {
2995         loff_t file_size;
2996         int res = 0;
2997
2998         if (!virt_dev->nullio) {
2999                 res = vdisk_get_file_size(virt_dev->file_name,
3000                                 virt_dev->blockio, &file_size);
3001                 if (res != 0)
3002                         goto out;
3003         } else
3004                 file_size = VDISK_NULLIO_SIZE;
3005
3006         if (file_size == virt_dev->file_size) {
3007                 PRINT_INFO("Size of virtual disk %s remained the same",
3008                         virt_dev->name);
3009                 goto out;
3010         }
3011
3012         res = scst_suspend_activity(true);
3013         if (res != 0)
3014                 goto out;
3015
3016         virt_dev->file_size = file_size;
3017         virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift;
3018
3019         scst_dev_del_all_thr_data(virt_dev->dev);
3020
3021         PRINT_INFO("New size of SCSI target virtual disk %s "
3022                 "(fs=%lldMB, bs=%d, nblocks=%lld, cyln=%lld%s)",
3023                 virt_dev->name, virt_dev->file_size >> 20,
3024                 virt_dev->block_size,
3025                 (long long unsigned int)virt_dev->nblocks,
3026                 (long long unsigned int)virt_dev->nblocks/64/32,
3027                 virt_dev->nblocks < 64*32 ? " !WARNING! cyln less "
3028                                                 "than 1" : "");
3029
3030         scst_capacity_data_changed(virt_dev->dev);
3031
3032         scst_resume_activity();
3033
3034 out:
3035         return res;
3036 }
3037
3038 /* scst_vdisk_mutex supposed to be held */
3039 static int vdisk_resync_size(struct vdev_type *vdt, char *p, const char *name)
3040 {
3041         struct scst_vdisk_dev *virt_dev;
3042         int res;
3043
3044         virt_dev = vdt->vfns.vdev_find(name);
3045         if (virt_dev == NULL) {
3046                 PRINT_ERROR("Device %s not found", name);
3047                 res = -EINVAL;
3048                 goto out;
3049         }
3050
3051         res = __vdisk_resync_size(virt_dev);
3052
3053 out:
3054         TRACE_EXIT_RES(res);
3055         return res;
3056 }
3057
3058 static void vdev_init(struct vdev_type *vdt, struct scst_vdisk_dev *virt_dev)
3059 {
3060         memset(virt_dev, 0, sizeof(*virt_dev));
3061         spin_lock_init(&virt_dev->flags_lock);
3062         virt_dev->vdt = vdt;
3063
3064         virt_dev->block_size = DEF_DISK_BLOCKSIZE;
3065         virt_dev->block_shift = DEF_DISK_BLOCKSIZE_SHIFT;
3066
3067         return;
3068 }
3069
3070 static struct scst_vdisk_dev *vdev_create(struct vdev_type *vdt)
3071 {
3072         struct scst_vdisk_dev *virt_dev;
3073
3074         virt_dev = kmalloc(sizeof(*virt_dev), GFP_KERNEL);
3075         if (virt_dev == NULL) {
3076                 PRINT_ERROR("Allocation of virtual device %s failed",
3077                         vdt->vdt_name);
3078                 goto out;
3079         }
3080
3081         vdt->vfns.vdev_init(vdt, virt_dev);
3082
3083 out:
3084         return virt_dev;
3085 }
3086
3087 static void vdev_deinit(struct scst_vdisk_dev *virt_dev)
3088 {
3089         kfree(virt_dev->file_name);
3090         return;
3091 }
3092
3093 static void vdev_destroy(struct scst_vdisk_dev *virt_dev)
3094 {
3095         virt_dev->vdt->vfns.vdev_deinit(virt_dev);
3096         kfree(virt_dev);
3097         return;
3098 }
3099
3100 static int vdisk_fileio_pre_register(struct scst_vdisk_dev *virt_dev)
3101 {
3102         int res = 0;
3103
3104         if ((virt_dev->file_name == NULL) ||
3105             (strcmp(virt_dev->file_name, VDEV_NONE_FILENAME) == 0)) {
3106                 PRINT_ERROR("%s", "File name required");
3107                 res = -EINVAL;
3108                 goto out;
3109         }
3110
3111         if (virt_dev->rd_only && (virt_dev->wt_flag || virt_dev->nv_cache)) {
3112                 PRINT_ERROR("Write options on read only device %s",
3113                         virt_dev->name);
3114                 res = -EINVAL;
3115                 goto out;
3116         }
3117
3118 out:
3119         return res;
3120 }
3121
3122 static int vdisk_blockio_pre_register(struct scst_vdisk_dev *virt_dev)
3123 {
3124         int res = 0;
3125
3126         if ((virt_dev->file_name == NULL) ||
3127             (strcmp(virt_dev->file_name, VDEV_NONE_FILENAME) == 0)) {
3128                 PRINT_ERROR("%s", "File name required");
3129                 res = -EINVAL;
3130                 goto out;
3131         }
3132
3133 out:
3134         return res;
3135 }
3136
3137 static void vdisk_blockio_init(struct vdev_type *vdt,
3138         struct scst_vdisk_dev *virt_dev)
3139 {
3140         struct vdisk_blockio_type *v;
3141
3142         v = container_of(vdt, struct vdisk_blockio_type, parent_vdt);
3143
3144         v->parent_vdt_vfns.vdev_init(vdt, virt_dev);
3145
3146         virt_dev->blockio = 1;
3147         return;
3148 }
3149
3150 static void vdisk_nullio_init(struct vdev_type *vdt,
3151         struct scst_vdisk_dev *virt_dev)
3152 {
3153         struct vdisk_nullio_type *v;
3154
3155         v = container_of(vdt, struct vdisk_nullio_type, parent_vdt);
3156
3157         v->parent_vdt_vfns.vdev_init(vdt, virt_dev);
3158
3159         virt_dev->nullio = 1;
3160         return;
3161 }
3162
3163 static int vdisk_parse_option(struct scst_vdisk_dev *virt_dev, char *p)
3164 {
3165         int res = -EINVAL;
3166
3167         TRACE_ENTRY();
3168
3169         if (!strncmp("READ_ONLY", p, 9)) {
3170                 res = 9;
3171                 virt_dev->rd_only = 1;
3172                 TRACE_DBG("%s", "READ_ONLY");
3173         } else if (!strncmp("REMOVABLE", p, 9)) {
3174                 res = 9;
3175                 virt_dev->removable = 1;
3176                 TRACE_DBG("%s", "REMOVABLE");
3177         }
3178
3179         TRACE_EXIT_RES(res);
3180         return res;
3181 }
3182
3183 static int vdisk_fileio_parse_option(struct scst_vdisk_dev *virt_dev, char *p)
3184 {
3185         int res;
3186
3187         TRACE_ENTRY();
3188
3189         res = vdisk_parse_option(virt_dev, p);
3190         if (res >= 0)
3191                 goto out;
3192
3193         if (!strncmp("WRITE_THROUGH", p, 13)) {
3194                 res = 13;
3195                 virt_dev->wt_flag = 1;
3196                 TRACE_DBG("%s", "WRITE_THROUGH");
3197         } else if (!strncmp("NV_CACHE", p, 8)) {
3198                 res = 8;
3199                 virt_dev->nv_cache = 1;
3200                 TRACE_DBG("%s", "NON-VOLATILE CACHE");
3201         } else if (!strncmp("O_DIRECT", p, 8)) {
3202                 res = 8;
3203 #if 0
3204                 virt_dev->o_direct_flag = 1;
3205                 TRACE_DBG("%s", "O_DIRECT");
3206 #else
3207                 PRINT_INFO("%s flag doesn't currently"
3208                         " work, ignoring it, use fileio_tgt "
3209                         "in O_DIRECT mode instead", "O_DIRECT");
3210 #endif
3211         }
3212
3213 out:
3214         TRACE_EXIT_RES(res);
3215         return res;
3216 }
3217
3218 /* scst_vdisk_mutex supposed to be held */
3219 static int vdev_open(struct vdev_type *vdt, char *p, const char *name)
3220 {
3221         int res = 0;
3222         char *file_name;
3223         struct scst_vdisk_dev *virt_dev;
3224         size_t len;
3225
3226         TRACE_ENTRY();
3227
3228         virt_dev = vdt->vfns.vdev_find(name);
3229         if (virt_dev != NULL) {
3230                 PRINT_ERROR("Virtual device with name %s already exist", name);
3231                 res = -EINVAL;
3232                 goto out;
3233         }
3234
3235         while (isspace(*p) && *p != '\0')
3236                 p++;
3237         file_name = p;
3238         if ((*file_name == '/') || (strcmp(file_name, VDEV_NONE_FILENAME) == 0)) {
3239                 while (!isspace(*p) && *p != '\0')
3240                         p++;
3241                 *p++ = '\0';
3242
3243                 TRACE_DBG("file name %s", file_name);
3244
3245                 while (isspace(*p) && *p != '\0')
3246                         p++;
3247         } else {
3248                 TRACE_DBG("file name %s", "not specified");
3249                 file_name = NULL;
3250         }
3251
3252         virt_dev = vdt->vfns.vdev_create(vdt);
3253         if (virt_dev == NULL) {
3254                 TRACE(TRACE_OUT_OF_MEM, "Creation of virt_dev %s failed", name);
3255                 res = -ENOMEM;
3256                 goto out;
3257         }
3258
3259         if (isdigit(*p)) {
3260                 uint32_t block_size;
3261                 int block_shift;
3262                 char *pp;
3263
3264                 block_size = simple_strtoul(p, &pp, 0);
3265                 p = pp;
3266                 if ((*p != '\0') && !isspace(*p)) {
3267                         PRINT_ERROR("Parse error: \"%s\"", p);
3268                         res = -EINVAL;
3269                         goto out_free_vdev;
3270                 }
3271                 while (isspace(*p) && *p != '\0')
3272                         p++;
3273
3274                 block_shift = scst_calc_block_shift(block_size);
3275                 if (block_shift < 9) {
3276                         res = -EINVAL;
3277                         goto out_free_vdev;
3278                 }
3279
3280                 TRACE_DBG("block_size %d, block_shift %d", block_size,
3281                         block_shift);
3282
3283                 virt_dev->block_size = block_size;
3284                 virt_dev->block_shift = block_shift;
3285         }
3286
3287         while (*p != '\0') {
3288                 while (isspace(*p) && *p != '\0')
3289                         p++;
3290
3291                 if (vdt->vfns.parse_option != NULL)
3292                         res = vdt->vfns.parse_option(virt_dev, p);
3293                 else
3294                         res = -EINVAL;
3295
3296                 if (res < 0) {
3297                         PRINT_ERROR("Unknown option \"%s\"", p);
3298                         goto out_free_vdev;
3299                 } else if (res == 0)
3300                         break;
3301
3302                 p += res;
3303
3304                 if (!isspace(*p) && (*p != '\0')) {
3305                         PRINT_ERROR("Syntax error on %s", p);
3306                         goto out_free_vdev;
3307                 }
3308         }
3309
3310         strcpy(virt_dev->name, name);
3311
3312         scnprintf(virt_dev->usn, sizeof(virt_dev->usn), "%llx",
3313                         vdisk_gen_dev_id_num(virt_dev));
3314         TRACE_DBG("usn %s", virt_dev->usn);
3315
3316         if (file_name != NULL) {
3317                 len = strlen(file_name) + 1;
3318                 virt_dev->file_name = kmalloc(len, GFP_KERNEL);
3319                 if (virt_dev->file_name == NULL) {
3320                         TRACE(TRACE_OUT_OF_MEM, "Allocation of file_name %s "
3321                                 "failed", file_name);
3322                         res = -ENOMEM;
3323                         goto out_free_vdev;
3324                 }
3325                 strncpy(virt_dev->file_name, file_name, len);
3326         }
3327
3328         if (vdt->vfns.pre_register != NULL) {
3329                 res = vdt->vfns.pre_register(virt_dev);
3330                 if (res != 0)
3331                         goto out_free_vpath;
3332         }
3333
3334         vdt->vfns.vdev_add(virt_dev);
3335
3336         vdisk_report_registering(virt_dev);
3337         virt_dev->virt_id = scst_register_virtual_device(vdt->vdt_devt,
3338                                                  virt_dev->name);
3339         if (virt_dev->virt_id < 0) {
3340                 res = virt_dev->virt_id;
3341                 goto out_del;
3342         }
3343
3344         TRACE_DBG("Added virt_dev (name %s, file name %s, id %d, block size "
3345                 "%d) to vdisk_dev_list", virt_dev->name, virt_dev->file_name,
3346                 virt_dev->virt_id, virt_dev->block_size);
3347
3348 out:
3349         TRACE_EXIT_RES(res);
3350         return res;
3351
3352 out_del:
3353         vdt->vfns.vdev_del(virt_dev);
3354
3355 out_free_vpath:
3356         kfree(virt_dev->file_name);
3357
3358 out_free_vdev:
3359         kfree(virt_dev);
3360         goto out;
3361 }
3362
3363 /* scst_vdisk_mutex supposed to be held */
3364 static int vdev_close(struct vdev_type *vdt, const char *name)
3365 {
3366         int res = 0;
3367         struct scst_vdisk_dev *virt_dev;
3368
3369         TRACE_ENTRY();
3370
3371         virt_dev = vdt->vfns.vdev_find(name);
3372         if (virt_dev == NULL) {
3373                 PRINT_ERROR("Device %s not found", name);
3374                 res = -EINVAL;
3375                 goto out;
3376         }
3377
3378         scst_unregister_virtual_device(virt_dev->virt_id);
3379
3380         PRINT_INFO("Virtual device %s unregistered", virt_dev->name);
3381         TRACE_DBG("virt_id %d unregister", virt_dev->virt_id);
3382
3383         vdt->vfns.vdev_del(virt_dev);
3384         vdt->vfns.vdev_destroy(virt_dev);
3385
3386 out:
3387         TRACE_EXIT_RES(res);
3388         return res;
3389 }
3390
3391 /* scst_vdisk_mutex supposed to be held */
3392 static void vdev_del(struct scst_vdisk_dev *virt_dev)
3393 {
3394         TRACE_ENTRY();
3395
3396         list_del(&virt_dev->vdisk_dev_list_entry);
3397
3398         TRACE_EXIT();
3399         return;
3400 }
3401
3402 /* scst_vdisk_mutex supposed to be held */
3403 static void vdisk_add(struct scst_vdisk_dev *virt_dev)
3404 {
3405         TRACE_ENTRY();
3406
3407         list_add_tail(&virt_dev->vdisk_dev_list_entry, &vdisk_dev_list);
3408
3409         TRACE_EXIT();
3410         return;
3411 }
3412
3413 /* scst_vdisk_mutex supposed to be held */
3414 static struct scst_vdisk_dev *vdisk_find(const char *name)
3415 {
3416         struct scst_vdisk_dev *res, *vv;
3417
3418         TRACE_ENTRY();
3419
3420         res = NULL;
3421         list_for_each_entry(vv, &vdisk_dev_list, vdisk_dev_list_entry) {
3422                 if (strcmp(vv->name, name) == 0) {
3423                         res = vv;
3424                         break;
3425                 }
3426         }
3427
3428         TRACE_EXIT_HRES((unsigned long)res);
3429         return res;
3430 }
3431
3432 /* scst_vdisk_mutex supposed to be held */
3433 static void vcdrom_add(struct scst_vdisk_dev *virt_dev)
3434 {
3435         TRACE_ENTRY();
3436
3437         list_add_tail(&virt_dev->vdisk_dev_list_entry, &vcdrom_dev_list);
3438
3439         TRACE_EXIT();
3440         return;
3441 }
3442
3443 /* scst_vdisk_mutex supposed to be held */
3444 static struct scst_vdisk_dev *vcdrom_find(const char *name)
3445 {
3446         struct scst_vdisk_dev *res, *vv;
3447
3448         TRACE_ENTRY();
3449
3450         res = NULL;
3451         list_for_each_entry(vv, &vcdrom_dev_list, vdisk_dev_list_entry) {
3452                 if (strcmp(vv->name, name) == 0) {
3453                         res = vv;
3454                         break;
3455                 }
3456         }
3457
3458         TRACE_EXIT_HRES((unsigned long)res);
3459         return res;
3460 }
3461
3462 static int vdisk_parse_cmd(struct vdev_type *vdt, char *p, int *action)
3463 {
3464         int res = -EINVAL;
3465
3466         TRACE_ENTRY();
3467
3468         if (!strncmp("resync_size", p, 11)) {
3469                 res = 11;
3470                 p += res;
3471                 *action = VDISK_ACTION_RESYNC_SIZE;
3472         }
3473
3474         TRACE_EXIT_RES(res);
3475         return res;
3476 }
3477
3478 /* scst_vdisk_mutex supposed to be held */
3479 static int vdisk_perform_cmd(struct vdev_type *vdt, int action, char *p,
3480         char *name)
3481 {
3482         int res = -EINVAL;
3483
3484         TRACE_ENTRY();
3485
3486         if (action == VDISK_ACTION_RESYNC_SIZE)
3487                 res = vdisk_resync_size(vdt, p, name);
3488
3489         TRACE_EXIT_RES(res);
3490         return res;
3491 }
3492
3493 static void vcdrom_init(struct vdev_type *vdt,
3494         struct scst_vdisk_dev *virt_dev)
3495 {
3496         struct vcdrom_type *vt;
3497
3498         vt = container_of(vdt, struct vcdrom_type, parent_vdt);
3499
3500         vt->parent_vdt_vfns.vdev_init(vdt, virt_dev);
3501
3502         virt_dev->rd_only = 1;
3503         virt_dev->removable = 1;
3504
3505         virt_dev->block_size = DEF_CDROM_BLOCKSIZE;
3506         virt_dev->block_shift = DEF_CDROM_BLOCKSIZE_SHIFT;
3507
3508         return;
3509 }
3510
3511 static int vcdrom_pre_register(struct scst_vdisk_dev *virt_dev)
3512 {
3513         int res = 0;
3514
3515         if ((virt_dev->file_name == NULL) ||
3516             (strcmp(virt_dev->file_name, VDEV_NONE_FILENAME) == 0))
3517                 virt_dev->cdrom_empty = 1;
3518
3519         if (virt_dev->block_size != DEF_CDROM_BLOCKSIZE) {
3520                 PRINT_WARNING("Block size %d for vortual device %s ignored",
3521                         virt_dev->block_size, virt_dev->name);
3522                 virt_dev->block_size = DEF_CDROM_BLOCKSIZE;
3523                 virt_dev->block_shift = DEF_CDROM_BLOCKSIZE_SHIFT;
3524         }
3525
3526         return res;
3527 }
3528
3529 /* scst_vdisk_mutex supposed to be held */
3530 static int vcdrom_change(struct vdev_type *vdt, char *p, const char *name)
3531 {
3532         loff_t err;
3533         struct scst_vdisk_dev *virt_dev;
3534         char *file_name, *fn = NULL, *old_fn;
3535         int len;
3536         int res = 0;
3537
3538         virt_dev = vdt->vfns.vdev_find(name);
3539         if (virt_dev == NULL) {
3540                 PRINT_ERROR("Virtual device with name "
3541                        "%s not found", name);
3542                 res = -EINVAL;
3543                 goto out;
3544         }
3545
3546         while (isspace(*p) && *p != '\0')
3547                 p++;
3548         file_name = p;
3549         while (!isspace(*p) && *p != '\0')
3550                 p++;
3551         *p++ = '\0';
3552         if (*file_name == '\0') {
3553                 virt_dev->cdrom_empty = 1;
3554                 TRACE_DBG("%s", "No media");
3555         } else if (*file_name != '/') {
3556                 PRINT_ERROR("File path \"%s\" is not "
3557                         "absolute", file_name);
3558                 res = -EINVAL;
3559                 goto out;
3560         } else
3561                 virt_dev->cdrom_empty = 0;
3562
3563         old_fn = virt_dev->file_name;
3564
3565         if (!virt_dev->cdrom_empty) {
3566                 len = strlen(file_name) + 1;
3567                &n