lkml.org 
[lkml]   [2022]   [Sep]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
SubjectRe: [PATCH v14 13/13] dm: add power-of-2 target for zoned devices with non power-of-2 zone sizes
From
>> +/*
>> + * This target works on the complete zoned device. Partial mapping is not
>> + * supported.
>> + * Construct a zoned po2 logical device: <dev-path>
>> + */
>> +static int dm_po2z_ctr(struct dm_target *ti, unsigned int argc, char **argv)
>> +{
>> + struct dm_po2z_target *dmh = NULL;
>> + int ret;
>> + sector_t zone_size;
>> + sector_t dev_capacity;
>> +
>> + if (argc != 1)
>> + return -EINVAL;
>> +
>> + dmh = kmalloc(sizeof(*dmh), GFP_KERNEL);
>> + if (!dmh)
>> + return -ENOMEM;
>> +
>> + ret = dm_get_device(ti, argv[0], dm_table_get_mode(ti->table),
>> + &dmh->dev);
>> + if (ret) {
>> + ti->error = "Device lookup failed";
>> + goto bad;
>> + }
>> +
>> + if (!bdev_is_zoned(dmh->dev->bdev)) {
>> + DMERR("%pg is not a zoned device", dmh->dev->bdev);
>> + ret = -EINVAL;
>> + goto bad;
>> + }
>> +
>> + zone_size = bdev_zone_sectors(dmh->dev->bdev);
>> + dev_capacity = get_capacity(dmh->dev->bdev->bd_disk);
>> + if (ti->len != dev_capacity) {
>> + DMERR("%pg Partial mapping of the target is not supported",
>> + dmh->dev->bdev);
>> + ret = -EINVAL;
>> + goto bad;
>> + }
>> +
>> + if (is_power_of_2(zone_size))
>> + DMWARN("%pg: underlying device has a power-of-2 number of sectors per zone",
>> + dmh->dev->bdev);
>> +
>> + dmh->zone_size = zone_size;
>> + dmh->zone_size_po2 = 1 << get_count_order_long(zone_size);
>> + dmh->zone_size_po2_shift = ilog2(dmh->zone_size_po2);
>> + dmh->zone_size_diff = dmh->zone_size_po2 - dmh->zone_size;
>> + ti->private = dmh;
>> + ti->max_io_len = dmh->zone_size_po2;
>> + dmh->nr_zones = npo2_zone_no(dmh, ti->len);
>> + ti->len = dmh->zone_size_po2 * dmh->nr_zones;
>> + return 0;
>> +
>> +bad:
>> + kfree(dmh);
>> + return ret;
>> +}
>
> This error handling still isn't correct. You're using
> dm_get_device(). If you return early due to error, _after_
> dm_get_device(), you need to dm_put_device().
>
> Basically you need a new label above "bad:" that calls dm_put_device()
> then falls through to "bad:". Or you need to explcitly call
> dm_put_device() before "goto bad;" in the if (ti->len != dev_capacity)
> error branch.
>

Ah. I naively assumed dtr will be called to cleanup but not in this case as
the ctr itself fails.

I will add an extra label on top of `bad` and use it for errors that
happens after `dm_get_device`. Thanks for pointing it out Mike.

\
 
 \ /
  Last update: 2022-09-21 19:34    [W:0.055 / U:22.940 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site