Commit 112ff512 authored by Stefan Haberland's avatar Stefan Haberland Committed by Jens Axboe

s390/dasd: add ioctl to perform a swap of the drivers copy pair

The newly defined ioctl BIODASDCOPYPAIRSWAP takes a structure that
specifies a copy pair that should be swapped. It will call the device
discipline function to perform the swap operation.

The structure looks as followed:

struct dasd_copypair_swap_data_t {
       char primary[20];
       char secondary[20];
       __u8 reserved[64];
};

where primary is the old primary device that will be replaced by the
secondary device. The old primary will become a secondary device
afterwards.
Signed-off-by: default avatarStefan Haberland <sth@linux.ibm.com>
Reviewed-by: default avatarJan Hoeppner <hoeppner@linux.ibm.com>
Link: https://lore.kernel.org/r/20220920192616.808070-6-sth@linux.ibm.comSigned-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 413862ca
...@@ -182,6 +182,18 @@ typedef struct format_data_t { ...@@ -182,6 +182,18 @@ typedef struct format_data_t {
unsigned int intensity; unsigned int intensity;
} format_data_t; } format_data_t;
/*
* struct dasd_copypair_swap_data_t
* represents all data necessary to issue a swap of the copy pair relation
*/
struct dasd_copypair_swap_data_t {
char primary[20]; /* BUSID of primary */
char secondary[20]; /* BUSID of secondary */
/* Reserved for future updates. */
__u8 reserved[64];
};
/* /*
* values to be used for format_data_t.intensity * values to be used for format_data_t.intensity
* 0/8: normal format * 0/8: normal format
...@@ -326,6 +338,8 @@ struct dasd_snid_ioctl_data { ...@@ -326,6 +338,8 @@ struct dasd_snid_ioctl_data {
#define BIODASDSATTR _IOW(DASD_IOCTL_LETTER,2,attrib_data_t) #define BIODASDSATTR _IOW(DASD_IOCTL_LETTER,2,attrib_data_t)
/* Release Allocated Space */ /* Release Allocated Space */
#define BIODASDRAS _IOW(DASD_IOCTL_LETTER, 3, format_data_t) #define BIODASDRAS _IOW(DASD_IOCTL_LETTER, 3, format_data_t)
/* Swap copy pair relation */
#define BIODASDCOPYPAIRSWAP _IOW(DASD_IOCTL_LETTER, 4, struct dasd_copypair_swap_data_t)
/* Get Sense Path Group ID (SNID) data */ /* Get Sense Path Group ID (SNID) data */
#define BIODASDSNID _IOWR(DASD_IOCTL_LETTER, 1, struct dasd_snid_ioctl_data) #define BIODASDSNID _IOWR(DASD_IOCTL_LETTER, 1, struct dasd_snid_ioctl_data)
......
...@@ -379,6 +379,56 @@ static int dasd_ioctl_release_space(struct block_device *bdev, void __user *argp ...@@ -379,6 +379,56 @@ static int dasd_ioctl_release_space(struct block_device *bdev, void __user *argp
return rc; return rc;
} }
/*
* Swap driver iternal copy relation.
*/
static int
dasd_ioctl_copy_pair_swap(struct block_device *bdev, void __user *argp)
{
struct dasd_copypair_swap_data_t data;
struct dasd_device *device;
int rc;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
device = dasd_device_from_gendisk(bdev->bd_disk);
if (!device)
return -ENODEV;
if (copy_from_user(&data, argp, sizeof(struct dasd_copypair_swap_data_t))) {
dasd_put_device(device);
return -EFAULT;
}
if (memchr_inv(data.reserved, 0, sizeof(data.reserved))) {
pr_warn("%s: Ivalid swap data specified.\n",
dev_name(&device->cdev->dev));
dasd_put_device(device);
return DASD_COPYPAIRSWAP_INVALID;
}
if (bdev_is_partition(bdev)) {
pr_warn("%s: The specified DASD is a partition and cannot be swapped\n",
dev_name(&device->cdev->dev));
dasd_put_device(device);
return DASD_COPYPAIRSWAP_INVALID;
}
if (!device->copy) {
pr_warn("%s: The specified DASD has no copy pair set up\n",
dev_name(&device->cdev->dev));
dasd_put_device(device);
return -ENODEV;
}
if (!device->discipline->copy_pair_swap) {
dasd_put_device(device);
return -EOPNOTSUPP;
}
rc = device->discipline->copy_pair_swap(device, data.primary,
data.secondary);
dasd_put_device(device);
return rc;
}
#ifdef CONFIG_DASD_PROFILE #ifdef CONFIG_DASD_PROFILE
/* /*
* Reset device profile information * Reset device profile information
...@@ -637,6 +687,9 @@ int dasd_ioctl(struct block_device *bdev, fmode_t mode, ...@@ -637,6 +687,9 @@ int dasd_ioctl(struct block_device *bdev, fmode_t mode,
case BIODASDRAS: case BIODASDRAS:
rc = dasd_ioctl_release_space(bdev, argp); rc = dasd_ioctl_release_space(bdev, argp);
break; break;
case BIODASDCOPYPAIRSWAP:
rc = dasd_ioctl_copy_pair_swap(bdev, argp);
break;
default: default:
/* if the discipline has an ioctl method try it. */ /* if the discipline has an ioctl method try it. */
rc = -ENOTTY; rc = -ENOTTY;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment