dm ioctl: introduce flag indicating uevent was generated
authorPeter Rajnoha <prajnoha@redhat.com>
Sat, 6 Mar 2010 02:32:31 +0000 (02:32 +0000)
committerAlasdair G Kergon <agk@redhat.com>
Sat, 6 Mar 2010 02:32:31 +0000 (02:32 +0000)
Set a new DM_UEVENT_GENERATED_FLAG when returning from ioctls to
indicate that a uevent was actually generated.  This tells the userspace
caller that it may need to wait for the event to be processed.

Signed-off-by: Peter Rajnoha <prajnoha@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
drivers/md/dm-ioctl.c
drivers/md/dm.c
drivers/md/dm.h
include/linux/dm-ioctl.h

index e3cf568..d7500e1 100644 (file)
@@ -285,7 +285,8 @@ retry:
        up_write(&_hash_lock);
 }
 
-static int dm_hash_rename(uint32_t cookie, const char *old, const char *new)
+static int dm_hash_rename(uint32_t cookie, uint32_t *flags, const char *old,
+                         const char *new)
 {
        char *new_name, *old_name;
        struct hash_cell *hc;
@@ -344,7 +345,8 @@ static int dm_hash_rename(uint32_t cookie, const char *old, const char *new)
                dm_table_put(table);
        }
 
-       dm_kobject_uevent(hc->md, KOBJ_CHANGE, cookie);
+       if (!dm_kobject_uevent(hc->md, KOBJ_CHANGE, cookie))
+               *flags |= DM_UEVENT_GENERATED_FLAG;
 
        dm_put(hc->md);
        up_write(&_hash_lock);
@@ -736,10 +738,10 @@ static int dev_remove(struct dm_ioctl *param, size_t param_size)
        __hash_remove(hc);
        up_write(&_hash_lock);
 
-       dm_kobject_uevent(md, KOBJ_REMOVE, param->event_nr);
+       if (!dm_kobject_uevent(md, KOBJ_REMOVE, param->event_nr))
+               param->flags |= DM_UEVENT_GENERATED_FLAG;
 
        dm_put(md);
-       param->data_size = 0;
        return 0;
 }
 
@@ -773,7 +775,9 @@ static int dev_rename(struct dm_ioctl *param, size_t param_size)
                return r;
 
        param->data_size = 0;
-       return dm_hash_rename(param->event_nr, param->name, new_name);
+
+       return dm_hash_rename(param->event_nr, &param->flags, param->name,
+                             new_name);
 }
 
 static int dev_set_geometry(struct dm_ioctl *param, size_t param_size)
@@ -899,8 +903,8 @@ static int do_resume(struct dm_ioctl *param)
 
        if (dm_suspended_md(md)) {
                r = dm_resume(md);
-               if (!r)
-                       dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr);
+               if (!r && !dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr))
+                       param->flags |= DM_UEVENT_GENERATED_FLAG;
        }
 
        if (old_map)
@@ -1477,6 +1481,7 @@ static int validate_params(uint cmd, struct dm_ioctl *param)
 {
        /* Always clear this flag */
        param->flags &= ~DM_BUFFER_FULL_FLAG;
+       param->flags &= ~DM_UEVENT_GENERATED_FLAG;
 
        /* Ignores parameters */
        if (cmd == DM_REMOVE_ALL_CMD ||
index 7199846..d21e128 100644 (file)
@@ -2618,18 +2618,19 @@ out:
 /*-----------------------------------------------------------------
  * Event notification.
  *---------------------------------------------------------------*/
-void dm_kobject_uevent(struct mapped_device *md, enum kobject_action action,
+int dm_kobject_uevent(struct mapped_device *md, enum kobject_action action,
                       unsigned cookie)
 {
        char udev_cookie[DM_COOKIE_LENGTH];
        char *envp[] = { udev_cookie, NULL };
 
        if (!cookie)
-               kobject_uevent(&disk_to_dev(md->disk)->kobj, action);
+               return kobject_uevent(&disk_to_dev(md->disk)->kobj, action);
        else {
                snprintf(udev_cookie, DM_COOKIE_LENGTH, "%s=%u",
                         DM_COOKIE_ENV_VAR_NAME, cookie);
-               kobject_uevent_env(&disk_to_dev(md->disk)->kobj, action, envp);
+               return kobject_uevent_env(&disk_to_dev(md->disk)->kobj,
+                                         action, envp);
        }
 }
 
index 8dadaa5..bad1724 100644 (file)
@@ -125,8 +125,8 @@ void dm_stripe_exit(void);
 int dm_open_count(struct mapped_device *md);
 int dm_lock_for_deletion(struct mapped_device *md);
 
-void dm_kobject_uevent(struct mapped_device *md, enum kobject_action action,
-                      unsigned cookie);
+int dm_kobject_uevent(struct mapped_device *md, enum kobject_action action,
+                     unsigned cookie);
 
 int dm_io_init(void);
 void dm_io_exit(void);
index aa95508..2c445e1 100644 (file)
@@ -266,9 +266,9 @@ enum {
 #define DM_DEV_SET_GEOMETRY    _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
 
 #define DM_VERSION_MAJOR       4
-#define DM_VERSION_MINOR       16
+#define DM_VERSION_MINOR       17
 #define DM_VERSION_PATCHLEVEL  0
-#define DM_VERSION_EXTRA       "-ioctl (2009-11-05)"
+#define DM_VERSION_EXTRA       "-ioctl (2010-03-05)"
 
 /* Status bits */
 #define DM_READONLY_FLAG       (1 << 0) /* In/Out */
@@ -316,4 +316,9 @@ enum {
  */
 #define DM_QUERY_INACTIVE_TABLE_FLAG   (1 << 12) /* In */
 
+/*
+ * If set, a uevent was generated for which the caller may need to wait.
+ */
+#define DM_UEVENT_GENERATED_FLAG       (1 << 13) /* Out */
+
 #endif                         /* _LINUX_DM_IOCTL_H */