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