Skip to content

Commit 437429a

Browse files
committed
Merge branch 'for-7.1/block' into for-next
* for-7.1/block: block: fix zones_cond memory leak on zone revalidation error paths loop: fix partition scan race between udev and loop_reread_partitions() sed-opal: Add STACK_RESET command
2 parents cdd71b7 + 2a2f520 commit 437429a

6 files changed

Lines changed: 91 additions & 7 deletions

File tree

block/blk-zoned.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2016,6 +2016,7 @@ static int disk_revalidate_zone_resources(struct gendisk *disk,
20162016
{
20172017
struct queue_limits *lim = &disk->queue->limits;
20182018
unsigned int pool_size;
2019+
int ret = 0;
20192020

20202021
args->disk = disk;
20212022
args->nr_zones =
@@ -2038,10 +2039,13 @@ static int disk_revalidate_zone_resources(struct gendisk *disk,
20382039
pool_size =
20392040
min(BLK_ZONE_WPLUG_DEFAULT_POOL_SIZE, args->nr_zones);
20402041

2041-
if (!disk->zone_wplugs_hash)
2042-
return disk_alloc_zone_resources(disk, pool_size);
2042+
if (!disk->zone_wplugs_hash) {
2043+
ret = disk_alloc_zone_resources(disk, pool_size);
2044+
if (ret)
2045+
kfree(args->zones_cond);
2046+
}
20432047

2044-
return 0;
2048+
return ret;
20452049
}
20462050

20472051
/*
@@ -2073,6 +2077,7 @@ static int disk_update_zone_resources(struct gendisk *disk,
20732077
disk->zone_capacity = args->zone_capacity;
20742078
disk->last_zone_capacity = args->last_zone_capacity;
20752079
disk_set_zones_cond_array(disk, args->zones_cond);
2080+
args->zones_cond = NULL;
20762081

20772082
/*
20782083
* Some devices can advertise zone resource limits that are larger than
@@ -2353,21 +2358,30 @@ int blk_revalidate_disk_zones(struct gendisk *disk)
23532358
}
23542359
memalloc_noio_restore(noio_flag);
23552360

2361+
if (ret <= 0)
2362+
goto free_resources;
2363+
23562364
/*
23572365
* If zones where reported, make sure that the entire disk capacity
23582366
* has been checked.
23592367
*/
2360-
if (ret > 0 && args.sector != capacity) {
2368+
if (args.sector != capacity) {
23612369
pr_warn("%s: Missing zones from sector %llu\n",
23622370
disk->disk_name, args.sector);
23632371
ret = -ENODEV;
2372+
goto free_resources;
23642373
}
23652374

2366-
if (ret > 0)
2367-
return disk_update_zone_resources(disk, &args);
2375+
ret = disk_update_zone_resources(disk, &args);
2376+
if (ret)
2377+
goto free_resources;
2378+
2379+
return 0;
23682380

2381+
free_resources:
23692382
pr_warn("%s: failed to revalidate zones\n", disk->disk_name);
23702383

2384+
kfree(args.zones_cond);
23712385
memflags = blk_mq_freeze_queue(q);
23722386
disk_free_zone_resources(disk);
23732387
blk_mq_unfreeze_queue(q, memflags);

block/disk-events.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,13 +290,14 @@ EXPORT_SYMBOL(disk_check_media_change);
290290
* Should be called when the media changes for @disk. Generates a uevent
291291
* and attempts to free all dentries and inodes and invalidates all block
292292
* device page cache entries in that case.
293+
*
294+
* Callers that need a partition re-scan should arrange for one explicitly.
293295
*/
294296
void disk_force_media_change(struct gendisk *disk)
295297
{
296298
disk_event_uevent(disk, DISK_EVENT_MEDIA_CHANGE);
297299
inc_diskseq(disk);
298300
bdev_mark_dead(disk->part0, true);
299-
set_bit(GD_NEED_PART_SCAN, &disk->state);
300301
}
301302
EXPORT_SYMBOL_GPL(disk_force_media_change);
302303

block/opal_proto.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
enum {
2020
TCG_SECP_00 = 0,
2121
TCG_SECP_01,
22+
TCG_SECP_02,
2223
};
2324

2425
/*
@@ -273,6 +274,25 @@ struct opal_header {
273274
struct opal_data_subpacket subpkt;
274275
};
275276

277+
/*
278+
* TCG_Storage_Architecture_Core_Spec_v2.01_r1.00
279+
* Section: 3.3.4.7.5 STACK_RESET
280+
*/
281+
#define OPAL_STACK_RESET 0x0002
282+
283+
struct opal_stack_reset {
284+
u8 extendedComID[4];
285+
__be32 request_code;
286+
};
287+
288+
struct opal_stack_reset_response {
289+
u8 extendedComID[4];
290+
__be32 request_code;
291+
u8 reserved0[2];
292+
__be16 data_length;
293+
__be32 response;
294+
};
295+
276296
#define FC_TPER 0x0001
277297
#define FC_LOCKING 0x0002
278298
#define FC_GEOMETRY 0x0003

block/sed-opal.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3545,6 +3545,50 @@ static int opal_get_sum_ranges(struct opal_dev *dev, struct opal_sum_ranges *opa
35453545
return ret;
35463546
}
35473547

3548+
static int opal_stack_reset(struct opal_dev *dev)
3549+
{
3550+
struct opal_stack_reset *req;
3551+
struct opal_stack_reset_response *resp;
3552+
int ret;
3553+
3554+
mutex_lock(&dev->dev_lock);
3555+
3556+
memset(dev->cmd, 0, IO_BUFFER_LENGTH);
3557+
req = (struct opal_stack_reset *)dev->cmd;
3558+
req->extendedComID[0] = dev->comid >> 8;
3559+
req->extendedComID[1] = dev->comid & 0xFF;
3560+
req->request_code = cpu_to_be32(OPAL_STACK_RESET);
3561+
3562+
ret = dev->send_recv(dev->data, dev->comid, TCG_SECP_02,
3563+
dev->cmd, IO_BUFFER_LENGTH, true);
3564+
if (ret) {
3565+
pr_debug("Error sending stack reset: %d\n", ret);
3566+
goto out;
3567+
}
3568+
3569+
memset(dev->resp, 0, IO_BUFFER_LENGTH);
3570+
ret = dev->send_recv(dev->data, dev->comid, TCG_SECP_02,
3571+
dev->resp, IO_BUFFER_LENGTH, false);
3572+
if (ret) {
3573+
pr_debug("Error receiving stack reset response: %d\n", ret);
3574+
goto out;
3575+
}
3576+
3577+
resp = (struct opal_stack_reset_response *)dev->resp;
3578+
if (be16_to_cpu(resp->data_length) != 4) {
3579+
pr_debug("Stack reset pending\n");
3580+
ret = -EBUSY;
3581+
goto out;
3582+
}
3583+
if (be32_to_cpu(resp->response) != 0) {
3584+
pr_debug("Stack reset failed: %u\n", be32_to_cpu(resp->response));
3585+
ret = -EIO;
3586+
}
3587+
out:
3588+
mutex_unlock(&dev->dev_lock);
3589+
return ret;
3590+
}
3591+
35483592
int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg)
35493593
{
35503594
void *p;
@@ -3642,6 +3686,9 @@ int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg)
36423686
case IOC_OPAL_GET_SUM_STATUS:
36433687
ret = opal_get_sum_ranges(dev, p, arg);
36443688
break;
3689+
case IOC_OPAL_STACK_RESET:
3690+
ret = opal_stack_reset(dev);
3691+
break;
36453692

36463693
default:
36473694
break;

include/linux/sed-opal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ static inline bool is_sed_ioctl(unsigned int cmd)
5757
case IOC_OPAL_LR_SET_START_LEN:
5858
case IOC_OPAL_ENABLE_DISABLE_LR:
5959
case IOC_OPAL_GET_SUM_STATUS:
60+
case IOC_OPAL_STACK_RESET:
6061
return true;
6162
}
6263
return false;

include/uapi/linux/sed-opal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,5 +245,6 @@ struct opal_revert_lsp {
245245
#define IOC_OPAL_LR_SET_START_LEN _IOW('p', 243, struct opal_user_lr_setup)
246246
#define IOC_OPAL_ENABLE_DISABLE_LR _IOW('p', 244, struct opal_user_lr_setup)
247247
#define IOC_OPAL_GET_SUM_STATUS _IOW('p', 245, struct opal_sum_ranges)
248+
#define IOC_OPAL_STACK_RESET _IO('p', 246)
248249

249250
#endif /* _UAPI_SED_OPAL_H */

0 commit comments

Comments
 (0)