2 * Copyright (C) 2001, 2002 Sistina Software (UK) Limited.
4 * This file is released under the GPL.
9 #include <linux/module.h>
10 #include <linux/vmalloc.h>
11 #include <linux/compatmac.h>
12 #include <linux/miscdevice.h>
13 #include <linux/dm-ioctl.h>
14 #include <linux/init.h>
15 #include <linux/wait.h>
16 #include <linux/blk.h>
17 #include <linux/slab.h>
19 #define DM_DRIVER_EMAIL "dm@uk.sistina.com"
21 /*-----------------------------------------------------------------
22 * The ioctl interface needs to be able to look up devices by
24 *---------------------------------------------------------------*/
26 struct list_head name_list
;
27 struct list_head uuid_list
;
31 struct mapped_device
*md
;
34 devfs_handle_t devfs_entry
;
37 #define NUM_BUCKETS 64
38 #define MASK_BUCKETS (NUM_BUCKETS - 1)
39 static struct list_head _name_buckets
[NUM_BUCKETS
];
40 static struct list_head _uuid_buckets
[NUM_BUCKETS
];
42 static devfs_handle_t _dev_dir
;
43 void dm_hash_remove_all(void);
46 * Guards access to all three tables.
48 static DECLARE_RWSEM(_hash_lock
);
50 static void init_buckets(struct list_head
*buckets
)
54 for (i
= 0; i
< NUM_BUCKETS
; i
++)
55 INIT_LIST_HEAD(buckets
+ i
);
58 int dm_hash_init(void)
60 init_buckets(_name_buckets
);
61 init_buckets(_uuid_buckets
);
62 _dev_dir
= devfs_mk_dir(0, DM_DIR
, NULL
);
66 void dm_hash_exit(void)
69 devfs_unregister(_dev_dir
);
72 /*-----------------------------------------------------------------
74 * We're not really concerned with the str hash function being
75 * fast since it's only used by the ioctl interface.
76 *---------------------------------------------------------------*/
77 static unsigned int hash_str(const char *str
)
79 const unsigned int hash_mult
= 2654435387U;
83 h
= (h
+ (unsigned int) *str
++) * hash_mult
;
85 return h
& MASK_BUCKETS
;
88 /*-----------------------------------------------------------------
89 * Code for looking up a device by name
90 *---------------------------------------------------------------*/
91 static struct hash_cell
*__get_name_cell(const char *str
)
93 struct list_head
*tmp
;
95 unsigned int h
= hash_str(str
);
97 list_for_each (tmp
, _name_buckets
+ h
) {
98 hc
= list_entry(tmp
, struct hash_cell
, name_list
);
99 if (!strcmp(hc
->name
, str
))
106 static struct hash_cell
*__get_uuid_cell(const char *str
)
108 struct list_head
*tmp
;
109 struct hash_cell
*hc
;
110 unsigned int h
= hash_str(str
);
112 list_for_each (tmp
, _uuid_buckets
+ h
) {
113 hc
= list_entry(tmp
, struct hash_cell
, uuid_list
);
114 if (!strcmp(hc
->uuid
, str
))
121 /*-----------------------------------------------------------------
122 * Inserting, removing and renaming a device.
123 *---------------------------------------------------------------*/
124 static inline char *kstrdup(const char *str
)
126 char *r
= kmalloc(strlen(str
) + 1, GFP_KERNEL
);
132 static struct hash_cell
*alloc_cell(const char *name
, const char *uuid
,
133 struct mapped_device
*md
)
135 struct hash_cell
*hc
;
137 hc
= kmalloc(sizeof(*hc
), GFP_KERNEL
);
141 hc
->name
= kstrdup(name
);
151 hc
->uuid
= kstrdup(uuid
);
159 INIT_LIST_HEAD(&hc
->name_list
);
160 INIT_LIST_HEAD(&hc
->uuid_list
);
165 static void free_cell(struct hash_cell
*hc
)
177 static int register_with_devfs(struct hash_cell
*hc
)
179 struct gendisk
*disk
= dm_disk(hc
->md
);
181 devfs_register(_dev_dir
, hc
->name
, DEVFS_FL_CURRENT_OWNER
,
182 disk
->major
, disk
->first_minor
,
183 S_IFBLK
| S_IRUSR
| S_IWUSR
| S_IRGRP
,
189 static int unregister_with_devfs(struct hash_cell
*hc
)
191 devfs_unregister(hc
->devfs_entry
);
196 * The kdev_t and uuid of a device can never change once it is
197 * initially inserted.
199 int dm_hash_insert(const char *name
, const char *uuid
, struct mapped_device
*md
)
201 struct hash_cell
*cell
;
204 * Allocate the new cells.
206 cell
= alloc_cell(name
, uuid
, md
);
211 * Insert the cell into all three hash tables.
213 down_write(&_hash_lock
);
214 if (__get_name_cell(name
))
217 list_add(&cell
->name_list
, _name_buckets
+ hash_str(name
));
220 if (__get_uuid_cell(uuid
)) {
221 list_del(&cell
->name_list
);
224 list_add(&cell
->uuid_list
, _uuid_buckets
+ hash_str(uuid
));
226 register_with_devfs(cell
);
228 up_write(&_hash_lock
);
233 up_write(&_hash_lock
);
238 void __hash_remove(struct hash_cell
*hc
)
240 /* remove from the dev hash */
241 list_del(&hc
->uuid_list
);
242 list_del(&hc
->name_list
);
243 unregister_with_devfs(hc
);
247 void dm_hash_remove_all(void)
250 struct hash_cell
*hc
;
251 struct list_head
*tmp
, *n
;
253 down_write(&_hash_lock
);
254 for (i
= 0; i
< NUM_BUCKETS
; i
++) {
255 list_for_each_safe (tmp
, n
, _name_buckets
+ i
) {
256 hc
= list_entry(tmp
, struct hash_cell
, name_list
);
260 up_write(&_hash_lock
);
263 int dm_hash_rename(const char *old
, const char *new)
265 char *new_name
, *old_name
;
266 struct hash_cell
*hc
;
271 new_name
= kstrdup(new);
275 down_write(&_hash_lock
);
280 hc
= __get_name_cell(new);
282 DMWARN("asked to rename to an already existing name %s -> %s",
284 up_write(&_hash_lock
);
289 * Is there such a device as 'old' ?
291 hc
= __get_name_cell(old
);
293 DMWARN("asked to rename a non existent device %s -> %s",
295 up_write(&_hash_lock
);
300 * rename and move the name cell.
302 list_del(&hc
->name_list
);
305 list_add(&hc
->name_list
, _name_buckets
+ hash_str(new_name
));
307 /* rename the device node in devfs */
308 unregister_with_devfs(hc
);
309 register_with_devfs(hc
);
311 up_write(&_hash_lock
);
317 /*-----------------------------------------------------------------
318 * Implementation of the ioctl commands
319 *---------------------------------------------------------------*/
322 * All the ioctl commands get dispatched to functions with this
325 typedef int (*ioctl_fn
)(struct dm_ioctl
*param
, struct dm_ioctl
*user
);
328 * Check a string doesn't overrun the chunk of
329 * memory we copied from userland.
331 static int valid_str(char *str
, void *begin
, void *end
)
333 while (((void *) str
>= begin
) && ((void *) str
< end
))
340 static int next_target(struct dm_target_spec
*last
, uint32_t next
,
341 void *begin
, void *end
,
342 struct dm_target_spec
**spec
, char **params
)
344 *spec
= (struct dm_target_spec
*)
345 ((unsigned char *) last
+ next
);
346 *params
= (char *) (*spec
+ 1);
348 if (*spec
< (last
+ 1) || ((void *) *spec
> end
))
351 return valid_str(*params
, begin
, end
);
354 static int populate_table(struct dm_table
*table
, struct dm_ioctl
*args
)
356 int i
= 0, r
, first
= 1;
357 struct dm_target_spec
*spec
;
361 if (!args
->target_count
) {
362 DMWARN("populate_table: no targets specified");
366 begin
= (void *) args
;
367 end
= begin
+ args
->data_size
;
369 for (i
= 0; i
< args
->target_count
; i
++) {
372 r
= next_target((struct dm_target_spec
*) args
,
374 begin
, end
, &spec
, ¶ms
);
376 r
= next_target(spec
, spec
->next
, begin
, end
,
380 DMWARN("unable to find target");
384 r
= dm_table_add_target(table
, spec
->target_type
,
385 spec
->sector_start
, spec
->length
,
388 DMWARN("internal error adding target to table");
395 return dm_table_complete(table
);
399 * Round up the ptr to the next 'align' boundary. Obviously
400 * 'align' must be a power of 2.
402 static inline void *align_ptr(void *ptr
, unsigned int align
)
405 return (void *) (((unsigned long) (ptr
+ align
)) & ~align
);
409 * Copies a dm_ioctl and an optional additional payload to
412 static int results_to_user(struct dm_ioctl
*user
, struct dm_ioctl
*param
,
413 void *data
, uint32_t len
)
419 ptr
= align_ptr(user
+ 1, sizeof(unsigned long));
420 param
->data_start
= ptr
- (void *) user
;
424 * The version number has already been filled in, so we
425 * just copy later fields.
427 r
= copy_to_user(&user
->data_size
, ¶m
->data_size
,
428 sizeof(*param
) - sizeof(param
->version
));
433 if (param
->data_start
+ len
> param
->data_size
)
436 if (copy_to_user(ptr
, data
, len
))
444 * Fills in a dm_ioctl structure, ready for sending back to
447 static int __info(struct mapped_device
*md
, struct dm_ioctl
*param
)
449 struct dm_table
*table
;
450 struct block_device
*bdev
;
451 struct gendisk
*disk
= dm_disk(md
);
453 param
->flags
= DM_EXISTS_FLAG
;
454 if (dm_suspended(md
))
455 param
->flags
|= DM_SUSPEND_FLAG
;
457 param
->dev
= MKDEV(disk
->major
, disk
->first_minor
);
458 bdev
= bdget(param
->dev
);
463 param
->flags
|= DM_READONLY_FLAG
;
465 param
->open_count
= bdev
->bd_openers
;
468 table
= dm_get_table(md
);
469 param
->target_count
= dm_table_get_num_targets(table
);
476 * Always use UUID for lookups if it's present, otherwise use name.
478 static inline struct mapped_device
*find_device(struct dm_ioctl
*param
)
480 struct hash_cell
*hc
;
481 struct mapped_device
*md
= NULL
;
483 down_read(&_hash_lock
);
484 hc
= *param
->uuid
? __get_uuid_cell(param
->uuid
) :
485 __get_name_cell(param
->name
);
490 * Sneakily write in both the name and the uuid
491 * while we have the cell.
493 strncpy(param
->name
, hc
->name
, sizeof(param
->name
));
495 strncpy(param
->uuid
, hc
->uuid
, sizeof(param
->uuid
) - 1);
497 param
->uuid
[0] = '\0';
501 up_read(&_hash_lock
);
506 #define ALIGNMENT sizeof(int)
507 static void *_align(void *ptr
, unsigned int a
)
509 register unsigned long align
= --a
;
511 return (void *) (((unsigned long) ptr
+ align
) & ~align
);
515 * Copies device info back to user space, used by
516 * the create and info ioctls.
518 static int info(struct dm_ioctl
*param
, struct dm_ioctl
*user
)
520 struct mapped_device
*md
;
524 md
= find_device(param
);
527 * Device not found - returns cleared exists flag.
535 return results_to_user(user
, param
, NULL
, 0);
538 static inline int get_mode(struct dm_ioctl
*param
)
540 int mode
= FMODE_READ
| FMODE_WRITE
;
542 if (param
->flags
& DM_READONLY_FLAG
)
548 static int check_name(const char *name
)
550 if (strchr(name
, '/')) {
551 DMWARN("invalid device name");
558 static int create(struct dm_ioctl
*param
, struct dm_ioctl
*user
)
562 struct mapped_device
*md
;
565 r
= check_name(param
->name
);
569 r
= dm_table_create(&t
, get_mode(param
));
573 r
= populate_table(t
, param
);
579 minor
= (param
->flags
& DM_PERSISTENT_DEV_FLAG
) ?
580 minor(to_kdev_t(param
->dev
)) : -1;
582 r
= dm_create(minor
, t
, &md
);
587 dm_table_put(t
); /* md will have grabbed its own reference */
589 set_disk_ro(dm_disk(md
), (param
->flags
& DM_READONLY_FLAG
));
590 r
= dm_hash_insert(param
->name
, *param
->uuid
? param
->uuid
: NULL
, md
);
593 return r
? r
: info(param
, user
);
597 * Build up the status struct for each target
599 static int __status(struct mapped_device
*md
, struct dm_ioctl
*param
,
600 char *outbuf
, int *len
)
603 struct dm_target_spec
*spec
;
606 struct dm_table
*table
= dm_get_table(md
);
608 if (param
->flags
& DM_STATUS_TABLE_FLAG
)
609 type
= STATUSTYPE_TABLE
;
611 type
= STATUSTYPE_INFO
;
615 /* Get all the target info */
616 num_targets
= dm_table_get_num_targets(table
);
617 for (i
= 0; i
< num_targets
; i
++) {
618 struct dm_target
*ti
= dm_table_get_target(table
, i
);
620 if (outptr
- outbuf
+
621 sizeof(struct dm_target_spec
) > param
->data_size
) {
626 spec
= (struct dm_target_spec
*) outptr
;
629 spec
->sector_start
= ti
->begin
;
630 spec
->length
= ti
->len
;
631 strncpy(spec
->target_type
, ti
->type
->name
,
632 sizeof(spec
->target_type
));
634 outptr
+= sizeof(struct dm_target_spec
);
636 /* Get the status/table string from the target driver */
637 if (ti
->type
->status
)
638 ti
->type
->status(ti
, type
, outptr
,
639 outbuf
+ param
->data_size
- outptr
);
643 outptr
+= strlen(outptr
) + 1;
644 _align(outptr
, ALIGNMENT
);
645 spec
->next
= outptr
- outbuf
;
648 param
->target_count
= num_targets
;
649 *len
= outptr
- outbuf
;
656 * Return the status of a device as a text string for each
659 static int get_status(struct dm_ioctl
*param
, struct dm_ioctl
*user
)
661 struct mapped_device
*md
;
666 md
= find_device(param
);
669 * Device not found - returns cleared exists flag.
673 /* We haven't a clue how long the resultant data will be so
674 just allocate as much as userland has allowed us and make sure
675 we don't overun it */
676 outbuf
= kmalloc(param
->data_size
, GFP_KERNEL
);
680 * Get the status of all targets
682 __status(md
, param
, outbuf
, &len
);
685 * Setup the basic dm_ioctl structure.
693 ret
= results_to_user(user
, param
, outbuf
, len
);
702 * Wait for a device to report an event
704 static int wait_device_event(struct dm_ioctl
*param
, struct dm_ioctl
*user
)
706 struct mapped_device
*md
;
707 struct dm_table
*table
;
708 DECLARE_WAITQUEUE(wq
, current
);
710 md
= find_device(param
);
713 * Device not found - returns cleared exists flag.
718 * Setup the basic dm_ioctl structure.
723 * Wait for a notification event
725 set_current_state(TASK_INTERRUPTIBLE
);
726 table
= dm_get_table(md
);
727 dm_table_add_wait_queue(table
, &wq
);
732 set_current_state(TASK_RUNNING
);
735 return results_to_user(user
, param
, NULL
, 0);
739 * Retrieves a list of devices used by a particular dm device.
741 static int dep(struct dm_ioctl
*param
, struct dm_ioctl
*user
)
744 struct mapped_device
*md
;
745 struct list_head
*tmp
;
747 struct dm_target_deps
*deps
= NULL
;
748 struct dm_table
*table
;
750 md
= find_device(param
);
753 table
= dm_get_table(md
);
756 * Setup the basic dm_ioctl structure.
764 list_for_each(tmp
, dm_table_get_devices(table
))
768 * Allocate a kernel space version of the dm_target_status
771 if (array_too_big(sizeof(*deps
), sizeof(*deps
->dev
), count
)) {
777 len
= sizeof(*deps
) + (sizeof(*deps
->dev
) * count
);
778 deps
= kmalloc(len
, GFP_KERNEL
);
786 * Fill in the devices.
790 list_for_each(tmp
, dm_table_get_devices(table
)) {
791 struct dm_dev
*dd
= list_entry(tmp
, struct dm_dev
, list
);
792 deps
->dev
[count
++] = dd
->bdev
->bd_dev
;
798 r
= results_to_user(user
, param
, deps
, len
);
804 static int remove(struct dm_ioctl
*param
, struct dm_ioctl
*user
)
806 struct hash_cell
*hc
;
808 down_write(&_hash_lock
);
809 hc
= *param
->uuid
? __get_uuid_cell(param
->uuid
) :
810 __get_name_cell(param
->name
);
812 DMWARN("device doesn't appear to be in the dev hash table.");
813 up_write(&_hash_lock
);
818 up_write(&_hash_lock
);
822 static int remove_all(struct dm_ioctl
*param
, struct dm_ioctl
*user
)
824 dm_hash_remove_all();
828 static int suspend(struct dm_ioctl
*param
, struct dm_ioctl
*user
)
831 struct mapped_device
*md
;
833 md
= find_device(param
);
837 if (param
->flags
& DM_SUSPEND_FLAG
)
846 static int reload(struct dm_ioctl
*param
, struct dm_ioctl
*user
)
849 struct mapped_device
*md
;
852 r
= dm_table_create(&t
, get_mode(param
));
856 r
= populate_table(t
, param
);
862 md
= find_device(param
);
868 r
= dm_swap_table(md
, t
);
875 set_disk_ro(dm_disk(md
), (param
->flags
& DM_READONLY_FLAG
));
878 r
= info(param
, user
);
882 static int rename(struct dm_ioctl
*param
, struct dm_ioctl
*user
)
885 char *new_name
= (char *) param
+ param
->data_start
;
887 if (valid_str(new_name
, (void *) param
,
888 (void *) param
+ param
->data_size
)) {
889 DMWARN("Invalid new logical volume name supplied.");
893 r
= check_name(new_name
);
897 return dm_hash_rename(param
->name
, new_name
);
901 /*-----------------------------------------------------------------
902 * Implementation of open/close/ioctl on the special char
904 *---------------------------------------------------------------*/
905 static ioctl_fn
lookup_ioctl(unsigned int cmd
)
911 {DM_VERSION_CMD
, NULL
}, /* version is dealt with elsewhere */
912 {DM_REMOVE_ALL_CMD
, remove_all
},
913 {DM_DEV_CREATE_CMD
, create
},
914 {DM_DEV_REMOVE_CMD
, remove
},
915 {DM_DEV_RELOAD_CMD
, reload
},
916 {DM_DEV_RENAME_CMD
, rename
},
917 {DM_DEV_SUSPEND_CMD
, suspend
},
918 {DM_DEV_DEPS_CMD
, dep
},
919 {DM_DEV_STATUS_CMD
, info
},
920 {DM_TARGET_STATUS_CMD
, get_status
},
921 {DM_TARGET_WAIT_CMD
, wait_device_event
},
924 return (cmd
>= ARRAY_SIZE(_ioctls
)) ? NULL
: _ioctls
[cmd
].fn
;
928 * As well as checking the version compatibility this always
929 * copies the kernel interface version out.
931 static int check_version(int cmd
, struct dm_ioctl
*user
)
936 if (copy_from_user(version
, user
->version
, sizeof(version
)))
939 if ((DM_VERSION_MAJOR
!= version
[0]) ||
940 (DM_VERSION_MINOR
< version
[1])) {
941 DMWARN("ioctl interface mismatch: "
942 "kernel(%u.%u.%u), user(%u.%u.%u), cmd(%d)",
943 DM_VERSION_MAJOR
, DM_VERSION_MINOR
,
944 DM_VERSION_PATCHLEVEL
,
945 version
[0], version
[1], version
[2], cmd
);
950 * Fill in the kernel version.
952 version
[0] = DM_VERSION_MAJOR
;
953 version
[1] = DM_VERSION_MINOR
;
954 version
[2] = DM_VERSION_PATCHLEVEL
;
955 if (copy_to_user(user
->version
, version
, sizeof(version
)))
961 static void free_params(struct dm_ioctl
*param
)
966 static int copy_params(struct dm_ioctl
*user
, struct dm_ioctl
**param
)
968 struct dm_ioctl tmp
, *dmi
;
970 if (copy_from_user(&tmp
, user
, sizeof(tmp
)))
973 if (tmp
.data_size
< sizeof(tmp
))
976 dmi
= (struct dm_ioctl
*) vmalloc(tmp
.data_size
);
980 if (copy_from_user(dmi
, user
, tmp
.data_size
)) {
989 static int validate_params(uint cmd
, struct dm_ioctl
*param
)
991 /* Unless creating, either name of uuid but not both */
992 if (cmd
!= DM_DEV_CREATE_CMD
) {
993 if ((!*param
->uuid
&& !*param
->name
) ||
994 (*param
->uuid
&& *param
->name
)) {
995 DMWARN("one of name or uuid must be supplied");
1000 /* Ensure strings are terminated */
1001 param
->name
[DM_NAME_LEN
- 1] = '\0';
1002 param
->uuid
[DM_UUID_LEN
- 1] = '\0';
1007 static int ctl_ioctl(struct inode
*inode
, struct file
*file
,
1008 uint command
, ulong u
)
1011 struct dm_ioctl
*param
;
1012 struct dm_ioctl
*user
= (struct dm_ioctl
*) u
;
1015 /* only root can play with this */
1016 if (!capable(CAP_SYS_ADMIN
))
1019 if (_IOC_TYPE(command
) != DM_IOCTL
)
1022 cmd
= _IOC_NR(command
);
1025 * Check the interface version passed in. This also
1026 * writes out the kernels interface version.
1028 r
= check_version(cmd
, user
);
1033 * Nothing more to do for the version command.
1035 if (cmd
== DM_VERSION_CMD
)
1038 fn
= lookup_ioctl(cmd
);
1040 DMWARN("dm_ctl_ioctl: unknown command 0x%x", command
);
1045 * Copy the parameters into kernel space.
1047 r
= copy_params(user
, ¶m
);
1051 r
= validate_params(cmd
, param
);
1057 r
= fn(param
, user
);
1062 static struct file_operations _ctl_fops
= {
1064 .owner
= THIS_MODULE
,
1067 static devfs_handle_t _ctl_handle
;
1069 static struct miscdevice _dm_misc
= {
1070 .minor
= MISC_DYNAMIC_MINOR
,
1076 * Create misc character device and link to DM_DIR/control.
1078 int __init
dm_interface_init(void)
1086 r
= misc_register(&_dm_misc
);
1088 DMERR("misc_register failed for control device");
1093 r
= devfs_mk_symlink(NULL
, DM_DIR
"/control", DEVFS_FL_DEFAULT
,
1094 "../misc/" DM_NAME
, &_ctl_handle
, NULL
);
1096 DMERR("devfs_mk_symlink failed for control device");
1099 DMINFO("%d.%d.%d%s initialised: %s", DM_VERSION_MAJOR
,
1100 DM_VERSION_MINOR
, DM_VERSION_PATCHLEVEL
, DM_VERSION_EXTRA
,
1106 misc_deregister(&_dm_misc
);
1110 void dm_interface_exit(void)
1114 devfs_remove(DM_DIR
"/control");
1116 if (misc_deregister(&_dm_misc
) < 0)
1117 DMERR("misc_deregister failed for control device");