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(BLKSSZGET, IOC_R, MK_PTR(TYPE_LONG))
|
||||
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
|
||||
IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_LONG))
|
||||
#endif
|
||||
|
@ -3696,6 +3696,59 @@ out:
|
||||
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,
|
||||
int fd, abi_long cmd, abi_long arg)
|
||||
{
|
||||
|
@ -252,4 +252,4 @@ STRUCT(blkpg_ioctl_arg,
|
||||
TYPE_INT, /* op */
|
||||
TYPE_INT, /* flags */
|
||||
TYPE_INT, /* datalen */
|
||||
MK_PTR(MK_STRUCT(STRUCT_blkpg_partition))) /* data */
|
||||
TYPE_PTRVOID) /* data */
|
||||
|
Loading…
x
Reference in New Issue
Block a user