mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Teresa Remmet <t.remmet@phytec.de>
To: barebox@lists.infradead.org
Subject: [PATCH 22/56] UBI: factorize code used to manipulate volumes at attach time
Date: Wed, 29 Aug 2018 14:19:38 +0200	[thread overview]
Message-ID: <1535545212-18871-23-git-send-email-t.remmet@phytec.de> (raw)
In-Reply-To: <1535545212-18871-1-git-send-email-t.remmet@phytec.de>

From: Boris Brezillon <boris.brezillon@free-electrons.com>

Volume creation/search code is duplicated in a few places (fastmap and
non fastmap code). Create some helpers to factorize the code.

Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Teresa Remmet <t.remmet@phytec.de>
---
 drivers/mtd/ubi/attach.c  | 151 +++++++++++++++++++++++++++++++++-------------
 drivers/mtd/ubi/fastmap.c |  27 +--------
 drivers/mtd/ubi/ubi.h     |   1 +
 3 files changed, 112 insertions(+), 67 deletions(-)

diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c
index 4d3a936ae861..d450f6c0d65b 100644
--- a/drivers/mtd/ubi/attach.c
+++ b/drivers/mtd/ubi/attach.c
@@ -89,6 +89,92 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai);
 static struct ubi_ec_hdr *ech;
 static struct ubi_vid_hdr *vidh;
 
+#define AV_FIND		BIT(0)
+#define AV_ADD		BIT(1)
+#define AV_FIND_OR_ADD	(AV_FIND | AV_ADD)
+
+/**
+ * find_or_add_av - internal function to find a volume, add a volume or do
+ *		    both (find and add if missing).
+ * @ai: attaching information
+ * @vol_id: the requested volume ID
+ * @flags: a combination of the %AV_FIND and %AV_ADD flags describing the
+ *	   expected operation. If only %AV_ADD is set, -EEXIST is returned
+ *	   if the volume already exists. If only %AV_FIND is set, NULL is
+ *	   returned if the volume does not exist. And if both flags are
+ *	   set, the helper first tries to find an existing volume, and if
+ *	   it does not exist it creates a new one.
+ * @created: in value used to inform the caller whether it"s a newly created
+ *	     volume or not.
+ *
+ * This function returns a pointer to a volume description or an ERR_PTR if
+ * the operation failed. It can also return NULL if only %AV_FIND is set and
+ * the volume does not exist.
+ */
+static struct ubi_ainf_volume *find_or_add_av(struct ubi_attach_info *ai,
+					      int vol_id, unsigned int flags,
+					      bool *created)
+{
+	struct ubi_ainf_volume *av;
+	struct rb_node **p = &ai->volumes.rb_node, *parent = NULL;
+
+	/* Walk the volume RB-tree to look if this volume is already present */
+	while (*p) {
+		parent = *p;
+		av = rb_entry(parent, struct ubi_ainf_volume, rb);
+
+		if (vol_id == av->vol_id) {
+			*created = false;
+
+			if (!(flags & AV_FIND))
+				return ERR_PTR(-EEXIST);
+
+			return av;
+		}
+
+		if (vol_id > av->vol_id)
+			p = &(*p)->rb_left;
+		else
+			p = &(*p)->rb_right;
+	}
+
+	if (!(flags & AV_ADD))
+		return NULL;
+
+	/* The volume is absent - add it */
+	av = kzalloc(sizeof(*av), GFP_KERNEL);
+	if (!av)
+		return ERR_PTR(-ENOMEM);
+
+	av->vol_id = vol_id;
+
+	if (vol_id > ai->highest_vol_id)
+		ai->highest_vol_id = vol_id;
+
+	rb_link_node(&av->rb, parent, p);
+	rb_insert_color(&av->rb, &ai->volumes);
+	ai->vols_found += 1;
+	*created = true;
+	dbg_bld("added volume %d", vol_id);
+	return av;
+}
+
+/**
+ * ubi_find_or_add_av - search for a volume in the attaching information and
+ *			add one if it does not exist.
+ * @ai: attaching information
+ * @vol_id: the requested volume ID
+ * @created: whether the volume has been created or not
+ *
+ * This function returns a pointer to the new volume description or an
+ * ERR_PTR if the operation failed.
+ */
+static struct ubi_ainf_volume *ubi_find_or_add_av(struct ubi_attach_info *ai,
+						  int vol_id, bool *created)
+{
+	return find_or_add_av(ai, vol_id, AV_FIND_OR_ADD, created);
+}
+
 /**
  * add_to_list - add physical eraseblock to a list.
  * @ai: attaching information
@@ -288,44 +374,20 @@ static struct ubi_ainf_volume *add_volume(struct ubi_attach_info *ai,
 					  const struct ubi_vid_hdr *vid_hdr)
 {
 	struct ubi_ainf_volume *av;
-	struct rb_node **p = &ai->volumes.rb_node, *parent = NULL;
+	bool created;
 
 	ubi_assert(vol_id == be32_to_cpu(vid_hdr->vol_id));
 
-	/* Walk the volume RB-tree to look if this volume is already present */
-	while (*p) {
-		parent = *p;
-		av = rb_entry(parent, struct ubi_ainf_volume, rb);
-
-		if (vol_id == av->vol_id)
-			return av;
+	av = ubi_find_or_add_av(ai, vol_id, &created);
+	if (IS_ERR(av) || !created)
+		return av;
 
-		if (vol_id > av->vol_id)
-			p = &(*p)->rb_left;
-		else
-			p = &(*p)->rb_right;
-	}
-
-	/* The volume is absent - add it */
-	av = kmalloc(sizeof(struct ubi_ainf_volume), GFP_KERNEL);
-	if (!av)
-		return ERR_PTR(-ENOMEM);
-
-	av->highest_lnum = av->leb_count = 0;
-	av->vol_id = vol_id;
-	av->root = RB_ROOT;
 	av->used_ebs = be32_to_cpu(vid_hdr->used_ebs);
 	av->data_pad = be32_to_cpu(vid_hdr->data_pad);
 	av->compat = vid_hdr->compat;
 	av->vol_type = vid_hdr->vol_type == UBI_VID_DYNAMIC ? UBI_DYNAMIC_VOLUME
 							    : UBI_STATIC_VOLUME;
-	if (vol_id > ai->highest_vol_id)
-		ai->highest_vol_id = vol_id;
 
-	rb_link_node(&av->rb, parent, p);
-	rb_insert_color(&av->rb, &ai->volumes);
-	ai->vols_found += 1;
-	dbg_bld("added volume %d", vol_id);
 	return av;
 }
 
@@ -620,6 +682,21 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum,
 }
 
 /**
+ * ubi_add_av - add volume to the attaching information.
+ * @ai: attaching information
+ * @vol_id: the requested volume ID
+ *
+ * This function returns a pointer to the new volume description or an
+ * ERR_PTR if the operation failed.
+ */
+struct ubi_ainf_volume *ubi_add_av(struct ubi_attach_info *ai, int vol_id)
+{
+	bool created;
+
+	return find_or_add_av(ai, vol_id, AV_ADD, &created);
+}
+
+/**
  * ubi_find_av - find volume in the attaching information.
  * @ai: attaching information
  * @vol_id: the requested volume ID
@@ -630,22 +707,10 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum,
 struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai,
 				    int vol_id)
 {
-	struct ubi_ainf_volume *av;
-	struct rb_node *p = ai->volumes.rb_node;
-
-	while (p) {
-		av = rb_entry(p, struct ubi_ainf_volume, rb);
-
-		if (vol_id == av->vol_id)
-			return av;
-
-		if (vol_id > av->vol_id)
-			p = p->rb_left;
-		else
-			p = p->rb_right;
-	}
+	bool created;
 
-	return NULL;
+	return find_or_add_av((struct ubi_attach_info *)ai, vol_id, AV_FIND,
+			      &created);
 }
 
 /**
diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
index c10ef0650760..b0979af62f18 100644
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -120,40 +120,19 @@ static struct ubi_ainf_volume *add_vol(struct ubi_attach_info *ai, int vol_id,
 				       int last_eb_bytes)
 {
 	struct ubi_ainf_volume *av;
-	struct rb_node **p = &ai->volumes.rb_node, *parent = NULL;
 
-	while (*p) {
-		parent = *p;
-		av = rb_entry(parent, struct ubi_ainf_volume, rb);
-
-		if (vol_id > av->vol_id)
-			p = &(*p)->rb_left;
-		else if (vol_id < av->vol_id)
-			p = &(*p)->rb_right;
-		else
-			return ERR_PTR(-EINVAL);
-	}
+	av = ubi_add_av(ai, vol_id);
+	if (IS_ERR(av))
+		return av;
 
-	av = kmalloc(sizeof(struct ubi_ainf_volume), GFP_KERNEL);
-	if (!av)
-		goto out;
-
-	av->highest_lnum = av->leb_count = av->used_ebs = 0;
-	av->vol_id = vol_id;
 	av->data_pad = data_pad;
 	av->last_data_size = last_eb_bytes;
 	av->compat = 0;
 	av->vol_type = vol_type;
-	av->root = RB_ROOT;
 	if (av->vol_type == UBI_STATIC_VOLUME)
 		av->used_ebs = used_ebs;
 
 	dbg_bld("found volume (ID %i)", vol_id);
-
-	rb_link_node(&av->rb, parent, p);
-	rb_insert_color(&av->rb, &ai->volumes);
-
-out:
 	return av;
 }
 
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index c2f54a4b0b3f..eb81298beff3 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -729,6 +729,7 @@ extern struct blocking_notifier_head ubi_notifiers;
 /* attach.c */
 int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum,
 		  int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips);
+struct ubi_ainf_volume *ubi_add_av(struct ubi_attach_info *ai, int vol_id);
 struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai,
 				    int vol_id);
 void ubi_remove_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av);
-- 
2.7.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

  parent reply	other threads:[~2018-08-29 12:21 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-29 12:19 [PATCH 00/56] Update Barebox UBI Teresa Remmet
2018-08-29 12:19 ` [PATCH 01/56] UBI: Fastmap: Fix memory leak while attaching Teresa Remmet
2018-08-29 12:19 ` [PATCH 02/56] UBI: Remove alloc_ai() slab name from parameter list Teresa Remmet
2018-08-29 12:19 ` [PATCH 03/56] UBI: Don't read back all data in ubi_eba_copy_leb() Teresa Remmet
2018-08-29 12:19 ` [PATCH 04/56] UBI: Modify wrong comment in ubi_leb_map function Teresa Remmet
2018-08-29 12:19 ` [PATCH 05/56] UBI: Clean up return in ubi_remove_volume() Teresa Remmet
2018-08-29 12:19 ` [PATCH 06/56] UBI: Set free_count to zero before walking through erase list Teresa Remmet
2018-08-29 12:19 ` [PATCH 07/56] UBI: Fix static volume checks when Fastmap is used Teresa Remmet
2018-08-29 12:19 ` [PATCH 08/56] ubi: Make recover_peb power cut aware Teresa Remmet
2018-08-29 12:19 ` [PATCH 09/56] ubi: Fix race condition between ubi device creation and udev Teresa Remmet
2018-08-29 12:19 ` [PATCH 10/56] ubi: Fix early logging Teresa Remmet
2018-08-29 12:19 ` [PATCH 11/56] ubi: Make volume resize power cut aware Teresa Remmet
2018-08-29 12:19 ` [PATCH 12/56] ubi: Fix scan_fast() comment Teresa Remmet
2018-08-29 12:19 ` [PATCH 13/56] ubi: Introduce vol_ignored() Teresa Remmet
2018-08-29 12:19 ` [PATCH 14/56] ubi: Fix whitespace issue in count_fastmap_pebs() Teresa Remmet
2018-08-29 12:19 ` [PATCH 15/56] ubi: Rework Fastmap attach base code Teresa Remmet
2018-08-29 12:19 ` [PATCH 16/56] ubi: Check whether the Fastmap anchor matches the super block Teresa Remmet
2018-08-29 12:19 ` [PATCH 17/56] ubi: Be more paranoid while seaching for the most recent Fastmap Teresa Remmet
2018-08-29 12:19 ` [PATCH 18/56] UBI: fastmap: use ubi_find_volume() instead of open coding it Teresa Remmet
2018-08-29 12:19 ` [PATCH 19/56] UBI: fix add_fastmap() to use the vid_hdr passed in argument Teresa Remmet
2018-08-29 12:19 ` [PATCH 20/56] UBI: fastmap: avoid multiple be32_to_cpu() when unneccesary Teresa Remmet
2018-08-29 12:19 ` [PATCH 21/56] UBI: fastmap: scrub PEB when bitflips are detected in a free PEB EC header Teresa Remmet
2018-08-29 12:19 ` Teresa Remmet [this message]
2018-08-29 12:19 ` [PATCH 23/56] UBI: factorize destroy_av() and ubi_remove_av() code Teresa Remmet
2018-08-29 12:19 ` [PATCH 24/56] UBI: fastmap: use ubi_rb_for_each_entry() in unmap_peb() Teresa Remmet
2018-08-29 12:19 ` [PATCH 25/56] UBI: fastmap: use ubi_io_{read, write}_data() instead of ubi_io_{read, write}() Teresa Remmet
2018-08-29 12:19 ` [PATCH 26/56] UBI: provide helpers to allocate and free aeb elements Teresa Remmet
2018-08-29 12:19 ` [PATCH 27/56] UBI: move the global ech and vidh variables into struct ubi_attach_info Teresa Remmet
2018-08-29 12:19 ` [PATCH 28/56] UBI: simplify recover_peb() code Teresa Remmet
2018-08-29 12:19 ` [PATCH 29/56] UBI: simplify LEB write and atomic LEB change code Teresa Remmet
2018-08-29 12:19 ` [PATCH 30/56] UBI: add an helper to check lnum validity Teresa Remmet
2018-08-29 12:19 ` [PATCH 31/56] UBI: provide an helper to check whether a LEB is mapped or not Teresa Remmet
2018-08-29 12:19 ` [PATCH 32/56] UBI: provide an helper to query LEB information Teresa Remmet
2018-08-29 12:19 ` [PATCH 33/56] UBI: hide EBA internals Teresa Remmet
2018-08-29 12:19 ` [PATCH 34/56] UBI: introduce the VID buffer concept Teresa Remmet
2018-08-29 12:19 ` [PATCH 35/56] ubi: Deal with interrupted erasures in WL Teresa Remmet
2018-08-29 12:19 ` [PATCH 36/56] ubi: Fix races around ubi_refill_pools() Teresa Remmet
2018-08-29 12:19 ` [PATCH 37/56] ubi: Fix Fastmap's update_vol() Teresa Remmet
2018-08-29 12:19 ` [PATCH 38/56] ubi: fix swapped arguments to call to ubi_alloc_aeb Teresa Remmet
2018-08-29 12:19 ` [PATCH 39/56] UBI: Fix crash in try_recover_peb() Teresa Remmet
2018-08-29 12:19 ` [PATCH 40/56] ubi: fastmap: Fix add_vol() return value test in ubi_attach_fastmap() Teresa Remmet
2018-08-29 12:19 ` [PATCH 41/56] UBI: Fix typos Teresa Remmet
2018-08-29 12:19 ` [PATCH 42/56] ubi/upd: Always flush after prepared for an update Teresa Remmet
2018-08-29 12:19 ` [PATCH 43/56] ubi: fastmap: Fix slab corruption Teresa Remmet
2018-08-29 12:20 ` [PATCH 44/56] ubi: pr_err() strings should end with newlines Teresa Remmet
2018-08-29 12:20 ` [PATCH 45/56] ubi: fastmap: fix spelling mistake: "invalidiate" -> "invalidate" Teresa Remmet
2018-08-29 12:20 ` [PATCH 46/56] UBI: Fix two typos in comments Teresa Remmet
2018-08-29 12:20 ` [PATCH 47/56] ubi: fastmap: Clean up the initialization of pointer p Teresa Remmet
2018-08-29 12:20 ` [PATCH 48/56] ubi: fastmap: Erase outdated anchor PEBs during attach Teresa Remmet
2018-08-29 12:20 ` [PATCH 49/56] ubi: Fastmap: Fix typo Teresa Remmet
2018-08-29 12:20 ` [PATCH 50/56] ubi: Fix copy/paste error in function documentation Teresa Remmet
2018-08-29 12:20 ` [PATCH 51/56] mtd: ubi: wl: Fix error return code in ubi_wl_init() Teresa Remmet
2018-08-29 12:20 ` [PATCH 52/56] ubi: fastmap: Correctly handle interrupted erasures in EBA Teresa Remmet
2018-08-29 12:20 ` [PATCH 53/56] ubi: fastmap: Check each mapping only once Teresa Remmet
2018-08-29 12:20 ` [PATCH 54/56] ubi: fastmap: Detect EBA mismatches on-the-fly Teresa Remmet
2018-08-29 12:20 ` [PATCH 55/56] mtd: ubi: Update ubi-media.h to dual license Teresa Remmet
2018-08-29 12:20 ` [PATCH 56/56] ubi: Initialize Fastmap checkmapping correctly Teresa Remmet
2018-08-31  6:25 ` [PATCH 00/56] Update Barebox UBI Sascha Hauer

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=1535545212-18871-23-git-send-email-t.remmet@phytec.de \
    --to=t.remmet@phytec.de \
    --cc=barebox@lists.infradead.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox