diff -uNrp xen-unstable.hg/tools/blktap/drivers/block-aio.c xen-unstable.hg/tools/blktap/drivers/block-aio.c --- xen-unstable.hg/tools/blktap/drivers/block-aio.c 2009-08-18 01:57:04.000000000 +0800 +++ xen-unstable.hg/tools/blktap/drivers/block-aio.c 2009-08-18 18:15:16.000000000 +0800 @@ -121,6 +121,7 @@ static inline void init_fds(struct disk_ static int tdaio_open (struct disk_driver *dd, const char *name, td_flag_t flags) { int i, fd, ret = 0, o_flags; + struct stat st; struct td_state *s = dd->td_state; struct tdaio_state *prv = (struct tdaio_state *)dd->private; @@ -134,23 +135,28 @@ static int tdaio_open (struct disk_drive /* Open the file */ o_flags = O_DIRECT | O_LARGEFILE | ((flags == TD_RDONLY) ? O_RDONLY : O_RDWR); - fd = open(name, o_flags); - if ( (fd == -1) && (errno == EINVAL) ) { - - /* Maybe O_DIRECT isn't supported. */ + /* Check O_DIRECT, for its bad performance in hole file */ + if (name && (stat(name, &st) == 0)) { + if (st.st_blocks < st.st_size/(512 * 2)) + o_flags &= ~O_DIRECT; + } + + fd = open(name, o_flags); + if ( (fd == -1) && (errno == EINVAL) ) { + /* Maybe O_DIRECT isn't supported. */ o_flags &= ~O_DIRECT; - fd = open(name, o_flags); - if (fd != -1) DPRINTF("WARNING: Accessing image without" - "O_DIRECT! (%s)\n", name); - - } else if (fd != -1) DPRINTF("open(%s) with O_DIRECT\n", name); - - if (fd == -1) { + fd = open(name, o_flags); + } + + if (fd == -1) { DPRINTF("Unable to open [%s] (%d)!\n", name, 0 - errno); - ret = 0 - errno; - goto done; - } + ret = 0 - errno; + goto done; + } + + DPRINTF("tap:aio open(%s) %s O_DIRECT\n", name, + o_flags & O_DIRECT ? "with" : "without"); prv->fd = fd; diff -uNrp xen-unstable.hg/tools/blktap/drivers/Makefile xen-unstable.hg/tools/blktap/drivers/Makefile --- xen-unstable.hg/tools/blktap/drivers/Makefile 2009-08-18 01:57:04.000000000 +0800 +++ xen-unstable.hg/tools/blktap/drivers/Makefile 2009-08-18 18:16:13.000000000 +0800 @@ -11,7 +11,7 @@ CFLAGS += -I../lib CFLAGS += $(CFLAGS_libxenctrl) CFLAGS += $(CFLAGS_libxenstore) CFLAGS += -I $(LIBAIO_DIR) -CFLAGS += -D_GNU_SOURCE +CFLAGS += -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 ifeq ($(shell . ./check_gcrypt $(CC)),yes) CFLAGS += -DUSE_GCRYPT