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