2012-04-18 06:19:31 +04:00
/*
* Copyright ( c ) 2012 The Chromium OS Authors .
2018-04-05 04:40:00 +03:00
* Copyright ( c ) 2012 - 2018 The strace developers .
2012-04-18 06:19:31 +04:00
* Written by Mike Frysinger < vapier @ gentoo . org > .
*
2018-12-10 03:00:00 +03:00
* SPDX - License - Identifier : LGPL - 2.1 - or - later
2012-04-18 06:19:31 +04:00
*/
# include "defs.h"
2015-07-04 17:40:02 +03:00
# include <linux/ioctl.h>
2012-04-18 06:19:31 +04:00
# include <linux/loop.h>
2016-12-19 03:15:27 +03:00
typedef struct loop_info struct_loop_info ;
# include DEF_MPERS_TYPE(struct_loop_info)
# include MPERS_DEFS
2017-07-09 16:54:01 +03:00
# include "print_fields.h"
2018-10-26 03:03:40 +03:00
# define XLAT_MACROS_ONLY
2018-12-30 18:35:21 +03:00
# include "xlat/loop_cmds.h"
2018-10-26 03:03:40 +03:00
# undef XLAT_MACROS_ONLY
2014-04-26 03:30:54 +04:00
# include "xlat/loop_flags_options.h"
# include "xlat/loop_crypt_type_options.h"
2012-04-18 06:19:31 +04:00
2015-07-04 17:40:02 +03:00
static void
2016-12-26 13:26:03 +03:00
decode_loop_info ( struct tcb * const tcp , const kernel_ulong_t addr )
2012-04-18 06:19:31 +04:00
{
2016-12-19 03:15:27 +03:00
struct_loop_info info ;
2012-04-18 06:19:31 +04:00
2015-07-04 17:40:02 +03:00
tprints ( " , " ) ;
if ( umove_or_printaddr ( tcp , addr , & info ) )
return ;
2012-04-18 06:19:31 +04:00
2016-05-30 01:28:28 +03:00
tprintf ( " {lo_number=%d " , info . lo_number ) ;
2012-04-18 06:19:31 +04:00
2015-07-04 17:40:02 +03:00
if ( ! abbrev ( tcp ) ) {
2017-07-09 16:54:01 +03:00
PRINT_FIELD_DEV ( " , " , info , lo_device ) ;
2016-12-19 03:15:27 +03:00
tprintf ( " , lo_inode=% " PRI_klu , ( kernel_ulong_t ) info . lo_inode ) ;
2017-07-09 16:54:01 +03:00
PRINT_FIELD_DEV ( " , " , info , lo_rdevice ) ;
2015-07-04 17:40:02 +03:00
}
2012-04-18 06:19:31 +04:00
2016-05-30 01:28:28 +03:00
tprintf ( " , lo_offset=%#x " , info . lo_offset ) ;
2012-04-18 06:19:31 +04:00
2015-07-04 17:40:02 +03:00
if ( ! abbrev ( tcp ) | | info . lo_encrypt_type ! = LO_CRYPT_NONE ) {
2016-05-30 01:28:28 +03:00
tprints ( " , lo_encrypt_type= " ) ;
2015-07-04 17:40:02 +03:00
printxval ( loop_crypt_type_options , info . lo_encrypt_type ,
" LO_CRYPT_??? " ) ;
2017-01-01 22:19:18 +03:00
/*
* It is converted to unsigned before use in kernel , see
* loop_info64_from_old in drivers / block / loop . c
*/
tprintf ( " , lo_encrypt_key_size=% " PRIu32 ,
( uint32_t ) info . lo_encrypt_key_size ) ;
2015-07-04 17:40:02 +03:00
}
2012-04-18 06:19:31 +04:00
2016-05-30 01:28:28 +03:00
tprints ( " , lo_flags= " ) ;
2015-07-04 17:40:02 +03:00
printflags ( loop_flags_options , info . lo_flags , " LO_FLAGS_??? " ) ;
2012-04-18 06:19:31 +04:00
2017-07-11 03:20:54 +03:00
PRINT_FIELD_CSTRING ( " , " , info , lo_name ) ;
2012-04-18 06:19:31 +04:00
2015-07-04 17:40:02 +03:00
if ( ! abbrev ( tcp ) | | info . lo_encrypt_type ! = LO_CRYPT_NONE ) {
2017-07-11 03:20:54 +03:00
const unsigned int lo_encrypt_key_size =
MIN ( ( unsigned ) info . lo_encrypt_key_size , LO_KEY_SIZE ) ;
PRINT_FIELD_STRING ( " , " , info , lo_encrypt_key ,
lo_encrypt_key_size , 0 ) ;
2015-07-04 17:40:02 +03:00
}
2012-04-18 06:19:31 +04:00
2015-07-04 17:40:02 +03:00
if ( ! abbrev ( tcp ) )
2016-12-19 03:15:27 +03:00
tprintf ( " , lo_init=[%# " PRI_klx " , %# " PRI_klx " ] "
2017-01-01 21:13:07 +03:00
" , reserved=[%#hhx, %#hhx, %#hhx, %#hhx]} " ,
2016-12-19 03:15:27 +03:00
( kernel_ulong_t ) info . lo_init [ 0 ] ,
( kernel_ulong_t ) info . lo_init [ 1 ] ,
2015-07-04 17:40:02 +03:00
info . reserved [ 0 ] , info . reserved [ 1 ] ,
info . reserved [ 2 ] , info . reserved [ 3 ] ) ;
else
tprints ( " , ...} " ) ;
}
2012-04-18 06:19:31 +04:00
2015-07-04 17:40:02 +03:00
static void
2016-12-26 13:26:03 +03:00
decode_loop_info64 ( struct tcb * const tcp , const kernel_ulong_t addr )
2015-07-04 17:40:02 +03:00
{
struct loop_info64 info64 ;
2012-04-18 06:19:31 +04:00
2015-07-04 17:40:02 +03:00
tprints ( " , " ) ;
if ( umove_or_printaddr ( tcp , addr , & info64 ) )
return ;
if ( ! abbrev ( tcp ) ) {
2017-07-09 16:54:01 +03:00
PRINT_FIELD_DEV ( " { " , info64 , lo_device ) ;
2016-12-26 19:36:37 +03:00
tprintf ( " , lo_inode=% " PRIu64 , ( uint64_t ) info64 . lo_inode ) ;
2017-07-09 16:54:01 +03:00
PRINT_FIELD_DEV ( " , " , info64 , lo_rdevice ) ;
2016-12-26 19:36:37 +03:00
tprintf ( " , lo_offset=%# " PRIx64 " , lo_sizelimit=% " PRIu64
" , lo_number=% " PRIu32 ,
2015-07-04 17:40:02 +03:00
( uint64_t ) info64 . lo_offset ,
( uint64_t ) info64 . lo_sizelimit ,
( uint32_t ) info64 . lo_number ) ;
} else {
2016-05-30 01:28:28 +03:00
tprintf ( " {lo_offset=%# " PRIx64 " , lo_number=% " PRIu32 ,
2015-07-04 17:40:02 +03:00
( uint64_t ) info64 . lo_offset ,
( uint32_t ) info64 . lo_number ) ;
}
2012-04-18 06:19:31 +04:00
2015-07-04 17:40:02 +03:00
if ( ! abbrev ( tcp ) | | info64 . lo_encrypt_type ! = LO_CRYPT_NONE ) {
2016-05-30 01:28:28 +03:00
tprints ( " , lo_encrypt_type= " ) ;
2015-07-04 17:40:02 +03:00
printxval ( loop_crypt_type_options , info64 . lo_encrypt_type ,
" LO_CRYPT_??? " ) ;
2016-05-30 01:28:28 +03:00
tprintf ( " , lo_encrypt_key_size=% " PRIu32 ,
2015-07-04 17:40:02 +03:00
info64 . lo_encrypt_key_size ) ;
}
2012-04-18 06:19:31 +04:00
2016-05-30 01:28:28 +03:00
tprints ( " , lo_flags= " ) ;
2015-07-04 17:40:02 +03:00
printflags ( loop_flags_options , info64 . lo_flags , " LO_FLAGS_??? " ) ;
2017-07-11 03:20:54 +03:00
PRINT_FIELD_CSTRING ( " , " , info64 , lo_file_name ) ;
2012-04-18 06:19:31 +04:00
2015-07-04 17:40:02 +03:00
if ( ! abbrev ( tcp ) | | info64 . lo_encrypt_type ! = LO_CRYPT_NONE ) {
2017-07-11 03:20:54 +03:00
PRINT_FIELD_CSTRING ( " , " , info64 , lo_crypt_name ) ;
const unsigned int lo_encrypt_key_size =
MIN ( ( unsigned ) info64 . lo_encrypt_key_size , LO_KEY_SIZE ) ;
PRINT_FIELD_STRING ( " , " , info64 , lo_encrypt_key ,
lo_encrypt_key_size , 0 ) ;
2015-07-04 17:40:02 +03:00
}
2012-04-18 06:19:31 +04:00
2015-07-04 17:40:02 +03:00
if ( ! abbrev ( tcp ) )
2016-05-30 01:34:30 +03:00
tprintf ( " , lo_init=[%# " PRIx64 " , %# " PRIx64 " ]} " ,
2015-07-04 17:40:02 +03:00
( uint64_t ) info64 . lo_init [ 0 ] ,
( uint64_t ) info64 . lo_init [ 1 ] ) ;
else
tprints ( " , ...} " ) ;
}
2012-04-18 06:19:31 +04:00
2016-12-19 03:15:27 +03:00
MPERS_PRINTER_DECL ( int , loop_ioctl ,
struct tcb * tcp , const unsigned int code ,
const kernel_ulong_t arg )
2015-07-04 17:40:02 +03:00
{
switch ( code ) {
case LOOP_GET_STATUS :
if ( entering ( tcp ) )
return 0 ;
2018-03-07 02:52:08 +03:00
ATTRIBUTE_FALLTHROUGH ;
2016-05-30 01:15:53 +03:00
case LOOP_SET_STATUS :
2015-07-04 17:40:02 +03:00
decode_loop_info ( tcp , arg ) ;
break ;
case LOOP_GET_STATUS64 :
if ( entering ( tcp ) )
return 0 ;
2018-03-07 02:52:08 +03:00
ATTRIBUTE_FALLTHROUGH ;
2016-05-30 01:15:53 +03:00
case LOOP_SET_STATUS64 :
2015-07-04 17:40:02 +03:00
decode_loop_info64 ( tcp , arg ) ;
break ;
2012-04-18 06:19:31 +04:00
case LOOP_CLR_FD :
case LOOP_SET_CAPACITY :
/* newer loop-control stuff */
case LOOP_CTL_GET_FREE :
/* Takes no arguments */
2015-07-04 17:40:02 +03:00
break ;
2012-04-18 06:19:31 +04:00
case LOOP_SET_FD :
case LOOP_CHANGE_FD :
2015-07-04 17:40:02 +03:00
tprints ( " , " ) ;
printfd ( tcp , arg ) ;
break ;
2012-04-18 06:19:31 +04:00
/* newer loop-control stuff */
case LOOP_CTL_ADD :
case LOOP_CTL_REMOVE :
2015-07-04 17:40:02 +03:00
tprintf ( " , %d " , ( int ) arg ) ;
break ;
2012-04-18 06:19:31 +04:00
2016-05-30 01:58:56 +03:00
case LOOP_SET_DIRECT_IO :
2017-09-19 14:32:05 +03:00
case LOOP_SET_BLOCK_SIZE :
2016-12-26 13:16:35 +03:00
tprintf ( " , % " PRI_klu , arg ) ;
2016-05-30 01:58:56 +03:00
break ;
2012-04-18 06:19:31 +04:00
default :
2015-07-04 17:40:02 +03:00
return RVAL_DECODED ;
2012-04-18 06:19:31 +04:00
}
2015-07-04 17:40:02 +03:00
2017-08-28 03:39:15 +03:00
return RVAL_IOCTL_DECODED ;
2012-04-18 06:19:31 +04:00
}