Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'bcachefs-2024-05-07.2' of https://evilpiepirate.org/git/bcachefs

Pull bcachefs fixes from Kent Overstreet:

- Various syzbot fixes; mainly small gaps in validation

- Fix an integer overflow in fiemap() which was preventing filefrag
from returning the full list of extents

- Fix a refcounting bug on the device refcount, turned up by new
assertions in the development branch

- Fix a device removal/readd bug; write_super() was repeatedly dropping
and retaking bch_dev->io_ref references

* tag 'bcachefs-2024-05-07.2' of https://evilpiepirate.org/git/bcachefs:
bcachefs: Add missing sched_annotate_sleep() in bch2_journal_flush_seq_async()
bcachefs: Fix race in bch2_write_super()
bcachefs: BCH_SB_LAYOUT_SIZE_BITS_MAX
bcachefs: Add missing skcipher_request_set_callback() call
bcachefs: Fix snapshot_t() usage in bch2_fs_quota_read_inode()
bcachefs: Fix shift-by-64 in bformat_needs_redo()
bcachefs: Guard against unknown k.k->type in __bkey_invalid()
bcachefs: Add missing validation for superblock section clean
bcachefs: Fix assert in bch2_alloc_v4_invalid()
bcachefs: fix overflow in fiemap
bcachefs: Add a better limit for maximum number of buckets
bcachefs: Fix lifetime issue in device iterator helpers
bcachefs: Fix bch2_dev_lookup() refcounting
bcachefs: Initialize bch_write_op->failed in inline data path
bcachefs: Fix refcount put in sb_field_resize error path
bcachefs: Inodes need extra padding for varint_decode_fast()
bcachefs: Fix early error path in bch2_fs_btree_key_cache_exit()
bcachefs: bucket_pos_to_bp_noerror()
bcachefs: don't free error pointers
bcachefs: Fix a scheduler splat in __bch2_next_write_buffer_flush_journal_buf()

+149 -70
+2 -2
fs/bcachefs/alloc_background.c
··· 244 244 struct bkey_s_c_alloc_v4 a = bkey_s_c_to_alloc_v4(k); 245 245 int ret = 0; 246 246 247 - bkey_fsck_err_on(alloc_v4_u64s(a.v) > bkey_val_u64s(k.k), c, err, 247 + bkey_fsck_err_on(alloc_v4_u64s_noerror(a.v) > bkey_val_u64s(k.k), c, err, 248 248 alloc_v4_val_size_bad, 249 249 "bad val size (%u > %zu)", 250 - alloc_v4_u64s(a.v), bkey_val_u64s(k.k)); 250 + alloc_v4_u64s_noerror(a.v), bkey_val_u64s(k.k)); 251 251 252 252 bkey_fsck_err_on(!BCH_ALLOC_V4_BACKPOINTERS_START(a.v) && 253 253 BCH_ALLOC_V4_NR_BACKPOINTERS(a.v), c, err,
+6 -2
fs/bcachefs/alloc_background.h
··· 126 126 return pos; 127 127 } 128 128 129 - static inline unsigned alloc_v4_u64s(const struct bch_alloc_v4 *a) 129 + static inline unsigned alloc_v4_u64s_noerror(const struct bch_alloc_v4 *a) 130 130 { 131 - unsigned ret = (BCH_ALLOC_V4_BACKPOINTERS_START(a) ?: 131 + return (BCH_ALLOC_V4_BACKPOINTERS_START(a) ?: 132 132 BCH_ALLOC_V4_U64s_V0) + 133 133 BCH_ALLOC_V4_NR_BACKPOINTERS(a) * 134 134 (sizeof(struct bch_backpointer) / sizeof(u64)); 135 + } 135 136 137 + static inline unsigned alloc_v4_u64s(const struct bch_alloc_v4 *a) 138 + { 139 + unsigned ret = alloc_v4_u64s_noerror(a); 136 140 BUG_ON(ret > U8_MAX - BKEY_U64s); 137 141 return ret; 138 142 }
+1 -1
fs/bcachefs/backpointers.c
··· 54 54 int ret = 0; 55 55 56 56 bkey_fsck_err_on((bp.v->bucket_offset >> MAX_EXTENT_COMPRESS_RATIO_SHIFT) >= ca->mi.bucket_size || 57 - !bpos_eq(bp.k->p, bucket_pos_to_bp(c, bucket, bp.v->bucket_offset)), 57 + !bpos_eq(bp.k->p, bucket_pos_to_bp_noerror(ca, bucket, bp.v->bucket_offset)), 58 58 c, err, 59 59 backpointer_bucket_offset_wrong, 60 60 "backpointer bucket_offset wrong");
+10 -4
fs/bcachefs/backpointers.h
··· 45 45 return POS(bp_pos.inode, sector_to_bucket(ca, bucket_sector)); 46 46 } 47 47 48 + static inline struct bpos bucket_pos_to_bp_noerror(const struct bch_dev *ca, 49 + struct bpos bucket, 50 + u64 bucket_offset) 51 + { 52 + return POS(bucket.inode, 53 + (bucket_to_sector(ca, bucket.offset) << 54 + MAX_EXTENT_COMPRESS_RATIO_SHIFT) + bucket_offset); 55 + } 56 + 48 57 /* 49 58 * Convert from pos in alloc btree + bucket offset to pos in backpointer btree: 50 59 */ ··· 62 53 u64 bucket_offset) 63 54 { 64 55 struct bch_dev *ca = bch_dev_bkey_exists(c, bucket.inode); 65 - struct bpos ret = POS(bucket.inode, 66 - (bucket_to_sector(ca, bucket.offset) << 67 - MAX_EXTENT_COMPRESS_RATIO_SHIFT) + bucket_offset); 68 - 56 + struct bpos ret = bucket_pos_to_bp_noerror(ca, bucket, bucket_offset); 69 57 EBUG_ON(!bkey_eq(bucket, bp_pos_to_bucket(c, ret))); 70 58 return ret; 71 59 }
+8
fs/bcachefs/bcachefs_format.h
··· 591 591 __le64 btree_allocated_bitmap; 592 592 }; 593 593 594 + /* 595 + * This limit comes from the bucket_gens array - it's a single allocation, and 596 + * kernel allocation are limited to INT_MAX 597 + */ 598 + #define BCH_MEMBER_NBUCKETS_MAX (INT_MAX - 64) 599 + 594 600 #define BCH_MEMBER_V1_BYTES 56 595 601 596 602 LE64_BITMASK(BCH_MEMBER_STATE, struct bch_member, flags, 0, 4) ··· 902 896 903 897 #define BCH_SB_SECTOR 8 904 898 #define BCH_SB_MEMBERS_MAX 64 /* XXX kill */ 899 + 900 + #define BCH_SB_LAYOUT_SIZE_BITS_MAX 16 /* 32 MB */ 905 901 906 902 struct bch_sb_layout { 907 903 __uuid_t magic; /* bcachefs superblock UUID */
+2 -2
fs/bcachefs/bkey_methods.c
··· 171 171 if (type >= BKEY_TYPE_NR) 172 172 return 0; 173 173 174 - bkey_fsck_err_on((type == BKEY_TYPE_btree || 175 - (flags & BKEY_INVALID_COMMIT)) && 174 + bkey_fsck_err_on(k.k->type < KEY_TYPE_MAX && 175 + (type == BKEY_TYPE_btree || (flags & BKEY_INVALID_COMMIT)) && 176 176 !(bch2_key_types_allowed[type] & BIT_ULL(k.k->type)), c, err, 177 177 bkey_invalid_type_for_btree, 178 178 "invalid key type for btree %s (%s)",
+8 -6
fs/bcachefs/btree_key_cache.c
··· 956 956 } 957 957 958 958 #ifdef __KERNEL__ 959 - for_each_possible_cpu(cpu) { 960 - struct btree_key_cache_freelist *f = 961 - per_cpu_ptr(bc->pcpu_freed, cpu); 959 + if (bc->pcpu_freed) { 960 + for_each_possible_cpu(cpu) { 961 + struct btree_key_cache_freelist *f = 962 + per_cpu_ptr(bc->pcpu_freed, cpu); 962 963 963 - for (i = 0; i < f->nr; i++) { 964 - ck = f->objs[i]; 965 - list_add(&ck->list, &items); 964 + for (i = 0; i < f->nr; i++) { 965 + ck = f->objs[i]; 966 + list_add(&ck->list, &items); 967 + } 966 968 } 967 969 } 968 970 #endif
+1
fs/bcachefs/checksum.c
··· 102 102 int ret; 103 103 104 104 skcipher_request_set_sync_tfm(req, tfm); 105 + skcipher_request_set_callback(req, 0, NULL, NULL); 105 106 skcipher_request_set_crypt(req, sg, sg, len, nonce.d); 106 107 107 108 ret = crypto_skcipher_encrypt(req);
+1
fs/bcachefs/errcode.h
··· 175 175 x(EINVAL, block_size_too_small) \ 176 176 x(EINVAL, bucket_size_too_small) \ 177 177 x(EINVAL, device_size_too_small) \ 178 + x(EINVAL, device_size_too_big) \ 178 179 x(EINVAL, device_not_a_member_of_filesystem) \ 179 180 x(EINVAL, device_has_been_removed) \ 180 181 x(EINVAL, device_splitbrain) \
+1 -1
fs/bcachefs/fs.c
··· 964 964 struct btree_iter iter; 965 965 struct bkey_s_c k; 966 966 struct bkey_buf cur, prev; 967 - struct bpos end = POS(ei->v.i_ino, (start + len) >> 9); 968 967 unsigned offset_into_extent, sectors; 969 968 bool have_extent = false; 970 969 u32 snapshot; ··· 973 974 if (ret) 974 975 return ret; 975 976 977 + struct bpos end = POS(ei->v.i_ino, (start + len) >> 9); 976 978 if (start + len < start) 977 979 return -EINVAL; 978 980
+20 -10
fs/bcachefs/io_write.c
··· 199 199 u64 new_i_size, 200 200 s64 i_sectors_delta) 201 201 { 202 - struct btree_iter iter; 203 - struct bkey_i *k; 204 - struct bkey_i_inode_v3 *inode; 205 202 /* 206 203 * Crazy performance optimization: 207 204 * Every extent update needs to also update the inode: the inode trigger ··· 211 214 * lost, but that's fine. 212 215 */ 213 216 unsigned inode_update_flags = BTREE_UPDATE_NOJOURNAL; 214 - int ret; 215 217 216 - k = bch2_bkey_get_mut_noupdate(trans, &iter, BTREE_ID_inodes, 218 + struct btree_iter iter; 219 + struct bkey_s_c k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_inodes, 217 220 SPOS(0, 218 221 extent_iter->pos.inode, 219 222 extent_iter->snapshot), 220 223 BTREE_ITER_CACHED); 221 - ret = PTR_ERR_OR_ZERO(k); 224 + int ret = bkey_err(k); 222 225 if (unlikely(ret)) 223 226 return ret; 224 227 225 - if (unlikely(k->k.type != KEY_TYPE_inode_v3)) { 226 - k = bch2_inode_to_v3(trans, k); 227 - ret = PTR_ERR_OR_ZERO(k); 228 + /* 229 + * varint_decode_fast(), in the inode .invalid method, reads up to 7 230 + * bytes past the end of the buffer: 231 + */ 232 + struct bkey_i *k_mut = bch2_trans_kmalloc_nomemzero(trans, bkey_bytes(k.k) + 8); 233 + ret = PTR_ERR_OR_ZERO(k_mut); 234 + if (unlikely(ret)) 235 + goto err; 236 + 237 + bkey_reassemble(k_mut, k); 238 + 239 + if (unlikely(k_mut->k.type != KEY_TYPE_inode_v3)) { 240 + k_mut = bch2_inode_to_v3(trans, k_mut); 241 + ret = PTR_ERR_OR_ZERO(k_mut); 228 242 if (unlikely(ret)) 229 243 goto err; 230 244 } 231 245 232 - inode = bkey_i_to_inode_v3(k); 246 + struct bkey_i_inode_v3 *inode = bkey_i_to_inode_v3(k_mut); 233 247 234 248 if (!(le64_to_cpu(inode->v.bi_flags) & BCH_INODE_i_size_dirty) && 235 249 new_i_size > le64_to_cpu(inode->v.bi_size)) { ··· 1512 1504 struct bkey_i_inline_data *id; 1513 1505 unsigned sectors; 1514 1506 int ret; 1507 + 1508 + memset(&op->failed, 0, sizeof(op->failed)); 1515 1509 1516 1510 op->flags |= BCH_WRITE_WROTE_DATA_INLINE; 1517 1511 op->flags |= BCH_WRITE_DONE;
+8
fs/bcachefs/journal.c
··· 706 706 707 707 spin_unlock(&j->lock); 708 708 709 + /* 710 + * We're called from bch2_journal_flush_seq() -> wait_event(); 711 + * but this might block. We won't usually block, so we won't 712 + * livelock: 713 + */ 714 + sched_annotate_sleep(); 709 715 ret = bch2_journal_res_get(j, &res, jset_u64s(0), 0); 710 716 if (ret) 711 717 return ret; ··· 876 870 { 877 871 struct journal_buf *ret = NULL; 878 872 873 + /* We're inside wait_event(), but using mutex_lock(: */ 874 + sched_annotate_sleep(); 879 875 mutex_lock(&j->buf_lock); 880 876 spin_lock(&j->lock); 881 877 max_seq = min(max_seq, journal_cur_seq(j));
+14 -8
fs/bcachefs/move.c
··· 968 968 return migrate_pred(c, arg, bkey_i_to_s_c(&b->key), io_opts, data_opts); 969 969 } 970 970 971 + /* 972 + * Ancient versions of bcachefs produced packed formats which could represent 973 + * keys that the in memory format cannot represent; this checks for those 974 + * formats so we can get rid of them. 975 + */ 971 976 static bool bformat_needs_redo(struct bkey_format *f) 972 977 { 973 - unsigned i; 974 - 975 - for (i = 0; i < f->nr_fields; i++) { 978 + for (unsigned i = 0; i < f->nr_fields; i++) { 979 + unsigned f_bits = f->bits_per_field[i]; 976 980 unsigned unpacked_bits = bch2_bkey_format_current.bits_per_field[i]; 977 981 u64 unpacked_mask = ~((~0ULL << 1) << (unpacked_bits - 1)); 978 982 u64 field_offset = le64_to_cpu(f->field_offset[i]); 979 983 980 - if (f->bits_per_field[i] > unpacked_bits) 984 + if (f_bits > unpacked_bits) 981 985 return true; 982 986 983 - if ((f->bits_per_field[i] == unpacked_bits) && field_offset) 987 + if ((f_bits == unpacked_bits) && field_offset) 984 988 return true; 985 989 986 - if (((field_offset + ((1ULL << f->bits_per_field[i]) - 1)) & 987 - unpacked_mask) < 988 - field_offset) 990 + u64 f_mask = f_bits 991 + ? ~((~0ULL << (f_bits - 1)) << 1) 992 + : 0; 993 + 994 + if (((field_offset + f_mask) & unpacked_mask) < field_offset) 989 995 return true; 990 996 } 991 997
+3 -5
fs/bcachefs/quota.c
··· 560 560 struct bch_fs *c = trans->c; 561 561 struct bch_inode_unpacked u; 562 562 struct bch_snapshot_tree s_t; 563 - int ret; 563 + u32 tree = bch2_snapshot_tree(c, k.k->p.snapshot); 564 564 565 - ret = bch2_snapshot_tree_lookup(trans, 566 - bch2_snapshot_tree(c, k.k->p.snapshot), &s_t); 565 + int ret = bch2_snapshot_tree_lookup(trans, tree, &s_t); 567 566 bch2_fs_inconsistent_on(bch2_err_matches(ret, ENOENT), c, 568 - "%s: snapshot tree %u not found", __func__, 569 - snapshot_t(c, k.k->p.snapshot)->tree); 567 + "%s: snapshot tree %u not found", __func__, tree); 570 568 if (ret) 571 569 return ret; 572 570
+2 -1
fs/bcachefs/recovery.c
··· 902 902 bch2_journal_keys_put_initial(c); 903 903 bch2_find_btree_nodes_exit(&c->found_btree_nodes); 904 904 } 905 - kfree(clean); 905 + if (!IS_ERR(clean)) 906 + kfree(clean); 906 907 907 908 if (!ret && 908 909 test_bit(BCH_FS_need_delete_dead_snapshots, &c->flags) &&
+14
fs/bcachefs/sb-clean.c
··· 278 278 return -BCH_ERR_invalid_sb_clean; 279 279 } 280 280 281 + for (struct jset_entry *entry = clean->start; 282 + entry != vstruct_end(&clean->field); 283 + entry = vstruct_next(entry)) { 284 + if ((void *) vstruct_next(entry) > vstruct_end(&clean->field)) { 285 + prt_str(err, "entry type "); 286 + bch2_prt_jset_entry_type(err, le16_to_cpu(entry->type)); 287 + prt_str(err, " overruns end of section"); 288 + return -BCH_ERR_invalid_sb_clean; 289 + } 290 + } 291 + 281 292 return 0; 282 293 } 283 294 ··· 306 295 for (entry = clean->start; 307 296 entry != vstruct_end(&clean->field); 308 297 entry = vstruct_next(entry)) { 298 + if ((void *) vstruct_next(entry) > vstruct_end(&clean->field)) 299 + break; 300 + 309 301 if (entry->type == BCH_JSET_ENTRY_btree_keys && 310 302 !entry->u64s) 311 303 continue;
+3 -3
fs/bcachefs/sb-members.c
··· 124 124 struct bch_sb *sb, 125 125 int i) 126 126 { 127 - if (le64_to_cpu(m.nbuckets) > LONG_MAX) { 128 - prt_printf(err, "device %u: too many buckets (got %llu, max %lu)", 129 - i, le64_to_cpu(m.nbuckets), LONG_MAX); 127 + if (le64_to_cpu(m.nbuckets) > BCH_MEMBER_NBUCKETS_MAX) { 128 + prt_printf(err, "device %u: too many buckets (got %llu, max %u)", 129 + i, le64_to_cpu(m.nbuckets), BCH_MEMBER_NBUCKETS_MAX); 130 130 return -BCH_ERR_invalid_sb_members; 131 131 } 132 132
+2 -2
fs/bcachefs/sb-members.h
··· 107 107 108 108 static inline struct bch_dev *bch2_get_next_dev(struct bch_fs *c, struct bch_dev *ca) 109 109 { 110 + rcu_read_lock(); 110 111 if (ca) 111 112 percpu_ref_put(&ca->ref); 112 113 113 - rcu_read_lock(); 114 114 if ((ca = __bch2_next_dev(c, ca, NULL))) 115 115 percpu_ref_get(&ca->ref); 116 116 rcu_read_unlock(); ··· 132 132 struct bch_dev *ca, 133 133 unsigned state_mask) 134 134 { 135 + rcu_read_lock(); 135 136 if (ca) 136 137 percpu_ref_put(&ca->io_ref); 137 138 138 - rcu_read_lock(); 139 139 while ((ca = __bch2_next_dev(c, ca, NULL)) && 140 140 (!((1 << ca->mi.state) & state_mask) || 141 141 !percpu_ref_tryget(&ca->io_ref)))
+34 -17
fs/bcachefs/super-io.c
··· 232 232 struct bch_sb_handle *dev_sb = &ca->disk_sb; 233 233 234 234 if (bch2_sb_realloc(dev_sb, le32_to_cpu(dev_sb->sb->u64s) + d)) { 235 - percpu_ref_put(&ca->ref); 235 + percpu_ref_put(&ca->io_ref); 236 236 return NULL; 237 237 } 238 238 } ··· 649 649 650 650 bytes = vstruct_bytes(sb->sb); 651 651 652 - if (bytes > 512 << sb->sb->layout.sb_max_size_bits) { 652 + if (bytes > 512ULL << min(BCH_SB_LAYOUT_SIZE_BITS_MAX, sb->sb->layout.sb_max_size_bits)) { 653 653 prt_printf(err, "Invalid superblock: too big (got %zu bytes, layout max %lu)", 654 654 bytes, 512UL << sb->sb->layout.sb_max_size_bits); 655 655 return -BCH_ERR_invalid_sb_too_big; ··· 923 923 struct bch_devs_mask sb_written; 924 924 bool wrote, can_mount_without_written, can_mount_with_written; 925 925 unsigned degraded_flags = BCH_FORCE_IF_DEGRADED; 926 + DARRAY(struct bch_dev *) online_devices = {}; 926 927 int ret = 0; 927 928 928 929 trace_and_count(c, write_super, c, _RET_IP_); ··· 936 935 closure_init_stack(cl); 937 936 memset(&sb_written, 0, sizeof(sb_written)); 938 937 938 + for_each_online_member(c, ca) { 939 + ret = darray_push(&online_devices, ca); 940 + if (bch2_fs_fatal_err_on(ret, c, "%s: error allocating online devices", __func__)) { 941 + percpu_ref_put(&ca->io_ref); 942 + goto out; 943 + } 944 + percpu_ref_get(&ca->io_ref); 945 + } 946 + 939 947 /* Make sure we're using the new magic numbers: */ 940 948 c->disk_sb.sb->magic = BCHFS_MAGIC; 941 949 c->disk_sb.sb->layout.magic = BCHFS_MAGIC; ··· 952 942 le64_add_cpu(&c->disk_sb.sb->seq, 1); 953 943 954 944 struct bch_sb_field_members_v2 *mi = bch2_sb_field_get(c->disk_sb.sb, members_v2); 955 - for_each_online_member(c, ca) 956 - __bch2_members_v2_get_mut(mi, ca->dev_idx)->seq = c->disk_sb.sb->seq; 945 + darray_for_each(online_devices, ca) 946 + __bch2_members_v2_get_mut(mi, (*ca)->dev_idx)->seq = c->disk_sb.sb->seq; 957 947 c->disk_sb.sb->write_time = cpu_to_le64(ktime_get_real_seconds()); 958 948 959 949 if (test_bit(BCH_FS_error, &c->flags)) ··· 969 959 bch2_sb_errors_from_cpu(c); 970 960 bch2_sb_downgrade_update(c); 971 961 972 - for_each_online_member(c, ca) 973 - bch2_sb_from_fs(c, ca); 962 + darray_for_each(online_devices, ca) 963 + bch2_sb_from_fs(c, (*ca)); 974 964 975 - for_each_online_member(c, ca) { 965 + darray_for_each(online_devices, ca) { 976 966 printbuf_reset(&err); 977 967 978 - ret = bch2_sb_validate(&ca->disk_sb, &err, WRITE); 968 + ret = bch2_sb_validate(&(*ca)->disk_sb, &err, WRITE); 979 969 if (ret) { 980 970 bch2_fs_inconsistent(c, "sb invalid before write: %s", err.buf); 981 - percpu_ref_put(&ca->io_ref); 982 971 goto out; 983 972 } 984 973 } ··· 1004 995 return -BCH_ERR_sb_not_downgraded; 1005 996 } 1006 997 1007 - for_each_online_member(c, ca) { 1008 - __set_bit(ca->dev_idx, sb_written.d); 1009 - ca->sb_write_error = 0; 998 + darray_for_each(online_devices, ca) { 999 + __set_bit((*ca)->dev_idx, sb_written.d); 1000 + (*ca)->sb_write_error = 0; 1010 1001 } 1011 1002 1012 - for_each_online_member(c, ca) 1013 - read_back_super(c, ca); 1003 + darray_for_each(online_devices, ca) 1004 + read_back_super(c, *ca); 1014 1005 closure_sync(cl); 1015 1006 1016 - for_each_online_member(c, ca) { 1007 + darray_for_each(online_devices, cap) { 1008 + struct bch_dev *ca = *cap; 1009 + 1017 1010 if (ca->sb_write_error) 1018 1011 continue; 1019 1012 ··· 1042 1031 1043 1032 do { 1044 1033 wrote = false; 1045 - for_each_online_member(c, ca) 1034 + darray_for_each(online_devices, cap) { 1035 + struct bch_dev *ca = *cap; 1046 1036 if (!ca->sb_write_error && 1047 1037 sb < ca->disk_sb.sb->layout.nr_superblocks) { 1048 1038 write_one_super(c, ca, sb); 1049 1039 wrote = true; 1050 1040 } 1041 + } 1051 1042 closure_sync(cl); 1052 1043 sb++; 1053 1044 } while (wrote); 1054 1045 1055 - for_each_online_member(c, ca) { 1046 + darray_for_each(online_devices, cap) { 1047 + struct bch_dev *ca = *cap; 1056 1048 if (ca->sb_write_error) 1057 1049 __clear_bit(ca->dev_idx, sb_written.d); 1058 1050 else ··· 1091 1077 out: 1092 1078 /* Make new options visible after they're persistent: */ 1093 1079 bch2_sb_update(c); 1080 + darray_for_each(online_devices, ca) 1081 + percpu_ref_put(&(*ca)->io_ref); 1082 + darray_exit(&online_devices); 1094 1083 printbuf_exit(&err); 1095 1084 return ret; 1096 1085 }
+9 -6
fs/bcachefs/super.c
··· 1959 1959 goto err; 1960 1960 } 1961 1961 1962 + if (nbuckets > BCH_MEMBER_NBUCKETS_MAX) { 1963 + bch_err(ca, "New device size too big (%llu greater than max %u)", 1964 + nbuckets, BCH_MEMBER_NBUCKETS_MAX); 1965 + ret = -BCH_ERR_device_size_too_big; 1966 + goto err; 1967 + } 1968 + 1962 1969 if (bch2_dev_is_online(ca) && 1963 1970 get_capacity(ca->disk_sb.bdev->bd_disk) < 1964 1971 ca->mi.bucket_size * nbuckets) { ··· 2011 2004 /* return with ref on ca->ref: */ 2012 2005 struct bch_dev *bch2_dev_lookup(struct bch_fs *c, const char *name) 2013 2006 { 2014 - rcu_read_lock(); 2015 - for_each_member_device_rcu(c, ca, NULL) 2016 - if (!strcmp(name, ca->name)) { 2017 - rcu_read_unlock(); 2007 + for_each_member_device(c, ca) 2008 + if (!strcmp(name, ca->name)) 2018 2009 return ca; 2019 - } 2020 - rcu_read_unlock(); 2021 2010 return ERR_PTR(-BCH_ERR_ENOENT_dev_not_found); 2022 2011 } 2023 2012