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 'for-6.17-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux

Pull btrfs fixes from David Sterba:

- fix delayed inode tracking in xarray, eviction can race with
insertion and leave behind a disconnected inode

- on systems with large page (64K) and small block size (4K) fix
compression read that can return partially filled folio

- slightly relax compression option format for backward compatibility,
allow to specify level for LZO although there's only one

- fix simple quota accounting of compressed extents

- validate minimum device size in 'device add'

- update maintainers' entry

* tag 'for-6.17-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
btrfs: don't allow adding block device of less than 1 MB
MAINTAINERS: update btrfs entry
btrfs: fix subvolume deletion lockup caused by inodes xarray race
btrfs: fix corruption reading compressed range when block size is smaller than page size
btrfs: accept and ignore compression level for lzo
btrfs: fix squota compressed stats leak

+56 -17
-1
MAINTAINERS
··· 5258 5258 5259 5259 BTRFS FILE SYSTEM 5260 5260 M: Chris Mason <clm@fb.com> 5261 - M: Josef Bacik <josef@toxicpanda.com> 5262 5261 M: David Sterba <dsterba@suse.com> 5263 5262 L: linux-btrfs@vger.kernel.org 5264 5263 S: Maintained
+30 -10
fs/btrfs/extent_io.c
··· 111 111 */ 112 112 unsigned long submit_bitmap; 113 113 struct readahead_control *ractl; 114 + 115 + /* 116 + * The start offset of the last used extent map by a read operation. 117 + * 118 + * This is for proper compressed read merge. 119 + * U64_MAX means we are starting the read and have made no progress yet. 120 + * 121 + * The current btrfs_bio_is_contig() only uses disk_bytenr as 122 + * the condition to check if the read can be merged with previous 123 + * bio, which is not correct. E.g. two file extents pointing to the 124 + * same extent but with different offset. 125 + * 126 + * So here we need to do extra checks to only merge reads that are 127 + * covered by the same extent map. 128 + * Just extent_map::start will be enough, as they are unique 129 + * inside the same inode. 130 + */ 131 + u64 last_em_start; 114 132 }; 115 133 116 134 static void submit_one_bio(struct btrfs_bio_ctrl *bio_ctrl) ··· 927 909 * return 0 on success, otherwise return error 928 910 */ 929 911 static int btrfs_do_readpage(struct folio *folio, struct extent_map **em_cached, 930 - struct btrfs_bio_ctrl *bio_ctrl, u64 *prev_em_start) 912 + struct btrfs_bio_ctrl *bio_ctrl) 931 913 { 932 914 struct inode *inode = folio->mapping->host; 933 915 struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); ··· 1037 1019 * non-optimal behavior (submitting 2 bios for the same extent). 1038 1020 */ 1039 1021 if (compress_type != BTRFS_COMPRESS_NONE && 1040 - prev_em_start && *prev_em_start != (u64)-1 && 1041 - *prev_em_start != em->start) 1022 + bio_ctrl->last_em_start != U64_MAX && 1023 + bio_ctrl->last_em_start != em->start) 1042 1024 force_bio_submit = true; 1043 1025 1044 - if (prev_em_start) 1045 - *prev_em_start = em->start; 1026 + bio_ctrl->last_em_start = em->start; 1046 1027 1047 1028 btrfs_free_extent_map(em); 1048 1029 em = NULL; ··· 1255 1238 const u64 start = folio_pos(folio); 1256 1239 const u64 end = start + folio_size(folio) - 1; 1257 1240 struct extent_state *cached_state = NULL; 1258 - struct btrfs_bio_ctrl bio_ctrl = { .opf = REQ_OP_READ }; 1241 + struct btrfs_bio_ctrl bio_ctrl = { 1242 + .opf = REQ_OP_READ, 1243 + .last_em_start = U64_MAX, 1244 + }; 1259 1245 struct extent_map *em_cached = NULL; 1260 1246 int ret; 1261 1247 1262 1248 lock_extents_for_read(inode, start, end, &cached_state); 1263 - ret = btrfs_do_readpage(folio, &em_cached, &bio_ctrl, NULL); 1249 + ret = btrfs_do_readpage(folio, &em_cached, &bio_ctrl); 1264 1250 btrfs_unlock_extent(&inode->io_tree, start, end, &cached_state); 1265 1251 1266 1252 btrfs_free_extent_map(em_cached); ··· 2603 2583 { 2604 2584 struct btrfs_bio_ctrl bio_ctrl = { 2605 2585 .opf = REQ_OP_READ | REQ_RAHEAD, 2606 - .ractl = rac 2586 + .ractl = rac, 2587 + .last_em_start = U64_MAX, 2607 2588 }; 2608 2589 struct folio *folio; 2609 2590 struct btrfs_inode *inode = BTRFS_I(rac->mapping->host); ··· 2612 2591 const u64 end = start + readahead_length(rac) - 1; 2613 2592 struct extent_state *cached_state = NULL; 2614 2593 struct extent_map *em_cached = NULL; 2615 - u64 prev_em_start = (u64)-1; 2616 2594 2617 2595 lock_extents_for_read(inode, start, end, &cached_state); 2618 2596 2619 2597 while ((folio = readahead_folio(rac)) != NULL) 2620 - btrfs_do_readpage(folio, &em_cached, &bio_ctrl, &prev_em_start); 2598 + btrfs_do_readpage(folio, &em_cached, &bio_ctrl); 2621 2599 2622 2600 btrfs_unlock_extent(&inode->io_tree, start, end, &cached_state); 2623 2601
+11 -1
fs/btrfs/inode.c
··· 5696 5696 bool empty = false; 5697 5697 5698 5698 xa_lock(&root->inodes); 5699 - entry = __xa_erase(&root->inodes, btrfs_ino(inode)); 5699 + /* 5700 + * This btrfs_inode is being freed and has already been unhashed at this 5701 + * point. It's possible that another btrfs_inode has already been 5702 + * allocated for the same inode and inserted itself into the root, so 5703 + * don't delete it in that case. 5704 + * 5705 + * Note that this shouldn't need to allocate memory, so the gfp flags 5706 + * don't really matter. 5707 + */ 5708 + entry = __xa_cmpxchg(&root->inodes, btrfs_ino(inode), inode, NULL, 5709 + GFP_ATOMIC); 5700 5710 if (entry == inode) 5701 5711 empty = xa_empty(&root->inodes); 5702 5712 xa_unlock(&root->inodes);
+4 -2
fs/btrfs/qgroup.c
··· 1455 1455 struct btrfs_qgroup *qgroup; 1456 1456 LIST_HEAD(qgroup_list); 1457 1457 u64 num_bytes = src->excl; 1458 + u64 num_bytes_cmpr = src->excl_cmpr; 1458 1459 int ret = 0; 1459 1460 1460 1461 qgroup = find_qgroup_rb(fs_info, ref_root); ··· 1467 1466 struct btrfs_qgroup_list *glist; 1468 1467 1469 1468 qgroup->rfer += sign * num_bytes; 1470 - qgroup->rfer_cmpr += sign * num_bytes; 1469 + qgroup->rfer_cmpr += sign * num_bytes_cmpr; 1471 1470 1472 1471 WARN_ON(sign < 0 && qgroup->excl < num_bytes); 1472 + WARN_ON(sign < 0 && qgroup->excl_cmpr < num_bytes_cmpr); 1473 1473 qgroup->excl += sign * num_bytes; 1474 - qgroup->excl_cmpr += sign * num_bytes; 1474 + qgroup->excl_cmpr += sign * num_bytes_cmpr; 1475 1475 1476 1476 if (sign > 0) 1477 1477 qgroup_rsv_add_by_qgroup(fs_info, qgroup, src);
+6 -3
fs/btrfs/super.c
··· 299 299 btrfs_set_opt(ctx->mount_opt, COMPRESS); 300 300 btrfs_clear_opt(ctx->mount_opt, NODATACOW); 301 301 btrfs_clear_opt(ctx->mount_opt, NODATASUM); 302 - } else if (btrfs_match_compress_type(string, "lzo", false)) { 302 + } else if (btrfs_match_compress_type(string, "lzo", true)) { 303 303 ctx->compress_type = BTRFS_COMPRESS_LZO; 304 - ctx->compress_level = 0; 304 + ctx->compress_level = btrfs_compress_str2level(BTRFS_COMPRESS_LZO, 305 + string + 3); 306 + if (string[3] == ':' && string[4]) 307 + btrfs_warn(NULL, "Compression level ignored for LZO"); 305 308 btrfs_set_opt(ctx->mount_opt, COMPRESS); 306 309 btrfs_clear_opt(ctx->mount_opt, NODATACOW); 307 310 btrfs_clear_opt(ctx->mount_opt, NODATASUM); ··· 1082 1079 seq_printf(seq, ",compress-force=%s", compress_type); 1083 1080 else 1084 1081 seq_printf(seq, ",compress=%s", compress_type); 1085 - if (info->compress_level) 1082 + if (info->compress_level && info->compress_type != BTRFS_COMPRESS_LZO) 1086 1083 seq_printf(seq, ":%d", info->compress_level); 1087 1084 } 1088 1085 if (btrfs_test_opt(info, NOSSD))
+5
fs/btrfs/volumes.c
··· 2722 2722 goto error; 2723 2723 } 2724 2724 2725 + if (bdev_nr_bytes(file_bdev(bdev_file)) <= BTRFS_DEVICE_RANGE_RESERVED) { 2726 + ret = -EINVAL; 2727 + goto error; 2728 + } 2729 + 2725 2730 if (fs_devices->seeding) { 2726 2731 seeding_dev = true; 2727 2732 down_write(&sb->s_umount);