Skip to content

Commit

Permalink
Merge tag 'for-6.15-rc5-tag' of git://git.kernel.org/pub/scm/linux/ke…
Browse files Browse the repository at this point in the history
…rnel/git/kdave/linux

Pull btrfs fixes from David Sterba:

 - revert device path canonicalization, this does not work as intended
   with namespaces and is not reliable in all setups

 - fix crash in scrub when checksum tree is not valid, e.g. when mounted
   with rescue=ignoredatacsums

 - fix crash when tracepoint btrfs_prelim_ref_insert is enabled

 - other minor fixups:
     - open code folio_index(), meant to be used in MM code
     - use matching type for sizeof in compression allocation

* tag 'for-6.15-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: open code folio_index() in btree_clear_folio_dirty_tag()
  Revert "btrfs: canonicalize the device path before adding it"
  btrfs: avoid NULL pointer dereference if no valid csum tree
  btrfs: handle empty eb->folios in num_extent_folios()
  btrfs: correct the order of prelim_ref arguments in btrfs__prelim_ref
  btrfs: compression: adjust cb->compressed_folios allocation type
  • Loading branch information
Linus Torvalds committed May 6, 2025
2 parents cccd033 + 38e5410 commit 0d8d44d
Show file tree
Hide file tree
Showing 6 changed files with 9 additions and 96 deletions.
2 changes: 1 addition & 1 deletion fs/btrfs/compression.c
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ void btrfs_submit_compressed_read(struct btrfs_bio *bbio)
free_extent_map(em);

cb->nr_folios = DIV_ROUND_UP(compressed_len, PAGE_SIZE);
cb->compressed_folios = kcalloc(cb->nr_folios, sizeof(struct page *), GFP_NOFS);
cb->compressed_folios = kcalloc(cb->nr_folios, sizeof(struct folio *), GFP_NOFS);
if (!cb->compressed_folios) {
ret = BLK_STS_RESOURCE;
goto out_free_bio;
Expand Down
4 changes: 2 additions & 2 deletions fs/btrfs/extent_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -3508,8 +3508,8 @@ static void btree_clear_folio_dirty_tag(struct folio *folio)
ASSERT(folio_test_locked(folio));
xa_lock_irq(&folio->mapping->i_pages);
if (!folio_test_dirty(folio))
__xa_clear_mark(&folio->mapping->i_pages,
folio_index(folio), PAGECACHE_TAG_DIRTY);
__xa_clear_mark(&folio->mapping->i_pages, folio->index,
PAGECACHE_TAG_DIRTY);
xa_unlock_irq(&folio->mapping->i_pages);
}

Expand Down
2 changes: 2 additions & 0 deletions fs/btrfs/extent_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,8 @@ static inline int __pure num_extent_pages(const struct extent_buffer *eb)
*/
static inline int __pure num_extent_folios(const struct extent_buffer *eb)
{
if (!eb->folios[0])
return 0;
if (folio_order(eb->folios[0]))
return 1;
return num_extent_pages(eb);
Expand Down
4 changes: 2 additions & 2 deletions fs/btrfs/scrub.c
Original file line number Diff line number Diff line change
Expand Up @@ -1541,8 +1541,8 @@ static int scrub_find_fill_first_stripe(struct btrfs_block_group *bg,
u64 extent_gen;
int ret;

if (unlikely(!extent_root)) {
btrfs_err(fs_info, "no valid extent root for scrub");
if (unlikely(!extent_root || !csum_root)) {
btrfs_err(fs_info, "no valid extent or csum root for scrub");
return -EUCLEAN;
}
memset(stripe->sectors, 0, sizeof(struct scrub_sector_verification) *
Expand Down
91 changes: 1 addition & 90 deletions fs/btrfs/volumes.c
Original file line number Diff line number Diff line change
Expand Up @@ -733,82 +733,6 @@ const u8 *btrfs_sb_fsid_ptr(const struct btrfs_super_block *sb)
return has_metadata_uuid ? sb->metadata_uuid : sb->fsid;
}

/*
* We can have very weird soft links passed in.
* One example is "/proc/self/fd/<fd>", which can be a soft link to
* a block device.
*
* But it's never a good idea to use those weird names.
* Here we check if the path (not following symlinks) is a good one inside
* "/dev/".
*/
static bool is_good_dev_path(const char *dev_path)
{
struct path path = { .mnt = NULL, .dentry = NULL };
char *path_buf = NULL;
char *resolved_path;
bool is_good = false;
int ret;

if (!dev_path)
goto out;

path_buf = kmalloc(PATH_MAX, GFP_KERNEL);
if (!path_buf)
goto out;

/*
* Do not follow soft link, just check if the original path is inside
* "/dev/".
*/
ret = kern_path(dev_path, 0, &path);
if (ret)
goto out;
resolved_path = d_path(&path, path_buf, PATH_MAX);
if (IS_ERR(resolved_path))
goto out;
if (strncmp(resolved_path, "/dev/", strlen("/dev/")))
goto out;
is_good = true;
out:
kfree(path_buf);
path_put(&path);
return is_good;
}

static int get_canonical_dev_path(const char *dev_path, char *canonical)
{
struct path path = { .mnt = NULL, .dentry = NULL };
char *path_buf = NULL;
char *resolved_path;
int ret;

if (!dev_path) {
ret = -EINVAL;
goto out;
}

path_buf = kmalloc(PATH_MAX, GFP_KERNEL);
if (!path_buf) {
ret = -ENOMEM;
goto out;
}

ret = kern_path(dev_path, LOOKUP_FOLLOW, &path);
if (ret)
goto out;
resolved_path = d_path(&path, path_buf, PATH_MAX);
if (IS_ERR(resolved_path)) {
ret = PTR_ERR(resolved_path);
goto out;
}
ret = strscpy(canonical, resolved_path, PATH_MAX);
out:
kfree(path_buf);
path_put(&path);
return ret;
}

static bool is_same_device(struct btrfs_device *device, const char *new_path)
{
struct path old = { .mnt = NULL, .dentry = NULL };
Expand Down Expand Up @@ -1513,23 +1437,12 @@ struct btrfs_device *btrfs_scan_one_device(const char *path, blk_mode_t flags,
bool new_device_added = false;
struct btrfs_device *device = NULL;
struct file *bdev_file;
char *canonical_path = NULL;
u64 bytenr;
dev_t devt;
int ret;

lockdep_assert_held(&uuid_mutex);

if (!is_good_dev_path(path)) {
canonical_path = kmalloc(PATH_MAX, GFP_KERNEL);
if (canonical_path) {
ret = get_canonical_dev_path(path, canonical_path);
if (ret < 0) {
kfree(canonical_path);
canonical_path = NULL;
}
}
}
/*
* Avoid an exclusive open here, as the systemd-udev may initiate the
* device scan which may race with the user's mount or mkfs command,
Expand Down Expand Up @@ -1574,8 +1487,7 @@ struct btrfs_device *btrfs_scan_one_device(const char *path, blk_mode_t flags,
goto free_disk_super;
}

device = device_list_add(canonical_path ? : path, disk_super,
&new_device_added);
device = device_list_add(path, disk_super, &new_device_added);
if (!IS_ERR(device) && new_device_added)
btrfs_free_stale_devices(device->devt, device);

Expand All @@ -1584,7 +1496,6 @@ struct btrfs_device *btrfs_scan_one_device(const char *path, blk_mode_t flags,

error_bdev_put:
fput(bdev_file);
kfree(canonical_path);

return device;
}
Expand Down
2 changes: 1 addition & 1 deletion include/trace/events/btrfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1928,7 +1928,7 @@ DECLARE_EVENT_CLASS(btrfs__prelim_ref,
TP_PROTO(const struct btrfs_fs_info *fs_info,
const struct prelim_ref *oldref,
const struct prelim_ref *newref, u64 tree_size),
TP_ARGS(fs_info, newref, oldref, tree_size),
TP_ARGS(fs_info, oldref, newref, tree_size),

TP_STRUCT__entry_btrfs(
__field( u64, root_id )
Expand Down

0 comments on commit 0d8d44d

Please sign in to comment.