Skip to content

Commit 8dde208

Browse files
committed
Merge tag 'for-5.15-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: - fix max_inline mount option limit on 64k page system - lockdep fixes: - update bdev time in a safer way - move bdev put outside of sb write section when removing device - fix possible deadlock when mounting seed/sprout filesystem - zoned mode: fix split extent accounting - minor include fixup * tag 'for-5.15-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: zoned: fix double counting of split ordered extent btrfs: fix lockdep warning while mounting sprout fs btrfs: delay blkdev_put until after the device remove btrfs: update the bdev time directly when closing btrfs: use correct header for div_u64 in misc.h btrfs: fix upper limit for max_inline for page size 64K
2 parents ae79394 + f79645d commit 8dde208

File tree

6 files changed

+77
-47
lines changed

6 files changed

+77
-47
lines changed

fs/btrfs/disk-io.c

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3314,6 +3314,30 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
33143314
*/
33153315
fs_info->compress_type = BTRFS_COMPRESS_ZLIB;
33163316

3317+
/*
3318+
* Flag our filesystem as having big metadata blocks if they are bigger
3319+
* than the page size.
3320+
*/
3321+
if (btrfs_super_nodesize(disk_super) > PAGE_SIZE) {
3322+
if (!(features & BTRFS_FEATURE_INCOMPAT_BIG_METADATA))
3323+
btrfs_info(fs_info,
3324+
"flagging fs with big metadata feature");
3325+
features |= BTRFS_FEATURE_INCOMPAT_BIG_METADATA;
3326+
}
3327+
3328+
/* Set up fs_info before parsing mount options */
3329+
nodesize = btrfs_super_nodesize(disk_super);
3330+
sectorsize = btrfs_super_sectorsize(disk_super);
3331+
stripesize = sectorsize;
3332+
fs_info->dirty_metadata_batch = nodesize * (1 + ilog2(nr_cpu_ids));
3333+
fs_info->delalloc_batch = sectorsize * 512 * (1 + ilog2(nr_cpu_ids));
3334+
3335+
fs_info->nodesize = nodesize;
3336+
fs_info->sectorsize = sectorsize;
3337+
fs_info->sectorsize_bits = ilog2(sectorsize);
3338+
fs_info->csums_per_leaf = BTRFS_MAX_ITEM_SIZE(fs_info) / fs_info->csum_size;
3339+
fs_info->stripesize = stripesize;
3340+
33173341
ret = btrfs_parse_options(fs_info, options, sb->s_flags);
33183342
if (ret) {
33193343
err = ret;
@@ -3340,30 +3364,6 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
33403364
if (features & BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA)
33413365
btrfs_info(fs_info, "has skinny extents");
33423366

3343-
/*
3344-
* flag our filesystem as having big metadata blocks if
3345-
* they are bigger than the page size
3346-
*/
3347-
if (btrfs_super_nodesize(disk_super) > PAGE_SIZE) {
3348-
if (!(features & BTRFS_FEATURE_INCOMPAT_BIG_METADATA))
3349-
btrfs_info(fs_info,
3350-
"flagging fs with big metadata feature");
3351-
features |= BTRFS_FEATURE_INCOMPAT_BIG_METADATA;
3352-
}
3353-
3354-
nodesize = btrfs_super_nodesize(disk_super);
3355-
sectorsize = btrfs_super_sectorsize(disk_super);
3356-
stripesize = sectorsize;
3357-
fs_info->dirty_metadata_batch = nodesize * (1 + ilog2(nr_cpu_ids));
3358-
fs_info->delalloc_batch = sectorsize * 512 * (1 + ilog2(nr_cpu_ids));
3359-
3360-
/* Cache block sizes */
3361-
fs_info->nodesize = nodesize;
3362-
fs_info->sectorsize = sectorsize;
3363-
fs_info->sectorsize_bits = ilog2(sectorsize);
3364-
fs_info->csums_per_leaf = BTRFS_MAX_ITEM_SIZE(fs_info) / fs_info->csum_size;
3365-
fs_info->stripesize = stripesize;
3366-
33673367
/*
33683368
* mixed block groups end up with duplicate but slightly offset
33693369
* extent buffers for the same range. It leads to corruptions

fs/btrfs/ioctl.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3223,6 +3223,8 @@ static long btrfs_ioctl_rm_dev_v2(struct file *file, void __user *arg)
32233223
struct inode *inode = file_inode(file);
32243224
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
32253225
struct btrfs_ioctl_vol_args_v2 *vol_args;
3226+
struct block_device *bdev = NULL;
3227+
fmode_t mode;
32263228
int ret;
32273229
bool cancel = false;
32283230

@@ -3255,9 +3257,9 @@ static long btrfs_ioctl_rm_dev_v2(struct file *file, void __user *arg)
32553257
/* Exclusive operation is now claimed */
32563258

32573259
if (vol_args->flags & BTRFS_DEVICE_SPEC_BY_ID)
3258-
ret = btrfs_rm_device(fs_info, NULL, vol_args->devid);
3260+
ret = btrfs_rm_device(fs_info, NULL, vol_args->devid, &bdev, &mode);
32593261
else
3260-
ret = btrfs_rm_device(fs_info, vol_args->name, 0);
3262+
ret = btrfs_rm_device(fs_info, vol_args->name, 0, &bdev, &mode);
32613263

32623264
btrfs_exclop_finish(fs_info);
32633265

@@ -3273,6 +3275,8 @@ static long btrfs_ioctl_rm_dev_v2(struct file *file, void __user *arg)
32733275
kfree(vol_args);
32743276
err_drop:
32753277
mnt_drop_write_file(file);
3278+
if (bdev)
3279+
blkdev_put(bdev, mode);
32763280
return ret;
32773281
}
32783282

@@ -3281,6 +3285,8 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg)
32813285
struct inode *inode = file_inode(file);
32823286
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
32833287
struct btrfs_ioctl_vol_args *vol_args;
3288+
struct block_device *bdev = NULL;
3289+
fmode_t mode;
32843290
int ret;
32853291
bool cancel;
32863292

@@ -3302,7 +3308,7 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg)
33023308
ret = exclop_start_or_cancel_reloc(fs_info, BTRFS_EXCLOP_DEV_REMOVE,
33033309
cancel);
33043310
if (ret == 0) {
3305-
ret = btrfs_rm_device(fs_info, vol_args->name, 0);
3311+
ret = btrfs_rm_device(fs_info, vol_args->name, 0, &bdev, &mode);
33063312
if (!ret)
33073313
btrfs_info(fs_info, "disk deleted %s", vol_args->name);
33083314
btrfs_exclop_finish(fs_info);
@@ -3311,7 +3317,8 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg)
33113317
kfree(vol_args);
33123318
out_drop_write:
33133319
mnt_drop_write_file(file);
3314-
3320+
if (bdev)
3321+
blkdev_put(bdev, mode);
33153322
return ret;
33163323
}
33173324

fs/btrfs/misc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
#include <linux/sched.h>
77
#include <linux/wait.h>
8-
#include <asm/div64.h>
8+
#include <linux/math64.h>
99
#include <linux/rbtree.h>
1010

1111
#define in_range(b, first, len) ((b) >= (first) && (b) < (first) + (len))

fs/btrfs/ordered-data.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,6 +1049,7 @@ static int clone_ordered_extent(struct btrfs_ordered_extent *ordered, u64 pos,
10491049
u64 len)
10501050
{
10511051
struct inode *inode = ordered->inode;
1052+
struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info;
10521053
u64 file_offset = ordered->file_offset + pos;
10531054
u64 disk_bytenr = ordered->disk_bytenr + pos;
10541055
u64 num_bytes = len;
@@ -1066,6 +1067,13 @@ static int clone_ordered_extent(struct btrfs_ordered_extent *ordered, u64 pos,
10661067
else
10671068
type = __ffs(flags_masked);
10681069

1070+
/*
1071+
* The splitting extent is already counted and will be added again
1072+
* in btrfs_add_ordered_extent_*(). Subtract num_bytes to avoid
1073+
* double counting.
1074+
*/
1075+
percpu_counter_add_batch(&fs_info->ordered_bytes, -num_bytes,
1076+
fs_info->delalloc_batch);
10691077
if (test_bit(BTRFS_ORDERED_COMPRESSED, &ordered->flags)) {
10701078
WARN_ON_ONCE(1);
10711079
ret = btrfs_add_ordered_extent_compress(BTRFS_I(inode),

fs/btrfs/volumes.c

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,8 @@ static int btrfs_free_stale_devices(const char *path,
558558
struct btrfs_device *device, *tmp_device;
559559
int ret = 0;
560560

561+
lockdep_assert_held(&uuid_mutex);
562+
561563
if (path)
562564
ret = -ENOENT;
563565

@@ -988,11 +990,12 @@ static struct btrfs_fs_devices *clone_fs_devices(struct btrfs_fs_devices *orig)
988990
struct btrfs_device *orig_dev;
989991
int ret = 0;
990992

993+
lockdep_assert_held(&uuid_mutex);
994+
991995
fs_devices = alloc_fs_devices(orig->fsid, NULL);
992996
if (IS_ERR(fs_devices))
993997
return fs_devices;
994998

995-
mutex_lock(&orig->device_list_mutex);
996999
fs_devices->total_devices = orig->total_devices;
9971000

9981001
list_for_each_entry(orig_dev, &orig->devices, dev_list) {
@@ -1024,10 +1027,8 @@ static struct btrfs_fs_devices *clone_fs_devices(struct btrfs_fs_devices *orig)
10241027
device->fs_devices = fs_devices;
10251028
fs_devices->num_devices++;
10261029
}
1027-
mutex_unlock(&orig->device_list_mutex);
10281030
return fs_devices;
10291031
error:
1030-
mutex_unlock(&orig->device_list_mutex);
10311032
free_fs_devices(fs_devices);
10321033
return ERR_PTR(ret);
10331034
}
@@ -1869,15 +1870,17 @@ static int btrfs_add_dev_item(struct btrfs_trans_handle *trans,
18691870
* Function to update ctime/mtime for a given device path.
18701871
* Mainly used for ctime/mtime based probe like libblkid.
18711872
*/
1872-
static void update_dev_time(const char *path_name)
1873+
static void update_dev_time(struct block_device *bdev)
18731874
{
1874-
struct file *filp;
1875+
struct inode *inode = bdev->bd_inode;
1876+
struct timespec64 now;
18751877

1876-
filp = filp_open(path_name, O_RDWR, 0);
1877-
if (IS_ERR(filp))
1878+
/* Shouldn't happen but just in case. */
1879+
if (!inode)
18781880
return;
1879-
file_update_time(filp);
1880-
filp_close(filp, NULL);
1881+
1882+
now = current_time(inode);
1883+
generic_update_time(inode, &now, S_MTIME | S_CTIME);
18811884
}
18821885

18831886
static int btrfs_rm_dev_item(struct btrfs_device *device)
@@ -2053,11 +2056,11 @@ void btrfs_scratch_superblocks(struct btrfs_fs_info *fs_info,
20532056
btrfs_kobject_uevent(bdev, KOBJ_CHANGE);
20542057

20552058
/* Update ctime/mtime for device path for libblkid */
2056-
update_dev_time(device_path);
2059+
update_dev_time(bdev);
20572060
}
20582061

20592062
int btrfs_rm_device(struct btrfs_fs_info *fs_info, const char *device_path,
2060-
u64 devid)
2063+
u64 devid, struct block_device **bdev, fmode_t *mode)
20612064
{
20622065
struct btrfs_device *device;
20632066
struct btrfs_fs_devices *cur_devices;
@@ -2171,15 +2174,26 @@ int btrfs_rm_device(struct btrfs_fs_info *fs_info, const char *device_path,
21712174
mutex_unlock(&fs_devices->device_list_mutex);
21722175

21732176
/*
2174-
* at this point, the device is zero sized and detached from
2175-
* the devices list. All that's left is to zero out the old
2176-
* supers and free the device.
2177+
* At this point, the device is zero sized and detached from the
2178+
* devices list. All that's left is to zero out the old supers and
2179+
* free the device.
2180+
*
2181+
* We cannot call btrfs_close_bdev() here because we're holding the sb
2182+
* write lock, and blkdev_put() will pull in the ->open_mutex on the
2183+
* block device and it's dependencies. Instead just flush the device
2184+
* and let the caller do the final blkdev_put.
21772185
*/
2178-
if (test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state))
2186+
if (test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state)) {
21792187
btrfs_scratch_superblocks(fs_info, device->bdev,
21802188
device->name->str);
2189+
if (device->bdev) {
2190+
sync_blockdev(device->bdev);
2191+
invalidate_bdev(device->bdev);
2192+
}
2193+
}
21812194

2182-
btrfs_close_bdev(device);
2195+
*bdev = device->bdev;
2196+
*mode = device->mode;
21832197
synchronize_rcu();
21842198
btrfs_free_device(device);
21852199

@@ -2706,7 +2720,7 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path
27062720
btrfs_forget_devices(device_path);
27072721

27082722
/* Update ctime/mtime for blkid or udev */
2709-
update_dev_time(device_path);
2723+
update_dev_time(bdev);
27102724

27112725
return ret;
27122726

fs/btrfs/volumes.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,8 @@ struct btrfs_device *btrfs_alloc_device(struct btrfs_fs_info *fs_info,
472472
const u8 *uuid);
473473
void btrfs_free_device(struct btrfs_device *device);
474474
int btrfs_rm_device(struct btrfs_fs_info *fs_info,
475-
const char *device_path, u64 devid);
475+
const char *device_path, u64 devid,
476+
struct block_device **bdev, fmode_t *mode);
476477
void __exit btrfs_cleanup_fs_uuids(void);
477478
int btrfs_num_copies(struct btrfs_fs_info *fs_info, u64 logical, u64 len);
478479
int btrfs_grow_device(struct btrfs_trans_handle *trans,

0 commit comments

Comments
 (0)