2011-01-15 20:15:31 +00:00
/*
* Copyright ( c ) 2009 , 2010 Jeff Mahoney < jeffm @ suse . com >
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* 2. Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ` ` AS IS ' ' AND ANY EXPRESS OR
* IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED .
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
* INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
* NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
# include "defs.h"
# include <linux/blkpg.h>
# include <linux/fs.h>
# include <linux/hdreg.h>
/* ioctls <= 114 are present in Linux 2.4. The following ones have been
* added since then and headers containing them may not be available on
* every system . */
# define BLKTRACE_BDEV_SIZE 32
struct blk_user_trace_setup {
char name [ BLKTRACE_BDEV_SIZE ] ; /* output */
uint16_t act_mask ; /* input */
uint32_t buf_size ; /* input */
uint32_t buf_nr ; /* input */
uint64_t start_lba ;
uint64_t end_lba ;
uint32_t pid ;
} ;
# ifndef BLKTRACESETUP
2015-07-05 15:15:03 +03:00
# define BLKTRACESETUP _IOWR(0x12,115,struct blk_user_trace_setup)
2011-01-15 20:15:31 +00:00
# endif
# ifndef BLKTRACESTART
2015-07-05 15:15:03 +03:00
# define BLKTRACESTART _IO(0x12,116)
2011-01-15 20:15:31 +00:00
# endif
2011-04-07 19:58:10 +00:00
# ifndef BLKTRACESTOP
2015-07-05 15:15:03 +03:00
# define BLKTRACESTOP _IO(0x12,117)
2011-01-15 20:15:31 +00:00
# endif
# ifndef BLKTRACETEARDOWN
2015-07-05 15:15:03 +03:00
# define BLKTRACETEARDOWN _IO(0x12,118)
2011-01-15 20:15:31 +00:00
# endif
# ifndef BLKDISCARD
2015-07-05 15:15:03 +03:00
# define BLKDISCARD _IO(0x12,119)
2011-01-15 20:15:31 +00:00
# endif
# ifndef BLKIOMIN
2015-07-05 15:15:03 +03:00
# define BLKIOMIN _IO(0x12,120)
2011-01-15 20:15:31 +00:00
# endif
# ifndef BLKIOOPT
2015-07-05 15:15:03 +03:00
# define BLKIOOPT _IO(0x12,121)
2011-01-15 20:15:31 +00:00
# endif
# ifndef BLKALIGNOFF
2015-07-05 15:15:03 +03:00
# define BLKALIGNOFF _IO(0x12,122)
2011-01-15 20:15:31 +00:00
# endif
# ifndef BLKPBSZGET
2015-07-05 15:15:03 +03:00
# define BLKPBSZGET _IO(0x12,123)
2011-01-15 20:15:31 +00:00
# endif
# ifndef BLKDISCARDZEROES
2015-07-05 15:15:03 +03:00
# define BLKDISCARDZEROES _IO(0x12,124)
2011-01-15 20:15:31 +00:00
# endif
# ifndef BLKSECDISCARD
2015-07-05 15:15:03 +03:00
# define BLKSECDISCARD _IO(0x12,125)
# endif
# ifndef BLKROTATIONAL
# define BLKROTATIONAL _IO(0x12,126)
# endif
# ifndef BLKZEROOUT
# define BLKZEROOUT _IO(0x12,127)
2011-01-15 20:15:31 +00:00
# endif
2014-04-25 23:30:54 +00:00
# include "xlat/blkpg_ops.h"
2011-01-15 20:15:31 +00:00
static void
2015-07-05 15:15:03 +03:00
print_blkpg_req ( struct tcb * tcp , const struct blkpg_ioctl_arg * blkpg )
2011-01-15 20:15:31 +00:00
{
struct blkpg_partition p ;
2011-09-01 10:00:28 +02:00
tprints ( " { " ) ;
2011-01-16 23:07:51 +00:00
printxval ( blkpg_ops , blkpg - > op , " BLKPG_??? " ) ;
2011-01-15 20:15:31 +00:00
2015-07-05 15:15:03 +03:00
tprintf ( " , flags=%d, datalen=%d, data= " ,
2011-01-16 23:07:51 +00:00
blkpg - > flags , blkpg - > datalen ) ;
2011-01-15 20:15:31 +00:00
2015-07-05 15:15:03 +03:00
if ( ! umove_or_printaddr ( tcp , ( long ) blkpg - > data , & p ) ) {
2015-01-25 01:04:01 +00:00
tprintf ( " {start=%lld, length=%lld, pno=%d, devname= " ,
p . start , p . length , p . pno ) ;
print_quoted_string ( p . devname , sizeof ( p . devname ) ,
QUOTE_0_TERMINATED ) ;
tprints ( " , volname= " ) ;
print_quoted_string ( p . volname , sizeof ( p . volname ) ,
QUOTE_0_TERMINATED ) ;
2015-07-05 15:15:03 +03:00
tprints ( " } " ) ;
2015-01-25 01:04:01 +00:00
}
2015-07-05 15:15:03 +03:00
tprints ( " } " ) ;
2011-01-15 20:15:31 +00:00
}
int
2015-07-05 15:15:03 +03:00
block_ioctl ( struct tcb * tcp , const unsigned int code , const long arg )
2011-01-15 20:15:31 +00:00
{
switch ( code ) {
2011-01-16 23:07:51 +00:00
/* take arg as a value, not as a pointer */
2011-01-15 20:15:31 +00:00
case BLKRASET :
case BLKFRASET :
2015-07-05 15:15:03 +03:00
tprintf ( " , %lu " , arg ) ;
2011-01-15 20:15:31 +00:00
break ;
2011-01-16 23:07:51 +00:00
/* take a signed int */
2011-01-15 20:15:31 +00:00
case BLKROSET :
case BLKBSZSET :
2015-07-05 15:15:03 +03:00
tprints ( " , " ) ;
printnum_int ( tcp , arg , " %d " ) ;
2011-01-15 20:15:31 +00:00
break ;
2015-07-05 15:15:03 +03:00
/* return an unsigned short */
2011-01-15 20:15:31 +00:00
case BLKSECTGET :
2015-07-05 15:15:03 +03:00
case BLKROTATIONAL :
if ( entering ( tcp ) )
return 0 ;
tprints ( " , " ) ;
printnum_short ( tcp , arg , " %hu " ) ;
2011-01-15 20:15:31 +00:00
break ;
2011-01-16 23:07:51 +00:00
/* return a signed int */
2011-01-15 20:15:31 +00:00
case BLKROGET :
case BLKBSZGET :
case BLKSSZGET :
case BLKALIGNOFF :
2015-07-05 15:15:03 +03:00
if ( entering ( tcp ) )
return 0 ;
tprints ( " , " ) ;
printnum_int ( tcp , arg , " %d " ) ;
2011-01-15 20:15:31 +00:00
break ;
2011-01-16 23:07:51 +00:00
/* return an unsigned int */
2011-01-15 20:15:31 +00:00
case BLKPBSZGET :
case BLKIOMIN :
case BLKIOOPT :
case BLKDISCARDZEROES :
2015-07-05 15:15:03 +03:00
if ( entering ( tcp ) )
return 0 ;
tprints ( " , " ) ;
printnum_int ( tcp , arg , " %u " ) ;
2011-01-15 20:15:31 +00:00
break ;
2011-01-16 23:07:51 +00:00
/* return a signed long */
2011-01-15 20:15:31 +00:00
case BLKRAGET :
case BLKFRAGET :
2015-07-05 15:15:03 +03:00
if ( entering ( tcp ) )
return 0 ;
tprints ( " , " ) ;
printnum_long ( tcp , arg , " %ld " ) ;
2011-01-15 20:15:31 +00:00
break ;
2011-01-16 23:07:51 +00:00
/* returns an unsigned long */
2011-01-15 20:15:31 +00:00
case BLKGETSIZE :
2015-07-05 15:15:03 +03:00
if ( entering ( tcp ) )
return 0 ;
tprints ( " , " ) ;
printnum_long ( tcp , arg , " %lu " ) ;
2011-01-15 20:15:31 +00:00
break ;
2011-08-16 21:36:16 +00:00
# ifdef HAVE_BLKGETSIZE64
2015-07-05 15:15:03 +03:00
/* returns an uint64_t */
2011-01-15 20:15:31 +00:00
case BLKGETSIZE64 :
2015-07-05 15:15:03 +03:00
if ( entering ( tcp ) )
return 0 ;
tprints ( " , " ) ;
printnum_int64 ( tcp , arg , " % " PRIu64 ) ;
2011-01-15 20:15:31 +00:00
break ;
2011-08-15 11:36:09 +02:00
# endif
2011-01-15 20:15:31 +00:00
2015-07-05 15:15:03 +03:00
/* takes a pair of uint64_t */
2011-01-15 20:15:31 +00:00
case BLKDISCARD :
case BLKSECDISCARD :
2015-07-05 15:15:03 +03:00
case BLKZEROOUT :
tprints ( " , " ) ;
printpair_int64 ( tcp , arg , " % " PRIx64 ) ;
2011-01-15 20:15:31 +00:00
break ;
2015-07-05 15:15:03 +03:00
/* More complex types */
2011-01-15 20:15:31 +00:00
case HDIO_GETGEO :
2015-07-05 15:15:03 +03:00
if ( entering ( tcp ) )
return 0 ;
else {
2011-01-15 20:15:31 +00:00
struct hd_geometry geo ;
2015-07-05 15:15:03 +03:00
tprints ( " , " ) ;
if ( ! umove_or_printaddr ( tcp , arg , & geo ) )
tprintf ( " {heads=%u, sectors=%u, "
2012-04-16 18:12:27 +02:00
" cylinders=%u, start=%lu} " ,
( unsigned ) geo . heads ,
( unsigned ) geo . sectors ,
( unsigned ) geo . cylinders ,
geo . start ) ;
2011-01-15 20:15:31 +00:00
}
break ;
2011-01-16 23:07:51 +00:00
2015-07-05 15:15:03 +03:00
case BLKPG : {
struct blkpg_ioctl_arg blkpg ;
tprints ( " , " ) ;
if ( ! umove_or_printaddr ( tcp , arg , & blkpg ) )
print_blkpg_req ( tcp , & blkpg ) ;
2011-01-15 20:15:31 +00:00
break ;
2015-07-05 15:15:03 +03:00
}
2011-01-16 23:07:51 +00:00
2011-01-15 20:15:31 +00:00
case BLKTRACESETUP :
if ( entering ( tcp ) ) {
struct blk_user_trace_setup buts ;
2015-07-05 15:15:03 +03:00
tprints ( " , " ) ;
if ( umove_or_printaddr ( tcp , arg , & buts ) )
break ;
tprintf ( " {act_mask=%u, buf_size=%u, "
" buf_nr=%u, start_lba=% " PRIu64 " , "
" end_lba=% " PRIu64 " , pid=%u " ,
( unsigned ) buts . act_mask , buts . buf_size ,
buts . buf_nr , buts . start_lba ,
buts . end_lba , buts . pid ) ;
return 1 ;
} else {
2011-01-15 20:15:31 +00:00
struct blk_user_trace_setup buts ;
2015-07-05 15:15:03 +03:00
if ( syserror ( tcp ) ) {
2015-01-25 01:04:01 +00:00
tprints ( " } " ) ;
2015-07-05 15:15:03 +03:00
break ;
}
tprints ( " , " ) ;
if ( umove ( tcp , arg , & buts ) < 0 ) {
tprints ( " ???} " ) ;
break ;
2015-01-25 01:04:01 +00:00
}
2015-07-05 15:15:03 +03:00
tprints ( " , name= " ) ;
print_quoted_string ( buts . name , sizeof ( buts . name ) ,
QUOTE_0_TERMINATED ) ;
tprints ( " } " ) ;
break ;
2011-01-15 20:15:31 +00:00
}
2011-01-16 23:07:51 +00:00
2014-11-21 16:13:16 -05:00
# ifdef FITRIM
/* First seen in linux-2.6.37 */
2015-07-05 15:15:03 +03:00
case FITRIM : {
struct fstrim_range fstrim ;
tprints ( " , " ) ;
if ( ! umove_or_printaddr ( tcp , arg , & fstrim ) )
tprintf ( " {start=%# " PRIx64 " , "
" len=%# " PRIx64 " , "
" minlen=%# " PRIx64 " } " ,
( uint64_t ) fstrim . start ,
( uint64_t ) fstrim . len ,
( uint64_t ) fstrim . minlen ) ;
2014-11-21 16:13:16 -05:00
break ;
2015-07-05 15:15:03 +03:00
}
2014-11-21 16:13:16 -05:00
# endif
2015-07-05 15:15:03 +03:00
/* No arguments */
case BLKRRPART :
case BLKFLSBUF :
2011-01-15 20:15:31 +00:00
case BLKTRACESTART :
case BLKTRACESTOP :
case BLKTRACETEARDOWN :
2015-07-05 15:15:03 +03:00
# ifdef FIFREEZE
case FIFREEZE :
case FITHAW :
# endif
2011-01-15 20:15:31 +00:00
break ;
2015-07-05 15:15:03 +03:00
default :
return RVAL_DECODED ;
}
2011-01-15 20:15:31 +00:00
2015-07-05 15:15:03 +03:00
return RVAL_DECODED | 1 ;
2011-01-15 20:15:31 +00:00
}