]> Git Repo - linux.git/commitdiff
Merge tag 'for-6.8-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
authorLinus Torvalds <[email protected]>
Wed, 14 Feb 2024 23:47:02 +0000 (15:47 -0800)
committerLinus Torvalds <[email protected]>
Wed, 14 Feb 2024 23:47:02 +0000 (15:47 -0800)
Pull btrfs fixes from David Sterba:
 "A few regular fixes and one fix for space reservation regression since
  6.7 that users have been reporting:

   - fix over-reservation of metadata chunks due to not keeping proper
     balance between global block reserve and delayed refs reserve; in
     practice this leaves behind empty metadata block groups, the
     workaround is to reclaim them by using the '-musage=1' balance
     filter

   - other space reservation fixes:
      - do not delete unused block group if it may be used soon
      - do not reserve space for checksums for NOCOW files

   - fix extent map assertion failure when writing out free space inode

   - reject encoded write if inode has nodatasum flag set

   - fix chunk map leak when loading block group zone info"

* tag 'for-6.8-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: don't refill whole delayed refs block reserve when starting transaction
  btrfs: zoned: fix chunk map leak when loading block group zone info
  btrfs: reject encoded write if inode has nodatasum flag set
  btrfs: don't reserve space for checksums when writing to nocow files
  btrfs: add new unused block groups to the list of unused block groups
  btrfs: do not delete unused block group if it may be used soon
  btrfs: add and use helper to check if block group is used
  btrfs: don't drop extent_map for free space inode on write error

1  2 
fs/btrfs/inode.c
fs/btrfs/zoned.c

diff --combined fs/btrfs/inode.c
index 1eb93d3962aac4608cda0255ea31d7e53dbc8da2,5f39462dceb0bbb105e2542e64d49967997a6359..f88e0ca8331d9b5448e8e07c89e5e66395c782b3
                        unwritten_start += logical_len;
                clear_extent_uptodate(io_tree, unwritten_start, end, NULL);
  
-               /* Drop extent maps for the part of the extent we didn't write. */
-               btrfs_drop_extent_map_range(inode, unwritten_start, end, false);
+               /*
+                * Drop extent maps for the part of the extent we didn't write.
+                *
+                * We have an exception here for the free_space_inode, this is
+                * because when we do btrfs_get_extent() on the free space inode
+                * we will search the commit root.  If this is a new block group
+                * we won't find anything, and we will trip over the assert in
+                * writepage where we do ASSERT(em->block_start !=
+                * EXTENT_MAP_HOLE).
+                *
+                * Theoretically we could also skip this for any NOCOW extent as
+                * we don't mess with the extent map tree in the NOCOW case, but
+                * for now simply skip this if we are the free space inode.
+                */
+               if (!btrfs_is_free_space_inode(inode))
+                       btrfs_drop_extent_map_range(inode, unwritten_start,
+                                                   end, false);
  
                /*
                 * If the ordered extent had an IOERR or something else went
@@@ -10273,6 -10288,13 +10288,13 @@@ ssize_t btrfs_do_encoded_write(struct k
        if (encoded->encryption != BTRFS_ENCODED_IO_ENCRYPTION_NONE)
                return -EINVAL;
  
+       /*
+        * Compressed extents should always have checksums, so error out if we
+        * have a NOCOW file or inode was created while mounted with NODATASUM.
+        */
+       if (inode->flags & BTRFS_INODE_NODATASUM)
+               return -EINVAL;
        orig_count = iov_iter_count(from);
  
        /* The extent size must be sane. */
@@@ -10977,7 -10999,7 +10999,7 @@@ static const struct address_space_opera
        .release_folio  = btrfs_release_folio,
        .migrate_folio  = btrfs_migrate_folio,
        .dirty_folio    = filemap_dirty_folio,
 -      .error_remove_page = generic_error_remove_page,
 +      .error_remove_folio = generic_error_remove_folio,
        .swap_activate  = btrfs_swap_activate,
        .swap_deactivate = btrfs_swap_deactivate,
  };
diff --combined fs/btrfs/zoned.c
index 168af9d000d168324fcc8355781517ddeedeefd1,afeb1dc1f43aed2162854faff0d3315ad37775ac..3a5d69ff25fc221f20c1e37a9854021eff246bad
@@@ -578,12 -578,26 +578,12 @@@ int btrfs_get_dev_zone_info(struct btrf
  
        kvfree(zones);
  
 -      switch (bdev_zoned_model(bdev)) {
 -      case BLK_ZONED_HM:
 +      if (bdev_is_zoned(bdev)) {
                model = "host-managed zoned";
                emulated = "";
 -              break;
 -      case BLK_ZONED_HA:
 -              model = "host-aware zoned";
 -              emulated = "";
 -              break;
 -      case BLK_ZONED_NONE:
 +      } else {
                model = "regular";
                emulated = "emulated ";
 -              break;
 -      default:
 -              /* Just in case */
 -              btrfs_err_in_rcu(fs_info, "zoned: unsupported model %d on %s",
 -                               bdev_zoned_model(bdev),
 -                               rcu_str_deref(device->name));
 -              ret = -EOPNOTSUPP;
 -              goto out_free_zone_info;
        }
  
        btrfs_info_in_rcu(fs_info,
  
  out:
        kvfree(zones);
 -out_free_zone_info:
        btrfs_destroy_dev_zone_info(device);
 -
        return ret;
  }
  
@@@ -672,7 -688,8 +672,7 @@@ static int btrfs_check_for_zoned_device
        struct btrfs_device *device;
  
        list_for_each_entry(device, &fs_info->fs_devices->devices, dev_list) {
 -              if (device->bdev &&
 -                  bdev_zoned_model(device->bdev) == BLK_ZONED_HM) {
 +              if (device->bdev && bdev_is_zoned(device->bdev)) {
                        btrfs_err(fs_info,
                                "zoned: mode not enabled but zoned device found: %pg",
                                device->bdev);
@@@ -1670,6 -1687,7 +1670,7 @@@ out
        }
        bitmap_free(active);
        kfree(zone_info);
+       btrfs_free_chunk_map(map);
  
        return ret;
  }
This page took 0.101747 seconds and 4 git commands to generate.