From patchwork Wed Nov 11 02:48:23 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alasdair G Kergon X-Patchwork-Id: 59240 X-Patchwork-Delegate: agk@redhat.com Received: from hormel.redhat.com (hormel1.redhat.com [209.132.177.33]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id nAB2mTQM008390 for ; Wed, 11 Nov 2009 02:48:29 GMT Received: from listman.util.phx.redhat.com (listman.util.phx.redhat.com [10.8.4.110]) by hormel.redhat.com (Postfix) with ESMTP id 2E7056191F5; Tue, 10 Nov 2009 21:48:28 -0500 (EST) Received: from int-mx05.intmail.prod.int.phx2.redhat.com (nat-pool.util.phx.redhat.com [10.8.5.200]) by listman.util.phx.redhat.com (8.13.1/8.13.1) with ESMTP id nAB2mQDt023217 for ; Tue, 10 Nov 2009 21:48:26 -0500 Received: from agk-dp.fab.redhat.com (agk-dp.fab.redhat.com [10.33.0.20]) by int-mx05.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id nAB2mOGi032478 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 10 Nov 2009 21:48:25 -0500 Received: from agk by agk-dp.fab.redhat.com with local (Exim 4.69) (envelope-from ) id 1N83Fw-00045z-1x; Wed, 11 Nov 2009 02:48:24 +0000 Date: Wed, 11 Nov 2009 02:48:23 +0000 From: Alasdair G Kergon To: dm-devel@redhat.com Message-ID: <20091111024823.GL17055@agk-dp.fab.redhat.com> Mail-Followup-To: dm-devel@redhat.com, Mike Snitzer , Mikulas Patocka , Jonathan Brassow , Kiyoshi Ueda , Jun'ichi Nomura , Milan Broz , Zdenek Kabelac , Heinz Mauelshagen References: <20091111011652.GK17055@agk-dp.fab.redhat.com> <20091111012040.GP6208@agk-dp.fab.redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20091111012040.GP6208@agk-dp.fab.redhat.com> Organization: Red Hat UK Ltd. Registered in England and Wales, number 03798903. Registered Office: Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SL4 1TE. User-Agent: Mutt/1.5.18 (2008-05-17) X-Scanned-By: MIMEDefang 2.67 on 10.5.11.18 X-loop: dm-devel@redhat.com Cc: Kiyoshi Ueda , Mike Snitzer , Heinz Mauelshagen , Mikulas Patocka , Zdenek Kabelac , "Jun'ichi Nomura" , Milan Broz Subject: [dm-devel] dm: keep old table until after resume succeeded X-BeenThere: dm-devel@redhat.com X-Mailman-Version: 2.1.5 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 Index: linux-2.6.32-rc6/drivers/md/dm-ioctl.c =================================================================== --- linux-2.6.32-rc6.orig/drivers/md/dm-ioctl.c +++ linux-2.6.32-rc6/drivers/md/dm-ioctl.c @@ -855,7 +855,7 @@ static int do_resume(struct dm_ioctl *pa unsigned suspend_flags = DM_SUSPEND_LOCKFS_FLAG; struct hash_cell *hc; struct mapped_device *md; - struct dm_table *new_map; + struct dm_table *new_map, *old_map = NULL; down_write(&_hash_lock); @@ -884,11 +884,11 @@ static int do_resume(struct dm_ioctl *pa if (!dm_suspended(md)) dm_suspend(md, suspend_flags); - r = dm_swap_table(md, new_map); - if (r) { + old_map = dm_swap_table(md, new_map); + if (IS_ERR(old_map)) { dm_table_destroy(new_map); dm_put(md); - return r; + return PTR_ERR(old_map); } if (dm_table_get_mode(new_map) & FMODE_WRITE) @@ -900,6 +900,8 @@ static int do_resume(struct dm_ioctl *pa if (dm_suspended(md)) r = dm_resume(md); + if (old_map) + dm_table_destroy(old_map); if (!r) { dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr); Index: linux-2.6.32-rc6/drivers/md/dm.c =================================================================== --- linux-2.6.32-rc6.orig/drivers/md/dm.c +++ linux-2.6.32-rc6/drivers/md/dm.c @@ -2026,9 +2026,13 @@ static void __set_size(struct mapped_dev mutex_unlock(&md->bdev->bd_inode->i_mutex); } -static int __bind(struct mapped_device *md, struct dm_table *t, - struct queue_limits *limits) +/* + * Returns old map, which caller must destroy. + */ +static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t, + struct queue_limits *limits) { + struct dm_table *old_map; struct request_queue *q = md->queue; sector_t size; unsigned long flags; @@ -2043,11 +2047,6 @@ static int __bind(struct mapped_device * __set_size(md, size); - if (!size) { - dm_table_destroy(t); - return 0; - } - dm_table_event_callback(t, event_callback, md); /* @@ -2063,11 +2062,12 @@ static int __bind(struct mapped_device * __bind_mempools(md, t); write_lock_irqsave(&md->map_lock, flags); + old_map = md->map; md->map = t; dm_table_set_restrictions(t, q, limits); write_unlock_irqrestore(&md->map_lock, flags); - return 0; + return old_map; } /* @@ -2361,13 +2361,13 @@ static void dm_rq_barrier_work(struct wo } /* - * Swap in a new table (destroying old one). + * Swap in a new table, returning the old one for the caller to destroy. */ -int dm_swap_table(struct mapped_device *md, struct dm_table *table) +struct dm_table *dm_swap_table(struct mapped_device *md, struct dm_table *table) { - struct dm_table *map; + struct dm_table *map = ERR_PTR(-EINVAL); struct queue_limits limits; - int r = -EINVAL; + int r; mutex_lock(&md->suspend_lock); @@ -2376,8 +2376,10 @@ int dm_swap_table(struct mapped_device * goto out; r = dm_calculate_queue_limits(table, &limits); - if (r) + if (r) { + map = ERR_PTR(r); goto out; + } /* cannot change the device type, once a table is bound */ if (md->map && @@ -2386,13 +2388,11 @@ int dm_swap_table(struct mapped_device * goto out; } - map = __unbind(md); - r = __bind(md, table, &limits); - dm_table_destroy(map); + map = __bind(md, table, &limits); out: mutex_unlock(&md->suspend_lock); - return r; + return map; } /* Index: linux-2.6.32-rc6/include/linux/device-mapper.h =================================================================== --- linux-2.6.32-rc6.orig/include/linux/device-mapper.h +++ linux-2.6.32-rc6/include/linux/device-mapper.h @@ -295,8 +295,10 @@ void dm_table_event(struct dm_table *t); /* * The device must be suspended before calling this method. + * Returns the previous table, which the caller must destroy. */ -int dm_swap_table(struct mapped_device *md, struct dm_table *t); +struct dm_table *dm_swap_table(struct mapped_device *md, + struct dm_table *t); /* * A wrapper around vmalloc.