c826b3e1799afaff6b0c29afb06304a607c9ed84
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / md / dm-ioctl.c
1 /*
2  * Copyright (C) 2001, 2002 Sistina Software (UK) Limited.
3  * Copyright (C) 2004 - 2006 Red Hat, Inc. All rights reserved.
4  *
5  * This file is released under the GPL.
6  */
7
8 #include "dm.h"
9
10 #include <linux/module.h>
11 #include <linux/vmalloc.h>
12 #include <linux/miscdevice.h>
13 #include <linux/init.h>
14 #include <linux/wait.h>
15 #include <linux/slab.h>
16 #include <linux/devfs_fs_kernel.h>
17 #include <linux/dm-ioctl.h>
18 #include <linux/hdreg.h>
19
20 #include <asm/uaccess.h>
21
22 #define DM_DRIVER_EMAIL "dm-devel@redhat.com"
23
24 /*-----------------------------------------------------------------
25  * The ioctl interface needs to be able to look up devices by
26  * name or uuid.
27  *---------------------------------------------------------------*/
28 struct hash_cell {
29         struct list_head name_list;
30         struct list_head uuid_list;
31
32         char *name;
33         char *uuid;
34         struct mapped_device *md;
35         struct dm_table *new_map;
36 };
37
38 struct vers_iter {
39     size_t param_size;
40     struct dm_target_versions *vers, *old_vers;
41     char *end;
42     uint32_t flags;
43 };
44
45
46 #define NUM_BUCKETS 64
47 #define MASK_BUCKETS (NUM_BUCKETS - 1)
48 static struct list_head _name_buckets[NUM_BUCKETS];
49 static struct list_head _uuid_buckets[NUM_BUCKETS];
50
51 static void dm_hash_remove_all(void);
52
53 /*
54  * Guards access to both hash tables.
55  */
56 static DECLARE_RWSEM(_hash_lock);
57
58 static void init_buckets(struct list_head *buckets)
59 {
60         unsigned int i;
61
62         for (i = 0; i < NUM_BUCKETS; i++)
63                 INIT_LIST_HEAD(buckets + i);
64 }
65
66 static int dm_hash_init(void)
67 {
68         init_buckets(_name_buckets);
69         init_buckets(_uuid_buckets);
70         devfs_mk_dir(DM_DIR);
71         return 0;
72 }
73
74 static void dm_hash_exit(void)
75 {
76         dm_hash_remove_all();
77         devfs_remove(DM_DIR);
78 }
79
80 /*-----------------------------------------------------------------
81  * Hash function:
82  * We're not really concerned with the str hash function being
83  * fast since it's only used by the ioctl interface.
84  *---------------------------------------------------------------*/
85 static unsigned int hash_str(const char *str)
86 {
87         const unsigned int hash_mult = 2654435387U;
88         unsigned int h = 0;
89
90         while (*str)
91                 h = (h + (unsigned int) *str++) * hash_mult;
92
93         return h & MASK_BUCKETS;
94 }
95
96 /*-----------------------------------------------------------------
97  * Code for looking up a device by name
98  *---------------------------------------------------------------*/
99 static struct hash_cell *__get_name_cell(const char *str)
100 {
101         struct hash_cell *hc;
102         unsigned int h = hash_str(str);
103
104         list_for_each_entry (hc, _name_buckets + h, name_list)
105                 if (!strcmp(hc->name, str)) {
106                         dm_get(hc->md);
107                         return hc;
108                 }
109
110         return NULL;
111 }
112
113 static struct hash_cell *__get_uuid_cell(const char *str)
114 {
115         struct hash_cell *hc;
116         unsigned int h = hash_str(str);
117
118         list_for_each_entry (hc, _uuid_buckets + h, uuid_list)
119                 if (!strcmp(hc->uuid, str)) {
120                         dm_get(hc->md);
121                         return hc;
122                 }
123
124         return NULL;
125 }
126
127 /*-----------------------------------------------------------------
128  * Inserting, removing and renaming a device.
129  *---------------------------------------------------------------*/
130 static struct hash_cell *alloc_cell(const char *name, const char *uuid,
131                                     struct mapped_device *md)
132 {
133         struct hash_cell *hc;
134
135         hc = kmalloc(sizeof(*hc), GFP_KERNEL);
136         if (!hc)
137                 return NULL;
138
139         hc->name = kstrdup(name, GFP_KERNEL);
140         if (!hc->name) {
141                 kfree(hc);
142                 return NULL;
143         }
144
145         if (!uuid)
146                 hc->uuid = NULL;
147
148         else {
149                 hc->uuid = kstrdup(uuid, GFP_KERNEL);
150                 if (!hc->uuid) {
151                         kfree(hc->name);
152                         kfree(hc);
153                         return NULL;
154                 }
155         }
156
157         INIT_LIST_HEAD(&hc->name_list);
158         INIT_LIST_HEAD(&hc->uuid_list);
159         hc->md = md;
160         hc->new_map = NULL;
161         return hc;
162 }
163
164 static void free_cell(struct hash_cell *hc)
165 {
166         if (hc) {
167                 kfree(hc->name);
168                 kfree(hc->uuid);
169                 kfree(hc);
170         }
171 }
172
173 /*
174  * devfs stuff.
175  */
176 static int register_with_devfs(struct hash_cell *hc)
177 {
178         struct gendisk *disk = dm_disk(hc->md);
179
180         devfs_mk_bdev(MKDEV(disk->major, disk->first_minor),
181                       S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP,
182                       DM_DIR "/%s", hc->name);
183         return 0;
184 }
185
186 static int unregister_with_devfs(struct hash_cell *hc)
187 {
188         devfs_remove(DM_DIR"/%s", hc->name);
189         return 0;
190 }
191
192 /*
193  * The kdev_t and uuid of a device can never change once it is
194  * initially inserted.
195  */
196 static int dm_hash_insert(const char *name, const char *uuid, struct mapped_device *md)
197 {
198         struct hash_cell *cell, *hc;
199
200         /*
201          * Allocate the new cells.
202          */
203         cell = alloc_cell(name, uuid, md);
204         if (!cell)
205                 return -ENOMEM;
206
207         /*
208          * Insert the cell into both hash tables.
209          */
210         down_write(&_hash_lock);
211         hc = __get_name_cell(name);
212         if (hc) {
213                 dm_put(hc->md);
214                 goto bad;
215         }
216
217         list_add(&cell->name_list, _name_buckets + hash_str(name));
218
219         if (uuid) {
220                 hc = __get_uuid_cell(uuid);
221                 if (hc) {
222                         list_del(&cell->name_list);
223                         dm_put(hc->md);
224                         goto bad;
225                 }
226                 list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid));
227         }
228         register_with_devfs(cell);
229         dm_get(md);
230         dm_set_mdptr(md, cell);
231         up_write(&_hash_lock);
232
233         return 0;
234
235  bad:
236         up_write(&_hash_lock);
237         free_cell(cell);
238         return -EBUSY;
239 }
240
241 static void __hash_remove(struct hash_cell *hc)
242 {
243         struct dm_table *table;
244
245         /* remove from the dev hash */
246         list_del(&hc->uuid_list);
247         list_del(&hc->name_list);
248         unregister_with_devfs(hc);
249         dm_set_mdptr(hc->md, NULL);
250
251         table = dm_get_table(hc->md);
252         if (table) {
253                 dm_table_event(table);
254                 dm_table_put(table);
255         }
256
257         if (hc->new_map)
258                 dm_table_put(hc->new_map);
259         dm_put(hc->md);
260         free_cell(hc);
261 }
262
263 static void dm_hash_remove_all(void)
264 {
265         int i;
266         struct hash_cell *hc;
267         struct list_head *tmp, *n;
268
269         down_write(&_hash_lock);
270         for (i = 0; i < NUM_BUCKETS; i++) {
271                 list_for_each_safe (tmp, n, _name_buckets + i) {
272                         hc = list_entry(tmp, struct hash_cell, name_list);
273                         __hash_remove(hc);
274                 }
275         }
276         up_write(&_hash_lock);
277 }
278
279 static int dm_hash_rename(const char *old, const char *new)
280 {
281         char *new_name, *old_name;
282         struct hash_cell *hc;
283         struct dm_table *table;
284
285         /*
286          * duplicate new.
287          */
288         new_name = kstrdup(new, GFP_KERNEL);
289         if (!new_name)
290                 return -ENOMEM;
291
292         down_write(&_hash_lock);
293
294         /*
295          * Is new free ?
296          */
297         hc = __get_name_cell(new);
298         if (hc) {
299                 DMWARN("asked to rename to an already existing name %s -> %s",
300                        old, new);
301                 dm_put(hc->md);
302                 up_write(&_hash_lock);
303                 kfree(new_name);
304                 return -EBUSY;
305         }
306
307         /*
308          * Is there such a device as 'old' ?
309          */
310         hc = __get_name_cell(old);
311         if (!hc) {
312                 DMWARN("asked to rename a non existent device %s -> %s",
313                        old, new);
314                 up_write(&_hash_lock);
315                 kfree(new_name);
316                 return -ENXIO;
317         }
318
319         /*
320          * rename and move the name cell.
321          */
322         unregister_with_devfs(hc);
323
324         list_del(&hc->name_list);
325         old_name = hc->name;
326         hc->name = new_name;
327         list_add(&hc->name_list, _name_buckets + hash_str(new_name));
328
329         /* rename the device node in devfs */
330         register_with_devfs(hc);
331
332         /*
333          * Wake up any dm event waiters.
334          */
335         table = dm_get_table(hc->md);
336         if (table) {
337                 dm_table_event(table);
338                 dm_table_put(table);
339         }
340
341         dm_put(hc->md);
342         up_write(&_hash_lock);
343         kfree(old_name);
344         return 0;
345 }
346
347 /*-----------------------------------------------------------------
348  * Implementation of the ioctl commands
349  *---------------------------------------------------------------*/
350 /*
351  * All the ioctl commands get dispatched to functions with this
352  * prototype.
353  */
354 typedef int (*ioctl_fn)(struct dm_ioctl *param, size_t param_size);
355
356 static int remove_all(struct dm_ioctl *param, size_t param_size)
357 {
358         dm_hash_remove_all();
359         param->data_size = 0;
360         return 0;
361 }
362
363 /*
364  * Round up the ptr to an 8-byte boundary.
365  */
366 #define ALIGN_MASK 7
367 static inline void *align_ptr(void *ptr)
368 {
369         return (void *) (((size_t) (ptr + ALIGN_MASK)) & ~ALIGN_MASK);
370 }
371
372 /*
373  * Retrieves the data payload buffer from an already allocated
374  * struct dm_ioctl.
375  */
376 static void *get_result_buffer(struct dm_ioctl *param, size_t param_size,
377                                size_t *len)
378 {
379         param->data_start = align_ptr(param + 1) - (void *) param;
380
381         if (param->data_start < param_size)
382                 *len = param_size - param->data_start;
383         else
384                 *len = 0;
385
386         return ((void *) param) + param->data_start;
387 }
388
389 static int list_devices(struct dm_ioctl *param, size_t param_size)
390 {
391         unsigned int i;
392         struct hash_cell *hc;
393         size_t len, needed = 0;
394         struct gendisk *disk;
395         struct dm_name_list *nl, *old_nl = NULL;
396
397         down_write(&_hash_lock);
398
399         /*
400          * Loop through all the devices working out how much
401          * space we need.
402          */
403         for (i = 0; i < NUM_BUCKETS; i++) {
404                 list_for_each_entry (hc, _name_buckets + i, name_list) {
405                         needed += sizeof(struct dm_name_list);
406                         needed += strlen(hc->name) + 1;
407                         needed += ALIGN_MASK;
408                 }
409         }
410
411         /*
412          * Grab our output buffer.
413          */
414         nl = get_result_buffer(param, param_size, &len);
415         if (len < needed) {
416                 param->flags |= DM_BUFFER_FULL_FLAG;
417                 goto out;
418         }
419         param->data_size = param->data_start + needed;
420
421         nl->dev = 0;    /* Flags no data */
422
423         /*
424          * Now loop through filling out the names.
425          */
426         for (i = 0; i < NUM_BUCKETS; i++) {
427                 list_for_each_entry (hc, _name_buckets + i, name_list) {
428                         if (old_nl)
429                                 old_nl->next = (uint32_t) ((void *) nl -
430                                                            (void *) old_nl);
431                         disk = dm_disk(hc->md);
432                         nl->dev = huge_encode_dev(MKDEV(disk->major, disk->first_minor));
433                         nl->next = 0;
434                         strcpy(nl->name, hc->name);
435
436                         old_nl = nl;
437                         nl = align_ptr(((void *) ++nl) + strlen(hc->name) + 1);
438                 }
439         }
440
441  out:
442         up_write(&_hash_lock);
443         return 0;
444 }
445
446 static void list_version_get_needed(struct target_type *tt, void *needed_param)
447 {
448     size_t *needed = needed_param;
449
450     *needed += sizeof(struct dm_target_versions);
451     *needed += strlen(tt->name);
452     *needed += ALIGN_MASK;
453 }
454
455 static void list_version_get_info(struct target_type *tt, void *param)
456 {
457     struct vers_iter *info = param;
458
459     /* Check space - it might have changed since the first iteration */
460     if ((char *)info->vers + sizeof(tt->version) + strlen(tt->name) + 1 >
461         info->end) {
462
463         info->flags = DM_BUFFER_FULL_FLAG;
464         return;
465     }
466
467     if (info->old_vers)
468         info->old_vers->next = (uint32_t) ((void *)info->vers -
469                                            (void *)info->old_vers);
470     info->vers->version[0] = tt->version[0];
471     info->vers->version[1] = tt->version[1];
472     info->vers->version[2] = tt->version[2];
473     info->vers->next = 0;
474     strcpy(info->vers->name, tt->name);
475
476     info->old_vers = info->vers;
477     info->vers = align_ptr(((void *) ++info->vers) + strlen(tt->name) + 1);
478 }
479
480 static int list_versions(struct dm_ioctl *param, size_t param_size)
481 {
482         size_t len, needed = 0;
483         struct dm_target_versions *vers;
484         struct vers_iter iter_info;
485
486         /*
487          * Loop through all the devices working out how much
488          * space we need.
489          */
490         dm_target_iterate(list_version_get_needed, &needed);
491
492         /*
493          * Grab our output buffer.
494          */
495         vers = get_result_buffer(param, param_size, &len);
496         if (len < needed) {
497                 param->flags |= DM_BUFFER_FULL_FLAG;
498                 goto out;
499         }
500         param->data_size = param->data_start + needed;
501
502         iter_info.param_size = param_size;
503         iter_info.old_vers = NULL;
504         iter_info.vers = vers;
505         iter_info.flags = 0;
506         iter_info.end = (char *)vers+len;
507
508         /*
509          * Now loop through filling out the names & versions.
510          */
511         dm_target_iterate(list_version_get_info, &iter_info);
512         param->flags |= iter_info.flags;
513
514  out:
515         return 0;
516 }
517
518
519
520 static int check_name(const char *name)
521 {
522         if (strchr(name, '/')) {
523                 DMWARN("invalid device name");
524                 return -EINVAL;
525         }
526
527         return 0;
528 }
529
530 /*
531  * Fills in a dm_ioctl structure, ready for sending back to
532  * userland.
533  */
534 static int __dev_status(struct mapped_device *md, struct dm_ioctl *param)
535 {
536         struct gendisk *disk = dm_disk(md);
537         struct dm_table *table;
538         struct block_device *bdev;
539
540         param->flags &= ~(DM_SUSPEND_FLAG | DM_READONLY_FLAG |
541                           DM_ACTIVE_PRESENT_FLAG);
542
543         if (dm_suspended(md))
544                 param->flags |= DM_SUSPEND_FLAG;
545
546         param->dev = huge_encode_dev(MKDEV(disk->major, disk->first_minor));
547
548         if (!(param->flags & DM_SKIP_BDGET_FLAG)) {
549                 bdev = bdget_disk(disk, 0);
550                 if (!bdev)
551                         return -ENXIO;
552
553                 /*
554                  * Yes, this will be out of date by the time it gets back
555                  * to userland, but it is still very useful for
556                  * debugging.
557                  */
558                 param->open_count = bdev->bd_openers;
559                 bdput(bdev);
560         } else
561                 param->open_count = -1;
562
563         if (disk->policy)
564                 param->flags |= DM_READONLY_FLAG;
565
566         param->event_nr = dm_get_event_nr(md);
567
568         table = dm_get_table(md);
569         if (table) {
570                 param->flags |= DM_ACTIVE_PRESENT_FLAG;
571                 param->target_count = dm_table_get_num_targets(table);
572                 dm_table_put(table);
573         } else
574                 param->target_count = 0;
575
576         return 0;
577 }
578
579 static int dev_create(struct dm_ioctl *param, size_t param_size)
580 {
581         int r, m = DM_ANY_MINOR;
582         struct mapped_device *md;
583
584         r = check_name(param->name);
585         if (r)
586                 return r;
587
588         if (param->flags & DM_PERSISTENT_DEV_FLAG)
589                 m = MINOR(huge_decode_dev(param->dev));
590
591         r = dm_create(m, &md);
592         if (r)
593                 return r;
594
595         r = dm_hash_insert(param->name, *param->uuid ? param->uuid : NULL, md);
596         if (r) {
597                 dm_put(md);
598                 return r;
599         }
600
601         param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
602
603         r = __dev_status(md, param);
604         dm_put(md);
605
606         return r;
607 }
608
609 /*
610  * Always use UUID for lookups if it's present, otherwise use name or dev.
611  */
612 static struct hash_cell *__find_device_hash_cell(struct dm_ioctl *param)
613 {
614         struct mapped_device *md;
615         void *mdptr = NULL;
616
617         if (*param->uuid)
618                 return __get_uuid_cell(param->uuid);
619
620         if (*param->name)
621                 return __get_name_cell(param->name);
622
623         md = dm_get_md(huge_decode_dev(param->dev));
624         if (md)
625                 mdptr = dm_get_mdptr(md);
626
627         return mdptr;
628 }
629
630 static struct mapped_device *find_device(struct dm_ioctl *param)
631 {
632         struct hash_cell *hc;
633         struct mapped_device *md = NULL;
634
635         down_read(&_hash_lock);
636         hc = __find_device_hash_cell(param);
637         if (hc) {
638                 md = hc->md;
639
640                 /*
641                  * Sneakily write in both the name and the uuid
642                  * while we have the cell.
643                  */
644                 strncpy(param->name, hc->name, sizeof(param->name));
645                 if (hc->uuid)
646                         strncpy(param->uuid, hc->uuid, sizeof(param->uuid)-1);
647                 else
648                         param->uuid[0] = '\0';
649
650                 if (hc->new_map)
651                         param->flags |= DM_INACTIVE_PRESENT_FLAG;
652                 else
653                         param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
654         }
655         up_read(&_hash_lock);
656
657         return md;
658 }
659
660 static int dev_remove(struct dm_ioctl *param, size_t param_size)
661 {
662         struct hash_cell *hc;
663         struct mapped_device *md;
664
665         down_write(&_hash_lock);
666         hc = __find_device_hash_cell(param);
667
668         if (!hc) {
669                 DMWARN("device doesn't appear to be in the dev hash table.");
670                 up_write(&_hash_lock);
671                 return -ENXIO;
672         }
673
674         md = hc->md;
675
676         __hash_remove(hc);
677         up_write(&_hash_lock);
678         dm_put(md);
679         param->data_size = 0;
680         return 0;
681 }
682
683 /*
684  * Check a string doesn't overrun the chunk of
685  * memory we copied from userland.
686  */
687 static int invalid_str(char *str, void *end)
688 {
689         while ((void *) str < end)
690                 if (!*str++)
691                         return 0;
692
693         return -EINVAL;
694 }
695
696 static int dev_rename(struct dm_ioctl *param, size_t param_size)
697 {
698         int r;
699         char *new_name = (char *) param + param->data_start;
700
701         if (new_name < (char *) (param + 1) ||
702             invalid_str(new_name, (void *) param + param_size)) {
703                 DMWARN("Invalid new logical volume name supplied.");
704                 return -EINVAL;
705         }
706
707         r = check_name(new_name);
708         if (r)
709                 return r;
710
711         param->data_size = 0;
712         return dm_hash_rename(param->name, new_name);
713 }
714
715 static int dev_set_geometry(struct dm_ioctl *param, size_t param_size)
716 {
717         int r = -EINVAL, x;
718         struct mapped_device *md;
719         struct hd_geometry geometry;
720         unsigned long indata[4];
721         char *geostr = (char *) param + param->data_start;
722
723         md = find_device(param);
724         if (!md)
725                 return -ENXIO;
726
727         if (geostr < (char *) (param + 1) ||
728             invalid_str(geostr, (void *) param + param_size)) {
729                 DMWARN("Invalid geometry supplied.");
730                 goto out;
731         }
732
733         x = sscanf(geostr, "%lu %lu %lu %lu", indata,
734                    indata + 1, indata + 2, indata + 3);
735
736         if (x != 4) {
737                 DMWARN("Unable to interpret geometry settings.");
738                 goto out;
739         }
740
741         if (indata[0] > 65535 || indata[1] > 255 ||
742             indata[2] > 255 || indata[3] > ULONG_MAX) {
743                 DMWARN("Geometry exceeds range limits.");
744                 goto out;
745         }
746
747         geometry.cylinders = indata[0];
748         geometry.heads = indata[1];
749         geometry.sectors = indata[2];
750         geometry.start = indata[3];
751
752         r = dm_set_geometry(md, &geometry);
753         if (!r)
754                 r = __dev_status(md, param);
755
756         param->data_size = 0;
757
758 out:
759         dm_put(md);
760         return r;
761 }
762
763 static int do_suspend(struct dm_ioctl *param)
764 {
765         int r = 0;
766         int do_lockfs = 1;
767         struct mapped_device *md;
768
769         md = find_device(param);
770         if (!md)
771                 return -ENXIO;
772
773         if (param->flags & DM_SKIP_LOCKFS_FLAG)
774                 do_lockfs = 0;
775
776         if (!dm_suspended(md))
777                 r = dm_suspend(md, do_lockfs);
778
779         if (!r)
780                 r = __dev_status(md, param);
781
782         dm_put(md);
783         return r;
784 }
785
786 static int do_resume(struct dm_ioctl *param)
787 {
788         int r = 0;
789         int do_lockfs = 1;
790         struct hash_cell *hc;
791         struct mapped_device *md;
792         struct dm_table *new_map;
793
794         down_write(&_hash_lock);
795
796         hc = __find_device_hash_cell(param);
797         if (!hc) {
798                 DMWARN("device doesn't appear to be in the dev hash table.");
799                 up_write(&_hash_lock);
800                 return -ENXIO;
801         }
802
803         md = hc->md;
804
805         new_map = hc->new_map;
806         hc->new_map = NULL;
807         param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
808
809         up_write(&_hash_lock);
810
811         /* Do we need to load a new map ? */
812         if (new_map) {
813                 /* Suspend if it isn't already suspended */
814                 if (param->flags & DM_SKIP_LOCKFS_FLAG)
815                         do_lockfs = 0;
816                 if (!dm_suspended(md))
817                         dm_suspend(md, do_lockfs);
818
819                 r = dm_swap_table(md, new_map);
820                 if (r) {
821                         dm_put(md);
822                         dm_table_put(new_map);
823                         return r;
824                 }
825
826                 if (dm_table_get_mode(new_map) & FMODE_WRITE)
827                         set_disk_ro(dm_disk(md), 0);
828                 else
829                         set_disk_ro(dm_disk(md), 1);
830
831                 dm_table_put(new_map);
832         }
833
834         if (dm_suspended(md))
835                 r = dm_resume(md);
836
837         if (!r)
838                 r = __dev_status(md, param);
839
840         dm_put(md);
841         return r;
842 }
843
844 /*
845  * Set or unset the suspension state of a device.
846  * If the device already is in the requested state we just return its status.
847  */
848 static int dev_suspend(struct dm_ioctl *param, size_t param_size)
849 {
850         if (param->flags & DM_SUSPEND_FLAG)
851                 return do_suspend(param);
852
853         return do_resume(param);
854 }
855
856 /*
857  * Copies device info back to user space, used by
858  * the create and info ioctls.
859  */
860 static int dev_status(struct dm_ioctl *param, size_t param_size)
861 {
862         int r;
863         struct mapped_device *md;
864
865         md = find_device(param);
866         if (!md)
867                 return -ENXIO;
868
869         r = __dev_status(md, param);
870         dm_put(md);
871         return r;
872 }
873
874 /*
875  * Build up the status struct for each target
876  */
877 static void retrieve_status(struct dm_table *table,
878                             struct dm_ioctl *param, size_t param_size)
879 {
880         unsigned int i, num_targets;
881         struct dm_target_spec *spec;
882         char *outbuf, *outptr;
883         status_type_t type;
884         size_t remaining, len, used = 0;
885
886         outptr = outbuf = get_result_buffer(param, param_size, &len);
887
888         if (param->flags & DM_STATUS_TABLE_FLAG)
889                 type = STATUSTYPE_TABLE;
890         else
891                 type = STATUSTYPE_INFO;
892
893         /* Get all the target info */
894         num_targets = dm_table_get_num_targets(table);
895         for (i = 0; i < num_targets; i++) {
896                 struct dm_target *ti = dm_table_get_target(table, i);
897
898                 remaining = len - (outptr - outbuf);
899                 if (remaining <= sizeof(struct dm_target_spec)) {
900                         param->flags |= DM_BUFFER_FULL_FLAG;
901                         break;
902                 }
903
904                 spec = (struct dm_target_spec *) outptr;
905
906                 spec->status = 0;
907                 spec->sector_start = ti->begin;
908                 spec->length = ti->len;
909                 strncpy(spec->target_type, ti->type->name,
910                         sizeof(spec->target_type));
911
912                 outptr += sizeof(struct dm_target_spec);
913                 remaining = len - (outptr - outbuf);
914                 if (remaining <= 0) {
915                         param->flags |= DM_BUFFER_FULL_FLAG;
916                         break;
917                 }
918
919                 /* Get the status/table string from the target driver */
920                 if (ti->type->status) {
921                         if (ti->type->status(ti, type, outptr, remaining)) {
922                                 param->flags |= DM_BUFFER_FULL_FLAG;
923                                 break;
924                         }
925                 } else
926                         outptr[0] = '\0';
927
928                 outptr += strlen(outptr) + 1;
929                 used = param->data_start + (outptr - outbuf);
930
931                 outptr = align_ptr(outptr);
932                 spec->next = outptr - outbuf;
933         }
934
935         if (used)
936                 param->data_size = used;
937
938         param->target_count = num_targets;
939 }
940
941 /*
942  * Wait for a device to report an event
943  */
944 static int dev_wait(struct dm_ioctl *param, size_t param_size)
945 {
946         int r;
947         struct mapped_device *md;
948         struct dm_table *table;
949
950         md = find_device(param);
951         if (!md)
952                 return -ENXIO;
953
954         /*
955          * Wait for a notification event
956          */
957         if (dm_wait_event(md, param->event_nr)) {
958                 r = -ERESTARTSYS;
959                 goto out;
960         }
961
962         /*
963          * The userland program is going to want to know what
964          * changed to trigger the event, so we may as well tell
965          * him and save an ioctl.
966          */
967         r = __dev_status(md, param);
968         if (r)
969                 goto out;
970
971         table = dm_get_table(md);
972         if (table) {
973                 retrieve_status(table, param, param_size);
974                 dm_table_put(table);
975         }
976
977  out:
978         dm_put(md);
979         return r;
980 }
981
982 static inline int get_mode(struct dm_ioctl *param)
983 {
984         int mode = FMODE_READ | FMODE_WRITE;
985
986         if (param->flags & DM_READONLY_FLAG)
987                 mode = FMODE_READ;
988
989         return mode;
990 }
991
992 static int next_target(struct dm_target_spec *last, uint32_t next, void *end,
993                        struct dm_target_spec **spec, char **target_params)
994 {
995         *spec = (struct dm_target_spec *) ((unsigned char *) last + next);
996         *target_params = (char *) (*spec + 1);
997
998         if (*spec < (last + 1))
999                 return -EINVAL;
1000
1001         return invalid_str(*target_params, end);
1002 }
1003
1004 static int populate_table(struct dm_table *table,
1005                           struct dm_ioctl *param, size_t param_size)
1006 {
1007         int r;
1008         unsigned int i = 0;
1009         struct dm_target_spec *spec = (struct dm_target_spec *) param;
1010         uint32_t next = param->data_start;
1011         void *end = (void *) param + param_size;
1012         char *target_params;
1013
1014         if (!param->target_count) {
1015                 DMWARN("populate_table: no targets specified");
1016                 return -EINVAL;
1017         }
1018
1019         for (i = 0; i < param->target_count; i++) {
1020
1021                 r = next_target(spec, next, end, &spec, &target_params);
1022                 if (r) {
1023                         DMWARN("unable to find target");
1024                         return r;
1025                 }
1026
1027                 r = dm_table_add_target(table, spec->target_type,
1028                                         (sector_t) spec->sector_start,
1029                                         (sector_t) spec->length,
1030                                         target_params);
1031                 if (r) {
1032                         DMWARN("error adding target to table");
1033                         return r;
1034                 }
1035
1036                 next = spec->next;
1037         }
1038
1039         return dm_table_complete(table);
1040 }
1041
1042 static int table_load(struct dm_ioctl *param, size_t param_size)
1043 {
1044         int r;
1045         struct hash_cell *hc;
1046         struct dm_table *t;
1047         struct mapped_device *md;
1048
1049         md = find_device(param);
1050         if (!md)
1051                 return -ENXIO;
1052
1053         r = dm_table_create(&t, get_mode(param), param->target_count, md);
1054         if (r)
1055                 goto out;
1056
1057         r = populate_table(t, param, param_size);
1058         if (r) {
1059                 dm_table_put(t);
1060                 goto out;
1061         }
1062
1063         down_write(&_hash_lock);
1064         hc = dm_get_mdptr(md);
1065         if (!hc || hc->md != md) {
1066                 DMWARN("device has been removed from the dev hash table.");
1067                 dm_table_put(t);
1068                 up_write(&_hash_lock);
1069                 r = -ENXIO;
1070                 goto out;
1071         }
1072
1073         if (hc->new_map)
1074                 dm_table_put(hc->new_map);
1075         hc->new_map = t;
1076         up_write(&_hash_lock);
1077
1078         param->flags |= DM_INACTIVE_PRESENT_FLAG;
1079         r = __dev_status(md, param);
1080
1081 out:
1082         dm_put(md);
1083
1084         return r;
1085 }
1086
1087 static int table_clear(struct dm_ioctl *param, size_t param_size)
1088 {
1089         int r;
1090         struct hash_cell *hc;
1091         struct mapped_device *md;
1092
1093         down_write(&_hash_lock);
1094
1095         hc = __find_device_hash_cell(param);
1096         if (!hc) {
1097                 DMWARN("device doesn't appear to be in the dev hash table.");
1098                 up_write(&_hash_lock);
1099                 return -ENXIO;
1100         }
1101
1102         if (hc->new_map) {
1103                 dm_table_put(hc->new_map);
1104                 hc->new_map = NULL;
1105         }
1106
1107         param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
1108
1109         r = __dev_status(hc->md, param);
1110         md = hc->md;
1111         up_write(&_hash_lock);
1112         dm_put(md);
1113         return r;
1114 }
1115
1116 /*
1117  * Retrieves a list of devices used by a particular dm device.
1118  */
1119 static void retrieve_deps(struct dm_table *table,
1120                           struct dm_ioctl *param, size_t param_size)
1121 {
1122         unsigned int count = 0;
1123         struct list_head *tmp;
1124         size_t len, needed;
1125         struct dm_dev *dd;
1126         struct dm_target_deps *deps;
1127
1128         deps = get_result_buffer(param, param_size, &len);
1129
1130         /*
1131          * Count the devices.
1132          */
1133         list_for_each (tmp, dm_table_get_devices(table))
1134                 count++;
1135
1136         /*
1137          * Check we have enough space.
1138          */
1139         needed = sizeof(*deps) + (sizeof(*deps->dev) * count);
1140         if (len < needed) {
1141                 param->flags |= DM_BUFFER_FULL_FLAG;
1142                 return;
1143         }
1144
1145         /*
1146          * Fill in the devices.
1147          */
1148         deps->count = count;
1149         count = 0;
1150         list_for_each_entry (dd, dm_table_get_devices(table), list)
1151                 deps->dev[count++] = huge_encode_dev(dd->bdev->bd_dev);
1152
1153         param->data_size = param->data_start + needed;
1154 }
1155
1156 static int table_deps(struct dm_ioctl *param, size_t param_size)
1157 {
1158         int r = 0;
1159         struct mapped_device *md;
1160         struct dm_table *table;
1161
1162         md = find_device(param);
1163         if (!md)
1164                 return -ENXIO;
1165
1166         r = __dev_status(md, param);
1167         if (r)
1168                 goto out;
1169
1170         table = dm_get_table(md);
1171         if (table) {
1172                 retrieve_deps(table, param, param_size);
1173                 dm_table_put(table);
1174         }
1175
1176  out:
1177         dm_put(md);
1178         return r;
1179 }
1180
1181 /*
1182  * Return the status of a device as a text string for each
1183  * target.
1184  */
1185 static int table_status(struct dm_ioctl *param, size_t param_size)
1186 {
1187         int r;
1188         struct mapped_device *md;
1189         struct dm_table *table;
1190
1191         md = find_device(param);
1192         if (!md)
1193                 return -ENXIO;
1194
1195         r = __dev_status(md, param);
1196         if (r)
1197                 goto out;
1198
1199         table = dm_get_table(md);
1200         if (table) {
1201                 retrieve_status(table, param, param_size);
1202                 dm_table_put(table);
1203         }
1204
1205  out:
1206         dm_put(md);
1207         return r;
1208 }
1209
1210 /*
1211  * Pass a message to the target that's at the supplied device offset.
1212  */
1213 static int target_message(struct dm_ioctl *param, size_t param_size)
1214 {
1215         int r, argc;
1216         char **argv;
1217         struct mapped_device *md;
1218         struct dm_table *table;
1219         struct dm_target *ti;
1220         struct dm_target_msg *tmsg = (void *) param + param->data_start;
1221
1222         md = find_device(param);
1223         if (!md)
1224                 return -ENXIO;
1225
1226         r = __dev_status(md, param);
1227         if (r)
1228                 goto out;
1229
1230         if (tmsg < (struct dm_target_msg *) (param + 1) ||
1231             invalid_str(tmsg->message, (void *) param + param_size)) {
1232                 DMWARN("Invalid target message parameters.");
1233                 r = -EINVAL;
1234                 goto out;
1235         }
1236
1237         r = dm_split_args(&argc, &argv, tmsg->message);
1238         if (r) {
1239                 DMWARN("Failed to split target message parameters");
1240                 goto out;
1241         }
1242
1243         table = dm_get_table(md);
1244         if (!table)
1245                 goto out_argv;
1246
1247         if (tmsg->sector >= dm_table_get_size(table)) {
1248                 DMWARN("Target message sector outside device.");
1249                 r = -EINVAL;
1250                 goto out_table;
1251         }
1252
1253         ti = dm_table_find_target(table, tmsg->sector);
1254         if (ti->type->message)
1255                 r = ti->type->message(ti, argc, argv);
1256         else {
1257                 DMWARN("Target type does not support messages");
1258                 r = -EINVAL;
1259         }
1260
1261  out_table:
1262         dm_table_put(table);
1263  out_argv:
1264         kfree(argv);
1265  out:
1266         param->data_size = 0;
1267         dm_put(md);
1268         return r;
1269 }
1270
1271 /*-----------------------------------------------------------------
1272  * Implementation of open/close/ioctl on the special char
1273  * device.
1274  *---------------------------------------------------------------*/
1275 static ioctl_fn lookup_ioctl(unsigned int cmd)
1276 {
1277         static struct {
1278                 int cmd;
1279                 ioctl_fn fn;
1280         } _ioctls[] = {
1281                 {DM_VERSION_CMD, NULL}, /* version is dealt with elsewhere */
1282                 {DM_REMOVE_ALL_CMD, remove_all},
1283                 {DM_LIST_DEVICES_CMD, list_devices},
1284
1285                 {DM_DEV_CREATE_CMD, dev_create},
1286                 {DM_DEV_REMOVE_CMD, dev_remove},
1287                 {DM_DEV_RENAME_CMD, dev_rename},
1288                 {DM_DEV_SUSPEND_CMD, dev_suspend},
1289                 {DM_DEV_STATUS_CMD, dev_status},
1290                 {DM_DEV_WAIT_CMD, dev_wait},
1291
1292                 {DM_TABLE_LOAD_CMD, table_load},
1293                 {DM_TABLE_CLEAR_CMD, table_clear},
1294                 {DM_TABLE_DEPS_CMD, table_deps},
1295                 {DM_TABLE_STATUS_CMD, table_status},
1296
1297                 {DM_LIST_VERSIONS_CMD, list_versions},
1298
1299                 {DM_TARGET_MSG_CMD, target_message},
1300                 {DM_DEV_SET_GEOMETRY_CMD, dev_set_geometry}
1301         };
1302
1303         return (cmd >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[cmd].fn;
1304 }
1305
1306 /*
1307  * As well as checking the version compatibility this always
1308  * copies the kernel interface version out.
1309  */
1310 static int check_version(unsigned int cmd, struct dm_ioctl __user *user)
1311 {
1312         uint32_t version[3];
1313         int r = 0;
1314
1315         if (copy_from_user(version, user->version, sizeof(version)))
1316                 return -EFAULT;
1317
1318         if ((DM_VERSION_MAJOR != version[0]) ||
1319             (DM_VERSION_MINOR < version[1])) {
1320                 DMWARN("ioctl interface mismatch: "
1321                        "kernel(%u.%u.%u), user(%u.%u.%u), cmd(%d)",
1322                        DM_VERSION_MAJOR, DM_VERSION_MINOR,
1323                        DM_VERSION_PATCHLEVEL,
1324                        version[0], version[1], version[2], cmd);
1325                 r = -EINVAL;
1326         }
1327
1328         /*
1329          * Fill in the kernel version.
1330          */
1331         version[0] = DM_VERSION_MAJOR;
1332         version[1] = DM_VERSION_MINOR;
1333         version[2] = DM_VERSION_PATCHLEVEL;
1334         if (copy_to_user(user->version, version, sizeof(version)))
1335                 return -EFAULT;
1336
1337         return r;
1338 }
1339
1340 static void free_params(struct dm_ioctl *param)
1341 {
1342         vfree(param);
1343 }
1344
1345 static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl **param)
1346 {
1347         struct dm_ioctl tmp, *dmi;
1348
1349         if (copy_from_user(&tmp, user, sizeof(tmp)))
1350                 return -EFAULT;
1351
1352         if (tmp.data_size < sizeof(tmp))
1353                 return -EINVAL;
1354
1355         dmi = (struct dm_ioctl *) vmalloc(tmp.data_size);
1356         if (!dmi)
1357                 return -ENOMEM;
1358
1359         if (copy_from_user(dmi, user, tmp.data_size)) {
1360                 vfree(dmi);
1361                 return -EFAULT;
1362         }
1363
1364         *param = dmi;
1365         return 0;
1366 }
1367
1368 static int validate_params(uint cmd, struct dm_ioctl *param)
1369 {
1370         /* Always clear this flag */
1371         param->flags &= ~DM_BUFFER_FULL_FLAG;
1372
1373         /* Ignores parameters */
1374         if (cmd == DM_REMOVE_ALL_CMD ||
1375             cmd == DM_LIST_DEVICES_CMD ||
1376             cmd == DM_LIST_VERSIONS_CMD)
1377                 return 0;
1378
1379         if ((cmd == DM_DEV_CREATE_CMD)) {
1380                 if (!*param->name) {
1381                         DMWARN("name not supplied when creating device");
1382                         return -EINVAL;
1383                 }
1384         } else if ((*param->uuid && *param->name)) {
1385                 DMWARN("only supply one of name or uuid, cmd(%u)", cmd);
1386                 return -EINVAL;
1387         }
1388
1389         /* Ensure strings are terminated */
1390         param->name[DM_NAME_LEN - 1] = '\0';
1391         param->uuid[DM_UUID_LEN - 1] = '\0';
1392
1393         return 0;
1394 }
1395
1396 static int ctl_ioctl(struct inode *inode, struct file *file,
1397                      uint command, ulong u)
1398 {
1399         int r = 0;
1400         unsigned int cmd;
1401         struct dm_ioctl *param;
1402         struct dm_ioctl __user *user = (struct dm_ioctl __user *) u;
1403         ioctl_fn fn = NULL;
1404         size_t param_size;
1405
1406         /* only root can play with this */
1407         if (!capable(CAP_SYS_ADMIN))
1408                 return -EACCES;
1409
1410         if (_IOC_TYPE(command) != DM_IOCTL)
1411                 return -ENOTTY;
1412
1413         cmd = _IOC_NR(command);
1414
1415         /*
1416          * Check the interface version passed in.  This also
1417          * writes out the kernel's interface version.
1418          */
1419         r = check_version(cmd, user);
1420         if (r)
1421                 return r;
1422
1423         /*
1424          * Nothing more to do for the version command.
1425          */
1426         if (cmd == DM_VERSION_CMD)
1427                 return 0;
1428
1429         fn = lookup_ioctl(cmd);
1430         if (!fn) {
1431                 DMWARN("dm_ctl_ioctl: unknown command 0x%x", command);
1432                 return -ENOTTY;
1433         }
1434
1435         /*
1436          * Trying to avoid low memory issues when a device is
1437          * suspended.
1438          */
1439         current->flags |= PF_MEMALLOC;
1440
1441         /*
1442          * Copy the parameters into kernel space.
1443          */
1444         r = copy_params(user, &param);
1445
1446         current->flags &= ~PF_MEMALLOC;
1447
1448         if (r)
1449                 return r;
1450
1451         r = validate_params(cmd, param);
1452         if (r)
1453                 goto out;
1454
1455         param_size = param->data_size;
1456         param->data_size = sizeof(*param);
1457         r = fn(param, param_size);
1458
1459         /*
1460          * Copy the results back to userland.
1461          */
1462         if (!r && copy_to_user(user, param, param->data_size))
1463                 r = -EFAULT;
1464
1465  out:
1466         free_params(param);
1467         return r;
1468 }
1469
1470 static struct file_operations _ctl_fops = {
1471         .ioctl   = ctl_ioctl,
1472         .owner   = THIS_MODULE,
1473 };
1474
1475 static struct miscdevice _dm_misc = {
1476         .minor          = MISC_DYNAMIC_MINOR,
1477         .name           = DM_NAME,
1478         .devfs_name     = "mapper/control",
1479         .fops           = &_ctl_fops
1480 };
1481
1482 /*
1483  * Create misc character device and link to DM_DIR/control.
1484  */
1485 int __init dm_interface_init(void)
1486 {
1487         int r;
1488
1489         r = dm_hash_init();
1490         if (r)
1491                 return r;
1492
1493         r = misc_register(&_dm_misc);
1494         if (r) {
1495                 DMERR("misc_register failed for control device");
1496                 dm_hash_exit();
1497                 return r;
1498         }
1499
1500         DMINFO("%d.%d.%d%s initialised: %s", DM_VERSION_MAJOR,
1501                DM_VERSION_MINOR, DM_VERSION_PATCHLEVEL, DM_VERSION_EXTRA,
1502                DM_DRIVER_EMAIL);
1503         return 0;
1504 }
1505
1506 void dm_interface_exit(void)
1507 {
1508         if (misc_deregister(&_dm_misc) < 0)
1509                 DMERR("misc_deregister failed for control device");
1510
1511         dm_hash_exit();
1512 }