1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56#include <linux/slab.h>
57#include <linux/pagemap.h>
58#include <linux/list_sort.h>
59#include "ubifs.h"
60
61
62
63
64
65
66#define SOFT_LEBS_LIMIT 4
67#define HARD_LEBS_LIMIT 32
68
69
70
71
72
73
74
75
76
77
78
79
80
81static int switch_gc_head(struct ubifs_info *c)
82{
83 int err, gc_lnum = c->gc_lnum;
84 struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf;
85
86 ubifs_assert(gc_lnum != -1);
87 dbg_gc("switch GC head from LEB %d:%d to LEB %d (waste %d bytes)",
88 wbuf->lnum, wbuf->offs + wbuf->used, gc_lnum,
89 c->leb_size - wbuf->offs - wbuf->used);
90
91 err = ubifs_wbuf_sync_nolock(wbuf);
92 if (err)
93 return err;
94
95
96
97
98
99 err = ubifs_leb_unmap(c, gc_lnum);
100 if (err)
101 return err;
102
103 err = ubifs_add_bud_to_log(c, GCHD, gc_lnum, 0);
104 if (err)
105 return err;
106
107 c->gc_lnum = -1;
108 err = ubifs_wbuf_seek_nolock(wbuf, gc_lnum, 0, UBI_LONGTERM);
109 return err;
110}
111
112
113
114
115
116
117
118
119
120
121int data_nodes_cmp(void *priv, struct list_head *a, struct list_head *b)
122{
123 ino_t inuma, inumb;
124 struct ubifs_info *c = priv;
125 struct ubifs_scan_node *sa, *sb;
126
127 cond_resched();
128 sa = list_entry(a, struct ubifs_scan_node, list);
129 sb = list_entry(b, struct ubifs_scan_node, list);
130 ubifs_assert(key_type(c, &sa->key) == UBIFS_DATA_KEY);
131 ubifs_assert(key_type(c, &sb->key) == UBIFS_DATA_KEY);
132
133 inuma = key_inum(c, &sa->key);
134 inumb = key_inum(c, &sb->key);
135
136 if (inuma == inumb) {
137 unsigned int blka = key_block(c, &sa->key);
138 unsigned int blkb = key_block(c, &sb->key);
139
140 if (blka <= blkb)
141 return -1;
142 } else if (inuma <= inumb)
143 return -1;
144
145 return 1;
146}
147
148
149
150
151
152
153
154
155
156
157
158int nondata_nodes_cmp(void *priv, struct list_head *a, struct list_head *b)
159{
160 int typea, typeb;
161 ino_t inuma, inumb;
162 struct ubifs_info *c = priv;
163 struct ubifs_scan_node *sa, *sb;
164
165 cond_resched();
166 sa = list_entry(a, struct ubifs_scan_node, list);
167 sb = list_entry(b, struct ubifs_scan_node, list);
168 typea = key_type(c, &sa->key);
169 typeb = key_type(c, &sb->key);
170 ubifs_assert(typea != UBIFS_DATA_KEY && typeb != UBIFS_DATA_KEY);
171
172
173 if (typea == UBIFS_INO_KEY) {
174 if (typeb == UBIFS_INO_KEY)
175 return sb->len - sa->len;
176 return -1;
177 }
178 if (typeb == UBIFS_INO_KEY)
179 return 1;
180
181 ubifs_assert(typea == UBIFS_DENT_KEY && typeb == UBIFS_DENT_KEY);
182 inuma = key_inum(c, &sa->key);
183 inumb = key_inum(c, &sb->key);
184
185 if (inuma == inumb) {
186 uint32_t hasha = key_hash(c, &sa->key);
187 uint32_t hashb = key_hash(c, &sb->key);
188
189 if (hasha <= hashb)
190 return -1;
191 } else if (inuma <= inumb)
192 return -1;
193
194 return 1;
195}
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224static int sort_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
225 struct list_head *nondata, int *min)
226{
227 struct ubifs_scan_node *snod, *tmp;
228
229 *min = INT_MAX;
230
231
232 list_for_each_entry_safe(snod, tmp, &sleb->nodes, list) {
233 int err;
234
235 ubifs_assert(snod->type != UBIFS_IDX_NODE);
236 ubifs_assert(snod->type != UBIFS_REF_NODE);
237 ubifs_assert(snod->type != UBIFS_CS_NODE);
238
239 err = ubifs_tnc_has_node(c, &snod->key, 0, sleb->lnum,
240 snod->offs, 0);
241 if (err < 0)
242 return err;
243
244 if (!err) {
245
246 list_del(&snod->list);
247 kfree(snod);
248 continue;
249 }
250
251 if (snod->len < *min)
252 *min = snod->len;
253
254 if (key_type(c, &snod->key) != UBIFS_DATA_KEY)
255 list_move_tail(&snod->list, nondata);
256 }
257
258
259 list_sort(c, &sleb->nodes, &data_nodes_cmp);
260 list_sort(c, nondata, &nondata_nodes_cmp);
261 return 0;
262}
263
264
265
266
267
268
269
270
271
272
273
274
275static int move_node(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
276 struct ubifs_scan_node *snod, struct ubifs_wbuf *wbuf)
277{
278 int err, new_lnum = wbuf->lnum, new_offs = wbuf->offs + wbuf->used;
279
280 cond_resched();
281 err = ubifs_wbuf_write_nolock(wbuf, snod->node, snod->len);
282 if (err)
283 return err;
284
285 err = ubifs_tnc_replace(c, &snod->key, sleb->lnum,
286 snod->offs, new_lnum, new_offs,
287 snod->len);
288 list_del(&snod->list);
289 kfree(snod);
290 return err;
291}
292
293
294
295
296
297
298
299
300
301
302
303static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb)
304{
305 int err, min;
306 LIST_HEAD(nondata);
307 struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf;
308
309 if (wbuf->lnum == -1) {
310
311
312
313
314 err = switch_gc_head(c);
315 if (err)
316 return err;
317 }
318
319 err = sort_nodes(c, sleb, &nondata, &min);
320 if (err)
321 goto out;
322
323
324 while (1) {
325 int avail;
326 struct ubifs_scan_node *snod, *tmp;
327
328
329 list_for_each_entry_safe(snod, tmp, &sleb->nodes, list) {
330 avail = c->leb_size - wbuf->offs - wbuf->used;
331 if (snod->len > avail)
332
333
334
335
336 break;
337
338 err = move_node(c, sleb, snod, wbuf);
339 if (err)
340 goto out;
341 }
342
343
344 list_for_each_entry_safe(snod, tmp, &nondata, list) {
345 avail = c->leb_size - wbuf->offs - wbuf->used;
346 if (avail < min)
347 break;
348
349 if (snod->len > avail) {
350
351
352
353
354
355
356
357 if (key_type(c, &snod->key) == UBIFS_DENT_KEY ||
358 snod->len == UBIFS_INO_NODE_SZ)
359 break;
360 continue;
361 }
362
363 err = move_node(c, sleb, snod, wbuf);
364 if (err)
365 goto out;
366 }
367
368 if (list_empty(&sleb->nodes) && list_empty(&nondata))
369 break;
370
371
372
373
374
375 err = switch_gc_head(c);
376 if (err)
377 goto out;
378 }
379
380 return 0;
381
382out:
383 list_splice_tail(&nondata, &sleb->nodes);
384 return err;
385}
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400static int gc_sync_wbufs(struct ubifs_info *c)
401{
402 int err, i;
403
404 for (i = 0; i < c->jhead_cnt; i++) {
405 if (i == GCHD)
406 continue;
407 err = ubifs_wbuf_sync(&c->jheads[i].wbuf);
408 if (err)
409 return err;
410 }
411 return 0;
412}
413
414
415
416
417
418
419
420
421
422
423int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp)
424{
425 struct ubifs_scan_leb *sleb;
426 struct ubifs_scan_node *snod;
427 struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf;
428 int err = 0, lnum = lp->lnum;
429
430 ubifs_assert(c->gc_lnum != -1 || wbuf->offs + wbuf->used == 0 ||
431 c->need_recovery);
432 ubifs_assert(c->gc_lnum != lnum);
433 ubifs_assert(wbuf->lnum != lnum);
434
435
436
437
438
439 sleb = ubifs_scan(c, lnum, 0, c->sbuf, 0);
440 if (IS_ERR(sleb))
441 return PTR_ERR(sleb);
442
443 ubifs_assert(!list_empty(&sleb->nodes));
444 snod = list_entry(sleb->nodes.next, struct ubifs_scan_node, list);
445
446 if (snod->type == UBIFS_IDX_NODE) {
447 struct ubifs_gced_idx_leb *idx_gc;
448
449 dbg_gc("indexing LEB %d (free %d, dirty %d)",
450 lnum, lp->free, lp->dirty);
451 list_for_each_entry(snod, &sleb->nodes, list) {
452 struct ubifs_idx_node *idx = snod->node;
453 int level = le16_to_cpu(idx->level);
454
455 ubifs_assert(snod->type == UBIFS_IDX_NODE);
456 key_read(c, ubifs_idx_key(c, idx), &snod->key);
457 err = ubifs_dirty_idx_node(c, &snod->key, level, lnum,
458 snod->offs);
459 if (err)
460 goto out;
461 }
462
463 idx_gc = kmalloc(sizeof(struct ubifs_gced_idx_leb), GFP_NOFS);
464 if (!idx_gc) {
465 err = -ENOMEM;
466 goto out;
467 }
468
469 idx_gc->lnum = lnum;
470 idx_gc->unmap = 0;
471 list_add(&idx_gc->list, &c->idx_gc);
472
473
474
475
476
477
478
479 err = ubifs_change_one_lp(c, lnum, c->leb_size, 0, 0,
480 LPROPS_INDEX, 1);
481 if (err)
482 goto out;
483 err = LEB_FREED_IDX;
484 } else {
485 dbg_gc("data LEB %d (free %d, dirty %d)",
486 lnum, lp->free, lp->dirty);
487
488 err = move_nodes(c, sleb);
489 if (err)
490 goto out_inc_seq;
491
492 err = gc_sync_wbufs(c);
493 if (err)
494 goto out_inc_seq;
495
496 err = ubifs_change_one_lp(c, lnum, c->leb_size, 0, 0, 0, 0);
497 if (err)
498 goto out_inc_seq;
499
500
501 c->gced_lnum = lnum;
502 smp_wmb();
503 c->gc_seq += 1;
504 smp_wmb();
505
506 if (c->gc_lnum == -1) {
507 c->gc_lnum = lnum;
508 err = LEB_RETAINED;
509 } else {
510 err = ubifs_wbuf_sync_nolock(wbuf);
511 if (err)
512 goto out;
513
514 err = ubifs_leb_unmap(c, lnum);
515 if (err)
516 goto out;
517
518 err = LEB_FREED;
519 }
520 }
521
522out:
523 ubifs_scan_destroy(sleb);
524 return err;
525
526out_inc_seq:
527
528 c->gced_lnum = lnum;
529 smp_wmb();
530 c->gc_seq += 1;
531 smp_wmb();
532 goto out;
533}
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571int ubifs_garbage_collect(struct ubifs_info *c, int anyway)
572{
573 int i, err, ret, min_space = c->dead_wm;
574 struct ubifs_lprops lp;
575 struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf;
576
577 ubifs_assert_cmt_locked(c);
578
579 if (ubifs_gc_should_commit(c))
580 return -EAGAIN;
581
582 mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead);
583
584 if (c->ro_media) {
585 ret = -EROFS;
586 goto out_unlock;
587 }
588
589
590 ubifs_assert(!wbuf->used);
591
592 for (i = 0; ; i++) {
593 int space_before = c->leb_size - wbuf->offs - wbuf->used;
594 int space_after;
595
596 cond_resched();
597
598
599 if (ubifs_gc_should_commit(c)) {
600 ret = -EAGAIN;
601 break;
602 }
603
604 if (i > SOFT_LEBS_LIMIT && !list_empty(&c->idx_gc)) {
605
606
607
608
609 dbg_gc("soft limit, some index LEBs GC'ed, -EAGAIN");
610 ubifs_commit_required(c);
611 ret = -EAGAIN;
612 break;
613 }
614
615 if (i > HARD_LEBS_LIMIT) {
616
617
618
619
620 dbg_gc("hard limit, -ENOSPC");
621 ret = -ENOSPC;
622 break;
623 }
624
625
626
627
628
629
630
631
632 ret = ubifs_find_dirty_leb(c, &lp, min_space, anyway ? 0 : 1);
633 if (ret) {
634 if (ret == -ENOSPC)
635 dbg_gc("no more dirty LEBs");
636 break;
637 }
638
639 dbg_gc("found LEB %d: free %d, dirty %d, sum %d "
640 "(min. space %d)", lp.lnum, lp.free, lp.dirty,
641 lp.free + lp.dirty, min_space);
642
643 if (lp.free + lp.dirty == c->leb_size) {
644
645 dbg_gc("LEB %d is free, return it", lp.lnum);
646
647
648
649
650 ubifs_assert(!(lp.flags & LPROPS_INDEX));
651 if (lp.free != c->leb_size) {
652
653
654
655
656
657
658 ret = gc_sync_wbufs(c);
659 if (ret)
660 goto out;
661 ret = ubifs_change_one_lp(c, lp.lnum,
662 c->leb_size, 0, 0, 0,
663 0);
664 if (ret)
665 goto out;
666 }
667 ret = ubifs_leb_unmap(c, lp.lnum);
668 if (ret)
669 goto out;
670 ret = lp.lnum;
671 break;
672 }
673
674 space_before = c->leb_size - wbuf->offs - wbuf->used;
675 if (wbuf->lnum == -1)
676 space_before = 0;
677
678 ret = ubifs_garbage_collect_leb(c, &lp);
679 if (ret < 0) {
680 if (ret == -EAGAIN || ret == -ENOSPC) {
681
682
683
684
685
686
687
688
689 err = ubifs_return_leb(c, lp.lnum);
690 if (err)
691 ret = err;
692 break;
693 }
694 goto out;
695 }
696
697 if (ret == LEB_FREED) {
698
699 dbg_gc("LEB %d freed, return", lp.lnum);
700 ret = lp.lnum;
701 break;
702 }
703
704 if (ret == LEB_FREED_IDX) {
705
706
707
708
709
710
711 dbg_gc("indexing LEB %d freed, continue", lp.lnum);
712 continue;
713 }
714
715 ubifs_assert(ret == LEB_RETAINED);
716 space_after = c->leb_size - wbuf->offs - wbuf->used;
717 dbg_gc("LEB %d retained, freed %d bytes", lp.lnum,
718 space_after - space_before);
719
720 if (space_after > space_before) {
721
722 min_space >>= 1;
723 if (min_space < c->dead_wm)
724 min_space = c->dead_wm;
725 continue;
726 }
727
728 dbg_gc("did not make progress");
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746 if (i < SOFT_LEBS_LIMIT) {
747 dbg_gc("try again");
748 continue;
749 }
750
751 min_space <<= 1;
752 if (min_space > c->dark_wm)
753 min_space = c->dark_wm;
754 dbg_gc("set min. space to %d", min_space);
755 }
756
757 if (ret == -ENOSPC && !list_empty(&c->idx_gc)) {
758 dbg_gc("no space, some index LEBs GC'ed, -EAGAIN");
759 ubifs_commit_required(c);
760 ret = -EAGAIN;
761 }
762
763 err = ubifs_wbuf_sync_nolock(wbuf);
764 if (!err)
765 err = ubifs_leb_unmap(c, c->gc_lnum);
766 if (err) {
767 ret = err;
768 goto out;
769 }
770out_unlock:
771 mutex_unlock(&wbuf->io_mutex);
772 return ret;
773
774out:
775 ubifs_assert(ret < 0);
776 ubifs_assert(ret != -ENOSPC && ret != -EAGAIN);
777 ubifs_ro_mode(c, ret);
778 ubifs_wbuf_sync_nolock(wbuf);
779 mutex_unlock(&wbuf->io_mutex);
780 ubifs_return_leb(c, lp.lnum);
781 return ret;
782}
783
784
785
786
787
788
789
790
791
792
793
794
795int ubifs_gc_start_commit(struct ubifs_info *c)
796{
797 struct ubifs_gced_idx_leb *idx_gc;
798 const struct ubifs_lprops *lp;
799 int err = 0, flags;
800
801 ubifs_get_lprops(c);
802
803
804
805
806
807 while (1) {
808 lp = ubifs_fast_find_freeable(c);
809 if (IS_ERR(lp)) {
810 err = PTR_ERR(lp);
811 goto out;
812 }
813 if (!lp)
814 break;
815 ubifs_assert(!(lp->flags & LPROPS_TAKEN));
816 ubifs_assert(!(lp->flags & LPROPS_INDEX));
817 err = ubifs_leb_unmap(c, lp->lnum);
818 if (err)
819 goto out;
820 lp = ubifs_change_lp(c, lp, c->leb_size, 0, lp->flags, 0);
821 if (IS_ERR(lp)) {
822 err = PTR_ERR(lp);
823 goto out;
824 }
825 ubifs_assert(!(lp->flags & LPROPS_TAKEN));
826 ubifs_assert(!(lp->flags & LPROPS_INDEX));
827 }
828
829
830 list_for_each_entry(idx_gc, &c->idx_gc, list)
831 idx_gc->unmap = 1;
832
833
834 while (1) {
835 lp = ubifs_fast_find_frdi_idx(c);
836 if (IS_ERR(lp)) {
837 err = PTR_ERR(lp);
838 goto out;
839 }
840 if (!lp)
841 break;
842 idx_gc = kmalloc(sizeof(struct ubifs_gced_idx_leb), GFP_NOFS);
843 if (!idx_gc) {
844 err = -ENOMEM;
845 goto out;
846 }
847 ubifs_assert(!(lp->flags & LPROPS_TAKEN));
848 ubifs_assert(lp->flags & LPROPS_INDEX);
849
850 flags = (lp->flags | LPROPS_TAKEN) ^ LPROPS_INDEX;
851 lp = ubifs_change_lp(c, lp, c->leb_size, 0, flags, 1);
852 if (IS_ERR(lp)) {
853 err = PTR_ERR(lp);
854 kfree(idx_gc);
855 goto out;
856 }
857 ubifs_assert(lp->flags & LPROPS_TAKEN);
858 ubifs_assert(!(lp->flags & LPROPS_INDEX));
859 idx_gc->lnum = lp->lnum;
860 idx_gc->unmap = 1;
861 list_add(&idx_gc->list, &c->idx_gc);
862 }
863out:
864 ubifs_release_lprops(c);
865 return err;
866}
867
868
869
870
871
872
873
874int ubifs_gc_end_commit(struct ubifs_info *c)
875{
876 struct ubifs_gced_idx_leb *idx_gc, *tmp;
877 struct ubifs_wbuf *wbuf;
878 int err = 0;
879
880 wbuf = &c->jheads[GCHD].wbuf;
881 mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead);
882 list_for_each_entry_safe(idx_gc, tmp, &c->idx_gc, list)
883 if (idx_gc->unmap) {
884 dbg_gc("LEB %d", idx_gc->lnum);
885 err = ubifs_leb_unmap(c, idx_gc->lnum);
886 if (err)
887 goto out;
888 err = ubifs_change_one_lp(c, idx_gc->lnum, LPROPS_NC,
889 LPROPS_NC, 0, LPROPS_TAKEN, -1);
890 if (err)
891 goto out;
892 list_del(&idx_gc->list);
893 kfree(idx_gc);
894 }
895out:
896 mutex_unlock(&wbuf->io_mutex);
897 return err;
898}
899
900
901
902
903
904
905
906
907
908void ubifs_destroy_idx_gc(struct ubifs_info *c)
909{
910 while (!list_empty(&c->idx_gc)) {
911 struct ubifs_gced_idx_leb *idx_gc;
912
913 idx_gc = list_entry(c->idx_gc.next, struct ubifs_gced_idx_leb,
914 list);
915 c->idx_gc_cnt -= 1;
916 list_del(&idx_gc->list);
917 kfree(idx_gc);
918 }
919}
920
921
922
923
924
925
926
927int ubifs_get_idx_gc_leb(struct ubifs_info *c)
928{
929 struct ubifs_gced_idx_leb *idx_gc;
930 int lnum;
931
932 if (list_empty(&c->idx_gc))
933 return -ENOSPC;
934 idx_gc = list_entry(c->idx_gc.next, struct ubifs_gced_idx_leb, list);
935 lnum = idx_gc->lnum;
936
937 list_del(&idx_gc->list);
938 kfree(idx_gc);
939 return lnum;
940}
941