1
2
3
4
5
6
7
8
9
10
11#ifndef __UBOOT__
12#include <linux/module.h>
13#include <linux/slab.h>
14#include <linux/namei.h>
15#include <linux/fs.h>
16#include <asm/div64.h>
17#else
18#include <ubi_uboot.h>
19#endif
20#include <linux/err.h>
21
22#include "ubi.h"
23
24
25
26
27
28
29
30
31
32void ubi_do_get_device_info(struct ubi_device *ubi, struct ubi_device_info *di)
33{
34 di->ubi_num = ubi->ubi_num;
35 di->leb_size = ubi->leb_size;
36 di->leb_start = ubi->leb_start;
37 di->min_io_size = ubi->min_io_size;
38 di->max_write_size = ubi->max_write_size;
39 di->ro_mode = ubi->ro_mode;
40#ifndef __UBOOT__
41 di->cdev = ubi->cdev.dev;
42#endif
43}
44EXPORT_SYMBOL_GPL(ubi_do_get_device_info);
45
46
47
48
49
50
51
52
53
54int ubi_get_device_info(int ubi_num, struct ubi_device_info *di)
55{
56 struct ubi_device *ubi;
57
58 if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES)
59 return -EINVAL;
60 ubi = ubi_get_device(ubi_num);
61 if (!ubi)
62 return -ENODEV;
63 ubi_do_get_device_info(ubi, di);
64 ubi_put_device(ubi);
65 return 0;
66}
67EXPORT_SYMBOL_GPL(ubi_get_device_info);
68
69
70
71
72
73
74
75void ubi_do_get_volume_info(struct ubi_device *ubi, struct ubi_volume *vol,
76 struct ubi_volume_info *vi)
77{
78 vi->vol_id = vol->vol_id;
79 vi->ubi_num = ubi->ubi_num;
80 vi->size = vol->reserved_pebs;
81 vi->used_bytes = vol->used_bytes;
82 vi->vol_type = vol->vol_type;
83 vi->corrupted = vol->corrupted;
84 vi->upd_marker = vol->upd_marker;
85 vi->alignment = vol->alignment;
86 vi->usable_leb_size = vol->usable_leb_size;
87 vi->name_len = vol->name_len;
88 vi->name = vol->name;
89 vi->cdev = vol->cdev.dev;
90}
91
92
93
94
95
96
97void ubi_get_volume_info(struct ubi_volume_desc *desc,
98 struct ubi_volume_info *vi)
99{
100 ubi_do_get_volume_info(desc->vol->ubi, desc->vol, vi);
101}
102EXPORT_SYMBOL_GPL(ubi_get_volume_info);
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode)
123{
124 int err;
125 struct ubi_volume_desc *desc;
126 struct ubi_device *ubi;
127 struct ubi_volume *vol;
128
129 dbg_gen("open device %d, volume %d, mode %d", ubi_num, vol_id, mode);
130
131 if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES)
132 return ERR_PTR(-EINVAL);
133
134 if (mode != UBI_READONLY && mode != UBI_READWRITE &&
135 mode != UBI_EXCLUSIVE && mode != UBI_METAONLY)
136 return ERR_PTR(-EINVAL);
137
138
139
140
141 ubi = ubi_get_device(ubi_num);
142 if (!ubi)
143 return ERR_PTR(-ENODEV);
144
145 if (vol_id < 0 || vol_id >= ubi->vtbl_slots) {
146 err = -EINVAL;
147 goto out_put_ubi;
148 }
149
150 desc = kmalloc(sizeof(struct ubi_volume_desc), GFP_KERNEL);
151 if (!desc) {
152 err = -ENOMEM;
153 goto out_put_ubi;
154 }
155
156 err = -ENODEV;
157 if (!try_module_get(THIS_MODULE))
158 goto out_free;
159
160 spin_lock(&ubi->volumes_lock);
161 vol = ubi->volumes[vol_id];
162 if (!vol)
163 goto out_unlock;
164
165 err = -EBUSY;
166 switch (mode) {
167 case UBI_READONLY:
168 if (vol->exclusive)
169 goto out_unlock;
170 vol->readers += 1;
171 break;
172
173 case UBI_READWRITE:
174 if (vol->exclusive || vol->writers > 0)
175 goto out_unlock;
176 vol->writers += 1;
177 break;
178
179 case UBI_EXCLUSIVE:
180 if (vol->exclusive || vol->writers || vol->readers ||
181 vol->metaonly)
182 goto out_unlock;
183 vol->exclusive = 1;
184 break;
185
186 case UBI_METAONLY:
187 if (vol->metaonly || vol->exclusive)
188 goto out_unlock;
189 vol->metaonly = 1;
190 break;
191 }
192 get_device(&vol->dev);
193 vol->ref_count += 1;
194 spin_unlock(&ubi->volumes_lock);
195
196 desc->vol = vol;
197 desc->mode = mode;
198
199 mutex_lock(&ubi->ckvol_mutex);
200 if (!vol->checked) {
201
202 err = ubi_check_volume(ubi, vol_id);
203 if (err < 0) {
204 mutex_unlock(&ubi->ckvol_mutex);
205 ubi_close_volume(desc);
206 return ERR_PTR(err);
207 }
208 if (err == 1) {
209 ubi_warn(ubi, "volume %d on UBI device %d is corrupted",
210 vol_id, ubi->ubi_num);
211 vol->corrupted = 1;
212 }
213 vol->checked = 1;
214 }
215 mutex_unlock(&ubi->ckvol_mutex);
216
217 return desc;
218
219out_unlock:
220 spin_unlock(&ubi->volumes_lock);
221 module_put(THIS_MODULE);
222out_free:
223 kfree(desc);
224out_put_ubi:
225 ubi_put_device(ubi);
226 ubi_err(ubi, "cannot open device %d, volume %d, error %d",
227 ubi_num, vol_id, err);
228 return ERR_PTR(err);
229}
230EXPORT_SYMBOL_GPL(ubi_open_volume);
231
232
233
234
235
236
237
238
239
240struct ubi_volume_desc *ubi_open_volume_nm(int ubi_num, const char *name,
241 int mode)
242{
243 int i, vol_id = -1, len;
244 struct ubi_device *ubi;
245 struct ubi_volume_desc *ret;
246
247 dbg_gen("open device %d, volume %s, mode %d", ubi_num, name, mode);
248
249 if (!name)
250 return ERR_PTR(-EINVAL);
251
252 len = strnlen(name, UBI_VOL_NAME_MAX + 1);
253 if (len > UBI_VOL_NAME_MAX)
254 return ERR_PTR(-EINVAL);
255
256 if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES)
257 return ERR_PTR(-EINVAL);
258
259 ubi = ubi_get_device(ubi_num);
260 if (!ubi)
261 return ERR_PTR(-ENODEV);
262
263 spin_lock(&ubi->volumes_lock);
264
265 for (i = 0; i < ubi->vtbl_slots; i++) {
266 struct ubi_volume *vol = ubi->volumes[i];
267
268 if (vol && len == vol->name_len && !strcmp(name, vol->name)) {
269 vol_id = i;
270 break;
271 }
272 }
273 spin_unlock(&ubi->volumes_lock);
274
275 if (vol_id >= 0)
276 ret = ubi_open_volume(ubi_num, vol_id, mode);
277 else
278 ret = ERR_PTR(-ENODEV);
279
280
281
282
283
284 ubi_put_device(ubi);
285 return ret;
286}
287EXPORT_SYMBOL_GPL(ubi_open_volume_nm);
288
289#ifndef __UBOOT__
290
291
292
293
294
295
296
297
298struct ubi_volume_desc *ubi_open_volume_path(const char *pathname, int mode)
299{
300 int error, ubi_num, vol_id, mod;
301 struct inode *inode;
302 struct path path;
303
304 dbg_gen("open volume %s, mode %d", pathname, mode);
305
306 if (!pathname || !*pathname)
307 return ERR_PTR(-EINVAL);
308
309 error = kern_path(pathname, LOOKUP_FOLLOW, &path);
310 if (error)
311 return ERR_PTR(error);
312
313 inode = d_backing_inode(path.dentry);
314 mod = inode->i_mode;
315 ubi_num = ubi_major2num(imajor(inode));
316 vol_id = iminor(inode) - 1;
317 path_put(&path);
318
319 if (!S_ISCHR(mod))
320 return ERR_PTR(-EINVAL);
321 if (vol_id >= 0 && ubi_num >= 0)
322 return ubi_open_volume(ubi_num, vol_id, mode);
323 return ERR_PTR(-ENODEV);
324}
325EXPORT_SYMBOL_GPL(ubi_open_volume_path);
326#endif
327
328
329
330
331
332void ubi_close_volume(struct ubi_volume_desc *desc)
333{
334 struct ubi_volume *vol = desc->vol;
335 struct ubi_device *ubi = vol->ubi;
336
337 dbg_gen("close device %d, volume %d, mode %d",
338 ubi->ubi_num, vol->vol_id, desc->mode);
339
340 spin_lock(&ubi->volumes_lock);
341 switch (desc->mode) {
342 case UBI_READONLY:
343 vol->readers -= 1;
344 break;
345 case UBI_READWRITE:
346 vol->writers -= 1;
347 break;
348 case UBI_EXCLUSIVE:
349 vol->exclusive = 0;
350 break;
351 case UBI_METAONLY:
352 vol->metaonly = 0;
353 break;
354 }
355 vol->ref_count -= 1;
356 spin_unlock(&ubi->volumes_lock);
357
358 kfree(desc);
359 put_device(&vol->dev);
360 ubi_put_device(ubi);
361 module_put(THIS_MODULE);
362}
363EXPORT_SYMBOL_GPL(ubi_close_volume);
364
365
366
367
368
369
370
371
372
373
374
375static int leb_read_sanity_check(struct ubi_volume_desc *desc, int lnum,
376 int offset, int len)
377{
378 struct ubi_volume *vol = desc->vol;
379 struct ubi_device *ubi = vol->ubi;
380 int vol_id = vol->vol_id;
381
382 if (vol_id < 0 || vol_id >= ubi->vtbl_slots || lnum < 0 ||
383 lnum >= vol->used_ebs || offset < 0 || len < 0 ||
384 offset + len > vol->usable_leb_size)
385 return -EINVAL;
386
387 if (vol->vol_type == UBI_STATIC_VOLUME) {
388 if (vol->used_ebs == 0)
389
390 return 0;
391 if (lnum == vol->used_ebs - 1 &&
392 offset + len > vol->last_eb_bytes)
393 return -EINVAL;
394 }
395
396 if (vol->upd_marker)
397 return -EBADF;
398
399 return 0;
400}
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429int ubi_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset,
430 int len, int check)
431{
432 struct ubi_volume *vol = desc->vol;
433 struct ubi_device *ubi = vol->ubi;
434 int err, vol_id = vol->vol_id;
435
436 dbg_gen("read %d bytes from LEB %d:%d:%d", len, vol_id, lnum, offset);
437
438 err = leb_read_sanity_check(desc, lnum, offset, len);
439 if (err < 0)
440 return err;
441
442 if (len == 0)
443 return 0;
444
445 err = ubi_eba_read_leb(ubi, vol, lnum, buf, offset, len, check);
446 if (err && mtd_is_eccerr(err) && vol->vol_type == UBI_STATIC_VOLUME) {
447 ubi_warn(ubi, "mark volume %d as corrupted", vol_id);
448 vol->corrupted = 1;
449 }
450
451 return err;
452}
453EXPORT_SYMBOL_GPL(ubi_leb_read);
454
455#ifndef __UBOOT__
456
457
458
459
460
461
462
463
464
465
466
467
468
469int ubi_leb_read_sg(struct ubi_volume_desc *desc, int lnum, struct ubi_sgl *sgl,
470 int offset, int len, int check)
471{
472 struct ubi_volume *vol = desc->vol;
473 struct ubi_device *ubi = vol->ubi;
474 int err, vol_id = vol->vol_id;
475
476 dbg_gen("read %d bytes from LEB %d:%d:%d", len, vol_id, lnum, offset);
477
478 err = leb_read_sanity_check(desc, lnum, offset, len);
479 if (err < 0)
480 return err;
481
482 if (len == 0)
483 return 0;
484
485 err = ubi_eba_read_leb_sg(ubi, vol, sgl, lnum, offset, len, check);
486 if (err && mtd_is_eccerr(err) && vol->vol_type == UBI_STATIC_VOLUME) {
487 ubi_warn(ubi, "mark volume %d as corrupted", vol_id);
488 vol->corrupted = 1;
489 }
490
491 return err;
492}
493EXPORT_SYMBOL_GPL(ubi_leb_read_sg);
494#endif
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521int ubi_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf,
522 int offset, int len)
523{
524 struct ubi_volume *vol = desc->vol;
525 struct ubi_device *ubi = vol->ubi;
526 int vol_id = vol->vol_id;
527
528 dbg_gen("write %d bytes to LEB %d:%d:%d", len, vol_id, lnum, offset);
529
530 if (vol_id < 0 || vol_id >= ubi->vtbl_slots)
531 return -EINVAL;
532
533 if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME)
534 return -EROFS;
535
536 if (lnum < 0 || lnum >= vol->reserved_pebs || offset < 0 || len < 0 ||
537 offset + len > vol->usable_leb_size ||
538 offset & (ubi->min_io_size - 1) || len & (ubi->min_io_size - 1))
539 return -EINVAL;
540
541 if (vol->upd_marker)
542 return -EBADF;
543
544 if (len == 0)
545 return 0;
546
547 return ubi_eba_write_leb(ubi, vol, lnum, buf, offset, len);
548}
549EXPORT_SYMBOL_GPL(ubi_leb_write);
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566int ubi_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf,
567 int len)
568{
569 struct ubi_volume *vol = desc->vol;
570 struct ubi_device *ubi = vol->ubi;
571 int vol_id = vol->vol_id;
572
573 dbg_gen("atomically write %d bytes to LEB %d:%d", len, vol_id, lnum);
574
575 if (vol_id < 0 || vol_id >= ubi->vtbl_slots)
576 return -EINVAL;
577
578 if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME)
579 return -EROFS;
580
581 if (lnum < 0 || lnum >= vol->reserved_pebs || len < 0 ||
582 len > vol->usable_leb_size || len & (ubi->min_io_size - 1))
583 return -EINVAL;
584
585 if (vol->upd_marker)
586 return -EBADF;
587
588 if (len == 0)
589 return 0;
590
591 return ubi_eba_atomic_leb_change(ubi, vol, lnum, buf, len);
592}
593EXPORT_SYMBOL_GPL(ubi_leb_change);
594
595
596
597
598
599
600
601
602
603
604
605
606
607int ubi_leb_erase(struct ubi_volume_desc *desc, int lnum)
608{
609 struct ubi_volume *vol = desc->vol;
610 struct ubi_device *ubi = vol->ubi;
611 int err;
612
613 dbg_gen("erase LEB %d:%d", vol->vol_id, lnum);
614
615 if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME)
616 return -EROFS;
617
618 if (lnum < 0 || lnum >= vol->reserved_pebs)
619 return -EINVAL;
620
621 if (vol->upd_marker)
622 return -EBADF;
623
624 err = ubi_eba_unmap_leb(ubi, vol, lnum);
625 if (err)
626 return err;
627
628 return ubi_wl_flush(ubi, vol->vol_id, lnum);
629}
630EXPORT_SYMBOL_GPL(ubi_leb_erase);
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668int ubi_leb_unmap(struct ubi_volume_desc *desc, int lnum)
669{
670 struct ubi_volume *vol = desc->vol;
671 struct ubi_device *ubi = vol->ubi;
672
673 dbg_gen("unmap LEB %d:%d", vol->vol_id, lnum);
674
675 if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME)
676 return -EROFS;
677
678 if (lnum < 0 || lnum >= vol->reserved_pebs)
679 return -EINVAL;
680
681 if (vol->upd_marker)
682 return -EBADF;
683
684 return ubi_eba_unmap_leb(ubi, vol, lnum);
685}
686EXPORT_SYMBOL_GPL(ubi_leb_unmap);
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704int ubi_leb_map(struct ubi_volume_desc *desc, int lnum)
705{
706 struct ubi_volume *vol = desc->vol;
707 struct ubi_device *ubi = vol->ubi;
708
709 dbg_gen("unmap LEB %d:%d", vol->vol_id, lnum);
710
711 if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME)
712 return -EROFS;
713
714 if (lnum < 0 || lnum >= vol->reserved_pebs)
715 return -EINVAL;
716
717 if (vol->upd_marker)
718 return -EBADF;
719
720 if (vol->eba_tbl[lnum] >= 0)
721 return -EBADMSG;
722
723 return ubi_eba_write_leb(ubi, vol, lnum, NULL, 0, 0);
724}
725EXPORT_SYMBOL_GPL(ubi_leb_map);
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743int ubi_is_mapped(struct ubi_volume_desc *desc, int lnum)
744{
745 struct ubi_volume *vol = desc->vol;
746
747 dbg_gen("test LEB %d:%d", vol->vol_id, lnum);
748
749 if (lnum < 0 || lnum >= vol->reserved_pebs)
750 return -EINVAL;
751
752 if (vol->upd_marker)
753 return -EBADF;
754
755 return vol->eba_tbl[lnum] >= 0;
756}
757EXPORT_SYMBOL_GPL(ubi_is_mapped);
758
759
760
761
762
763
764
765
766
767int ubi_sync(int ubi_num)
768{
769 struct ubi_device *ubi;
770
771 ubi = ubi_get_device(ubi_num);
772 if (!ubi)
773 return -ENODEV;
774
775 mtd_sync(ubi->mtd);
776 ubi_put_device(ubi);
777 return 0;
778}
779EXPORT_SYMBOL_GPL(ubi_sync);
780
781
782
783
784
785
786
787
788
789
790
791
792
793int ubi_flush(int ubi_num, int vol_id, int lnum)
794{
795 struct ubi_device *ubi;
796 int err = 0;
797
798 ubi = ubi_get_device(ubi_num);
799 if (!ubi)
800 return -ENODEV;
801
802 err = ubi_wl_flush(ubi, vol_id, lnum);
803 ubi_put_device(ubi);
804 return err;
805}
806EXPORT_SYMBOL_GPL(ubi_flush);
807
808#ifndef __UBOOT__
809BLOCKING_NOTIFIER_HEAD(ubi_notifiers);
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827int ubi_register_volume_notifier(struct notifier_block *nb,
828 int ignore_existing)
829{
830 int err;
831
832 err = blocking_notifier_chain_register(&ubi_notifiers, nb);
833 if (err != 0)
834 return err;
835 if (ignore_existing)
836 return 0;
837
838
839
840
841
842
843
844 mutex_lock(&ubi_devices_mutex);
845 ubi_enumerate_volumes(nb);
846 mutex_unlock(&ubi_devices_mutex);
847
848 return err;
849}
850EXPORT_SYMBOL_GPL(ubi_register_volume_notifier);
851
852
853
854
855
856
857
858
859int ubi_unregister_volume_notifier(struct notifier_block *nb)
860{
861 return blocking_notifier_chain_unregister(&ubi_notifiers, nb);
862}
863EXPORT_SYMBOL_GPL(ubi_unregister_volume_notifier);
864#endif
865