Jan M. Nelken wrote:
> From my point of view, this is unlikely (my investigation points to the bug in DB2), but I can be wrong.
For your convenience I tested ioctl BLKGETSIZE64 results:
As you can see - number of sectors returned is wrong in all cases.
LOL
(fdisk Blocks: 8001) BLKGETSIZE64: /dev/hda1: 8193024 sectors
CORRECT
(fdisk Blocks: 2080386) BLKGETSIZE64: /dev/hda2: 2130315264 sectors
CORRECT
(fdisk Blocks: 36997695) BLKGETSIZE64: /dev/hda3: 1024 sectors
WRONG
(fdisk Blocks: 10514511) BLKGETSIZE64: /dev/hda5: 2176924672 sectors
WRONG
(fdisk Blocks: 1558273+) BLKGETSIZE64: /dev/hda6: 1595672064 sectors
CORRECT
(fdisk Blocks: 24924816) BLKGETSIZE64: /dev/hda7: 4048175104 sectors
WRONG
I see 3 correct results, and 3 wrong results. But it's likely something wrong in your code, not in ioctl(), because you mistakenly count BYTES returned by ioctl(BLKGETSIZ E64) as SECTORS.
I can not review your code, because it's omitted, but you could try this (see below) code instead (really, anyone invited to). I've never seen incorrect results from it.
--
Konstantin Andreev.
--( tests )-----------------------------------
root@life dev# fdisk -l /dev/hda
Disk /dev/hda: 16 heads, 63 sectors, 19386 cylinders
Units = cylinders of 1008 * 512 bytes
Device Boot Start End Blocks Id System
/dev/hda1 1 18966 9558643+ 83 Linux
/dev/hda2 18966 19380 208845 82 Linux swap
root@life dev# ./chkdev /dev/hda{,1,2}
/dev/hda: ior: (0,0) blocks: 19541088 (of 512) bytes: 10005037056 (0x25458c000) 4K pages: 2442636
/dev/hda1: ior: (0,0) blocks: 19117287 (of 512) bytes: 9788050944 (0x24769ce00) 4K pages: 2389660(+ 3584 bytes)
/dev/hda2: ior: (0,0) blocks: 417690 (of 512) bytes: 213857280 (0xcbf3400) 4K pages: 52211(+ 1024 bytes)
avalon db2 # blockdev --getsize /dev/xd{1,2,3}
234441648
234441648
781422768
avalon db2 # ./chkdev /dev/xd{1,2,3}
/dev/xd1: ior: (0,0) blocks: 234441648 (of 512) bytes: 120034123776 (0x1bf2976000) 4K pages: 29305206
/dev/xd2: ior: (0,0) blocks: 234441648 (of 512) bytes: 120034123776 (0x1bf2976000) 4K pages: 29305206
/dev/xd3: ior: (0,0) blocks: 781422768 (of 512) bytes: 400088457216 (0x5d27216000) 4K pages: 97677846
avalon db2 # echo "0 8388616 linear /dev/xd1 48297272" | dmsetup create foo
avalon db2 # ./chkdev /dev/mapper/foo
/dev/mapper/foo: ior: (0,0) blocks: 8388616 (of 512) bytes: 4294971392 (0x100001000) 4K pages: 1048577
root@life dev# uname -a
Linux life 2.6.17.6lf39 #5 PREEMPT Thu Jul 20 15:47:40 MSD 2006 i686 i686 i386 GNU/Linux
avalon db2 # uname -a
Linux avalon 2.6.21.1-av11 #6 SMP PREEMPT Thu May 10 22:12:16 MSD 2007 i686 Intel(R) Pentium(R) 4 CPU 3.20GHz GenuineIntel GNU/Linux
--( source )-----------------------------------
/* Compile with "gcc -Wall chkdev.c -o chkdev" */
#define _GNU_SOURCE
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdarg.h>
#include <sys/ioctl.h>
#include <stdint.h>
#define BLKGETSIZE _IO(0x12,96)
#define BLKGETSIZE64 0x80041272
#define PAGESIZE 4096
void libcerr( const char *format, ... );
const char *myname = NULL;
int main( int argc, char *argv[] ) {
int io1, io2, fd, j;
uint32_t blocks;
uint64_t bytes;
myname = basename( argv[0] );
for( j = 1; j < argc; ++ j ) {
fd = open( argv[j], O_RDONLY|O_DIRE CT|O_LARGEFILE| O_NONBLOCK );
if( fd < 0 ) {
libcerr( "open(%s)", argv[j] );
continue;
}
io1 = ioctl( fd, BLKGETSIZE, & blocks );
io2 = ioctl( fd, BLKGETSIZE64, & bytes );
if( io1 == -1 )
libcerr( "ioctl(%s,BLKGE TSIZE)", argv[j] );
if( io2 == -1 )
libcerr( "ioctl(%s,BLKGE TSIZE64)", argv[j] );
close( fd );
// ***** print results *****
printf( "%s: ior: (%i,%i)", argv[j], io1, io2 );
if( io1 != -1 ) {
printf( " blocks: %u", blocks );
if( io2 != -1 )
printf( " (of %llu)", bytes / blocks );
}
if( io2 != -1 ) {
printf( " bytes: %llu (0x%llx) 4K pages: %llu",
bytes, bytes, bytes / PAGESIZE );
if( 0 != (bytes %= PAGESIZE) )
printf( "(+ %u bytes)", (unsigned)bytes );
}
putc( '\n', stdout );
} // next device
return 0;
}
void libcerr( const char *format, ... ) {
va_list v;
fwrite( myname, 1, strlen(myname), stderr );
fwrite( ": ", 1, 2, stderr );
va_start( v, format );
vfprintf( stderr, format, v );
va_end( v );
fprintf( stderr, ": [%i] %s.\n", errno, strerror( errno ));
}
--( end )-----------------------------------