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

Merge tag 'for-6.12-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux

Pull btrfs fixes from David Sterba:

- mount option fixes:
- fix handling of compression mount options on remount
- reject rw remount in case there are options that don't work
in read-write mode (like rescue options)

- fix zone accounting of unusable space

- fix in-memory corruption when merging extent maps

- fix delalloc range locking for sector < page

- use more convenient default value of drop subtree threshold, clean
more subvolumes without the fallback to marking quotas inconsistent

- fix smatch warning about incorrect value passed to ERR_PTR

* tag 'for-6.12-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
btrfs: fix passing 0 to ERR_PTR in btrfs_search_dir_index_item()
btrfs: reject ro->rw reconfiguration if there are hard ro requirements
btrfs: fix read corruption due to race with extent map merging
btrfs: fix the delalloc range locking if sector size < page size
btrfs: qgroup: set a more sane default value for subtree drop threshold
btrfs: clear force-compress on remount when compress mount option is given
btrfs: zoned: fix zone unusable accounting for freed reserved extent

+45 -34
+2
fs/btrfs/block-group.c
··· 3819 3819 spin_lock(&cache->lock); 3820 3820 if (cache->ro) 3821 3821 space_info->bytes_readonly += num_bytes; 3822 + else if (btrfs_is_zoned(cache->fs_info)) 3823 + space_info->bytes_zone_unusable += num_bytes; 3822 3824 cache->reserved -= num_bytes; 3823 3825 space_info->bytes_reserved -= num_bytes; 3824 3826 space_info->max_extent_size = 0;
+2 -2
fs/btrfs/dir-item.c
··· 347 347 return di; 348 348 } 349 349 /* Adjust return code if the key was not found in the next leaf. */ 350 - if (ret > 0) 351 - ret = 0; 350 + if (ret >= 0) 351 + ret = -ENOENT; 352 352 353 353 return ERR_PTR(ret); 354 354 }
+1 -1
fs/btrfs/disk-io.c
··· 1959 1959 fs_info->qgroup_seq = 1; 1960 1960 fs_info->qgroup_ulist = NULL; 1961 1961 fs_info->qgroup_rescan_running = false; 1962 - fs_info->qgroup_drop_subtree_thres = BTRFS_MAX_LEVEL; 1962 + fs_info->qgroup_drop_subtree_thres = BTRFS_QGROUP_DROP_SUBTREE_THRES_DEFAULT; 1963 1963 mutex_init(&fs_info->qgroup_rescan_lock); 1964 1964 } 1965 1965
+9 -8
fs/btrfs/extent_io.c
··· 262 262 263 263 for (i = 0; i < found_folios; i++) { 264 264 struct folio *folio = fbatch.folios[i]; 265 - u32 len = end + 1 - start; 265 + u64 range_start; 266 + u32 range_len; 266 267 267 268 if (folio == locked_folio) 268 269 continue; 269 270 270 - if (btrfs_folio_start_writer_lock(fs_info, folio, start, 271 - len)) 272 - goto out; 273 - 271 + folio_lock(folio); 274 272 if (!folio_test_dirty(folio) || folio->mapping != mapping) { 275 - btrfs_folio_end_writer_lock(fs_info, folio, start, 276 - len); 273 + folio_unlock(folio); 277 274 goto out; 278 275 } 276 + range_start = max_t(u64, folio_pos(folio), start); 277 + range_len = min_t(u64, folio_pos(folio) + folio_size(folio), 278 + end + 1) - range_start; 279 + btrfs_folio_set_writer_lock(fs_info, folio, range_start, range_len); 279 280 280 - processed_end = folio_pos(folio) + folio_size(folio) - 1; 281 + processed_end = range_start + range_len - 1; 281 282 } 282 283 folio_batch_release(&fbatch); 283 284 cond_resched();
+16 -15
fs/btrfs/extent_map.c
··· 243 243 /* 244 244 * Handle the on-disk data extents merge for @prev and @next. 245 245 * 246 + * @prev: left extent to merge 247 + * @next: right extent to merge 248 + * @merged: the extent we will not discard after the merge; updated with new values 249 + * 250 + * After this, one of the two extents is the new merged extent and the other is 251 + * removed from the tree and likely freed. Note that @merged is one of @prev/@next 252 + * so there is const/non-const aliasing occurring here. 253 + * 246 254 * Only touches disk_bytenr/disk_num_bytes/offset/ram_bytes. 247 255 * For now only uncompressed regular extent can be merged. 248 - * 249 - * @prev and @next will be both updated to point to the new merged range. 250 - * Thus one of them should be removed by the caller. 251 256 */ 252 - static void merge_ondisk_extents(struct extent_map *prev, struct extent_map *next) 257 + static void merge_ondisk_extents(const struct extent_map *prev, const struct extent_map *next, 258 + struct extent_map *merged) 253 259 { 254 260 u64 new_disk_bytenr; 255 261 u64 new_disk_num_bytes; ··· 290 284 new_disk_bytenr; 291 285 new_offset = prev->disk_bytenr + prev->offset - new_disk_bytenr; 292 286 293 - prev->disk_bytenr = new_disk_bytenr; 294 - prev->disk_num_bytes = new_disk_num_bytes; 295 - prev->ram_bytes = new_disk_num_bytes; 296 - prev->offset = new_offset; 297 - 298 - next->disk_bytenr = new_disk_bytenr; 299 - next->disk_num_bytes = new_disk_num_bytes; 300 - next->ram_bytes = new_disk_num_bytes; 301 - next->offset = new_offset; 287 + merged->disk_bytenr = new_disk_bytenr; 288 + merged->disk_num_bytes = new_disk_num_bytes; 289 + merged->ram_bytes = new_disk_num_bytes; 290 + merged->offset = new_offset; 302 291 } 303 292 304 293 static void dump_extent_map(struct btrfs_fs_info *fs_info, const char *prefix, ··· 362 361 em->generation = max(em->generation, merge->generation); 363 362 364 363 if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE) 365 - merge_ondisk_extents(merge, em); 364 + merge_ondisk_extents(merge, em, em); 366 365 em->flags |= EXTENT_FLAG_MERGED; 367 366 368 367 validate_extent_map(fs_info, em); ··· 379 378 if (rb && can_merge_extent_map(merge) && mergeable_maps(em, merge)) { 380 379 em->len += merge->len; 381 380 if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE) 382 - merge_ondisk_extents(em, merge); 381 + merge_ondisk_extents(em, merge, em); 383 382 validate_extent_map(fs_info, em); 384 383 rb_erase(&merge->rb_node, &tree->root); 385 384 RB_CLEAR_NODE(&merge->rb_node);
+2 -5
fs/btrfs/inode.c
··· 4368 4368 */ 4369 4369 if (btrfs_ino(inode) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID) { 4370 4370 di = btrfs_search_dir_index_item(root, path, dir_ino, &fname.disk_name); 4371 - if (IS_ERR_OR_NULL(di)) { 4372 - if (!di) 4373 - ret = -ENOENT; 4374 - else 4375 - ret = PTR_ERR(di); 4371 + if (IS_ERR(di)) { 4372 + ret = PTR_ERR(di); 4376 4373 btrfs_abort_transaction(trans, ret); 4377 4374 goto out; 4378 4375 }
+1 -1
fs/btrfs/qgroup.c
··· 1407 1407 fs_info->quota_root = NULL; 1408 1408 fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_ON; 1409 1409 fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_SIMPLE_MODE; 1410 - fs_info->qgroup_drop_subtree_thres = BTRFS_MAX_LEVEL; 1410 + fs_info->qgroup_drop_subtree_thres = BTRFS_QGROUP_DROP_SUBTREE_THRES_DEFAULT; 1411 1411 spin_unlock(&fs_info->qgroup_lock); 1412 1412 1413 1413 btrfs_free_qgroup_config(fs_info);
+2
fs/btrfs/qgroup.h
··· 121 121 #define BTRFS_QGROUP_RUNTIME_FLAG_CANCEL_RESCAN (1ULL << 63) 122 122 #define BTRFS_QGROUP_RUNTIME_FLAG_NO_ACCOUNTING (1ULL << 62) 123 123 124 + #define BTRFS_QGROUP_DROP_SUBTREE_THRES_DEFAULT (3) 125 + 124 126 /* 125 127 * Record a dirty extent, and info qgroup to update quota on it 126 128 */
+10 -2
fs/btrfs/super.c
··· 340 340 fallthrough; 341 341 case Opt_compress: 342 342 case Opt_compress_type: 343 + /* 344 + * Provide the same semantics as older kernels that don't use fs 345 + * context, specifying the "compress" option clears 346 + * "force-compress" without the need to pass 347 + * "compress-force=[no|none]" before specifying "compress". 348 + */ 349 + if (opt != Opt_compress_force && opt != Opt_compress_force_type) 350 + btrfs_clear_opt(ctx->mount_opt, FORCE_COMPRESS); 351 + 343 352 if (opt == Opt_compress || opt == Opt_compress_force) { 344 353 ctx->compress_type = BTRFS_COMPRESS_ZLIB; 345 354 ctx->compress_level = BTRFS_ZLIB_DEFAULT_LEVEL; ··· 1507 1498 sync_filesystem(sb); 1508 1499 set_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state); 1509 1500 1510 - if (!mount_reconfigure && 1511 - !btrfs_check_options(fs_info, &ctx->mount_opt, fc->sb_flags)) 1501 + if (!btrfs_check_options(fs_info, &ctx->mount_opt, fc->sb_flags)) 1512 1502 return -EINVAL; 1513 1503 1514 1504 ret = btrfs_check_features(fs_info, !(fc->sb_flags & SB_RDONLY));