From: Artem Bityutskiy <dedekind@infradead.org>
To: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Cc: Frank Haverkamp <haver@vnet.ibm.com>,
Christoph Hellwig <hch@infradead.org>,
David Woodhouse <dwmw2@infradead.org>,
Josh Boyer <jwboyer@linux.vnet.ibm.com>,
Artem Bityutskiy <dedekind@infradead.org>
Subject: [PATCH 13/22 take 3] UBI: accounting unit
Date: Wed, 14 Mar 2007 17:20:39 +0200 [thread overview]
Message-ID: <20070314152039.1112.31606.sendpatchset@localhost.localdomain> (raw)
In-Reply-To: <20070314151934.1112.70126.sendpatchset@localhost.localdomain>
diff -auNrp tmp-from/drivers/mtd/ubi/account.c tmp-to/drivers/mtd/ubi/account.c
--- tmp-from/drivers/mtd/ubi/account.c 1970-01-01 02:00:00.000000000 +0200
+++ tmp-to/drivers/mtd/ubi/account.c 2007-03-14 17:15:50.000000000 +0200
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) International Business Machines Corp., 2006
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Artem B. Bityutskiy
+ */
+
+/*
+ * UBI accounting unit.
+ *
+ * This unit is responsible for maintaining physical eraseblock accounting to
+ * prevent overcommitment.
+ */
+
+#include <linux/err.h>
+#include "ubi.h"
+
+/* The lowest number PEBs reserved for bad PEB handling */
+#define MIN_RESEVED_PEBS 1
+
+/**
+ * ubi_acc_reserve - reserve a number of physical eraseblocks.
+ *
+ * @ubi: the UBI device description object
+ * @pebs: how many physical eraseblocks to reserve
+ *
+ * This function returns zero in case of success and %-ENOSPC if there is no
+ * enough physical eraseblocks.
+ */
+int ubi_acc_reserve(struct ubi_info *ubi, int pebs)
+{
+ ubi_assert(pebs > 0);
+
+ spin_lock(&ubi->acc.lock);
+ ubi_assert(ubi->acc.avail_pebs >= 0);
+ if (pebs > ubi->acc.avail_pebs) {
+ dbg_err("not enough PEBs: requested %d, available %d",
+ pebs, ubi->acc.avail_pebs);
+ spin_unlock(&ubi->acc.lock);
+ return -ENOSPC;
+ }
+ ubi->acc.avail_pebs -= pebs;
+ ubi->acc.rsvd_pebs += pebs;
+ spin_unlock(&ubi->acc.lock);
+ return 0;
+}
+
+/**
+ * ubi_acc_free - free a number of reserved physical eraseblocks.
+ *
+ * @ubi: the UBI device description object
+ * @pebs: how many physical eraseblocks to free
+ */
+void ubi_acc_free(struct ubi_info *ubi, int pebs)
+{
+ ubi_assert(pebs > 0);
+
+ spin_lock(&ubi->acc.lock);
+ ubi_assert(pebs <= ubi->acc.rsvd_pebs);
+ ubi->acc.rsvd_pebs -= pebs;
+ ubi->acc.avail_pebs += pebs;
+ ubi_assert(ubi->acc.rsvd_pebs >= 0);
+ spin_unlock(&ubi->acc.lock);
+}
+
+/**
+ * calculate_beb_rsvd_max - calculate how many PEBs must be reserved for bad
+ * eraseblock handling.
+ *
+ * @ubi: the UBI device description object
+ */
+static void calculate_beb_rsvd_max(struct ubi_info *ubi)
+{
+ ubi->acc.beb_rsvd_max = ubi->io.good_peb_count/100;
+ ubi->acc.beb_rsvd_max *= CONFIG_MTD_UBI_BEB_RESERVE;
+ if (ubi->acc.beb_rsvd_max < MIN_RESEVED_PEBS)
+ ubi->acc.beb_rsvd_max = MIN_RESEVED_PEBS;
+}
+
+/**
+ * ubi_acc_peb_marked_bad - a physical eraseblock was marked as bad,
+ * re-calculate accounting.
+ *
+ * @ubi: the UBI device description object
+ */
+void ubi_acc_peb_marked_bad(struct ubi_info *ubi)
+{
+ int need;
+
+ ubi_assert(ubi->acc.beb_rsvd_pebs >= 0);
+
+ if (!ubi->io.bad_allowed)
+ return;
+
+ spin_lock(&ubi->acc.lock);
+ if (ubi->acc.beb_rsvd_pebs == 0) {
+ ubi_warn("no reserved physical eraseblocks");
+ ubi_ro_mode(ubi);
+ }
+ calculate_beb_rsvd_max(ubi);
+ ubi->acc.beb_rsvd_pebs -= 1;
+ need = ubi->acc.beb_rsvd_max = ubi->acc.beb_rsvd_pebs;
+ if (need > 0) {
+ int alloc;
+
+ alloc = ubi->acc.avail_pebs >= need ? need
+ : ubi->acc.avail_pebs;
+ ubi->acc.avail_pebs -= alloc;
+ ubi->acc.rsvd_pebs += alloc;
+ ubi->acc.beb_rsvd_pebs += alloc;
+ }
+ if (ubi->acc.beb_rsvd_pebs == 0)
+ ubi_warn("last PEB from the reserved pool was used");
+ spin_unlock(&ubi->acc.lock);
+}
+
+/**
+ * acc_info_check - check sanity and consistency of accounting information.
+ *
+ * @ubi: the UBI device description object
+ *
+ * We do not trust data read from the flash media and we check that the
+ * accounting information is consistent, because it is formed using on-flash
+ * data. This function returns zero if everything is fine and %-EINVAL if some
+ * inconsistency was found.
+ */
+static int acc_info_check(const struct ubi_info *ubi)
+{
+ if (ubi->acc.avail_pebs < 0 || ubi->acc.rsvd_pebs < 0)
+ goto bad;
+
+ if (ubi->acc.avail_pebs > ubi->io.good_peb_count) {
+ dbg_err("bad avail_pebs");
+ goto bad;
+ }
+
+ if (ubi->acc.rsvd_pebs > ubi->io.good_peb_count ||
+ ubi->acc.rsvd_pebs < ubi->vtbl.vol_count) {
+ dbg_err("bad rsvd_pebs");
+ goto bad;
+ }
+
+ if (ubi->acc.avail_pebs + ubi->acc.rsvd_pebs !=
+ ubi->io.good_peb_count) {
+ dbg_err("accounting error");
+ goto bad;
+ }
+
+ return 0;
+
+bad:
+ ubi_err("accounting check failed");
+ dbg_err("avail_pebs %d, rsvd_pebs %d, ubi->io.good_peb_count %d",
+ ubi->acc.avail_pebs, ubi->acc.rsvd_pebs,
+ ubi->io.good_peb_count);
+ return -EINVAL;
+}
+
+/**
+ * ubi_acc_init_scan - initialize the accounting unit using scanning
+ * information.
+ *
+ * @ubi: the UBI device description object
+ * @si: a pointer to the scanning information
+ *
+ * This function returns zero in case of success and a negative error code in
+ * case of failure.
+ */
+int ubi_acc_init_scan(struct ubi_info *ubi, struct ubi_scan_info *si)
+{
+ int err, i;
+ const struct ubi_vtbl_vtr *vtr;
+
+ dbg_uif("initialize the accounting unit");
+
+ spin_lock_init(&ubi->acc.lock);
+
+ for (i = 0; i < UBI_INT_VOL_COUNT; i++) {
+ vtr = ubi_vtbl_get_vtr(ubi, UBI_INTERNAL_VOL_START + i);
+ ubi_assert(!IS_ERR(vtr));
+ ubi->acc.rsvd_pebs += vtr->reserved_pebs;
+ }
+
+ for (i = 0; i < ubi->vtbl.vt_slots; i++) {
+ vtr = ubi_vtbl_get_vtr(ubi, i);
+ if (IS_ERR(vtr))
+ continue;
+ ubi->acc.rsvd_pebs += vtr->reserved_pebs;
+ }
+
+ ubi->acc.rsvd_pebs += si->alien_peb_count;
+ ubi->acc.avail_pebs = ubi->io.good_peb_count - ubi->acc.rsvd_pebs;
+
+ if (ubi->io.bad_allowed) {
+ calculate_beb_rsvd_max(ubi);
+
+ if (ubi->acc.avail_pebs < ubi->acc.beb_rsvd_max) {
+ /* No enough free physical eraseblocks */
+ ubi->acc.beb_rsvd_pebs = ubi->acc.avail_pebs;
+ ubi_warn("cannot reserve enough PEBs for bad PEB "
+ "handling, reserved %d, need %d",
+ ubi->acc.beb_rsvd_pebs, ubi->acc.beb_rsvd_max);
+ } else
+ ubi->acc.beb_rsvd_pebs = ubi->acc.beb_rsvd_max;
+
+ ubi->acc.avail_pebs -= ubi->acc.beb_rsvd_pebs;
+ ubi->acc.rsvd_pebs += ubi->acc.beb_rsvd_pebs;
+ }
+
+ /* Check accounting information sanity and consistency */
+ err = acc_info_check(ubi);
+ if (err)
+ return err;
+
+ dbg_uif("accounting unit is initialized");
+ dbg_uif("avail_pebs %d rsvd_pebs %d, max_volumes %d",
+ ubi->acc.avail_pebs, ubi->acc.rsvd_pebs, ubi->vtbl.vt_slots);
+
+ return 0;
+}
next prev parent reply other threads:[~2007-03-14 15:24 UTC|newest]
Thread overview: 88+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-03-14 15:19 [PATCH 00/22 take 3] UBI: Unsorted Block Images Artem Bityutskiy
2007-03-14 15:19 ` [PATCH 01/22 take 3] UBI: on-flash data structures header Artem Bityutskiy
2007-03-14 15:19 ` [PATCH 02/22 take 3] UBI: user-space API header Artem Bityutskiy
2007-03-14 15:19 ` [PATCH 03/22 take 3] UBI: kernel-space " Artem Bityutskiy
2007-03-14 15:19 ` [PATCH 04/22 take 3] UBI: internal header Artem Bityutskiy
2007-03-14 15:19 ` [PATCH 05/22 take 3] UBI: startup code Artem Bityutskiy
2007-03-14 15:20 ` [PATCH 06/22 take 3] UBI: scanning unit Artem Bityutskiy
2007-03-14 15:20 ` [PATCH 07/22 take 3] UBI: I/O unit Artem Bityutskiy
2007-03-14 15:20 ` [PATCH 08/22 take 3] UBI: volume table unit Artem Bityutskiy
2007-03-14 15:20 ` [PATCH 09/22 take 3] UBI: wear-leveling unit Artem Bityutskiy
2007-03-14 15:20 ` [PATCH 10/22 take 3] UBI: EBA unit Artem Bityutskiy
2007-03-15 19:07 ` Andrew Morton
2007-03-15 21:24 ` Randy Dunlap
2007-03-15 23:29 ` Josh Boyer
2007-03-16 1:49 ` Randy Dunlap
2007-03-16 10:23 ` Artem Bityutskiy
2007-03-16 10:21 ` Artem Bityutskiy
2007-03-16 14:55 ` Randy Dunlap
2007-03-16 10:14 ` Artem Bityutskiy
2007-03-14 15:20 ` [PATCH 11/22 take 3] UBI: user-interfaces unit Artem Bityutskiy
2007-03-14 15:20 ` [PATCH 12/22 take 3] UBI: update functionality Artem Bityutskiy
2007-03-14 15:20 ` Artem Bityutskiy [this message]
2007-03-14 15:20 ` [PATCH 14/22 take 3] UBI: volume management functionality Artem Bityutskiy
2007-03-14 15:20 ` [PATCH 15/22 take 3] UBI: sysfs functionality Artem Bityutskiy
2007-03-14 15:20 ` [PATCH 16/22 take 3] UBI: character devices functionality Artem Bityutskiy
2007-03-14 15:21 ` [PATCH 17/22 take 3] UBI: gluebi functionality Artem Bityutskiy
2007-03-14 15:21 ` [PATCH 18/22 take 3] UBI: misc stuff Artem Bityutskiy
2007-03-14 15:21 ` [PATCH 19/22 take 3] UBI: debugging stuff Artem Bityutskiy
2007-03-14 15:21 ` [PATCH 20/22 take 3] UBI: JFFS2 UBI support Artem Bityutskiy
2007-03-14 15:21 ` [PATCH 21/22 take 3] UBI: update MAINTAINERS Artem Bityutskiy
2007-03-14 15:21 ` [PATCH 22/22 take 3] UBI: Linux build integration Artem Bityutskiy
2007-03-18 16:27 ` [PATCH 00/22 take 3] UBI: Unsorted Block Images Matt Mackall
2007-03-18 16:49 ` Artem Bityutskiy
2007-03-18 19:18 ` Matt Mackall
2007-03-18 20:31 ` Josh Boyer
2007-03-19 17:08 ` Matt Mackall
2007-03-19 18:16 ` Josh Boyer
2007-03-19 19:54 ` Matt Mackall
2007-03-19 20:18 ` Artem Bityutskiy
2007-03-19 21:05 ` Thomas Gleixner
2007-03-19 22:32 ` Matt Mackall
2007-03-20 0:42 ` Thomas Gleixner
2007-03-20 1:05 ` Matt Mackall
2007-03-20 6:28 ` Thomas Gleixner
2007-03-21 11:05 ` Jörn Engel
2007-03-21 11:25 ` Thomas Gleixner
2007-03-21 11:35 ` Jörn Engel
2007-03-21 11:57 ` Thomas Gleixner
2007-03-21 12:31 ` Jörn Engel
2007-03-21 12:39 ` Artem Bityutskiy
2007-03-21 11:36 ` Artem Bityutskiy
2007-03-25 20:08 ` Jörn Engel
2007-03-25 21:49 ` David Lang
2007-03-25 22:55 ` Jörn Engel
2007-03-25 23:46 ` David Woodhouse
2007-03-26 0:01 ` Jörn Engel
2007-03-26 0:21 ` David Woodhouse
2007-03-26 1:04 ` Jörn Engel
2007-03-26 9:45 ` David Woodhouse
2007-03-26 9:51 ` Jörn Engel
2007-03-26 10:07 ` David Woodhouse
2007-03-26 10:02 ` Thomas Gleixner
2007-03-26 10:49 ` Artem Bityutskiy
2007-03-26 11:30 ` Jörn Engel
2007-03-19 21:06 ` Artem Bityutskiy
2007-03-19 21:36 ` Matt Mackall
2007-03-20 0:43 ` Thomas Gleixner
2007-03-20 12:25 ` Artem Bityutskiy
2007-03-20 13:52 ` Theodore Tso
2007-03-20 15:14 ` Artem Bityutskiy
2007-03-20 15:59 ` Josh Boyer
2007-03-20 18:58 ` David Lang
2007-03-20 20:05 ` Artem Bityutskiy
2007-03-20 21:36 ` David Woodhouse
2007-03-21 8:54 ` Artem Bityutskiy
2007-03-20 21:32 ` David Woodhouse
2007-03-21 13:03 ` Jörn Engel
2007-03-20 22:03 ` Theodore Tso
2007-03-21 8:44 ` Artem Bityutskiy
2007-03-21 13:50 ` Theodore Tso
2007-03-21 13:59 ` Josh Boyer
2007-03-21 14:02 ` Artem Bityutskiy
2007-03-21 15:38 ` Frank Haverkamp
2007-03-21 20:26 ` David Lang
2007-03-20 12:13 ` Josh Boyer
2007-03-19 19:03 ` Thomas Gleixner
2007-03-19 20:12 ` Matt Mackall
2007-03-19 21:04 ` Thomas Gleixner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070314152039.1112.31606.sendpatchset@localhost.localdomain \
--to=dedekind@infradead.org \
--cc=dwmw2@infradead.org \
--cc=haver@vnet.ibm.com \
--cc=hch@infradead.org \
--cc=jwboyer@linux.vnet.ibm.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.