From patchwork Fri Mar 27 21:38:43 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonthan Brassow X-Patchwork-Id: 14799 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 n2RLcm1j012832 for ; Fri, 27 Mar 2009 21:38:49 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 D9FAF61A719; Fri, 27 Mar 2009 17:38:48 -0400 (EDT) Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by listman.util.phx.redhat.com (8.13.1/8.13.1) with ESMTP id n2RLckj2007873 for ; Fri, 27 Mar 2009 17:38:46 -0400 Received: from hydrogen.msp.redhat.com (hydrogen.msp.redhat.com [10.15.80.1]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id n2RLcpkA026148 for ; Fri, 27 Mar 2009 17:38:51 -0400 Received: from hydrogen.msp.redhat.com (localhost.localdomain [127.0.0.1]) by hydrogen.msp.redhat.com (8.14.1/8.14.1) with ESMTP id n2RLciKS018068 for ; Fri, 27 Mar 2009 16:38:44 -0500 Received: (from jbrassow@localhost) by hydrogen.msp.redhat.com (8.14.1/8.14.1/Submit) id n2RLchN5018067 for dm-devel@redhat.com; Fri, 27 Mar 2009 16:38:43 -0500 Date: Fri, 27 Mar 2009 16:38:43 -0500 From: Jonathan Brassow Message-Id: <200903272138.n2RLchN5018067@hydrogen.msp.redhat.com> To: dm-devel@redhat.com X-Scanned-By: MIMEDefang 2.58 on 172.16.52.254 X-loop: dm-devel@redhat.com Subject: [dm-devel] [PATCH 2 of 2] DM Snapshot: blocking lookup_exception workaround 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 Patch name: dm-snap-blocking-lookup_exception-workaround.patch This patch is just a workaround to make the cluster exception store (cluster-aware snapshots) work. It basically, makes the snapshot mapping functions ignore the fact that the lookup_exception function will block. The proper fix would be to have a separate thread in dm-snap.c that would be used if an exception store returned -EWOULDBLOCK from lookup_exception. --- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel Index: linux-2.6/drivers/md/dm-snap.c =================================================================== --- linux-2.6.orig/drivers/md/dm-snap.c +++ linux-2.6/drivers/md/dm-snap.c @@ -1070,7 +1070,7 @@ static int snapshot_map(struct dm_target /* If the block is already remapped - use that, else remap it */ rtn = ss->store->type->lookup_exception(ss->store, chunk, - &new_chunk, 0, 0); + &new_chunk, 0, 1); if (!rtn) { remap_exception(ss, bio, new_chunk); goto out_unlock; @@ -1108,7 +1108,7 @@ static int snapshot_map(struct dm_target rtn = ss->store->type->lookup_exception(ss->store, chunk, &new_chunk, - 0, 0); + 0, 1); if (!rtn) { dm_free_exception(ss->pending, &pe->e); remap_exception(ss, bio, new_chunk); @@ -1290,7 +1290,7 @@ static int __origin_write(struct list_he * ref_count is initialised to 1 so pending_complete() * won't destroy the primary_pe while we're inside this loop. */ - rtn = store->type->lookup_exception(store, chunk, NULL, 1, 0); + rtn = store->type->lookup_exception(store, chunk, NULL, 1, 1); if (!rtn) goto next_snapshot; @@ -1315,7 +1315,7 @@ static int __origin_write(struct list_he } rtn = store->type->lookup_exception(store, chunk, - NULL, 1, 0); + NULL, 1, 1); if (!rtn) { dm_free_exception(snap->pending, &pe->e); goto next_snapshot; Index: linux-2.6/drivers/md/dm-ex-store-clusterized.c =================================================================== --- linux-2.6.orig/drivers/md/dm-ex-store-clusterized.c +++ linux-2.6/drivers/md/dm-ex-store-clusterized.c @@ -7,6 +7,7 @@ */ #include #include +#include #include "dm-exception-store.h" #define DM_MSG_PREFIX "clusterized exception store" @@ -14,6 +15,9 @@ struct clusterized_c { struct dm_exception_store *core_store; + struct completion resume_completion; + struct work_struct resume_work; + struct rw_semaphore lock; int current_dl_mode; @@ -170,6 +174,19 @@ static int cluster_unlock(struct cluster return r; } +static void resume_core(struct work_struct *work) +{ + int r; + struct clusterized_c *cc; + + cc = container_of(work, struct clusterized_c, resume_work); + + r = cc->core_store->type->resume(cc->core_store); + if (r) + DMERR("Core resume failed"); + complete(&cc->resume_completion); +} + /* * clusterized_ctr * @store @@ -227,6 +244,8 @@ static int clusterized_ctr(struct dm_exc init_rwsem(&cc->lock); init_completion(&cc->dlm_completion); + init_completion(&cc->resume_completion); + INIT_WORK(&cc->resume_work, resume_core); /* Create (or join) the lock space */ r = dlm_new_lockspace(store->type->name, strlen(store->type->name), @@ -438,7 +457,8 @@ static int clusterized_lookup_exception( * re-reading its metadata and updating its cache. IOW, it must * be able to resume multiple times before a suspend is issued. */ - cc->core_store->type->resume(cc->core_store); + schedule_work(&cc->resume_work); + wait_for_completion(&cc->resume_completion); cc->metadata_counter = cc->cluster_metadata_counter; cluster_unlock(cc);