diff options
author | Richard Weinberger <richard@nod.at> | 2015-08-11 17:27:44 -0400 |
---|---|---|
committer | Richard Weinberger <richard@nod.at> | 2015-10-03 17:25:30 -0400 |
commit | 1cb8f9776c7dcadc57885c6653943511d282633b (patch) | |
tree | 8ca9bb2c2e241511cdb93398dcadd245480801fe /drivers/mtd/ubi | |
parent | be186cc4de35fcfe766d2938c13ddf3935d6c159 (diff) |
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: Jörg Krause <joerg.krause@embedded.rocks>
Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'drivers/mtd/ubi')
-rw-r--r-- | drivers/mtd/ubi/fastmap-wl.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/mtd/ubi/fastmap-wl.c b/drivers/mtd/ubi/fastmap-wl.c index b2a665398bca..30d3999dddba 100644 --- a/drivers/mtd/ubi/fastmap-wl.c +++ b/drivers/mtd/ubi/fastmap-wl.c | |||
@@ -172,6 +172,30 @@ void ubi_refill_pools(struct ubi_device *ubi) | |||
172 | } | 172 | } |
173 | 173 | ||
174 | /** | 174 | /** |
175 | * produce_free_peb - produce a free physical eraseblock. | ||
176 | * @ubi: UBI device description object | ||
177 | * | ||
178 | * This function tries to make a free PEB by means of synchronous execution of | ||
179 | * pending works. This may be needed if, for example the background thread is | ||
180 | * disabled. Returns zero in case of success and a negative error code in case | ||
181 | * of failure. | ||
182 | */ | ||
183 | static int produce_free_peb(struct ubi_device *ubi) | ||
184 | { | ||
185 | int err; | ||
186 | |||
187 | while (!ubi->free.rb_node && ubi->works_count) { | ||
188 | dbg_wl("do one work synchronously"); | ||
189 | err = do_work(ubi); | ||
190 | |||
191 | if (err) | ||
192 | return err; | ||
193 | } | ||
194 | |||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | /** | ||
175 | * ubi_wl_get_peb - get a physical eraseblock. | 199 | * ubi_wl_get_peb - get a physical eraseblock. |
176 | * @ubi: UBI device description object | 200 | * @ubi: UBI device description object |
177 | * | 201 | * |
@@ -213,6 +237,11 @@ again: | |||
213 | } | 237 | } |
214 | retried = 1; | 238 | retried = 1; |
215 | up_read(&ubi->fm_eba_sem); | 239 | up_read(&ubi->fm_eba_sem); |
240 | ret = produce_free_peb(ubi); | ||
241 | if (ret < 0) { | ||
242 | down_read(&ubi->fm_eba_sem); | ||
243 | goto out; | ||
244 | } | ||
216 | goto again; | 245 | goto again; |
217 | } | 246 | } |
218 | 247 | ||