1 // SPDX-License-Identifier: GPL-2.0 1 2 3 #include "bcachefs.h" 4 #include "journal_sb.h" 5 #include "darray.h" 6 7 #include <linux/sort.h> 8 9 /* BCH_SB_FIELD_journal: */ 10 11 static int u64_cmp(const void *_l, const void 12 { 13 const u64 *l = _l; 14 const u64 *r = _r; 15 16 return cmp_int(*l, *r); 17 } 18 19 static int bch2_sb_journal_validate(struct bch 20 enum bch_valid 21 { 22 struct bch_sb_field_journal *journal = 23 struct bch_member m = bch2_sb_member_g 24 int ret = -BCH_ERR_invalid_sb_journal; 25 unsigned nr; 26 unsigned i; 27 u64 *b; 28 29 nr = bch2_nr_journal_buckets(journal); 30 if (!nr) 31 return 0; 32 33 b = kmalloc_array(nr, sizeof(u64), GFP 34 if (!b) 35 return -BCH_ERR_ENOMEM_sb_jour 36 37 for (i = 0; i < nr; i++) 38 b[i] = le64_to_cpu(journal->bu 39 40 sort(b, nr, sizeof(u64), u64_cmp, NULL 41 42 if (!b[0]) { 43 prt_printf(err, "journal bucke 44 goto err; 45 } 46 47 if (b[0] < le16_to_cpu(m.first_bucket) 48 prt_printf(err, "journal bucke 49 b[0], le16_to_cpu(m.fir 50 goto err; 51 } 52 53 if (b[nr - 1] >= le64_to_cpu(m.nbucket 54 prt_printf(err, "journal bucke 55 b[nr - 1], le64_to_cpu( 56 goto err; 57 } 58 59 for (i = 0; i + 1 < nr; i++) 60 if (b[i] == b[i + 1]) { 61 prt_printf(err, "dupli 62 goto err; 63 } 64 65 ret = 0; 66 err: 67 kfree(b); 68 return ret; 69 } 70 71 static void bch2_sb_journal_to_text(struct pri 72 struct bch 73 { 74 struct bch_sb_field_journal *journal = 75 unsigned i, nr = bch2_nr_journal_bucke 76 77 prt_printf(out, "Buckets: "); 78 for (i = 0; i < nr; i++) 79 prt_printf(out, " %llu", le64_ 80 prt_newline(out); 81 } 82 83 const struct bch_sb_field_ops bch_sb_field_ops 84 .validate = bch2_sb_journal_vali 85 .to_text = bch2_sb_journal_to_t 86 }; 87 88 struct u64_range { 89 u64 start; 90 u64 end; 91 }; 92 93 static int u64_range_cmp(const void *_l, const 94 { 95 const struct u64_range *l = _l; 96 const struct u64_range *r = _r; 97 98 return cmp_int(l->start, r->start); 99 } 100 101 static int bch2_sb_journal_v2_validate(struct 102 enum bch_valid 103 { 104 struct bch_sb_field_journal_v2 *journa 105 struct bch_member m = bch2_sb_member_g 106 int ret = -BCH_ERR_invalid_sb_journal; 107 unsigned nr; 108 unsigned i; 109 struct u64_range *b; 110 111 nr = bch2_sb_field_journal_v2_nr_entri 112 if (!nr) 113 return 0; 114 115 b = kmalloc_array(nr, sizeof(*b), GFP_ 116 if (!b) 117 return -BCH_ERR_ENOMEM_sb_jour 118 119 for (i = 0; i < nr; i++) { 120 b[i].start = le64_to_cpu(journ 121 b[i].end = b[i].start + le64_t 122 } 123 124 sort(b, nr, sizeof(*b), u64_range_cmp, 125 126 if (!b[0].start) { 127 prt_printf(err, "journal bucke 128 goto err; 129 } 130 131 if (b[0].start < le16_to_cpu(m.first_b 132 prt_printf(err, "journal bucke 133 b[0].start, le16_to_cpu 134 goto err; 135 } 136 137 if (b[nr - 1].end > le64_to_cpu(m.nbuc 138 prt_printf(err, "journal bucke 139 b[nr - 1].end - 1, le64 140 goto err; 141 } 142 143 for (i = 0; i + 1 < nr; i++) { 144 if (b[i].end > b[i + 1].start) 145 prt_printf(err, "dupli 146 b[i].start, b[i 147 goto err; 148 } 149 } 150 151 ret = 0; 152 err: 153 kfree(b); 154 return ret; 155 } 156 157 static void bch2_sb_journal_v2_to_text(struct 158 struct bch 159 { 160 struct bch_sb_field_journal_v2 *journa 161 unsigned i, nr = bch2_sb_field_journal 162 163 prt_printf(out, "Buckets: "); 164 for (i = 0; i < nr; i++) 165 prt_printf(out, " %llu-%llu", 166 le64_to_cpu(journal->d[ 167 le64_to_cpu(journal->d[ 168 prt_newline(out); 169 } 170 171 const struct bch_sb_field_ops bch_sb_field_ops 172 .validate = bch2_sb_journal_v2_v 173 .to_text = bch2_sb_journal_v2_t 174 }; 175 176 int bch2_journal_buckets_to_sb(struct bch_fs * 177 u64 *buckets, u 178 { 179 struct bch_sb_field_journal_v2 *j; 180 unsigned i, dst = 0, nr_compacted = 1; 181 182 if (c) 183 lockdep_assert_held(&c->sb_loc 184 185 if (!nr) { 186 bch2_sb_field_delete(&ca->disk 187 bch2_sb_field_delete(&ca->disk 188 return 0; 189 } 190 191 for (i = 0; i + 1 < nr; i++) 192 if (buckets[i] + 1 != buckets[ 193 nr_compacted++; 194 195 j = bch2_sb_field_resize(&ca->disk_sb, 196 (sizeof(*j) + sizeof( 197 if (!j) 198 return -BCH_ERR_ENOSPC_sb_jour 199 200 bch2_sb_field_delete(&ca->disk_sb, BCH 201 202 j->d[dst].start = cpu_to_le64(buckets[ 203 j->d[dst].nr = cpu_to_le64(1); 204 205 for (i = 1; i < nr; i++) { 206 if (buckets[i] == buckets[i - 207 le64_add_cpu(&j->d[dst 208 } else { 209 dst++; 210 j->d[dst].start = cpu_ 211 j->d[dst].nr = cpu_ 212 } 213 } 214 215 BUG_ON(dst + 1 != nr_compacted); 216 return 0; 217 } 218
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.