From patchwork Mon Jun 18 16:18:55 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Weinberger X-Patchwork-Id: 165513 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:4978:20e::2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 760C1B706D for ; Tue, 19 Jun 2012 02:22:08 +1000 (EST) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1Sgegy-0000wz-PQ; Mon, 18 Jun 2012 16:20:40 +0000 Received: from a.ns.miles-group.at ([95.130.255.143] helo=radon.swed.at) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1Sgefx-0000f8-My for linux-mtd@lists.infradead.org; Mon, 18 Jun 2012 16:19:39 +0000 Received: (qmail 14375 invoked by uid 89); 18 Jun 2012 16:19:36 -0000 Received: by simscan 1.3.1 ppid: 14119, pid: 14372, t: 0.1258s scanners: attach: 1.3.1 clamav: 0.96.5/m:53 Received: from unknown (HELO localhost.localdomain) (richard@nod.at@212.62.202.73) by radon.swed.at with ESMTPA; 18 Jun 2012 16:19:35 -0000 From: Richard Weinberger To: linux-mtd@lists.infradead.org Subject: [PATCH 12/22] UBI: Fastmap: Locking fixes Date: Mon, 18 Jun 2012 18:18:55 +0200 Message-Id: <1340036345-96726-13-git-send-email-richard@nod.at> X-Mailer: git-send-email 1.7.6.5 In-Reply-To: <1340036345-96726-1-git-send-email-richard@nod.at> References: <1340036345-96726-1-git-send-email-richard@nod.at> X-Spam-Note: CRM114 invocation failed X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: artem.bityutskiy@linux.intel.com, linux-kernel@vger.kernel.org, adrian.hunter@intel.com, Heinz.Egger@linutronix.de, thomas.wucher@linutronix.de, shmulik.ladkani@gmail.com, Richard Weinberger , tglx@linutronix.de, Marius.Mazarel@ugal.ro, tim.bird@am.sony.com X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-mtd-bounces@lists.infradead.org Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Add a new rw semaphore to block EBA table changes while creating the fastmap. Signed-off-by: Richard Weinberger --- drivers/mtd/ubi/eba.c | 12 ++++++++++++ drivers/mtd/ubi/fastmap.c | 2 ++ drivers/mtd/ubi/ubi.h | 2 ++ 3 files changed, 16 insertions(+), 0 deletions(-) diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index d112b10..2bee8be 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -340,7 +340,9 @@ int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol, dbg_eba("erase LEB %d:%d, PEB %d", vol_id, lnum, pnum); + down_read(&ubi->fm_sem); vol->eba_tbl[lnum] = UBI_LEB_UNMAPPED; + up_read(&ubi->fm_sem); err = ubi_wl_put_peb(ubi, pnum, 0); out_unlock: @@ -549,7 +551,9 @@ retry: mutex_unlock(&ubi->buf_mutex); ubi_free_vid_hdr(ubi, vid_hdr); + down_read(&ubi->fm_sem); vol->eba_tbl[lnum] = new_pnum; + up_read(&ubi->fm_sem); ubi_wl_put_peb(ubi, pnum, 1); ubi_msg("data was successfully recovered"); @@ -667,7 +671,9 @@ retry: } } + down_read(&ubi->fm_sem); vol->eba_tbl[lnum] = pnum; + up_read(&ubi->fm_sem); leb_write_unlock(ubi, vol_id, lnum); ubi_free_vid_hdr(ubi, vid_hdr); @@ -785,7 +791,9 @@ retry: } ubi_assert(vol->eba_tbl[lnum] < 0); + down_read(&ubi->fm_sem); vol->eba_tbl[lnum] = pnum; + up_read(&ubi->fm_sem); leb_write_unlock(ubi, vol_id, lnum); ubi_free_vid_hdr(ubi, vid_hdr); @@ -906,7 +914,9 @@ retry: goto out_leb_unlock; } + down_read(&ubi->fm_sem); vol->eba_tbl[lnum] = pnum; + up_read(&ubi->fm_sem); out_leb_unlock: leb_write_unlock(ubi, vol_id, lnum); @@ -1154,7 +1164,9 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, } ubi_assert(vol->eba_tbl[lnum] == from); + down_read(&ubi->fm_sem); vol->eba_tbl[lnum] = to; + up_read(&ubi->fm_sem); out_unlock_buf: mutex_unlock(&ubi->buf_mutex); diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index ff09fd4..33a14cf 100644 --- a/drivers/mtd/ubi/fastmap.c +++ b/drivers/mtd/ubi/fastmap.c @@ -1418,9 +1418,11 @@ int ubi_update_fastmap(struct ubi_device *ubi) kfree(old_fm); + down_write(&ubi->fm_sem); down_write(&ubi->work_sem); ret = ubi_write_fastmap(ubi, new_fm); up_write(&ubi->work_sem); + up_write(&ubi->fm_sem); out_unlock: mutex_unlock(&ubi->fm_mutex); diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 8588f9c..8abbcd5 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -384,6 +384,7 @@ struct ubi_wl_entry; * @fm_pool: in-memory data structure of the fastmap pool * @fm_pool_mutex: serializes ubi_wl_get_peb() * @fm_mutex: serializes ubi_update_fastmap() + * @fm_sem: allows ubi_update_fastmap() to block EBA table changes * @attached_by_scanning: this UBI device was attached by the old scanning * methold. All fastmap volumes have to be deleted. * @@ -482,6 +483,7 @@ struct ubi_device { struct ubi_fastmap_layout *fm; struct ubi_fm_pool fm_pool; struct ubi_fm_pool fm_wl_pool; + struct rw_semaphore fm_sem; struct mutex fm_mutex; struct mutex fm_pool_mutex; int attached_by_scanning;