Skip to content

Commit 7015108

Browse files
mikechristieMike Snitzer
authored andcommitted
dm: Start pr_reserve from the same starting path
When an app does a pr_reserve it will go to whatever path we happen to be using at the time. This can result in errors when the app does a second pr_reserve call and expects success but gets a failure because the reserve is not done on the holder's path. This commit has us always start trying to do reserves from the first path in the first group. Windows failover clustering will produce the type of pattern above. With this commit, we will now pass its validation test for this case. Signed-off-by: Mike Christie <[email protected]> Signed-off-by: Mike Snitzer <[email protected]>
1 parent 8dd87f3 commit 7015108

File tree

1 file changed

+32
-14
lines changed

1 file changed

+32
-14
lines changed

drivers/md/dm.c

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3078,6 +3078,7 @@ struct dm_pr {
30783078
u32 flags;
30793079
bool fail_early;
30803080
int ret;
3081+
enum pr_type type;
30813082
};
30823083

30833084
static int dm_call_pr(struct block_device *bdev, iterate_devices_callout_fn fn,
@@ -3175,25 +3176,42 @@ static int dm_pr_register(struct block_device *bdev, u64 old_key, u64 new_key,
31753176
return ret;
31763177
}
31773178

3179+
3180+
static int __dm_pr_reserve(struct dm_target *ti, struct dm_dev *dev,
3181+
sector_t start, sector_t len, void *data)
3182+
{
3183+
struct dm_pr *pr = data;
3184+
const struct pr_ops *ops = dev->bdev->bd_disk->fops->pr_ops;
3185+
3186+
if (!ops || !ops->pr_reserve) {
3187+
pr->ret = -EOPNOTSUPP;
3188+
return -1;
3189+
}
3190+
3191+
pr->ret = ops->pr_reserve(dev->bdev, pr->old_key, pr->type, pr->flags);
3192+
if (!pr->ret)
3193+
return -1;
3194+
3195+
return 0;
3196+
}
3197+
31783198
static int dm_pr_reserve(struct block_device *bdev, u64 key, enum pr_type type,
31793199
u32 flags)
31803200
{
3181-
struct mapped_device *md = bdev->bd_disk->private_data;
3182-
const struct pr_ops *ops;
3183-
int r, srcu_idx;
3201+
struct dm_pr pr = {
3202+
.old_key = key,
3203+
.flags = flags,
3204+
.type = type,
3205+
.fail_early = false,
3206+
.ret = 0,
3207+
};
3208+
int ret;
31843209

3185-
r = dm_prepare_ioctl(md, &srcu_idx, &bdev);
3186-
if (r < 0)
3187-
goto out;
3210+
ret = dm_call_pr(bdev, __dm_pr_reserve, &pr);
3211+
if (ret)
3212+
return ret;
31883213

3189-
ops = bdev->bd_disk->fops->pr_ops;
3190-
if (ops && ops->pr_reserve)
3191-
r = ops->pr_reserve(bdev, key, type, flags);
3192-
else
3193-
r = -EOPNOTSUPP;
3194-
out:
3195-
dm_unprepare_ioctl(md, srcu_idx);
3196-
return r;
3214+
return pr.ret;
31973215
}
31983216

31993217
static int dm_pr_release(struct block_device *bdev, u64 key, enum pr_type type)

0 commit comments

Comments
 (0)