>> +/* >> + * 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. -- dm-devel mailing list dm-devel@xxxxxxxxxx https://listman.redhat.com/mailman/listinfo/dm-devel