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: Stefan Haberland <sth@linux.ibm.com> Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com> Link: https://lore.kernel.org/r/20220920192616.808070-6-sth@linux.ibm.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Родитель
413862caad
Коммит
112ff512fc
|
@ -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 {
|
||||||
#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 @@ out_err:
|
||||||
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,
|
||||||
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;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче