linux-user: Convert blkpg to use a special subop handler
The blkpg ioctl can take different payloads depending on the opcode in its payload structure. Create a new special ioctl handler that can only deal with partition style ones for now. This patch fixes running parted for me. Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
This commit is contained in:
parent
40645c7bfd
commit
a59b5e35d1
|
@ -78,7 +78,8 @@
|
||||||
IOCTL(BLKRAGET, IOC_R, MK_PTR(TYPE_LONG))
|
IOCTL(BLKRAGET, IOC_R, MK_PTR(TYPE_LONG))
|
||||||
IOCTL(BLKSSZGET, IOC_R, MK_PTR(TYPE_LONG))
|
IOCTL(BLKSSZGET, IOC_R, MK_PTR(TYPE_LONG))
|
||||||
IOCTL(BLKBSZGET, IOC_R, MK_PTR(TYPE_INT))
|
IOCTL(BLKBSZGET, IOC_R, MK_PTR(TYPE_INT))
|
||||||
IOCTL(BLKPG, IOC_W, MK_PTR(MK_STRUCT(STRUCT_blkpg_ioctl_arg)))
|
IOCTL_SPECIAL(BLKPG, IOC_W, do_ioctl_blkpg,
|
||||||
|
MK_PTR(MK_STRUCT(STRUCT_blkpg_ioctl_arg)))
|
||||||
#ifdef FIBMAP
|
#ifdef FIBMAP
|
||||||
IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_LONG))
|
IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_LONG))
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3696,6 +3696,59 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static abi_long do_ioctl_blkpg(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
|
||||||
|
abi_long cmd, abi_long arg)
|
||||||
|
{
|
||||||
|
void *argptr;
|
||||||
|
int target_size;
|
||||||
|
const argtype *arg_type = ie->arg_type;
|
||||||
|
const argtype part_arg_type[] = { MK_STRUCT(STRUCT_blkpg_partition) };
|
||||||
|
abi_long ret;
|
||||||
|
|
||||||
|
struct blkpg_ioctl_arg *host_blkpg = (void*)buf_temp;
|
||||||
|
struct blkpg_partition host_part;
|
||||||
|
|
||||||
|
/* Read and convert blkpg */
|
||||||
|
arg_type++;
|
||||||
|
target_size = thunk_type_size(arg_type, 0);
|
||||||
|
argptr = lock_user(VERIFY_READ, arg, target_size, 1);
|
||||||
|
if (!argptr) {
|
||||||
|
ret = -TARGET_EFAULT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
|
||||||
|
unlock_user(argptr, arg, 0);
|
||||||
|
|
||||||
|
switch (host_blkpg->op) {
|
||||||
|
case BLKPG_ADD_PARTITION:
|
||||||
|
case BLKPG_DEL_PARTITION:
|
||||||
|
/* payload is struct blkpg_partition */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Unknown opcode */
|
||||||
|
ret = -TARGET_EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read and convert blkpg->data */
|
||||||
|
arg = (abi_long)(uintptr_t)host_blkpg->data;
|
||||||
|
target_size = thunk_type_size(part_arg_type, 0);
|
||||||
|
argptr = lock_user(VERIFY_READ, arg, target_size, 1);
|
||||||
|
if (!argptr) {
|
||||||
|
ret = -TARGET_EFAULT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
thunk_convert(&host_part, argptr, part_arg_type, THUNK_HOST);
|
||||||
|
unlock_user(argptr, arg, 0);
|
||||||
|
|
||||||
|
/* Swizzle the data pointer to our local copy and call! */
|
||||||
|
host_blkpg->data = &host_part;
|
||||||
|
ret = get_errno(ioctl(fd, ie->host_cmd, host_blkpg));
|
||||||
|
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp,
|
static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp,
|
||||||
int fd, abi_long cmd, abi_long arg)
|
int fd, abi_long cmd, abi_long arg)
|
||||||
{
|
{
|
||||||
|
|
|
@ -252,4 +252,4 @@ STRUCT(blkpg_ioctl_arg,
|
||||||
TYPE_INT, /* op */
|
TYPE_INT, /* op */
|
||||||
TYPE_INT, /* flags */
|
TYPE_INT, /* flags */
|
||||||
TYPE_INT, /* datalen */
|
TYPE_INT, /* datalen */
|
||||||
MK_PTR(MK_STRUCT(STRUCT_blkpg_partition))) /* data */
|
TYPE_PTRVOID) /* data */
|
||||||
|
|
Loading…
Reference in New Issue