#if 0 # # This LD_PRELOAD-able module keeps buffers [passed to /dev/raw/...] # aligned according to 'man raw'. Maintaining appropriate blocking # factor is still up to the application this module will be # LD_PRELOAD-ed to. Most common example would most likely be: # # env LD_PRELOAD=`pwd`/aligned_io.so tar cBbf 64 /dev/raw/raw1 ... # /bin/sh << EOS MODNAME=\`basename "$0" .c\` (set -x; gcc -O -fomit-frame-pointer -fPIC -shared -o \$MODNAME.so "$0") [ $# -gt 0 ] && (set -x; env LD_PRELOAD=`pwd`/\$MODNAME.so $*) EOS exit # #endif #ifndef __linux # error "Linux only, at least for the moment..." #endif #include #include #include #include #include #include #define ALIGN 2048 #define ASIZE (32*1024) #ifndef DEBUG #define DEBUG 0 #endif static void *aligned_buffer; typedef ssize_t (*io_op) (int fd,void *buf,size_t count); extern ssize_t __write(int fd, void *buf, size_t count); extern ssize_t __read(int fd, void *buf, size_t count); static ssize_t do_io (io_op op,int fd,void *buf,size_t count) { int ret; #if DEBUG fprintf (stderr,"-%d:%p\n",fd,buf); #endif if ((size_t)buf&(ALIGN-1)) { if (aligned_buffer == NULL) aligned_buffer = mmap (NULL,ASIZE,PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON,-1,0); #if DEBUG fprintf (stderr,"+%d:%p\n",fd,aligned_buffer); #endif /* I count on caller to notice that the return value is smaller */ if (count>ASIZE) count=ASIZE; if (op==__write) memcpy (aligned_buffer,buf,count); ret=(*op) (fd,aligned_buffer,count); if (op==__read && ret>0) memcpy (buf,aligned_buffer,ret); return ret; } return (*op) (fd,buf,count); } ssize_t write(int fd, const void *buf, size_t count) { return do_io (__write,fd,(void *)buf,count); } ssize_t read(int fd, void *buf, size_t count) { return do_io (__read,fd,buf,count); }