From patchwork Thu Mar 18 13:58:12 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Broz X-Patchwork-Id: 86716 Received: from mx02.colomx.prod.int.phx2.redhat.com (mx4-phx2.redhat.com [209.132.183.25]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o2IDxxtC009209 for ; Thu, 18 Mar 2010 14:00:35 GMT Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx02.colomx.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o2IDwdo2016061; Thu, 18 Mar 2010 09:58:39 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o2IDwb4v026077 for ; Thu, 18 Mar 2010 09:58:37 -0400 Received: from localhost.localdomain (vpn2-9-191.ams2.redhat.com [10.36.9.191]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o2IDwUlA012053; Thu, 18 Mar 2010 09:58:31 -0400 From: Milan Broz To: dm-devel@redhat.com, kay.sievers@vrfy.org Date: Thu, 18 Mar 2010 14:58:12 +0100 Message-Id: <1268920694-10960-1-git-send-email-mbroz@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-loop: dm-devel@redhat.com Cc: Milan Broz Subject: [dm-devel] [PATCH 1/3] Send KOBJ_ADD event after dm resume ioctl. X-BeenThere: dm-devel@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk Reply-To: device-mapper development List-Id: device-mapper development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Thu, 18 Mar 2010 14:00:36 +0000 (UTC) diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index d7500e1..b670922 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -61,6 +61,24 @@ static DECLARE_RWSEM(_hash_lock); */ static DEFINE_MUTEX(dm_hash_cells_mutex); +static void dm_ioctl_uevent(struct mapped_device *md, + enum kobject_action action, + unsigned cookie, + uint32_t *dm_flags) +{ + /* + * The first change event is translated to add event. + */ + if (!dm_initialised_md(md)) { + if (action == KOBJ_CHANGE) + action = KOBJ_ADD; + WARN_ON(action != KOBJ_ADD); + } + + if (!dm_kobject_uevent(md, action, cookie)) + *dm_flags |= DM_UEVENT_GENERATED_FLAG; +} + static void init_buckets(struct list_head *buckets) { unsigned int i; @@ -345,8 +363,7 @@ static int dm_hash_rename(uint32_t cookie, uint32_t *flags, const char *old, dm_table_put(table); } - if (!dm_kobject_uevent(hc->md, KOBJ_CHANGE, cookie)) - *flags |= DM_UEVENT_GENERATED_FLAG; + dm_ioctl_uevent(hc->md, KOBJ_CHANGE, cookie, flags); dm_put(hc->md); up_write(&_hash_lock); @@ -738,8 +755,7 @@ static int dev_remove(struct dm_ioctl *param, size_t param_size) __hash_remove(hc); up_write(&_hash_lock); - if (!dm_kobject_uevent(md, KOBJ_REMOVE, param->event_nr)) - param->flags |= DM_UEVENT_GENERATED_FLAG; + dm_ioctl_uevent(md, KOBJ_REMOVE, param->event_nr, ¶m->flags); dm_put(md); return 0; @@ -903,8 +919,9 @@ 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)) - param->flags |= DM_UEVENT_GENERATED_FLAG; + if (!r) + dm_ioctl_uevent(md, KOBJ_CHANGE, param->event_nr, + ¶m->flags); } if (old_map) diff --git a/drivers/md/dm.c b/drivers/md/dm.c index d21e128..7b364d7 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -109,6 +109,7 @@ EXPORT_SYMBOL_GPL(dm_get_rq_mapinfo); #define DMF_DELETING 4 #define DMF_NOFLUSH_SUSPENDING 5 #define DMF_QUEUE_IO_TO_THREAD 6 +#define DMF_INITIALISED 7 /* * Work processed by per-device workqueue. @@ -1932,6 +1933,7 @@ static struct mapped_device *alloc_dev(int minor) md->disk->queue = md->queue; md->disk->private_data = md; sprintf(md->disk->disk_name, "dm-%d", minor); + md->disk->flags |= GENHD_FL_SUPPRESS_ADD_EVENT; add_disk(md->disk); format_dev_t(md->name, MKDEV(_major, minor)); @@ -2619,19 +2621,30 @@ out: * Event notification. *---------------------------------------------------------------*/ int dm_kobject_uevent(struct mapped_device *md, enum kobject_action action, - unsigned cookie) + unsigned cookie) { char udev_cookie[DM_COOKIE_LENGTH]; char *envp[] = { udev_cookie, NULL }; + int r = 0; + + if (action == KOBJ_ADD) { + set_bit(DMF_INITIALISED, &md->flags); + dev_set_uevent_suppress(disk_to_dev(md->disk), 0); + } if (!cookie) - return kobject_uevent(&disk_to_dev(md->disk)->kobj, action); + r = kobject_uevent(&disk_to_dev(md->disk)->kobj, action); else { snprintf(udev_cookie, DM_COOKIE_LENGTH, "%s=%u", DM_COOKIE_ENV_VAR_NAME, cookie); - return kobject_uevent_env(&disk_to_dev(md->disk)->kobj, + r = kobject_uevent_env(&disk_to_dev(md->disk)->kobj, action, envp); } + + if (!r && dev_get_uevent_suppress(disk_to_dev(md->disk))) + r = -EINVAL; + + return r; } uint32_t dm_next_uevent_seq(struct mapped_device *md) @@ -2698,6 +2711,11 @@ int dm_suspended_md(struct mapped_device *md) return test_bit(DMF_SUSPENDED, &md->flags); } +int dm_initialised_md(struct mapped_device *md) +{ + return test_bit(DMF_INITIALISED, &md->flags); +} + int dm_suspended(struct dm_target *ti) { return dm_suspended_md(dm_table_get_md(ti->table)); diff --git a/drivers/md/dm.h b/drivers/md/dm.h index bad1724..1e9d7fc 100644 --- a/drivers/md/dm.h +++ b/drivers/md/dm.h @@ -99,6 +99,11 @@ int dm_deleting_md(struct mapped_device *md); int dm_suspended_md(struct mapped_device *md); /* + * Is the device initialised? (Add event was sent.) + */ +int dm_initialised_md(struct mapped_device *md); + +/* * The device-mapper can be driven through one of two interfaces; * ioctl or filesystem, depending which patch you have applied. */ diff --git a/fs/partitions/check.c b/fs/partitions/check.c index e8865c1..916173b 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c @@ -526,6 +526,10 @@ void register_disk(struct gendisk *disk) blkdev_put(bdev, FMODE_READ); exit: + /* caller will send ADD event later */ + if (disk->flags & GENHD_FL_SUPPRESS_ADD_EVENT) + return; + /* announce disk after possible partitions are created */ dev_set_uevent_suppress(ddev, 0); kobject_uevent(&ddev->kobj, KOBJ_ADD); diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 56b5051..ade71ff 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -116,6 +116,7 @@ struct hd_struct { #define GENHD_FL_SUPPRESS_PARTITION_INFO 32 #define GENHD_FL_EXT_DEVT 64 /* allow extended devt */ #define GENHD_FL_NATIVE_CAPACITY 128 +#define GENHD_FL_SUPPRESS_ADD_EVENT 256 #define BLK_SCSI_MAX_CMDS (256) #define BLK_SCSI_CMD_PER_LONG (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8))