Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1cb8f977 authored by Richard Weinberger's avatar Richard Weinberger
Browse files

ubi: fastmap: Implement produce_free_peb()



If fastmap requests a free PEB for a pool and UBI is busy
with erasing PEBs we need to offer a function to wait for one.
We can reuse produce_free_peb() from the non-fastmap WL code
but with different locking semantics.

Cc: stable@vger.kernel.org # 4.1.x-
Reported-and-tested-by: default avatarJörg Krause <joerg.krause@embedded.rocks>
Signed-off-by: default avatarRichard Weinberger <richard@nod.at>
parent be186cc4
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -171,6 +171,30 @@ void ubi_refill_pools(struct ubi_device *ubi)
	spin_unlock(&ubi->wl_lock);
}

/**
 * produce_free_peb - produce a free physical eraseblock.
 * @ubi: UBI device description object
 *
 * This function tries to make a free PEB by means of synchronous execution of
 * pending works. This may be needed if, for example the background thread is
 * disabled. Returns zero in case of success and a negative error code in case
 * of failure.
 */
static int produce_free_peb(struct ubi_device *ubi)
{
	int err;

	while (!ubi->free.rb_node && ubi->works_count) {
		dbg_wl("do one work synchronously");
		err = do_work(ubi);

		if (err)
			return err;
	}

	return 0;
}

/**
 * ubi_wl_get_peb - get a physical eraseblock.
 * @ubi: UBI device description object
@@ -213,6 +237,11 @@ int ubi_wl_get_peb(struct ubi_device *ubi)
		}
		retried = 1;
		up_read(&ubi->fm_eba_sem);
		ret = produce_free_peb(ubi);
		if (ret < 0) {
			down_read(&ubi->fm_eba_sem);
			goto out;
		}
		goto again;
	}