From patchwork Mon Mar 8 04:42:10 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kiyoshi Ueda X-Patchwork-Id: 83995 Received: from mx01.colomx.prod.int.phx2.redhat.com (mx3-phx2.redhat.com [209.132.183.24]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o284kiD1022882 for ; Mon, 8 Mar 2010 04:47:20 GMT Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx01.colomx.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o284iCPI008422; Sun, 7 Mar 2010 23:44:14 -0500 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o284iB68026699 for ; Sun, 7 Mar 2010 23:44:11 -0500 Received: from mx1.redhat.com (ext-mx09.extmail.prod.ext.phx2.redhat.com [10.5.110.13]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o284i6no022598; Sun, 7 Mar 2010 23:44:06 -0500 Received: from tyo202.gate.nec.co.jp (TYO202.gate.nec.co.jp [202.32.8.206]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o284hsGF013212; Sun, 7 Mar 2010 23:43:54 -0500 Received: from mailgate3.nec.co.jp ([10.7.69.195]) by tyo202.gate.nec.co.jp (8.13.8/8.13.4) with ESMTP id o284hr7w005095; Mon, 8 Mar 2010 13:43:53 +0900 (JST) Received: (from root@localhost) by mailgate3.nec.co.jp (8.11.7/3.7W-MAILGATE-NEC) id o284hrn04845; Mon, 8 Mar 2010 13:43:53 +0900 (JST) Received: from mail02.kamome.nec.co.jp (mail02.kamome.nec.co.jp [10.25.43.5]) by mailsv3.nec.co.jp (8.13.8/8.13.4) with ESMTP id o284hpaB020848; Mon, 8 Mar 2010 13:43:52 +0900 (JST) Received: from kaishu.jp.nec.com ([10.26.220.5] [10.26.220.5]) by mail03.kamome.nec.co.jp with ESMTP id BT-MMP-1155608; Mon, 8 Mar 2010 13:42:17 +0900 Received: from elcondor.linux.bs1.fc.nec.co.jp ([10.34.125.195] [10.34.125.195]) by mail.jp.nec.com with ESMTP; Mon, 8 Mar 2010 13:42:14 +0900 Message-ID: <4B948022.40301@ct.jp.nec.com> Date: Mon, 08 Mar 2010 13:42:10 +0900 From: Kiyoshi Ueda User-Agent: Thunderbird 2.0.0.23 (X11/20090825) MIME-Version: 1.0 To: Alasdair Kergon X-RedHat-Spam-Score: 0 () X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-Scanned-By: MIMEDefang 2.67 on 10.5.110.13 X-loop: dm-devel@redhat.com Cc: device-mapper development , Mikulas Patocka Subject: [dm-devel] [PATCH] dm: separate device deletion from dm_put() 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: , 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]); Mon, 08 Mar 2010 04:47:20 +0000 (UTC) Index: 2.6.33/drivers/md/dm-ioctl.c =================================================================== --- 2.6.33.orig/drivers/md/dm-ioctl.c +++ 2.6.33/drivers/md/dm-ioctl.c @@ -252,6 +252,7 @@ static void dm_hash_remove_all(int keep_ int i, dev_skipped, dev_removed; struct hash_cell *hc; struct list_head *tmp, *n; + struct mapped_device *md; down_write(&_hash_lock); @@ -260,13 +261,14 @@ retry: for (i = 0; i < NUM_BUCKETS; i++) { list_for_each_safe (tmp, n, _name_buckets + i) { hc = list_entry(tmp, struct hash_cell, name_list); + md = hc->md; - if (keep_open_devices && - dm_lock_for_deletion(hc->md)) { + if (keep_open_devices && dm_lock_for_deletion(md)) { dev_skipped++; continue; } __hash_remove(hc); + dm_destroy(md); dev_removed = 1; } } @@ -640,6 +642,7 @@ static int dev_create(struct dm_ioctl *p r = dm_hash_insert(param->name, *param->uuid ? param->uuid : NULL, md); if (r) { dm_put(md); + dm_destroy(md); return r; } @@ -742,6 +745,7 @@ static int dev_remove(struct dm_ioctl *p param->flags |= DM_UEVENT_GENERATED_FLAG; dm_put(md); + dm_destroy(md); return 0; } Index: 2.6.33/drivers/md/dm.c =================================================================== --- 2.6.33.orig/drivers/md/dm.c +++ 2.6.33/drivers/md/dm.c @@ -2175,6 +2175,7 @@ void dm_set_mdptr(struct mapped_device * void dm_get(struct mapped_device *md) { atomic_inc(&md->holders); + BUG_ON(test_bit(DMF_FREEING, &md->flags)); } const char *dm_device_name(struct mapped_device *md) @@ -2183,27 +2184,41 @@ const char *dm_device_name(struct mapped } EXPORT_SYMBOL_GPL(dm_device_name); -void dm_put(struct mapped_device *md) +void dm_destroy(struct mapped_device *md) { struct dm_table *map; - BUG_ON(test_bit(DMF_FREEING, &md->flags)); + might_sleep(); - if (atomic_dec_and_lock(&md->holders, &_minor_lock)) { - map = dm_get_live_table(md); - idr_replace(&_minor_idr, MINOR_ALLOCED, - MINOR(disk_devt(dm_disk(md)))); - set_bit(DMF_FREEING, &md->flags); - spin_unlock(&_minor_lock); - if (!dm_suspended_md(md)) { - dm_table_presuspend_targets(map); - dm_table_postsuspend_targets(map); - } - dm_sysfs_exit(md); - dm_table_put(map); - dm_table_destroy(__unbind(md)); - free_dev(md); + spin_lock(&_minor_lock); + map = dm_get_live_table(md); + idr_replace(&_minor_idr, MINOR_ALLOCED, MINOR(disk_devt(dm_disk(md)))); + set_bit(DMF_FREEING, &md->flags); + spin_unlock(&_minor_lock); + + if (!dm_suspended_md(md)) { + dm_table_presuspend_targets(map); + dm_table_postsuspend_targets(map); } + + /* + * Rare but there may be I/O requests still going to complete, + * for example. Wait for all references to disappear. + * No one shouldn't increment the reference count of the mapped_device, + * after the mapped_device becomes DMF_FREEING state. + */ + while (atomic_read(&md->holders)) + msleep(1); + + dm_sysfs_exit(md); + dm_table_put(map); + dm_table_destroy(__unbind(md)); + free_dev(md); +} + +void dm_put(struct mapped_device *md) +{ + atomic_dec(&md->holders); } EXPORT_SYMBOL_GPL(dm_put); Index: 2.6.33/drivers/md/dm.h =================================================================== --- 2.6.33.orig/drivers/md/dm.h +++ 2.6.33/drivers/md/dm.h @@ -122,6 +122,10 @@ void dm_linear_exit(void); int dm_stripe_init(void); void dm_stripe_exit(void); +/* + * mapped_device operations + */ +void dm_destroy(struct mapped_device *md); int dm_open_count(struct mapped_device *md); int dm_lock_for_deletion(struct mapped_device *md);