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