diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-10 12:31:45 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-10 12:31:45 -0500 |
commit | fc1495bf99de6f65066b3234813180301ff8b693 (patch) | |
tree | 4858db540f3c57f6f998383056ad4714b969660c /drivers/mtd/ubi | |
parent | 5476ffd2b78f06cce31a57f8611162918fe1ae3a (diff) | |
parent | b38882f5c066dc681679e90f1903eda323e605b1 (diff) |
Merge git://git.infradead.org/ubifs-2.6
* git://git.infradead.org/ubifs-2.6:
UBIFS: fix return code in check_leaf
UBI: flush wl before clearing update marker
MAINTAINERS: change e-mail of Artem Bityutskiy
UBIFS: remove manual O_SYNC handling
UBIFS: support mounting of UBI volume character devices
UBI: Add ubi_open_volume_path
Diffstat (limited to 'drivers/mtd/ubi')
-rw-r--r-- | drivers/mtd/ubi/kapi.c | 40 | ||||
-rw-r--r-- | drivers/mtd/ubi/upd.c | 20 |
2 files changed, 51 insertions, 9 deletions
diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c index 88a72e9c8beb..277786ebaa2c 100644 --- a/drivers/mtd/ubi/kapi.c +++ b/drivers/mtd/ubi/kapi.c | |||
@@ -22,6 +22,8 @@ | |||
22 | 22 | ||
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/err.h> | 24 | #include <linux/err.h> |
25 | #include <linux/namei.h> | ||
26 | #include <linux/fs.h> | ||
25 | #include <asm/div64.h> | 27 | #include <asm/div64.h> |
26 | #include "ubi.h" | 28 | #include "ubi.h" |
27 | 29 | ||
@@ -280,6 +282,44 @@ struct ubi_volume_desc *ubi_open_volume_nm(int ubi_num, const char *name, | |||
280 | EXPORT_SYMBOL_GPL(ubi_open_volume_nm); | 282 | EXPORT_SYMBOL_GPL(ubi_open_volume_nm); |
281 | 283 | ||
282 | /** | 284 | /** |
285 | * ubi_open_volume_path - open UBI volume by its character device node path. | ||
286 | * @pathname: volume character device node path | ||
287 | * @mode: open mode | ||
288 | * | ||
289 | * This function is similar to 'ubi_open_volume()', but opens a volume the path | ||
290 | * to its character device node. | ||
291 | */ | ||
292 | struct ubi_volume_desc *ubi_open_volume_path(const char *pathname, int mode) | ||
293 | { | ||
294 | int error, ubi_num, vol_id; | ||
295 | struct ubi_volume_desc *ret; | ||
296 | struct inode *inode; | ||
297 | struct path path; | ||
298 | |||
299 | dbg_gen("open volume %s, mode %d", pathname, mode); | ||
300 | |||
301 | if (!pathname || !*pathname) | ||
302 | return ERR_PTR(-EINVAL); | ||
303 | |||
304 | error = kern_path(pathname, LOOKUP_FOLLOW, &path); | ||
305 | if (error) | ||
306 | return ERR_PTR(error); | ||
307 | |||
308 | inode = path.dentry->d_inode; | ||
309 | ubi_num = ubi_major2num(imajor(inode)); | ||
310 | vol_id = iminor(inode) - 1; | ||
311 | |||
312 | if (vol_id >= 0 && ubi_num >= 0) | ||
313 | ret = ubi_open_volume(ubi_num, vol_id, mode); | ||
314 | else | ||
315 | ret = ERR_PTR(-ENODEV); | ||
316 | |||
317 | path_put(&path); | ||
318 | return ret; | ||
319 | } | ||
320 | EXPORT_SYMBOL_GPL(ubi_open_volume_path); | ||
321 | |||
322 | /** | ||
283 | * ubi_close_volume - close UBI volume. | 323 | * ubi_close_volume - close UBI volume. |
284 | * @desc: volume descriptor | 324 | * @desc: volume descriptor |
285 | */ | 325 | */ |
diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c index 74fdc40c8627..c1d7b880c795 100644 --- a/drivers/mtd/ubi/upd.c +++ b/drivers/mtd/ubi/upd.c | |||
@@ -147,12 +147,14 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol, | |||
147 | } | 147 | } |
148 | 148 | ||
149 | if (bytes == 0) { | 149 | if (bytes == 0) { |
150 | err = ubi_wl_flush(ubi); | ||
151 | if (err) | ||
152 | return err; | ||
153 | |||
150 | err = clear_update_marker(ubi, vol, 0); | 154 | err = clear_update_marker(ubi, vol, 0); |
151 | if (err) | 155 | if (err) |
152 | return err; | 156 | return err; |
153 | err = ubi_wl_flush(ubi); | 157 | vol->updating = 0; |
154 | if (!err) | ||
155 | vol->updating = 0; | ||
156 | } | 158 | } |
157 | 159 | ||
158 | vol->upd_buf = vmalloc(ubi->leb_size); | 160 | vol->upd_buf = vmalloc(ubi->leb_size); |
@@ -362,16 +364,16 @@ int ubi_more_update_data(struct ubi_device *ubi, struct ubi_volume *vol, | |||
362 | 364 | ||
363 | ubi_assert(vol->upd_received <= vol->upd_bytes); | 365 | ubi_assert(vol->upd_received <= vol->upd_bytes); |
364 | if (vol->upd_received == vol->upd_bytes) { | 366 | if (vol->upd_received == vol->upd_bytes) { |
367 | err = ubi_wl_flush(ubi); | ||
368 | if (err) | ||
369 | return err; | ||
365 | /* The update is finished, clear the update marker */ | 370 | /* The update is finished, clear the update marker */ |
366 | err = clear_update_marker(ubi, vol, vol->upd_bytes); | 371 | err = clear_update_marker(ubi, vol, vol->upd_bytes); |
367 | if (err) | 372 | if (err) |
368 | return err; | 373 | return err; |
369 | err = ubi_wl_flush(ubi); | 374 | vol->updating = 0; |
370 | if (err == 0) { | 375 | err = to_write; |
371 | vol->updating = 0; | 376 | vfree(vol->upd_buf); |
372 | err = to_write; | ||
373 | vfree(vol->upd_buf); | ||
374 | } | ||
375 | } | 377 | } |
376 | 378 | ||
377 | return err; | 379 | return err; |