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