Re: [PATCH] btrfs: free unlinked replace target on initialization failure
Qu Wenruo <[email protected]>
| Newsgroups | org.kernel.vger.linux-btrfs,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
在 2026/8/8 14:12, Guanghui Yang 写道: > btrfs_init_dev_replace_tgtdev() allocates the replacement target before > looking up its dev_t and initializing its zoned device information. If > either lookup_bdev() or btrfs_get_dev_zone_info() fails, the device has > not been linked into fs_devices->devices yet, but the error path only > drops the block device file reference. > > Free the allocated device on this error path to release its name, > allocation state, zone info, and the device itself. > > Signed-off-by: Guanghui Yang <[email protected]> I have a very strong feeling that you're using LLM hunting down bugs. In that case, be responsible and disclose the usage of LLM. > --- > fs/btrfs/dev-replace.c | 4 ++++ > fs/btrfs/volumes.c | 2 +- > fs/btrfs/volumes.h | 1 + > 3 files changed, 6 insertions(+), 1 deletion(-) > > diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c > index 318ddb790..3c17481c9 100644 > --- a/fs/btrfs/dev-replace.c > +++ b/fs/btrfs/dev-replace.c > @@ -240,6 +240,7 @@ static int btrfs_init_dev_replace_tgtdev(struct btrfs_fs_info *fs_info, > struct block_device *bdev; > u64 devid = BTRFS_DEV_REPLACE_DEVID; > int ret = 0; > + bool device_allocated = false; You can just initialize @device to NULL, and use that pointer to determine if the device is properly allocated. > > *device_out = NULL; > if (srcdev->fs_devices->seeding) { > @@ -287,6 +288,7 @@ static int btrfs_init_dev_replace_tgtdev(struct btrfs_fs_info *fs_info, > ret = PTR_ERR(device); > goto error; > } > + device_allocated = true; > > ret = lookup_bdev(device_path, &device->devt); > if (ret) > @@ -327,6 +329,8 @@ static int btrfs_init_dev_replace_tgtdev(struct btrfs_fs_info *fs_info, > return 0; > > error: > + if (device_allocated) > + btrfs_free_device(device); > bdev_fput(bdev_file); > return ret; > } > diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c > index a8e27db8e..c479f268a 100644 > --- a/fs/btrfs/volumes.c > +++ b/fs/btrfs/volumes.c > @@ -402,7 +402,7 @@ static struct btrfs_fs_devices *alloc_fs_devices(const u8 *fsid) > return fs_devs; > } > > -static void btrfs_free_device(struct btrfs_device *device) > +void btrfs_free_device(struct btrfs_device *device) > { > WARN_ON(!list_empty(&device->post_commit_list)); > /* > diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h > index eaf23c0dc..ecab3ce3c 100644 > --- a/fs/btrfs/volumes.h > +++ b/fs/btrfs/volumes.h > @@ -795,6 +795,7 @@ int btrfs_run_dev_stats(struct btrfs_trans_handle *trans); > void btrfs_rm_dev_replace_remove_srcdev(struct btrfs_device *srcdev); > void btrfs_rm_dev_replace_free_srcdev(struct btrfs_device *srcdev); > void btrfs_destroy_dev_replace_tgtdev(struct btrfs_device *tgtdev); > +void btrfs_free_device(struct btrfs_device *device); > unsigned long btrfs_full_stripe_len(struct btrfs_fs_info *fs_info, > u64 logical); > u64 btrfs_calc_stripe_length(const struct btrfs_chunk_map *map);