|
@@ -28,7 +28,7 @@ struct dm_file {
|
|
|
* poll will wait until the global event number is greater than
|
|
|
* this value.
|
|
|
*/
|
|
|
- unsigned global_event_nr;
|
|
|
+ volatile unsigned global_event_nr;
|
|
|
};
|
|
|
|
|
|
/*-----------------------------------------------------------------
|
|
@@ -464,9 +464,9 @@ void dm_deferred_remove(void)
|
|
|
* All the ioctl commands get dispatched to functions with this
|
|
|
* prototype.
|
|
|
*/
|
|
|
-typedef int (*ioctl_fn)(struct dm_ioctl *param, size_t param_size);
|
|
|
+typedef int (*ioctl_fn)(struct file *filp, struct dm_ioctl *param, size_t param_size);
|
|
|
|
|
|
-static int remove_all(struct dm_ioctl *param, size_t param_size)
|
|
|
+static int remove_all(struct file *filp, struct dm_ioctl *param, size_t param_size)
|
|
|
{
|
|
|
dm_hash_remove_all(true, !!(param->flags & DM_DEFERRED_REMOVE), false);
|
|
|
param->data_size = 0;
|
|
@@ -499,7 +499,7 @@ static void *get_result_buffer(struct dm_ioctl *param, size_t param_size,
|
|
|
return ((void *) param) + param->data_start;
|
|
|
}
|
|
|
|
|
|
-static int list_devices(struct dm_ioctl *param, size_t param_size)
|
|
|
+static int list_devices(struct file *filp, struct dm_ioctl *param, size_t param_size)
|
|
|
{
|
|
|
unsigned int i;
|
|
|
struct hash_cell *hc;
|
|
@@ -590,7 +590,7 @@ static void list_version_get_info(struct target_type *tt, void *param)
|
|
|
info->vers = align_ptr(((void *) ++info->vers) + strlen(tt->name) + 1);
|
|
|
}
|
|
|
|
|
|
-static int list_versions(struct dm_ioctl *param, size_t param_size)
|
|
|
+static int list_versions(struct file *filp, struct dm_ioctl *param, size_t param_size)
|
|
|
{
|
|
|
size_t len, needed = 0;
|
|
|
struct dm_target_versions *vers;
|
|
@@ -732,7 +732,7 @@ static void __dev_status(struct mapped_device *md, struct dm_ioctl *param)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static int dev_create(struct dm_ioctl *param, size_t param_size)
|
|
|
+static int dev_create(struct file *filp, struct dm_ioctl *param, size_t param_size)
|
|
|
{
|
|
|
int r, m = DM_ANY_MINOR;
|
|
|
struct mapped_device *md;
|
|
@@ -824,7 +824,7 @@ static struct mapped_device *find_device(struct dm_ioctl *param)
|
|
|
return md;
|
|
|
}
|
|
|
|
|
|
-static int dev_remove(struct dm_ioctl *param, size_t param_size)
|
|
|
+static int dev_remove(struct file *filp, struct dm_ioctl *param, size_t param_size)
|
|
|
{
|
|
|
struct hash_cell *hc;
|
|
|
struct mapped_device *md;
|
|
@@ -889,7 +889,7 @@ static int invalid_str(char *str, void *end)
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
-static int dev_rename(struct dm_ioctl *param, size_t param_size)
|
|
|
+static int dev_rename(struct file *filp, struct dm_ioctl *param, size_t param_size)
|
|
|
{
|
|
|
int r;
|
|
|
char *new_data = (char *) param + param->data_start;
|
|
@@ -919,7 +919,7 @@ static int dev_rename(struct dm_ioctl *param, size_t param_size)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int dev_set_geometry(struct dm_ioctl *param, size_t param_size)
|
|
|
+static int dev_set_geometry(struct file *filp, struct dm_ioctl *param, size_t param_size)
|
|
|
{
|
|
|
int r = -EINVAL, x;
|
|
|
struct mapped_device *md;
|
|
@@ -1068,7 +1068,7 @@ static int do_resume(struct dm_ioctl *param)
|
|
|
* Set or unset the suspension state of a device.
|
|
|
* If the device already is in the requested state we just return its status.
|
|
|
*/
|
|
|
-static int dev_suspend(struct dm_ioctl *param, size_t param_size)
|
|
|
+static int dev_suspend(struct file *filp, struct dm_ioctl *param, size_t param_size)
|
|
|
{
|
|
|
if (param->flags & DM_SUSPEND_FLAG)
|
|
|
return do_suspend(param);
|
|
@@ -1080,7 +1080,7 @@ static int dev_suspend(struct dm_ioctl *param, size_t param_size)
|
|
|
* Copies device info back to user space, used by
|
|
|
* the create and info ioctls.
|
|
|
*/
|
|
|
-static int dev_status(struct dm_ioctl *param, size_t param_size)
|
|
|
+static int dev_status(struct file *filp, struct dm_ioctl *param, size_t param_size)
|
|
|
{
|
|
|
struct mapped_device *md;
|
|
|
|
|
@@ -1171,7 +1171,7 @@ static void retrieve_status(struct dm_table *table,
|
|
|
/*
|
|
|
* Wait for a device to report an event
|
|
|
*/
|
|
|
-static int dev_wait(struct dm_ioctl *param, size_t param_size)
|
|
|
+static int dev_wait(struct file *filp, struct dm_ioctl *param, size_t param_size)
|
|
|
{
|
|
|
int r = 0;
|
|
|
struct mapped_device *md;
|
|
@@ -1208,6 +1208,19 @@ out:
|
|
|
return r;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Remember the global event number and make it possible to poll
|
|
|
+ * for further events.
|
|
|
+ */
|
|
|
+static int dev_arm_poll(struct file *filp, struct dm_ioctl *param, size_t param_size)
|
|
|
+{
|
|
|
+ struct dm_file *priv = filp->private_data;
|
|
|
+
|
|
|
+ priv->global_event_nr = atomic_read(&dm_global_event_nr);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static inline fmode_t get_mode(struct dm_ioctl *param)
|
|
|
{
|
|
|
fmode_t mode = FMODE_READ | FMODE_WRITE;
|
|
@@ -1277,7 +1290,7 @@ static bool is_valid_type(enum dm_queue_mode cur, enum dm_queue_mode new)
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
-static int table_load(struct dm_ioctl *param, size_t param_size)
|
|
|
+static int table_load(struct file *filp, struct dm_ioctl *param, size_t param_size)
|
|
|
{
|
|
|
int r;
|
|
|
struct hash_cell *hc;
|
|
@@ -1364,7 +1377,7 @@ err:
|
|
|
return r;
|
|
|
}
|
|
|
|
|
|
-static int table_clear(struct dm_ioctl *param, size_t param_size)
|
|
|
+static int table_clear(struct file *filp, struct dm_ioctl *param, size_t param_size)
|
|
|
{
|
|
|
struct hash_cell *hc;
|
|
|
struct mapped_device *md;
|
|
@@ -1438,7 +1451,7 @@ static void retrieve_deps(struct dm_table *table,
|
|
|
param->data_size = param->data_start + needed;
|
|
|
}
|
|
|
|
|
|
-static int table_deps(struct dm_ioctl *param, size_t param_size)
|
|
|
+static int table_deps(struct file *filp, struct dm_ioctl *param, size_t param_size)
|
|
|
{
|
|
|
struct mapped_device *md;
|
|
|
struct dm_table *table;
|
|
@@ -1464,7 +1477,7 @@ static int table_deps(struct dm_ioctl *param, size_t param_size)
|
|
|
* Return the status of a device as a text string for each
|
|
|
* target.
|
|
|
*/
|
|
|
-static int table_status(struct dm_ioctl *param, size_t param_size)
|
|
|
+static int table_status(struct file *filp, struct dm_ioctl *param, size_t param_size)
|
|
|
{
|
|
|
struct mapped_device *md;
|
|
|
struct dm_table *table;
|
|
@@ -1519,7 +1532,7 @@ static int message_for_md(struct mapped_device *md, unsigned argc, char **argv,
|
|
|
/*
|
|
|
* Pass a message to the target that's at the supplied device offset.
|
|
|
*/
|
|
|
-static int target_message(struct dm_ioctl *param, size_t param_size)
|
|
|
+static int target_message(struct file *filp, struct dm_ioctl *param, size_t param_size)
|
|
|
{
|
|
|
int r, argc;
|
|
|
char **argv;
|
|
@@ -1636,7 +1649,8 @@ static ioctl_fn lookup_ioctl(unsigned int cmd, int *ioctl_flags)
|
|
|
{DM_LIST_VERSIONS_CMD, 0, list_versions},
|
|
|
|
|
|
{DM_TARGET_MSG_CMD, 0, target_message},
|
|
|
- {DM_DEV_SET_GEOMETRY_CMD, 0, dev_set_geometry}
|
|
|
+ {DM_DEV_SET_GEOMETRY_CMD, 0, dev_set_geometry},
|
|
|
+ {DM_DEV_ARM_POLL, IOCTL_FLAGS_NO_PARAMS, dev_arm_poll},
|
|
|
};
|
|
|
|
|
|
if (unlikely(cmd >= ARRAY_SIZE(_ioctls)))
|
|
@@ -1791,7 +1805,7 @@ static int validate_params(uint cmd, struct dm_ioctl *param)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
|
|
|
+static int ctl_ioctl(struct file *file, uint command, struct dm_ioctl __user *user)
|
|
|
{
|
|
|
int r = 0;
|
|
|
int ioctl_flags;
|
|
@@ -1845,7 +1859,7 @@ static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
|
|
|
goto out;
|
|
|
|
|
|
param->data_size = offsetof(struct dm_ioctl, data);
|
|
|
- r = fn(param, input_param_size);
|
|
|
+ r = fn(file, param, input_param_size);
|
|
|
|
|
|
if (unlikely(param->flags & DM_BUFFER_FULL_FLAG) &&
|
|
|
unlikely(ioctl_flags & IOCTL_FLAGS_NO_PARAMS))
|
|
@@ -1864,7 +1878,7 @@ out:
|
|
|
|
|
|
static long dm_ctl_ioctl(struct file *file, uint command, ulong u)
|
|
|
{
|
|
|
- return (long)ctl_ioctl(command, (struct dm_ioctl __user *)u);
|
|
|
+ return (long)ctl_ioctl(file, command, (struct dm_ioctl __user *)u);
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_COMPAT
|