Merge remote-tracking branch 'mjt/mjt-iov2' into staging
authorAnthony Liguori <aliguori@us.ibm.com>
Mon, 9 Jul 2012 17:35:06 +0000 (12:35 -0500)
committerAnthony Liguori <aliguori@us.ibm.com>
Mon, 9 Jul 2012 17:35:06 +0000 (12:35 -0500)
* mjt/mjt-iov2:
  rewrite iov_send_recv() and move it to iov.c
  cleanup qemu_co_sendv(), qemu_co_recvv() and friends
  export iov_send_recv() and use it in iov_send() and iov_recv()
  rename qemu_sendv to iov_send, change proto and move declarations to iov.h
  change qemu_iovec_to_buf() to match other to,from_buf functions
  consolidate qemu_iovec_copy() and qemu_iovec_concat() and make them consistent
  allow qemu_iovec_from_buffer() to specify offset from which to start copying
  consolidate qemu_iovec_memset{,_skip}() into single function and use existing iov_memset()
  rewrite iov_* functions
  change iov_* function prototypes to be more appropriate
  virtio-serial-bus: use correct lengths in control_out() message

Conflicts:
tests/Makefile

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
14 files changed:
1  2 
Makefile
Makefile.objs
block.c
block/iscsi.c
block/qcow2.c
block/qed.c
block/rbd.c
block/sheepdog.c
hw/rtl8139.c
hw/usb/core.c
hw/virtio-balloon.c
hw/virtio-serial-bus.c
qemu-common.h
tests/Makefile

diff --combined Makefile
index bad0e3142a6de930b171dbbcec1f0ae97e87ad0a,017836bc025edf1328b842af93c99e9b990b3ee1..34d6a9e52c52a1f54c0da203558f670b1a6c9484
+++ b/Makefile
@@@ -33,7 -33,7 +33,7 @@@ configure: 
  .PHONY: all clean cscope distclean dvi html info install install-doc \
        pdf recurse-all speed tar tarbin test build-all
  
 -$(call set-vpath, $(SRC_PATH):$(SRC_PATH)/hw)
 +$(call set-vpath, $(SRC_PATH))
  
  LIBS+=-lz $(LIBS_TOOLS)
  
@@@ -91,18 -91,19 +91,18 @@@ qemu-options.def: $(SRC_PATH)/qemu-opti
  
  SUBDIR_RULES=$(patsubst %,subdir-%, $(TARGET_DIRS))
  
 -subdir-%: $(GENERATED_HEADERS)
 +subdir-%:
        $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C $* V="$(V)" TARGET_DIR="$*/" all,)
  
  ifneq ($(wildcard config-host.mak),)
  include $(SRC_PATH)/Makefile.objs
  endif
  
 -$(universal-obj-y) $(common-obj-y): $(GENERATED_HEADERS)
  subdir-libcacard: $(oslib-obj-y) $(trace-obj-y) qemu-timer-common.o
  
 -$(filter %-softmmu,$(SUBDIR_RULES)): $(universal-obj-y) $(trace-obj-y) $(common-obj-y) subdir-libdis
 +$(filter %-softmmu,$(SUBDIR_RULES)): $(universal-obj-y) $(trace-obj-y) $(common-obj-y) $(extra-obj-y) subdir-libdis
  
 -$(filter %-user,$(SUBDIR_RULES)): $(GENERATED_HEADERS) $(universal-obj-y) $(trace-obj-y) subdir-libdis-user subdir-libuser
 +$(filter %-user,$(SUBDIR_RULES)): $(universal-obj-y) $(trace-obj-y) subdir-libdis-user subdir-libuser
  
  ROMSUBDIR_RULES=$(patsubst %,romsubdir-%, $(ROMS))
  romsubdir-%:
@@@ -120,7 -121,7 +120,7 @@@ QEMU_CFLAGS += -I$(SRC_PATH)/includ
  
  ui/cocoa.o: ui/cocoa.m
  
 -ui/sdl.o audio/sdlaudio.o ui/sdl_zoom.o baum.o: QEMU_CFLAGS += $(SDL_CFLAGS)
 +ui/sdl.o audio/sdlaudio.o ui/sdl_zoom.o hw/baum.o: QEMU_CFLAGS += $(SDL_CFLAGS)
  
  ui/vnc.o: QEMU_CFLAGS += $(VNC_TLS_CFLAGS)
  
@@@ -141,22 -142,20 +141,23 @@@ libcacard.la
  install-libcacard:
        @echo "libtool is missing, please install and rerun configure"; exit 1
  else
 -libcacard.la: $(GENERATED_HEADERS) $(oslib-obj-y) qemu-timer-common.o $(addsuffix .lo, $(basename $(trace-obj-y)))
 +libcacard.la: $(oslib-obj-y) qemu-timer-common.o $(addsuffix .lo, $(basename $(trace-obj-y)))
        $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libcacard V="$(V)" TARGET_DIR="$*/" libcacard.la,)
  
  install-libcacard: libcacard.la
        $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libcacard V="$(V)" TARGET_DIR="$*/" install-libcacard,)
  endif
 +
 +vscclient$(EXESUF): $(libcacard-y) $(oslib-obj-y) $(trace-obj-y) qemu-timer-common.o libcacard/vscclient.o
 +      $(call quiet-command,$(CC) $(LDFLAGS) -o $@ $^ $(libcacard_libs) $(LIBS),"  LINK  $@")
 +
  ######################################################################
  
  qemu-img.o: qemu-img-cmds.h
 -qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o cmd.o qemu-ga.o: $(GENERATED_HEADERS)
  
  tools-obj-y = $(oslib-obj-y) $(trace-obj-y) qemu-tool.o qemu-timer.o \
-       qemu-timer-common.o main-loop.o notify.o iohandler.o cutils.o async.o
+       qemu-timer-common.o main-loop.o notify.o \
+       iohandler.o cutils.o iov.o async.o
  tools-obj-$(CONFIG_POSIX) += compatfd.o
  
  qemu-img$(EXESUF): qemu-img.o $(tools-obj-y) $(block-obj-y)
@@@ -164,6 -163,7 +165,6 @@@ qemu-nbd$(EXESUF): qemu-nbd.o $(tools-o
  qemu-io$(EXESUF): qemu-io.o cmd.o $(tools-obj-y) $(block-obj-y)
  
  qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
 -qemu-bridge-helper.o: $(GENERATED_HEADERS)
  
  fsdev/virtfs-proxy-helper$(EXESUF): fsdev/virtfs-proxy-helper.o fsdev/virtio-9p-marshal.o oslib-posix.o $(trace-obj-y)
  fsdev/virtfs-proxy-helper$(EXESUF): LIBS += -lcap
  qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx
        $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@,"  GEN   $@")
  
 -$(qapi-obj-y): $(GENERATED_HEADERS)
 -qapi-dir := $(BUILD_DIR)/qapi-generated
  qemu-ga$(EXESUF): LIBS = $(LIBS_QGA)
 -qemu-ga$(EXESUF): QEMU_CFLAGS += -I $(qapi-dir)
 +qemu-ga$(EXESUF): QEMU_CFLAGS += -I qapi-generated
  
  gen-out-type = $(subst .,-,$(suffix $@))
  
@@@ -180,15 -182,15 +181,15 @@@ ifneq ($(wildcard config-host.mak),
  include $(SRC_PATH)/tests/Makefile
  endif
  
 -$(qapi-dir)/qga-qapi-types.c $(qapi-dir)/qga-qapi-types.h :\
 +qapi-generated/qga-qapi-types.c qapi-generated/qga-qapi-types.h :\
  $(SRC_PATH)/qapi-schema-guest.json $(SRC_PATH)/scripts/qapi-types.py
 -      $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o "$(qapi-dir)" -p "qga-" < $<, "  GEN   $@")
 -$(qapi-dir)/qga-qapi-visit.c $(qapi-dir)/qga-qapi-visit.h :\
 +      $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o qapi-generated -p "qga-" < $<, "  GEN   $@")
 +qapi-generated/qga-qapi-visit.c qapi-generated/qga-qapi-visit.h :\
  $(SRC_PATH)/qapi-schema-guest.json $(SRC_PATH)/scripts/qapi-visit.py
 -      $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o "$(qapi-dir)" -p "qga-" < $<, "  GEN   $@")
 -$(qapi-dir)/qga-qmp-commands.h $(qapi-dir)/qga-qmp-marshal.c :\
 +      $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o qapi-generated -p "qga-" < $<, "  GEN   $@")
 +qapi-generated/qga-qmp-commands.h qapi-generated/qga-qmp-marshal.c :\
  $(SRC_PATH)/qapi-schema-guest.json $(SRC_PATH)/scripts/qapi-commands.py
 -      $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -o "$(qapi-dir)" -p "qga-" < $<, "  GEN   $@")
 +      $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -o qapi-generated -p "qga-" < $<, "  GEN   $@")
  
  qapi-types.c qapi-types.h :\
  $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py
@@@ -200,10 -202,10 +201,10 @@@ qmp-commands.h qmp-marshal.c :
  $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py
        $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -m -o "." < $<, "  GEN   $@")
  
 -QGALIB_OBJ=$(addprefix $(qapi-dir)/, qga-qapi-types.o qga-qapi-visit.o qga-qmp-marshal.o)
 -QGALIB_GEN=$(addprefix $(qapi-dir)/, qga-qapi-types.h qga-qapi-visit.h qga-qmp-commands.h)
 -$(QGALIB_OBJ): $(QGALIB_GEN) $(GENERATED_HEADERS)
 -$(qga-obj-y) qemu-ga.o: $(QGALIB_GEN) $(GENERATED_HEADERS)
 +QGALIB_OBJ=$(addprefix qapi-generated/, qga-qapi-types.o qga-qapi-visit.o qga-qmp-marshal.o)
 +QGALIB_GEN=$(addprefix qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qmp-commands.h)
 +$(QGALIB_OBJ): $(QGALIB_GEN)
 +$(qga-obj-y) qemu-ga.o: $(QGALIB_GEN)
  
  qemu-ga$(EXESUF): qemu-ga.o $(qga-obj-y) $(tools-obj-y) $(qapi-obj-y) $(qobject-obj-y) $(version-obj-y) $(QGALIB_OBJ)
  
@@@ -217,7 -219,6 +218,7 @@@ clean
        rm -Rf .libs
        rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d net/*.o net/*.d fsdev/*.o fsdev/*.d ui/*.o ui/*.d qapi/*.o qapi/*.d qga/*.o qga/*.d
        rm -f qom/*.o qom/*.d
 +      rm -f usb/*.o usb/*.d hw/*.o hw/*.d
        rm -f qemu-img-cmds.h
        rm -f trace/*.o trace/*.d
        rm -f trace-dtrace.dtrace trace-dtrace.dtrace-timestamp
        rm -f trace-dtrace.h trace-dtrace.h-timestamp
        rm -f $(foreach f,$(GENERATED_HEADERS),$(f) $(f)-timestamp)
        rm -f $(foreach f,$(GENERATED_SOURCES),$(f) $(f)-timestamp)
 -      rm -rf $(qapi-dir)
 +      rm -rf qapi-generated
        $(MAKE) -C tests/tcg clean
        for d in $(ALL_SUBDIRS) $(QEMULIBS) libcacard; do \
        if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \
@@@ -249,8 -250,7 +250,8 @@@ distclean: clea
  
  KEYMAPS=da     en-gb  et  fr     fr-ch  is  lt  modifiers  no  pt-br  sv \
  ar      de     en-us  fi  fr-be  hr     it  lv  nl         pl  ru     th \
 -common  de-ch  es     fo  fr-ca  hu     ja  mk  nl-be      pt  sl     tr
 +common  de-ch  es     fo  fr-ca  hu     ja  mk  nl-be      pt  sl     tr \
 +bepo
  
  ifdef INSTALL_BLOBS
  BLOBS=bios.bin sgabios.bin vgabios.bin vgabios-cirrus.bin \
@@@ -260,6 -260,7 +261,6 @@@ pxe-e1000.rom pxe-eepro100.rom pxe-ne2k
  pxe-pcnet.rom pxe-rtl8139.rom pxe-virtio.rom \
  qemu-icon.bmp \
  bamboo.dtb petalogix-s3adsp1800.dtb petalogix-ml605.dtb \
 -mpc8544ds.dtb \
  multiboot.bin linuxboot.bin kvmvapic.bin \
  s390-zipl.rom \
  spapr-rtas.bin slof.bin \
@@@ -271,7 -272,6 +272,7 @@@ endi
  install-doc: $(DOCS)
        $(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)"
        $(INSTALL_DATA) qemu-doc.html  qemu-tech.html "$(DESTDIR)$(qemu_docdir)"
 +      $(INSTALL_DATA) QMP/qmp-commands.txt "$(DESTDIR)$(qemu_docdir)"
  ifdef CONFIG_POSIX
        $(INSTALL_DIR) "$(DESTDIR)$(mandir)/man1"
        $(INSTALL_DATA) qemu.1 qemu-img.1 "$(DESTDIR)$(mandir)/man1"
@@@ -400,10 -400,5 +401,10 @@@ tar
        cd /tmp && tar zcvf ~/$(FILE).tar.gz $(FILE) --exclude CVS --exclude .git --exclude .svn
        rm -rf /tmp/$(FILE)
  
 +# Add a dependency on the generated files, so that they are always
 +# rebuilt before other object files
 +Makefile: $(GENERATED_HEADERS)
 +
  # Include automatically generated dependency files
 --include $(wildcard *.d audio/*.d slirp/*.d block/*.d net/*.d ui/*.d qapi/*.d qga/*.d)
 +# All subdir dependencies come automatically from our recursive subdir rules
 +-include $(wildcard *.d)
diff --combined Makefile.objs
index 625c4d5da77d75eb9b490c7a55d12b5daf6a73ca,f173946fd20fe995501f8592e523e3b58e273e46..5ebbcfa17173aee5c8c1a17459ca91374b736308
@@@ -1,7 -1,6 +1,7 @@@
  #######################################################################
  # Target-independent parts used in system and user emulation
  universal-obj-y =
 +universal-obj-y += qemu-log.o
  
  #######################################################################
  # QObject
@@@ -13,7 -12,9 +13,7 @@@ universal-obj-y += $(qobject-obj-y
  
  #######################################################################
  # QOM
 -include $(SRC_PATH)/qom/Makefile
 -qom-obj-y = $(addprefix qom/, $(qom-y))
 -qom-obj-twice-y = $(addprefix qom/, $(qom-twice-y))
 +qom-obj-y = qom/
  
  universal-obj-y += $(qom-obj-y)
  
@@@ -41,18 -42,50 +41,18 @@@ coroutine-obj-$(CONFIG_WIN32) += corout
  #######################################################################
  # block-obj-y is code used by both qemu system emulation and qemu-img
  
- block-obj-y = cutils.o cache-utils.o qemu-option.o module.o async.o
+ block-obj-y = cutils.o iov.o cache-utils.o qemu-option.o module.o async.o
  block-obj-y += nbd.o block.o aio.o aes.o qemu-config.o qemu-progress.o qemu-sockets.o
  block-obj-y += $(coroutine-obj-y) $(qobject-obj-y) $(version-obj-y)
  block-obj-$(CONFIG_POSIX) += posix-aio-compat.o
  block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
 -
 -block-nested-y += raw.o cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o vvfat.o
 -block-nested-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o qcow2-cache.o
 -block-nested-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o
 -block-nested-y += qed-check.o
 -block-nested-y += parallels.o nbd.o blkdebug.o sheepdog.o blkverify.o
 -block-nested-y += stream.o
 -block-nested-$(CONFIG_WIN32) += raw-win32.o
 -block-nested-$(CONFIG_POSIX) += raw-posix.o
 -block-nested-$(CONFIG_LIBISCSI) += iscsi.o
 -block-nested-$(CONFIG_CURL) += curl.o
 -block-nested-$(CONFIG_RBD) += rbd.o
 -
 -block-obj-y +=  $(addprefix block/, $(block-nested-y))
 -
 -net-obj-y = net.o
 -net-nested-y = queue.o checksum.o util.o
 -net-nested-y += socket.o
 -net-nested-y += dump.o
 -net-nested-$(CONFIG_POSIX) += tap.o
 -net-nested-$(CONFIG_LINUX) += tap-linux.o
 -net-nested-$(CONFIG_WIN32) += tap-win32.o
 -net-nested-$(CONFIG_BSD) += tap-bsd.o
 -net-nested-$(CONFIG_SOLARIS) += tap-solaris.o
 -net-nested-$(CONFIG_AIX) += tap-aix.o
 -net-nested-$(CONFIG_HAIKU) += tap-haiku.o
 -net-nested-$(CONFIG_SLIRP) += slirp.o
 -net-nested-$(CONFIG_VDE) += vde.o
 -net-obj-y += $(addprefix net/, $(net-nested-y))
 +block-obj-y += block/
  
  ifeq ($(CONFIG_VIRTIO)$(CONFIG_VIRTFS)$(CONFIG_PCI),yyy)
  # Lots of the fsdev/9pcode is pulled in by vl.c via qemu_fsdev_add.
  # only pull in the actual virtio-9p device if we also enabled virtio.
  CONFIG_REALLY_VIRTFS=y
 -fsdev-nested-y = qemu-fsdev.o virtio-9p-marshal.o
 -else
 -fsdev-nested-y = qemu-fsdev-dummy.o
  endif
 -fsdev-obj-$(CONFIG_VIRTFS) += $(addprefix fsdev/, $(fsdev-nested-y))
  
  ######################################################################
  # Target independent part of system emulation. The long term path is to
  # single QEMU executable should support all CPUs and machines.
  
  common-obj-y = $(block-obj-y) blockdev.o
 -common-obj-y += $(net-obj-y)
 -common-obj-y += $(qom-obj-twice-y)
 -common-obj-$(CONFIG_LINUX) += $(fsdev-obj-$(CONFIG_LINUX))
 +common-obj-y += net.o net/
 +common-obj-y += qom/
  common-obj-y += readline.o console.o cursor.o
  common-obj-y += $(oslib-obj-y)
  common-obj-$(CONFIG_WIN32) += os-win32.o
  common-obj-$(CONFIG_POSIX) += os-posix.o
  
 +common-obj-$(CONFIG_LINUX) += fsdev/
 +extra-obj-$(CONFIG_LINUX) += fsdev/
 +
  common-obj-y += tcg-runtime.o host-utils.o main-loop.o
 -common-obj-y += irq.o input.o
 -common-obj-$(CONFIG_PTIMER) += ptimer.o
 -common-obj-$(CONFIG_MAX7310) += max7310.o
 -common-obj-$(CONFIG_WM8750) += wm8750.o
 -common-obj-$(CONFIG_TWL92230) += twl92230.o
 -common-obj-$(CONFIG_TSC2005) += tsc2005.o
 -common-obj-$(CONFIG_LM832X) += lm832x.o
 -common-obj-$(CONFIG_TMP105) += tmp105.o
 -common-obj-$(CONFIG_STELLARIS_INPUT) += stellaris_input.o
 -common-obj-$(CONFIG_SSD0303) += ssd0303.o
 -common-obj-$(CONFIG_SSD0323) += ssd0323.o
 -common-obj-$(CONFIG_ADS7846) += ads7846.o
 -common-obj-$(CONFIG_MAX111X) += max111x.o
 -common-obj-$(CONFIG_DS1338) += ds1338.o
 -common-obj-y += i2c.o smbus.o smbus_eeprom.o
 -common-obj-y += eeprom93xx.o
 -common-obj-y += scsi-disk.o cdrom.o
 -common-obj-y += scsi-generic.o scsi-bus.o
 -common-obj-y += hid.o
 -common-obj-y += usb/core.o usb/bus.o usb/desc.o usb/dev-hub.o
 -common-obj-y += usb/host-$(HOST_USB).o
 -common-obj-y += usb/dev-hid.o usb/dev-storage.o usb/dev-wacom.o
 -common-obj-y += usb/dev-serial.o usb/dev-network.o usb/dev-audio.o
 -common-obj-$(CONFIG_SSI) += ssi.o
 -common-obj-$(CONFIG_SSI_SD) += ssi-sd.o
 -common-obj-$(CONFIG_SD) += sd.o
 -common-obj-y += bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o
 -common-obj-y += bt-hci-csr.o usb/dev-bluetooth.o
 +common-obj-y += input.o
  common-obj-y += buffered_file.o migration.o migration-tcp.o
  common-obj-y += qemu-char.o #aio.o
 -common-obj-y += msmouse.o ps2.o
 -common-obj-y += qdev.o qdev-properties.o qdev-monitor.o
  common-obj-y += block-migration.o iohandler.o
  common-obj-y += pflib.o
  common-obj-y += bitmap.o bitops.o
  
 -common-obj-$(CONFIG_BRLAPI) += baum.o
  common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
  common-obj-$(CONFIG_WIN32) += version.o
  
 -common-obj-$(CONFIG_SPICE) += ui/spice-core.o ui/spice-input.o ui/spice-display.o spice-qemu-char.o
 -
 -audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
 -audio-obj-$(CONFIG_SDL) += sdlaudio.o
 -audio-obj-$(CONFIG_OSS) += ossaudio.o
 -audio-obj-$(CONFIG_SPICE) += spiceaudio.o
 -audio-obj-$(CONFIG_COREAUDIO) += coreaudio.o
 -audio-obj-$(CONFIG_ALSA) += alsaaudio.o
 -audio-obj-$(CONFIG_DSOUND) += dsoundaudio.o
 -audio-obj-$(CONFIG_FMOD) += fmodaudio.o
 -audio-obj-$(CONFIG_ESD) += esdaudio.o
 -audio-obj-$(CONFIG_PA) += paaudio.o
 -audio-obj-$(CONFIG_WINWAVE) += winwaveaudio.o
 -audio-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o
 -audio-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o
 -audio-obj-y += wavcapture.o
 -common-obj-y += $(addprefix audio/, $(audio-obj-y))
 -
 -ui-obj-y += keymaps.o
 -ui-obj-$(CONFIG_SDL) += sdl.o sdl_zoom.o x_keymap.o
 -ui-obj-$(CONFIG_COCOA) += cocoa.o
 -ui-obj-$(CONFIG_CURSES) += curses.o
 -vnc-obj-y += vnc.o d3des.o
 -vnc-obj-y += vnc-enc-zlib.o vnc-enc-hextile.o
 -vnc-obj-y += vnc-enc-tight.o vnc-palette.o
 -vnc-obj-y += vnc-enc-zrle.o
 -vnc-obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o
 -vnc-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o
 -ifdef CONFIG_VNC_THREAD
 -vnc-obj-y += vnc-jobs-async.o
 -else
 -vnc-obj-y += vnc-jobs-sync.o
 -endif
 -common-obj-y += $(addprefix ui/, $(ui-obj-y))
 -common-obj-$(CONFIG_VNC) += $(addprefix ui/, $(vnc-obj-y))
 +common-obj-$(CONFIG_SPICE) += spice-qemu-char.o
 +
 +common-obj-y += audio/
 +common-obj-y += hw/
 +common-obj-y += ui/
 +common-obj-y += bt-host.o bt-vhci.o
  
  common-obj-y += iov.o acl.o
  common-obj-$(CONFIG_POSIX) += compatfd.o
  common-obj-y += notify.o event_notifier.o
  common-obj-y += qemu-timer.o qemu-timer-common.o
  
 -slirp-obj-y = cksum.o if.o ip_icmp.o ip_input.o ip_output.o
 -slirp-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o
 -slirp-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o arp_table.o
 -common-obj-$(CONFIG_SLIRP) += $(addprefix slirp/, $(slirp-obj-y))
 -
 -# xen backend driver support
 -common-obj-$(CONFIG_XEN_BACKEND) += xen_backend.o xen_devconfig.o
 -common-obj-$(CONFIG_XEN_BACKEND) += xen_console.o xenfb.o xen_disk.o xen_nic.o
 +common-obj-$(CONFIG_SLIRP) += slirp/
  
  ######################################################################
  # libuser
  user-obj-y =
  user-obj-y += envlist.o path.o
  user-obj-y += tcg-runtime.o host-utils.o
- user-obj-y += cutils.o cache-utils.o
+ user-obj-y += cutils.o iov.o cache-utils.o
  user-obj-y += module.o
  user-obj-y += qemu-user.o
  user-obj-y += $(trace-obj-y)
 -user-obj-y += $(qom-obj-twice-y)
 +user-obj-y += qom/
  
  ######################################################################
  # libhw
  
 -hw-obj-y =
 -hw-obj-y += vl.o loader.o
 -hw-obj-$(CONFIG_VIRTIO) += virtio-console.o
 -hw-obj-y += usb/libhw.o
 -hw-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
 -hw-obj-y += fw_cfg.o
 -hw-obj-$(CONFIG_PCI) += pci.o pci_bridge.o pci_bridge_dev.o
 -hw-obj-$(CONFIG_PCI) += msix.o msi.o
 -hw-obj-$(CONFIG_PCI) += shpc.o
 -hw-obj-$(CONFIG_PCI) += slotid_cap.o
 -hw-obj-$(CONFIG_PCI) += pci_host.o pcie_host.o
 -hw-obj-$(CONFIG_PCI) += ioh3420.o xio3130_upstream.o xio3130_downstream.o
 -hw-obj-y += watchdog.o
 -hw-obj-$(CONFIG_ISA_MMIO) += isa_mmio.o
 -hw-obj-$(CONFIG_ECC) += ecc.o
 -hw-obj-$(CONFIG_NAND) += nand.o
 -hw-obj-$(CONFIG_PFLASH_CFI01) += pflash_cfi01.o
 -hw-obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o
 -
 -hw-obj-$(CONFIG_M48T59) += m48t59.o
 -hw-obj-$(CONFIG_ESCC) += escc.o
 -hw-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
 -
 -hw-obj-$(CONFIG_SERIAL) += serial.o
 -hw-obj-$(CONFIG_PARALLEL) += parallel.o
 -hw-obj-$(CONFIG_I8254) += i8254_common.o i8254.o
 -hw-obj-$(CONFIG_PCSPK) += pcspk.o
 -hw-obj-$(CONFIG_PCKBD) += pckbd.o
 -hw-obj-$(CONFIG_USB_UHCI) += usb/hcd-uhci.o
 -hw-obj-$(CONFIG_USB_OHCI) += usb/hcd-ohci.o
 -hw-obj-$(CONFIG_USB_EHCI) += usb/hcd-ehci.o
 -hw-obj-$(CONFIG_USB_XHCI) += usb/hcd-xhci.o
 -hw-obj-$(CONFIG_FDC) += fdc.o
 -hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
 -hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
 -hw-obj-$(CONFIG_DMA) += dma.o
 -hw-obj-$(CONFIG_I82374) += i82374.o
 -hw-obj-$(CONFIG_HPET) += hpet.o
 -hw-obj-$(CONFIG_APPLESMC) += applesmc.o
 -hw-obj-$(CONFIG_SMARTCARD) += usb/dev-smartcard-reader.o ccid-card-passthru.o
 -hw-obj-$(CONFIG_SMARTCARD_NSS) += ccid-card-emulated.o
 -hw-obj-$(CONFIG_USB_REDIR) += usb/redirect.o
 -hw-obj-$(CONFIG_I8259) += i8259_common.o i8259.o
 -
 -# PPC devices
 -hw-obj-$(CONFIG_PREP_PCI) += prep_pci.o
 -hw-obj-$(CONFIG_I82378) += i82378.o
 -# Mac shared devices
 -hw-obj-$(CONFIG_MACIO) += macio.o
 -hw-obj-$(CONFIG_CUDA) += cuda.o
 -hw-obj-$(CONFIG_ADB) += adb.o
 -hw-obj-$(CONFIG_MAC_NVRAM) += mac_nvram.o
 -hw-obj-$(CONFIG_MAC_DBDMA) += mac_dbdma.o
 -# OldWorld PowerMac
 -hw-obj-$(CONFIG_HEATHROW_PIC) += heathrow_pic.o
 -hw-obj-$(CONFIG_GRACKLE_PCI) += grackle_pci.o
 -# NewWorld PowerMac
 -hw-obj-$(CONFIG_UNIN_PCI) += unin_pci.o
 -hw-obj-$(CONFIG_DEC_PCI) += dec_pci.o
 -# PowerPC E500 boards
 -hw-obj-$(CONFIG_PPCE500_PCI) += ppce500_pci.o
 -
 -# MIPS devices
 -hw-obj-$(CONFIG_PIIX4) += piix4.o
 -hw-obj-$(CONFIG_G364FB) += g364fb.o
 -hw-obj-$(CONFIG_JAZZ_LED) += jazz_led.o
 -
 -# PCI watchdog devices
 -hw-obj-$(CONFIG_PCI) += wdt_i6300esb.o
 -
 -hw-obj-$(CONFIG_PCI) += pcie.o pcie_aer.o pcie_port.o
 -
 -# PCI network cards
 -hw-obj-$(CONFIG_NE2000_PCI) += ne2000.o
 -hw-obj-$(CONFIG_EEPRO100_PCI) += eepro100.o
 -hw-obj-$(CONFIG_PCNET_PCI) += pcnet-pci.o
 -hw-obj-$(CONFIG_PCNET_COMMON) += pcnet.o
 -hw-obj-$(CONFIG_E1000_PCI) += e1000.o
 -hw-obj-$(CONFIG_RTL8139_PCI) += rtl8139.o
 -
 -hw-obj-$(CONFIG_SMC91C111) += smc91c111.o
 -hw-obj-$(CONFIG_LAN9118) += lan9118.o
 -hw-obj-$(CONFIG_NE2000_ISA) += ne2000-isa.o
 -hw-obj-$(CONFIG_OPENCORES_ETH) += opencores_eth.o
 -
 -# IDE
 -hw-obj-$(CONFIG_IDE_CORE) += ide/core.o ide/atapi.o
 -hw-obj-$(CONFIG_IDE_QDEV) += ide/qdev.o
 -hw-obj-$(CONFIG_IDE_PCI) += ide/pci.o
 -hw-obj-$(CONFIG_IDE_ISA) += ide/isa.o
 -hw-obj-$(CONFIG_IDE_PIIX) += ide/piix.o
 -hw-obj-$(CONFIG_IDE_CMD646) += ide/cmd646.o
 -hw-obj-$(CONFIG_IDE_MACIO) += ide/macio.o
 -hw-obj-$(CONFIG_IDE_VIA) += ide/via.o
 -hw-obj-$(CONFIG_AHCI) += ide/ahci.o
 -hw-obj-$(CONFIG_AHCI) += ide/ich.o
 -
 -# SCSI layer
 -hw-obj-$(CONFIG_LSI_SCSI_PCI) += lsi53c895a.o
 -hw-obj-$(CONFIG_ESP) += esp.o
 -
 -hw-obj-y += dma-helpers.o sysbus.o isa-bus.o
 -hw-obj-y += qdev-addr.o
 -
 -# VGA
 -hw-obj-$(CONFIG_VGA_PCI) += vga-pci.o
 -hw-obj-$(CONFIG_VGA_ISA) += vga-isa.o
 -hw-obj-$(CONFIG_VGA_ISA_MM) += vga-isa-mm.o
 -hw-obj-$(CONFIG_VMWARE_VGA) += vmware_vga.o
 -hw-obj-$(CONFIG_VMMOUSE) += vmmouse.o
 -hw-obj-$(CONFIG_VGA_CIRRUS) += cirrus_vga.o
 -
 -hw-obj-$(CONFIG_RC4030) += rc4030.o
 -hw-obj-$(CONFIG_DP8393X) += dp8393x.o
 -hw-obj-$(CONFIG_DS1225Y) += ds1225y.o
 -hw-obj-$(CONFIG_MIPSNET) += mipsnet.o
 -
 -hw-obj-y += qtest.o
 -
 -# Sound
 -sound-obj-y =
 -sound-obj-$(CONFIG_SB16) += sb16.o
 -sound-obj-$(CONFIG_ES1370) += es1370.o
 -sound-obj-$(CONFIG_AC97) += ac97.o
 -sound-obj-$(CONFIG_ADLIB) += fmopl.o adlib.o
 -sound-obj-$(CONFIG_GUS) += gus.o gusemu_hal.o gusemu_mixer.o
 -sound-obj-$(CONFIG_CS4231A) += cs4231a.o
 -sound-obj-$(CONFIG_HDA) += intel-hda.o hda-audio.o
 -
 -adlib.o fmopl.o: QEMU_CFLAGS += -DBUILD_Y8950=0
 -hw-obj-$(CONFIG_SOUND) += $(sound-obj-y)
 -
 -9pfs-nested-$(CONFIG_VIRTFS)  = virtio-9p.o
 -9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-local.o virtio-9p-xattr.o
 -9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-xattr-user.o virtio-9p-posix-acl.o
 -9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-coth.o cofs.o codir.o cofile.o
 -9pfs-nested-$(CONFIG_VIRTFS) += coxattr.o virtio-9p-synth.o
 -9pfs-nested-$(CONFIG_OPEN_BY_HANDLE) +=  virtio-9p-handle.o
 -9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-proxy.o
 -
 -hw-obj-$(CONFIG_REALLY_VIRTFS) += $(addprefix 9pfs/, $(9pfs-nested-y))
 +hw-obj-y = vl.o dma-helpers.o qtest.o hw/
  
  ######################################################################
  # libdis
@@@ -188,29 -425,31 +188,29 @@@ ifneq ($(TRACE_BACKEND),dtrace
  trace-obj-y = trace.o
  endif
  
 -trace-nested-$(CONFIG_TRACE_DEFAULT) += default.o
 -
 -trace-nested-$(CONFIG_TRACE_SIMPLE) += simple.o
 +trace-obj-$(CONFIG_TRACE_DEFAULT) += trace/default.o
 +trace-obj-$(CONFIG_TRACE_SIMPLE) += trace/simple.o
  trace-obj-$(CONFIG_TRACE_SIMPLE) += qemu-timer-common.o
 -
 -trace-nested-$(CONFIG_TRACE_STDERR) += stderr.o
 -
 -trace-nested-y += control.o
 -
 -trace-obj-y += $(addprefix trace/, $(trace-nested-y))
 +trace-obj-$(CONFIG_TRACE_STDERR) += trace/stderr.o
 +trace-obj-y += trace/control.o
  
  $(trace-obj-y): $(GENERATED_HEADERS)
  
  ######################################################################
  # smartcard
  
 -libcacard-y = cac.o event.o vcard.o vreader.o vcard_emul_nss.o vcard_emul_type.o card_7816.o
 +libcacard-y += libcacard/cac.o libcacard/event.o
 +libcacard-y += libcacard/vcard.o libcacard/vreader.o
 +libcacard-y += libcacard/vcard_emul_nss.o
 +libcacard-y += libcacard/vcard_emul_type.o
 +libcacard-y += libcacard/card_7816.o
 +
 +common-obj-$(CONFIG_SMARTCARD_NSS) += $(libcacard-y)
  
  ######################################################################
  # qapi
  
 -qapi-nested-y = qapi-visit-core.o qapi-dealloc-visitor.o qmp-input-visitor.o
 -qapi-nested-y += qmp-output-visitor.o qmp-registry.o qmp-dispatch.o
 -qapi-nested-y += string-input-visitor.o string-output-visitor.o
 -qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y))
 +qapi-obj-y = qapi/
  
  common-obj-y += qmp-marshal.o qapi-visit.o qapi-types.o
  common-obj-y += qmp.o hmp.o
@@@ -220,7 -459,11 +220,7 @@@ universal-obj-y += $(qapi-obj-y
  ######################################################################
  # guest agent
  
 -qga-nested-y = commands.o guest-agent-command-state.o
 -qga-nested-$(CONFIG_POSIX) += commands-posix.o channel-posix.o
 -qga-nested-$(CONFIG_WIN32) += commands-win32.o channel-win32.o service-win32.o
 -qga-obj-y = $(addprefix qga/, $(qga-nested-y))
 -qga-obj-y += qemu-ga.o module.o
 +qga-obj-y = qga/ qemu-ga.o module.o
  qga-obj-$(CONFIG_WIN32) += oslib-win32.o
  qga-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-sockets.o qemu-option.o
  
@@@ -230,13 -473,3 +230,13 @@@ vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS
  
  QEMU_CFLAGS+=$(GLIB_CFLAGS)
  
 +nested-vars += \
 +      hw-obj-y \
 +      qga-obj-y \
 +      block-obj-y \
 +      qom-obj-y \
 +      qapi-obj-y \
 +      user-obj-y \
 +      common-obj-y \
 +      extra-obj-y
 +dummy := $(call unnest-vars)
diff --combined block.c
index b410ed646784892b992a02a746a5684190370833,63b7ae083ca2452f47f649295d4525271552ce3a..0c923f2ae9c93716aff33bb45947f63a7ad30a2e
+++ b/block.c
@@@ -649,13 -649,12 +649,13 @@@ static int bdrv_open_common(BlockDriver
      bs->opaque = g_malloc0(drv->instance_size);
  
      bs->enable_write_cache = !!(flags & BDRV_O_CACHE_WB);
 +    open_flags = flags | BDRV_O_CACHE_WB;
  
      /*
       * Clear flags that are internal to the block layer before opening the
       * image.
       */
 -    open_flags = flags & ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
 +    open_flags &= ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
  
      /*
       * Snapshots should be writable.
@@@ -971,130 -970,98 +971,130 @@@ static void bdrv_rebind(BlockDriverStat
      }
  }
  
 +static void bdrv_move_feature_fields(BlockDriverState *bs_dest,
 +                                     BlockDriverState *bs_src)
 +{
 +    /* move some fields that need to stay attached to the device */
 +    bs_dest->open_flags         = bs_src->open_flags;
 +
 +    /* dev info */
 +    bs_dest->dev_ops            = bs_src->dev_ops;
 +    bs_dest->dev_opaque         = bs_src->dev_opaque;
 +    bs_dest->dev                = bs_src->dev;
 +    bs_dest->buffer_alignment   = bs_src->buffer_alignment;
 +    bs_dest->copy_on_read       = bs_src->copy_on_read;
 +
 +    bs_dest->enable_write_cache = bs_src->enable_write_cache;
 +
 +    /* i/o timing parameters */
 +    bs_dest->slice_time         = bs_src->slice_time;
 +    bs_dest->slice_start        = bs_src->slice_start;
 +    bs_dest->slice_end          = bs_src->slice_end;
 +    bs_dest->io_limits          = bs_src->io_limits;
 +    bs_dest->io_base            = bs_src->io_base;
 +    bs_dest->throttled_reqs     = bs_src->throttled_reqs;
 +    bs_dest->block_timer        = bs_src->block_timer;
 +    bs_dest->io_limits_enabled  = bs_src->io_limits_enabled;
 +
 +    /* geometry */
 +    bs_dest->cyls               = bs_src->cyls;
 +    bs_dest->heads              = bs_src->heads;
 +    bs_dest->secs               = bs_src->secs;
 +    bs_dest->translation        = bs_src->translation;
 +
 +    /* r/w error */
 +    bs_dest->on_read_error      = bs_src->on_read_error;
 +    bs_dest->on_write_error     = bs_src->on_write_error;
 +
 +    /* i/o status */
 +    bs_dest->iostatus_enabled   = bs_src->iostatus_enabled;
 +    bs_dest->iostatus           = bs_src->iostatus;
 +
 +    /* dirty bitmap */
 +    bs_dest->dirty_count        = bs_src->dirty_count;
 +    bs_dest->dirty_bitmap       = bs_src->dirty_bitmap;
 +
 +    /* job */
 +    bs_dest->in_use             = bs_src->in_use;
 +    bs_dest->job                = bs_src->job;
 +
 +    /* keep the same entry in bdrv_states */
 +    pstrcpy(bs_dest->device_name, sizeof(bs_dest->device_name),
 +            bs_src->device_name);
 +    bs_dest->list = bs_src->list;
 +}
 +
  /*
 - * Add new bs contents at the top of an image chain while the chain is
 - * live, while keeping required fields on the top layer.
 + * Swap bs contents for two image chains while they are live,
 + * while keeping required fields on the BlockDriverState that is
 + * actually attached to a device.
   *
   * This will modify the BlockDriverState fields, and swap contents
 - * between bs_new and bs_top. Both bs_new and bs_top are modified.
 + * between bs_new and bs_old. Both bs_new and bs_old are modified.
   *
   * bs_new is required to be anonymous.
   *
   * This function does not create any image files.
   */
 -void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top)
 +void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old)
  {
      BlockDriverState tmp;
  
 -    /* bs_new must be anonymous */
 +    /* bs_new must be anonymous and shouldn't have anything fancy enabled */
      assert(bs_new->device_name[0] == '\0');
 +    assert(bs_new->dirty_bitmap == NULL);
 +    assert(bs_new->job == NULL);
 +    assert(bs_new->dev == NULL);
 +    assert(bs_new->in_use == 0);
 +    assert(bs_new->io_limits_enabled == false);
 +    assert(bs_new->block_timer == NULL);
  
      tmp = *bs_new;
 +    *bs_new = *bs_old;
 +    *bs_old = tmp;
  
 -    /* there are some fields that need to stay on the top layer: */
 -    tmp.open_flags        = bs_top->open_flags;
 +    /* there are some fields that should not be swapped, move them back */
 +    bdrv_move_feature_fields(&tmp, bs_old);
 +    bdrv_move_feature_fields(bs_old, bs_new);
 +    bdrv_move_feature_fields(bs_new, &tmp);
  
 -    /* dev info */
 -    tmp.dev_ops           = bs_top->dev_ops;
 -    tmp.dev_opaque        = bs_top->dev_opaque;
 -    tmp.dev               = bs_top->dev;
 -    tmp.buffer_alignment  = bs_top->buffer_alignment;
 -    tmp.copy_on_read      = bs_top->copy_on_read;
 -
 -    /* i/o timing parameters */
 -    tmp.slice_time        = bs_top->slice_time;
 -    tmp.slice_start       = bs_top->slice_start;
 -    tmp.slice_end         = bs_top->slice_end;
 -    tmp.io_limits         = bs_top->io_limits;
 -    tmp.io_base           = bs_top->io_base;
 -    tmp.throttled_reqs    = bs_top->throttled_reqs;
 -    tmp.block_timer       = bs_top->block_timer;
 -    tmp.io_limits_enabled = bs_top->io_limits_enabled;
 -
 -    /* geometry */
 -    tmp.cyls              = bs_top->cyls;
 -    tmp.heads             = bs_top->heads;
 -    tmp.secs              = bs_top->secs;
 -    tmp.translation       = bs_top->translation;
 +    /* bs_new shouldn't be in bdrv_states even after the swap!  */
 +    assert(bs_new->device_name[0] == '\0');
  
 -    /* r/w error */
 -    tmp.on_read_error     = bs_top->on_read_error;
 -    tmp.on_write_error    = bs_top->on_write_error;
 +    /* Check a few fields that should remain attached to the device */
 +    assert(bs_new->dev == NULL);
 +    assert(bs_new->job == NULL);
 +    assert(bs_new->in_use == 0);
 +    assert(bs_new->io_limits_enabled == false);
 +    assert(bs_new->block_timer == NULL);
  
 -    /* i/o status */
 -    tmp.iostatus_enabled  = bs_top->iostatus_enabled;
 -    tmp.iostatus          = bs_top->iostatus;
 +    bdrv_rebind(bs_new);
 +    bdrv_rebind(bs_old);
 +}
  
 -    /* keep the same entry in bdrv_states */
 -    pstrcpy(tmp.device_name, sizeof(tmp.device_name), bs_top->device_name);
 -    tmp.list = bs_top->list;
 +/*
 + * Add new bs contents at the top of an image chain while the chain is
 + * live, while keeping required fields on the top layer.
 + *
 + * This will modify the BlockDriverState fields, and swap contents
 + * between bs_new and bs_top. Both bs_new and bs_top are modified.
 + *
 + * bs_new is required to be anonymous.
 + *
 + * This function does not create any image files.
 + */
 +void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top)
 +{
 +    bdrv_swap(bs_new, bs_top);
  
      /* The contents of 'tmp' will become bs_top, as we are
       * swapping bs_new and bs_top contents. */
 -    tmp.backing_hd = bs_new;
 -    pstrcpy(tmp.backing_file, sizeof(tmp.backing_file), bs_top->filename);
 -    bdrv_get_format(bs_top, tmp.backing_format, sizeof(tmp.backing_format));
 -
 -    /* swap contents of the fixed new bs and the current top */
 -    *bs_new = *bs_top;
 -    *bs_top = tmp;
 -
 -    /* device_name[] was carried over from the old bs_top.  bs_new
 -     * shouldn't be in bdrv_states, so we need to make device_name[]
 -     * reflect the anonymity of bs_new
 -     */
 -    bs_new->device_name[0] = '\0';
 -
 -    /* clear the copied fields in the new backing file */
 -    bdrv_detach_dev(bs_new, bs_new->dev);
 -
 -    qemu_co_queue_init(&bs_new->throttled_reqs);
 -    memset(&bs_new->io_base,   0, sizeof(bs_new->io_base));
 -    memset(&bs_new->io_limits, 0, sizeof(bs_new->io_limits));
 -    bdrv_iostatus_disable(bs_new);
 -
 -    /* we don't use bdrv_io_limits_disable() for this, because we don't want
 -     * to affect or delete the block_timer, as it has been moved to bs_top */
 -    bs_new->io_limits_enabled = false;
 -    bs_new->block_timer       = NULL;
 -    bs_new->slice_time        = 0;
 -    bs_new->slice_start       = 0;
 -    bs_new->slice_end         = 0;
 -
 -    bdrv_rebind(bs_new);
 -    bdrv_rebind(bs_top);
 +    bs_top->backing_hd = bs_new;
 +    bs_top->open_flags &= ~BDRV_O_NO_BACKING;
 +    pstrcpy(bs_top->backing_file, sizeof(bs_top->backing_file),
 +            bs_new->filename);
 +    pstrcpy(bs_top->backing_format, sizeof(bs_top->backing_format),
 +            bs_new->drv ? bs_new->drv->format_name : "");
  }
  
  void bdrv_delete(BlockDriverState *bs)
@@@ -1255,14 -1222,14 +1255,14 @@@ bool bdrv_dev_is_medium_locked(BlockDri
   * free of errors) or -errno when an internal error occurred. The results of the
   * check are stored in res.
   */
 -int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res)
 +int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix)
  {
      if (bs->drv->bdrv_check == NULL) {
          return -ENOTSUP;
      }
  
      memset(res, 0, sizeof(*res));
 -    return bs->drv->bdrv_check(bs, res);
 +    return bs->drv->bdrv_check(bs, res, fix);
  }
  
  #define COMMIT_BUF_SECTORS 2048
@@@ -1639,20 -1606,6 +1639,20 @@@ int bdrv_read(BlockDriverState *bs, int
      return bdrv_rw_co(bs, sector_num, buf, nb_sectors, false);
  }
  
 +/* Just like bdrv_read(), but with I/O throttling temporarily disabled */
 +int bdrv_read_unthrottled(BlockDriverState *bs, int64_t sector_num,
 +                          uint8_t *buf, int nb_sectors)
 +{
 +    bool enabled;
 +    int ret;
 +
 +    enabled = bs->io_limits_enabled;
 +    bs->io_limits_enabled = false;
 +    ret = bdrv_read(bs, 0, buf, 1);
 +    bs->io_limits_enabled = enabled;
 +    return ret;
 +}
 +
  #define BITS_PER_LONG  (sizeof(unsigned long) * 8)
  
  static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num,
@@@ -1805,8 -1758,8 +1805,8 @@@ int bdrv_pwrite_sync(BlockDriverState *
          return ret;
      }
  
 -    /* No flush needed for cache modes that use O_DSYNC */
 -    if ((bs->open_flags & BDRV_O_CACHE_WB) != 0) {
 +    /* No flush needed for cache modes that already do it */
 +    if (bs->enable_write_cache) {
          bdrv_flush(bs);
      }
  
@@@ -1855,9 -1808,6 +1855,9 @@@ static int coroutine_fn bdrv_co_do_copy
          ret = bdrv_co_do_write_zeroes(bs, cluster_sector_num,
                                        cluster_nb_sectors);
      } else {
 +        /* This does not change the data on the disk, it is not necessary
 +         * to flush even in cache=writethrough mode.
 +         */
          ret = drv->bdrv_co_writev(bs, cluster_sector_num, cluster_nb_sectors,
                                    &bounce_qiov);
      }
      }
  
      skip_bytes = (sector_num - cluster_sector_num) * BDRV_SECTOR_SIZE;
-     qemu_iovec_from_buffer(qiov, bounce_buffer + skip_bytes,
-                            nb_sectors * BDRV_SECTOR_SIZE);
+     qemu_iovec_from_buf(qiov, 0, bounce_buffer + skip_bytes,
+                         nb_sectors * BDRV_SECTOR_SIZE);
  
  err:
      qemu_vfree(bounce_buffer);
@@@ -2027,10 -1977,6 +2027,10 @@@ static int coroutine_fn bdrv_co_do_writ
          ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov);
      }
  
 +    if (ret == 0 && !bs->enable_write_cache) {
 +        ret = bdrv_co_flush(bs);
 +    }
 +
      if (bs->dirty_bitmap) {
          set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
      }
@@@ -2150,10 -2096,11 +2150,10 @@@ static int guess_disk_lchs(BlockDriverS
                             int *pcylinders, int *pheads, int *psectors)
  {
      uint8_t buf[BDRV_SECTOR_SIZE];
 -    int ret, i, heads, sectors, cylinders;
 +    int i, heads, sectors, cylinders;
      struct partition *p;
      uint32_t nr_sects;
      uint64_t nb_sectors;
 -    bool enabled;
  
      bdrv_get_geometry(bs, &nb_sectors);
  
       * but also in async I/O mode. So the I/O throttling function has to
       * be disabled temporarily here, not permanently.
       */
 -    enabled = bs->io_limits_enabled;
 -    bs->io_limits_enabled = false;
 -    ret = bdrv_read(bs, 0, buf, 1);
 -    bs->io_limits_enabled = enabled;
 -    if (ret < 0)
 +    if (bdrv_read_unthrottled(bs, 0, buf, 1) < 0) {
          return -1;
 +    }
      /* test msdos magic */
      if (buf[510] != 0x55 || buf[511] != 0xaa)
          return -1;
@@@ -2347,40 -2297,46 +2347,40 @@@ void bdrv_get_floppy_geometry_hint(Bloc
      uint64_t nb_sectors, size;
      int i, first_match, match;
  
 -    bdrv_get_geometry_hint(bs, nb_heads, max_track, last_sect);
 -    if (*nb_heads != 0 && *max_track != 0 && *last_sect != 0) {
 -        /* User defined disk */
 -        *rate = FDRIVE_RATE_500K;
 -    } else {
 -        bdrv_get_geometry(bs, &nb_sectors);
 -        match = -1;
 -        first_match = -1;
 -        for (i = 0; ; i++) {
 -            parse = &fd_formats[i];
 -            if (parse->drive == FDRIVE_DRV_NONE) {
 +    bdrv_get_geometry(bs, &nb_sectors);
 +    match = -1;
 +    first_match = -1;
 +    for (i = 0; ; i++) {
 +        parse = &fd_formats[i];
 +        if (parse->drive == FDRIVE_DRV_NONE) {
 +            break;
 +        }
 +        if (drive_in == parse->drive ||
 +            drive_in == FDRIVE_DRV_NONE) {
 +            size = (parse->max_head + 1) * parse->max_track *
 +                parse->last_sect;
 +            if (nb_sectors == size) {
 +                match = i;
                  break;
              }
 -            if (drive_in == parse->drive ||
 -                drive_in == FDRIVE_DRV_NONE) {
 -                size = (parse->max_head + 1) * parse->max_track *
 -                    parse->last_sect;
 -                if (nb_sectors == size) {
 -                    match = i;
 -                    break;
 -                }
 -                if (first_match == -1) {
 -                    first_match = i;
 -                }
 -            }
 -        }
 -        if (match == -1) {
              if (first_match == -1) {
 -                match = 1;
 -            } else {
 -                match = first_match;
 +                first_match = i;
              }
 -            parse = &fd_formats[match];
          }
 -        *nb_heads = parse->max_head + 1;
 -        *max_track = parse->max_track;
 -        *last_sect = parse->last_sect;
 -        *drive = parse->drive;
 -        *rate = parse->rate;
      }
 +    if (match == -1) {
 +        if (first_match == -1) {
 +            match = 1;
 +        } else {
 +            match = first_match;
 +        }
 +        parse = &fd_formats[match];
 +    }
 +    *nb_heads = parse->max_head + 1;
 +    *max_track = parse->max_track;
 +    *last_sect = parse->last_sect;
 +    *drive = parse->drive;
 +    *rate = parse->rate;
  }
  
  int bdrv_get_translation_hint(BlockDriverState *bs)
@@@ -2415,11 -2371,6 +2415,11 @@@ int bdrv_enable_write_cache(BlockDriver
      return bs->enable_write_cache;
  }
  
 +void bdrv_set_enable_write_cache(BlockDriverState *bs, bool wce)
 +{
 +    bs->enable_write_cache = wce;
 +}
 +
  int bdrv_is_encrypted(BlockDriverState *bs)
  {
      if (bs->backing_hd && bs->backing_hd->encrypted)
@@@ -2462,9 -2413,13 +2462,9 @@@ int bdrv_set_key(BlockDriverState *bs, 
      return ret;
  }
  
 -void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
 +const char *bdrv_get_format_name(BlockDriverState *bs)
  {
 -    if (!bs->drv) {
 -        buf[0] = '\0';
 -    } else {
 -        pstrcpy(buf, buf_size, bs->drv->format_name);
 -    }
 +    return bs->drv ? bs->drv->format_name : NULL;
  }
  
  void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
@@@ -2511,11 -2466,6 +2511,11 @@@ const char *bdrv_get_device_name(BlockD
      return bs->device_name;
  }
  
 +int bdrv_get_flags(BlockDriverState *bs)
 +{
 +    return bs->open_flags;
 +}
 +
  void bdrv_flush_all(void)
  {
      BlockDriverState *bs;
@@@ -2619,55 -2569,6 +2619,55 @@@ int bdrv_is_allocated(BlockDriverState 
      return data.ret;
  }
  
 +/*
 + * Given an image chain: ... -> [BASE] -> [INTER1] -> [INTER2] -> [TOP]
 + *
 + * Return true if the given sector is allocated in any image between
 + * BASE and TOP (inclusive).  BASE can be NULL to check if the given
 + * sector is allocated in any image of the chain.  Return false otherwise.
 + *
 + * 'pnum' is set to the number of sectors (including and immediately following
 + *  the specified sector) that are known to be in the same
 + *  allocated/unallocated state.
 + *
 + */
 +int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *top,
 +                                            BlockDriverState *base,
 +                                            int64_t sector_num,
 +                                            int nb_sectors, int *pnum)
 +{
 +    BlockDriverState *intermediate;
 +    int ret, n = nb_sectors;
 +
 +    intermediate = top;
 +    while (intermediate && intermediate != base) {
 +        int pnum_inter;
 +        ret = bdrv_co_is_allocated(intermediate, sector_num, nb_sectors,
 +                                   &pnum_inter);
 +        if (ret < 0) {
 +            return ret;
 +        } else if (ret) {
 +            *pnum = pnum_inter;
 +            return 1;
 +        }
 +
 +        /*
 +         * [sector_num, nb_sectors] is unallocated on top but intermediate
 +         * might have
 +         *
 +         * [sector_num+x, nr_sectors] allocated.
 +         */
 +        if (n > pnum_inter) {
 +            n = pnum_inter;
 +        }
 +
 +        intermediate = intermediate->backing_hd;
 +    }
 +
 +    *pnum = n;
 +    return 0;
 +}
 +
  BlockInfoList *qmp_query_block(Error **errp)
  {
      BlockInfoList *head = NULL, *cur_item = NULL;
@@@ -3200,13 -3101,13 +3200,13 @@@ static int multiwrite_merge(BlockDriver
              // Add the first request to the merged one. If the requests are
              // overlapping, drop the last sectors of the first request.
              size = (reqs[i].sector - reqs[outidx].sector) << 9;
-             qemu_iovec_concat(qiov, reqs[outidx].qiov, size);
+             qemu_iovec_concat(qiov, reqs[outidx].qiov, 0, size);
  
              // We should need to add any zeros between the two requests
              assert (reqs[i].sector <= oldreq_last);
  
              // Add the second request
-             qemu_iovec_concat(qiov, reqs[i].qiov, reqs[i].qiov->size);
+             qemu_iovec_concat(qiov, reqs[i].qiov, 0, reqs[i].qiov->size);
  
              reqs[outidx].nb_sectors = qiov->size >> 9;
              reqs[outidx].qiov = qiov;
@@@ -3481,7 -3382,7 +3481,7 @@@ static void bdrv_aio_bh_cb(void *opaque
      BlockDriverAIOCBSync *acb = opaque;
  
      if (!acb->is_write)
-         qemu_iovec_from_buffer(acb->qiov, acb->bounce, acb->qiov->size);
+         qemu_iovec_from_buf(acb->qiov, 0, acb->bounce, acb->qiov->size);
      qemu_vfree(acb->bounce);
      acb->common.cb(acb->common.opaque, acb->ret);
      qemu_bh_delete(acb->bh);
@@@ -3507,7 -3408,7 +3507,7 @@@ static BlockDriverAIOCB *bdrv_aio_rw_ve
      acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
  
      if (is_write) {
-         qemu_iovec_to_buffer(acb->qiov, acb->bounce);
+         qemu_iovec_to_buf(acb->qiov, 0, acb->bounce, qiov->size);
          acb->ret = bs->drv->bdrv_write(bs, sector_num, acb->bounce, nb_sectors);
      } else {
          acb->ret = bs->drv->bdrv_read(bs, sector_num, acb->bounce, nb_sectors);
diff --combined block/iscsi.c
index ac65277048bad08fa5c57906671f93d36d965e2d,ecb7a2211ec5eaba56c0347d119e72ce42c48536..993a86d829fefd03ab8e3f059bd08dff683c9fea
  #include <iscsi/iscsi.h>
  #include <iscsi/scsi-lowlevel.h>
  
 +#ifdef __linux__
 +#include <scsi/sg.h>
 +#include <hw/scsi-defs.h>
 +#endif
  
  typedef struct IscsiLun {
      struct iscsi_context *iscsi;
@@@ -60,9 -56,6 +60,9 @@@ typedef struct IscsiAIOCB 
      int canceled;
      size_t read_size;
      size_t read_offset;
 +#ifdef __linux__
 +    sg_io_hdr_t *ioh;
 +#endif
  } IscsiAIOCB;
  
  struct IscsiTask {
@@@ -247,8 -240,7 +247,7 @@@ iscsi_aio_writev(BlockDriverState *bs, 
      /* this will allow us to get rid of 'buf' completely */
      size = nb_sectors * BDRV_SECTOR_SIZE;
      acb->buf = g_malloc(size);
-     qemu_iovec_to_buffer(acb->qiov, acb->buf);
+     qemu_iovec_to_buf(acb->qiov, 0, acb->buf, size);
  
      acb->task = malloc(sizeof(struct scsi_task));
      if (acb->task == NULL) {
@@@ -522,136 -514,6 +521,136 @@@ iscsi_aio_discard(BlockDriverState *bs
      return &acb->common;
  }
  
 +#ifdef __linux__
 +static void
 +iscsi_aio_ioctl_cb(struct iscsi_context *iscsi, int status,
 +                     void *command_data, void *opaque)
 +{
 +    IscsiAIOCB *acb = opaque;
 +
 +    if (acb->canceled != 0) {
 +        qemu_aio_release(acb);
 +        scsi_free_scsi_task(acb->task);
 +        acb->task = NULL;
 +        return;
 +    }
 +
 +    acb->status = 0;
 +    if (status < 0) {
 +        error_report("Failed to ioctl(SG_IO) to iSCSI lun. %s",
 +                     iscsi_get_error(iscsi));
 +        acb->status = -EIO;
 +    }
 +
 +    acb->ioh->driver_status = 0;
 +    acb->ioh->host_status   = 0;
 +    acb->ioh->resid         = 0;
 +
 +#define SG_ERR_DRIVER_SENSE    0x08
 +
 +    if (status == SCSI_STATUS_CHECK_CONDITION && acb->task->datain.size >= 2) {
 +        int ss;
 +
 +        acb->ioh->driver_status |= SG_ERR_DRIVER_SENSE;
 +
 +        acb->ioh->sb_len_wr = acb->task->datain.size - 2;
 +        ss = (acb->ioh->mx_sb_len >= acb->ioh->sb_len_wr) ?
 +             acb->ioh->mx_sb_len : acb->ioh->sb_len_wr;
 +        memcpy(acb->ioh->sbp, &acb->task->datain.data[2], ss);
 +    }
 +
 +    iscsi_schedule_bh(iscsi_readv_writev_bh_cb, acb);
 +    scsi_free_scsi_task(acb->task);
 +    acb->task = NULL;
 +}
 +
 +static BlockDriverAIOCB *iscsi_aio_ioctl(BlockDriverState *bs,
 +        unsigned long int req, void *buf,
 +        BlockDriverCompletionFunc *cb, void *opaque)
 +{
 +    IscsiLun *iscsilun = bs->opaque;
 +    struct iscsi_context *iscsi = iscsilun->iscsi;
 +    struct iscsi_data data;
 +    IscsiAIOCB *acb;
 +
 +    assert(req == SG_IO);
 +
 +    acb = qemu_aio_get(&iscsi_aio_pool, bs, cb, opaque);
 +
 +    acb->iscsilun = iscsilun;
 +    acb->canceled    = 0;
 +    acb->buf         = NULL;
 +    acb->ioh         = buf;
 +
 +    acb->task = malloc(sizeof(struct scsi_task));
 +    if (acb->task == NULL) {
 +        error_report("iSCSI: Failed to allocate task for scsi command. %s",
 +                     iscsi_get_error(iscsi));
 +        qemu_aio_release(acb);
 +        return NULL;
 +    }
 +    memset(acb->task, 0, sizeof(struct scsi_task));
 +
 +    switch (acb->ioh->dxfer_direction) {
 +    case SG_DXFER_TO_DEV:
 +        acb->task->xfer_dir = SCSI_XFER_WRITE;
 +        break;
 +    case SG_DXFER_FROM_DEV:
 +        acb->task->xfer_dir = SCSI_XFER_READ;
 +        break;
 +    default:
 +        acb->task->xfer_dir = SCSI_XFER_NONE;
 +        break;
 +    }
 +
 +    acb->task->cdb_size = acb->ioh->cmd_len;
 +    memcpy(&acb->task->cdb[0], acb->ioh->cmdp, acb->ioh->cmd_len);
 +    acb->task->expxferlen = acb->ioh->dxfer_len;
 +
 +    if (acb->task->xfer_dir == SCSI_XFER_WRITE) {
 +        data.data = acb->ioh->dxferp;
 +        data.size = acb->ioh->dxfer_len;
 +    }
 +    if (iscsi_scsi_command_async(iscsi, iscsilun->lun, acb->task,
 +                                 iscsi_aio_ioctl_cb,
 +                                 (acb->task->xfer_dir == SCSI_XFER_WRITE) ?
 +                                     &data : NULL,
 +                                 acb) != 0) {
 +        scsi_free_scsi_task(acb->task);
 +        qemu_aio_release(acb);
 +        return NULL;
 +    }
 +
 +    /* tell libiscsi to read straight into the buffer we got from ioctl */
 +    if (acb->task->xfer_dir == SCSI_XFER_READ) {
 +        scsi_task_add_data_in_buffer(acb->task,
 +                                     acb->ioh->dxfer_len,
 +                                     acb->ioh->dxferp);
 +    }
 +
 +    iscsi_set_events(iscsilun);
 +
 +    return &acb->common;
 +}
 +
 +static int iscsi_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
 +{
 +    IscsiLun *iscsilun = bs->opaque;
 +
 +    switch (req) {
 +    case SG_GET_VERSION_NUM:
 +        *(int *)buf = 30000;
 +        break;
 +    case SG_GET_SCSI_ID:
 +        ((struct sg_scsi_id *)buf)->scsi_type = iscsilun->type;
 +        break;
 +    default:
 +        return -1;
 +    }
 +    return 0;
 +}
 +#endif
 +
  static int64_t
  iscsi_getlength(BlockDriverState *bs)
  {
@@@ -1022,16 -884,6 +1021,16 @@@ static int iscsi_open(BlockDriverState 
      if (iscsi_url != NULL) {
          iscsi_destroy_url(iscsi_url);
      }
 +
 +    /* Medium changer or tape. We dont have any emulation for this so this must
 +     * be sg ioctl compatible. We force it to be sg, otherwise qemu will try
 +     * to read from the device to guess the image format.
 +     */
 +    if (iscsilun->type == TYPE_MEDIUM_CHANGER ||
 +        iscsilun->type == TYPE_TAPE) {
 +        bs->sg = 1;
 +    }
 +
      return 0;
  
  failed:
@@@ -1073,11 -925,6 +1072,11 @@@ static BlockDriver bdrv_iscsi = 
      .bdrv_aio_flush  = iscsi_aio_flush,
  
      .bdrv_aio_discard = iscsi_aio_discard,
 +
 +#ifdef __linux__
 +    .bdrv_ioctl       = iscsi_ioctl,
 +    .bdrv_aio_ioctl   = iscsi_aio_ioctl,
 +#endif
  };
  
  static void iscsi_block_init(void)
diff --combined block/qcow2.c
index 5be5ace6944db3c1c37465a5972a9f40027a1993,1b5b36cfc16cc11dfc11d3aeee6f5e5fb9fdbc96..870148ddf8f57e2b46d944d277e9b08ccceafc37
@@@ -220,6 -220,7 +220,6 @@@ static int qcow2_open(BlockDriverState 
      int len, i, ret = 0;
      QCowHeader header;
      uint64_t ext_end;
 -    bool writethrough;
  
      ret = bdrv_pread(bs->file, 0, &header, sizeof(header));
      if (ret < 0) {
          goto fail;
      }
  
 -    if (!bs->read_only && s->autoclear_features != 0) {
 -        s->autoclear_features = 0;
 -        ret = qcow2_update_header(bs);
 -        if (ret < 0) {
 -            goto fail;
 -        }
 -    }
 -
      /* Check support for various header values */
      if (header.refcount_order != 4) {
          report_unsupported(bs, "%d bit reference counts",
      }
  
      /* alloc L2 table/refcount block cache */
 -    writethrough = ((flags & BDRV_O_CACHE_WB) == 0);
 -    s->l2_table_cache = qcow2_cache_create(bs, L2_CACHE_SIZE, writethrough);
 -    s->refcount_block_cache = qcow2_cache_create(bs, REFCOUNT_CACHE_SIZE,
 -        writethrough);
 +    s->l2_table_cache = qcow2_cache_create(bs, L2_CACHE_SIZE);
 +    s->refcount_block_cache = qcow2_cache_create(bs, REFCOUNT_CACHE_SIZE);
  
      s->cluster_cache = g_malloc(s->cluster_size);
      /* one more sector for decompressed data alignment */
          goto fail;
      }
  
 +    /* Clear unknown autoclear feature bits */
 +    if (!bs->read_only && s->autoclear_features != 0) {
 +        s->autoclear_features = 0;
 +        ret = qcow2_update_header(bs);
 +        if (ret < 0) {
 +            goto fail;
 +        }
 +    }
 +
      /* Initialise locks */
      qemu_co_mutex_init(&s->lock);
  
  #ifdef DEBUG_ALLOC
      {
          BdrvCheckResult result = {0};
 -        qcow2_check_refcounts(bs, &result);
 +        qcow2_check_refcounts(bs, &result, 0);
      }
  #endif
      return ret;
@@@ -508,7 -510,7 +508,7 @@@ int qcow2_backing_read1(BlockDriverStat
      else
          n1 = bs->total_sectors - sector_num;
  
-     qemu_iovec_memset_skip(qiov, 0, 512 * (nb_sectors - n1), 512 * n1);
+     qemu_iovec_memset(qiov, 512 * n1, 0, 512 * (nb_sectors - n1));
  
      return n1;
  }
@@@ -547,7 -549,7 +547,7 @@@ static coroutine_fn int qcow2_co_readv(
          index_in_cluster = sector_num & (s->cluster_sectors - 1);
  
          qemu_iovec_reset(&hd_qiov);
-         qemu_iovec_copy(&hd_qiov, qiov, bytes_done,
+         qemu_iovec_concat(&hd_qiov, qiov, bytes_done,
              cur_nr_sectors * 512);
  
          switch (ret) {
                  }
              } else {
                  /* Note: in this case, no need to wait */
-                 qemu_iovec_memset(&hd_qiov, 0, 512 * cur_nr_sectors);
+                 qemu_iovec_memset(&hd_qiov, 0, 0, 512 * cur_nr_sectors);
              }
              break;
  
                  ret = -EIO;
                  goto fail;
              }
-             qemu_iovec_memset(&hd_qiov, 0, 512 * cur_nr_sectors);
+             qemu_iovec_memset(&hd_qiov, 0, 0, 512 * cur_nr_sectors);
              break;
  
          case QCOW2_CLUSTER_COMPRESSED:
                  goto fail;
              }
  
-             qemu_iovec_from_buffer(&hd_qiov,
+             qemu_iovec_from_buf(&hd_qiov, 0,
                  s->cluster_cache + index_in_cluster * 512,
                  512 * cur_nr_sectors);
              break;
              if (s->crypt_method) {
                  qcow2_encrypt_sectors(s, sector_num,  cluster_data,
                      cluster_data, cur_nr_sectors, 0, &s->aes_decrypt_key);
-                 qemu_iovec_reset(&hd_qiov);
-                 qemu_iovec_copy(&hd_qiov, qiov, bytes_done,
-                     cur_nr_sectors * 512);
-                 qemu_iovec_from_buffer(&hd_qiov, cluster_data,
-                     512 * cur_nr_sectors);
+                 qemu_iovec_from_buf(qiov, bytes_done,
+                     cluster_data, 512 * cur_nr_sectors);
              }
              break;
  
@@@ -721,7 -720,7 +718,7 @@@ static coroutine_fn int qcow2_co_writev
          assert((cluster_offset & 511) == 0);
  
          qemu_iovec_reset(&hd_qiov);
-         qemu_iovec_copy(&hd_qiov, qiov, bytes_done,
+         qemu_iovec_concat(&hd_qiov, qiov, bytes_done,
              cur_nr_sectors * 512);
  
          if (s->crypt_method) {
  
              assert(hd_qiov.size <=
                     QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
-             qemu_iovec_to_buffer(&hd_qiov, cluster_data);
+             qemu_iovec_to_buf(&hd_qiov, 0, cluster_data, hd_qiov.size);
  
              qcow2_encrypt_sectors(s, sector_num, cluster_data,
                  cluster_data, cur_nr_sectors, 1, &s->aes_encrypt_key);
@@@ -1468,10 -1467,9 +1465,10 @@@ static int qcow2_get_info(BlockDriverSt
  }
  
  
 -static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result)
 +static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result,
 +                       BdrvCheckMode fix)
  {
 -    return qcow2_check_refcounts(bs, result);
 +    return qcow2_check_refcounts(bs, result, fix);
  }
  
  #if 0
diff --combined block/qed.c
index dd2832a93b19bd19b4778593954514ac94a99b43,847417a3d6a7c84fcca06c9489c20a8e93b87f9b..5f3eefa3af00cff76c16748778e8c20a480b552e
@@@ -736,7 -736,7 +736,7 @@@ static void qed_read_backing_file(BDRVQ
      /* Zero all sectors if reading beyond the end of the backing file */
      if (pos >= backing_length ||
          pos + qiov->size > backing_length) {
-         qemu_iovec_memset(qiov, 0, qiov->size);
+         qemu_iovec_memset(qiov, 0, 0, qiov->size);
      }
  
      /* Complete now if there are no backing file sectors to read */
      /* If the read straddles the end of the backing file, shorten it */
      size = MIN((uint64_t)backing_length - pos, qiov->size);
  
 -    BLKDBG_EVENT(s->bs->file, BLKDBG_READ_BACKING);
 +    BLKDBG_EVENT(s->bs->file, BLKDBG_READ_BACKING_AIO);
      bdrv_aio_readv(s->bs->backing_hd, pos / BDRV_SECTOR_SIZE,
                     qiov, size / BDRV_SECTOR_SIZE, cb, opaque);
  }
@@@ -1131,7 -1131,7 +1131,7 @@@ static void qed_aio_write_alloc(QEDAIOC
  
      acb->cur_nclusters = qed_bytes_to_clusters(s,
              qed_offset_into_cluster(s, acb->cur_pos) + len);
-     qemu_iovec_copy(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len);
+     qemu_iovec_concat(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len);
  
      if (acb->flags & QED_AIOCB_ZERO) {
          /* Skip ahead if the clusters are already zero */
@@@ -1177,7 -1177,7 +1177,7 @@@ static void qed_aio_write_inplace(QEDAI
  
      /* Calculate the I/O vector */
      acb->cur_cluster = offset;
-     qemu_iovec_copy(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len);
+     qemu_iovec_concat(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len);
  
      /* Do the actual write */
      qed_aio_write_main(acb, 0);
@@@ -1247,11 -1247,11 +1247,11 @@@ static void qed_aio_read_data(void *opa
          goto err;
      }
  
-     qemu_iovec_copy(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len);
+     qemu_iovec_concat(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len);
  
      /* Handle zero cluster and backing file reads */
      if (ret == QED_CLUSTER_ZERO) {
-         qemu_iovec_memset(&acb->cur_qiov, 0, acb->cur_qiov.size);
+         qemu_iovec_memset(&acb->cur_qiov, 0, 0, acb->cur_qiov.size);
          qed_aio_next_io(acb, 0);
          return;
      } else if (ret != QED_CLUSTER_FOUND) {
@@@ -1517,12 -1517,11 +1517,12 @@@ static void bdrv_qed_invalidate_cache(B
      bdrv_qed_open(bs, bs->open_flags);
  }
  
 -static int bdrv_qed_check(BlockDriverState *bs, BdrvCheckResult *result)
 +static int bdrv_qed_check(BlockDriverState *bs, BdrvCheckResult *result,
 +                          BdrvCheckMode fix)
  {
      BDRVQEDState *s = bs->opaque;
  
 -    return qed_check(s, result, false);
 +    return qed_check(s, result, !!fix);
  }
  
  static QEMUOptionParameter qed_create_options[] = {
diff --combined block/rbd.c
index eebc3344620058322bb53ba8376af4a82388d277,49a4787b556adc4343053be447196ccd1d8a947d..5a0f79fc8f38e90c5c635a86b60db4c0f2f20c2f
@@@ -476,25 -476,6 +476,25 @@@ static int qemu_rbd_open(BlockDriverSta
          s->snap = g_strdup(snap_buf);
      }
  
 +    /*
 +     * Fallback to more conservative semantics if setting cache
 +     * options fails. Ignore errors from setting rbd_cache because the
 +     * only possible error is that the option does not exist, and
 +     * librbd defaults to no caching. If write through caching cannot
 +     * be set up, fall back to no caching.
 +     */
 +    if (flags & BDRV_O_NOCACHE) {
 +        rados_conf_set(s->cluster, "rbd_cache", "false");
 +    } else {
 +        rados_conf_set(s->cluster, "rbd_cache", "true");
 +        if (!(flags & BDRV_O_CACHE_WB)) {
 +            r = rados_conf_set(s->cluster, "rbd_cache_max_dirty", "0");
 +            if (r < 0) {
 +                rados_conf_set(s->cluster, "rbd_cache", "false");
 +            }
 +        }
 +    }
 +
      if (strstr(conf, "conf=") == NULL) {
          /* try default location, but ignore failure */
          rados_conf_read_file(s->cluster, NULL);
@@@ -639,7 -620,7 +639,7 @@@ static void rbd_aio_bh_cb(void *opaque
      RBDAIOCB *acb = opaque;
  
      if (acb->cmd == RBD_AIO_READ) {
-         qemu_iovec_from_buffer(acb->qiov, acb->bounce, acb->qiov->size);
+         qemu_iovec_from_buf(acb->qiov, 0, acb->bounce, acb->qiov->size);
      }
      qemu_vfree(acb->bounce);
      acb->common.cb(acb->common.opaque, (acb->ret > 0 ? 0 : acb->ret));
@@@ -693,7 -674,7 +693,7 @@@ static BlockDriverAIOCB *rbd_start_aio(
      acb->bh = NULL;
  
      if (cmd == RBD_AIO_WRITE) {
-         qemu_iovec_to_buffer(acb->qiov, acb->bounce);
+         qemu_iovec_to_buf(acb->qiov, 0, acb->bounce, qiov->size);
      }
  
      buf = acb->bounce;
diff --combined block/sheepdog.c
index 6e73efbad151f929ad33ed72d6e8137fbc7c8160,2c7aecec4f2e605be72b07b475241071fd95baa6..809df39d9e7dd22010c82e71d3ba9c68ae616ceb
@@@ -259,7 -259,8 +259,7 @@@ typedef struct AIOReq 
      uint8_t flags;
      uint32_t id;
  
 -    QLIST_ENTRY(AIOReq) outstanding_aio_siblings;
 -    QLIST_ENTRY(AIOReq) aioreq_siblings;
 +    QLIST_ENTRY(AIOReq) aio_siblings;
  } AIOReq;
  
  enum AIOCBState {
@@@ -282,7 -283,8 +282,7 @@@ struct SheepdogAIOCB 
      void (*aio_done_func)(SheepdogAIOCB *);
  
      int canceled;
 -
 -    QLIST_HEAD(aioreq_head, AIOReq) aioreq_head;
 +    int nr_pending;
  };
  
  typedef struct BDRVSheepdogState {
      Coroutine *co_recv;
  
      uint32_t aioreq_seq_num;
 -    QLIST_HEAD(outstanding_aio_head, AIOReq) outstanding_aio_head;
 +    QLIST_HEAD(inflight_aio_head, AIOReq) inflight_aio_head;
 +    QLIST_HEAD(pending_aio_head, AIOReq) pending_aio_head;
  } BDRVSheepdogState;
  
  static const char * sd_strerror(int err)
   * Sheepdog I/O handling:
   *
   * 1. In sd_co_rw_vector, we send the I/O requests to the server and
 - *    link the requests to the outstanding_list in the
 + *    link the requests to the inflight_list in the
   *    BDRVSheepdogState.  The function exits without waiting for
   *    receiving the response.
   *
@@@ -385,18 -386,21 +385,18 @@@ static inline AIOReq *alloc_aio_req(BDR
      aio_req->flags = flags;
      aio_req->id = s->aioreq_seq_num++;
  
 -    QLIST_INSERT_HEAD(&s->outstanding_aio_head, aio_req,
 -                      outstanding_aio_siblings);
 -    QLIST_INSERT_HEAD(&acb->aioreq_head, aio_req, aioreq_siblings);
 -
 +    acb->nr_pending++;
      return aio_req;
  }
  
 -static inline int free_aio_req(BDRVSheepdogState *s, AIOReq *aio_req)
 +static inline void free_aio_req(BDRVSheepdogState *s, AIOReq *aio_req)
  {
      SheepdogAIOCB *acb = aio_req->aiocb;
 -    QLIST_REMOVE(aio_req, outstanding_aio_siblings);
 -    QLIST_REMOVE(aio_req, aioreq_siblings);
 +
 +    QLIST_REMOVE(aio_req, aio_siblings);
      g_free(aio_req);
  
 -    return !QLIST_EMPTY(&acb->aioreq_head);
 +    acb->nr_pending--;
  }
  
  static void coroutine_fn sd_finish_aiocb(SheepdogAIOCB *acb)
@@@ -442,7 -446,7 +442,7 @@@ static SheepdogAIOCB *sd_aio_setup(Bloc
      acb->canceled = 0;
      acb->coroutine = qemu_coroutine_self();
      acb->ret = 0;
 -    QLIST_INIT(&acb->aioreq_head);
 +    acb->nr_pending = 0;
      return acb;
  }
  
@@@ -518,8 -522,8 +518,8 @@@ static int send_req(int sockfd, Sheepdo
      return ret;
  }
  
 -static int send_co_req(int sockfd, SheepdogReq *hdr, void *data,
 -                       unsigned int *wlen)
 +static coroutine_fn int send_co_req(int sockfd, SheepdogReq *hdr, void *data,
 +                                    unsigned int *wlen)
  {
      int ret;
  
  
      return ret;
  }
 +
 +static coroutine_fn int do_co_req(int sockfd, SheepdogReq *hdr, void *data,
 +                                  unsigned int *wlen, unsigned int *rlen);
 +
  static int do_req(int sockfd, SheepdogReq *hdr, void *data,
                    unsigned int *wlen, unsigned int *rlen)
  {
      int ret;
  
 +    if (qemu_in_coroutine()) {
 +        return do_co_req(sockfd, hdr, data, wlen, rlen);
 +    }
 +
      socket_set_block(sockfd);
      ret = send_req(sockfd, hdr, data, wlen);
      if (ret < 0) {
@@@ -580,21 -576,10 +580,21 @@@ out
      return ret;
  }
  
 -static int do_co_req(int sockfd, SheepdogReq *hdr, void *data,
 -                     unsigned int *wlen, unsigned int *rlen)
 +static void restart_co_req(void *opaque)
 +{
 +    Coroutine *co = opaque;
 +
 +    qemu_coroutine_enter(co, NULL);
 +}
 +
 +static coroutine_fn int do_co_req(int sockfd, SheepdogReq *hdr, void *data,
 +                                  unsigned int *wlen, unsigned int *rlen)
  {
      int ret;
 +    Coroutine *co;
 +
 +    co = qemu_coroutine_self();
 +    qemu_aio_set_fd_handler(sockfd, NULL, restart_co_req, NULL, co);
  
      socket_set_block(sockfd);
      ret = send_co_req(sockfd, hdr, data, wlen);
          goto out;
      }
  
 +    qemu_aio_set_fd_handler(sockfd, restart_co_req, NULL, NULL, co);
 +
      ret = qemu_co_recv(sockfd, hdr, sizeof(*hdr));
      if (ret < sizeof(*hdr)) {
          error_report("failed to get a rsp, %s", strerror(errno));
      }
      ret = 0;
  out:
 +    qemu_aio_set_fd_handler(sockfd, NULL, NULL, NULL, NULL);
      socket_set_nonblock(sockfd);
      return ret;
  }
@@@ -634,41 -616,32 +634,41 @@@ static int coroutine_fn add_aio_request
                             struct iovec *iov, int niov, int create,
                             enum AIOCBState aiocb_type);
  
 +
 +static AIOReq *find_pending_req(BDRVSheepdogState *s, uint64_t oid)
 +{
 +    AIOReq *aio_req;
 +
 +    QLIST_FOREACH(aio_req, &s->pending_aio_head, aio_siblings) {
 +        if (aio_req->oid == oid) {
 +            return aio_req;
 +        }
 +    }
 +
 +    return NULL;
 +}
 +
  /*
   * This function searchs pending requests to the object `oid', and
   * sends them.
   */
 -static void coroutine_fn send_pending_req(BDRVSheepdogState *s, uint64_t oid, uint32_t id)
 +static void coroutine_fn send_pending_req(BDRVSheepdogState *s, uint64_t oid)
  {
 -    AIOReq *aio_req, *next;
 +    AIOReq *aio_req;
      SheepdogAIOCB *acb;
      int ret;
  
 -    QLIST_FOREACH_SAFE(aio_req, &s->outstanding_aio_head,
 -                       outstanding_aio_siblings, next) {
 -        if (id == aio_req->id) {
 -            continue;
 -        }
 -        if (aio_req->oid != oid) {
 -            continue;
 -        }
 -
 +    while ((aio_req = find_pending_req(s, oid)) != NULL) {
          acb = aio_req->aiocb;
 +        /* move aio_req from pending list to inflight one */
 +        QLIST_REMOVE(aio_req, aio_siblings);
 +        QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
          ret = add_aio_request(s, aio_req, acb->qiov->iov,
                                acb->qiov->niov, 0, acb->aiocb_type);
          if (ret < 0) {
              error_report("add_aio_request is failed");
              free_aio_req(s, aio_req);
 -            if (QLIST_EMPTY(&acb->aioreq_head)) {
 +            if (!acb->nr_pending) {
                  sd_finish_aiocb(acb);
              }
          }
@@@ -689,9 -662,10 +689,9 @@@ static void coroutine_fn aio_read_respo
      int ret;
      AIOReq *aio_req = NULL;
      SheepdogAIOCB *acb;
 -    int rest;
      unsigned long idx;
  
 -    if (QLIST_EMPTY(&s->outstanding_aio_head)) {
 +    if (QLIST_EMPTY(&s->inflight_aio_head)) {
          goto out;
      }
  
          goto out;
      }
  
 -    /* find the right aio_req from the outstanding_aio list */
 -    QLIST_FOREACH(aio_req, &s->outstanding_aio_head, outstanding_aio_siblings) {
 +    /* find the right aio_req from the inflight aio list */
 +    QLIST_FOREACH(aio_req, &s->inflight_aio_head, aio_siblings) {
          if (aio_req->id == rsp.id) {
              break;
          }
               * create requests are not allowed, so we search the
               * pending requests here.
               */
 -            send_pending_req(s, vid_to_data_oid(s->inode.vdi_id, idx), rsp.id);
 +            send_pending_req(s, vid_to_data_oid(s->inode.vdi_id, idx));
          }
          break;
      case AIOCB_READ_UDATA:
-         ret = qemu_co_recvv(fd, acb->qiov->iov, rsp.data_length,
-                             aio_req->iov_offset);
+         ret = qemu_co_recvv(fd, acb->qiov->iov, acb->qiov->niov,
+                             aio_req->iov_offset, rsp.data_length);
          if (ret < 0) {
              error_report("failed to get the data, %s", strerror(errno));
              goto out;
          error_report("%s", sd_strerror(rsp.result));
      }
  
 -    rest = free_aio_req(s, aio_req);
 -    if (!rest) {
 +    free_aio_req(s, aio_req);
 +    if (!acb->nr_pending) {
          /*
           * We've finished all requests which belong to the AIOCB, so
           * we can switch back to sd_co_readv/writev now.
@@@ -793,8 -767,7 +793,8 @@@ static int aio_flush_request(void *opaq
  {
      BDRVSheepdogState *s = opaque;
  
 -    return !QLIST_EMPTY(&s->outstanding_aio_head);
 +    return !QLIST_EMPTY(&s->inflight_aio_head) ||
 +        !QLIST_EMPTY(&s->pending_aio_head);
  }
  
  static int set_nodelay(int fd)
@@@ -1019,7 -992,7 +1019,7 @@@ static int coroutine_fn add_aio_request
      }
  
      if (wlen) {
-         ret = qemu_co_sendv(s->fd, iov, wlen, aio_req->iov_offset);
+         ret = qemu_co_sendv(s->fd, iov, niov, aio_req->iov_offset, wlen);
          if (ret < 0) {
              qemu_co_mutex_unlock(&s->lock);
              error_report("failed to send a data, %s", strerror(errno));
@@@ -1111,8 -1084,7 +1111,8 @@@ static int sd_open(BlockDriverState *bs
  
      strstart(filename, "sheepdog:", (const char **)&filename);
  
 -    QLIST_INIT(&s->outstanding_aio_head);
 +    QLIST_INIT(&s->inflight_aio_head);
 +    QLIST_INIT(&s->pending_aio_head);
      s->fd = -1;
  
      memset(vdi, 0, sizeof(vdi));
@@@ -1474,7 -1446,6 +1474,7 @@@ static void coroutine_fn sd_write_done(
          iov.iov_len = sizeof(s->inode);
          aio_req = alloc_aio_req(s, acb, vid_to_vdi_oid(s->inode.vdi_id),
                                  data_len, offset, 0, 0, offset);
 +        QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
          ret = add_aio_request(s, aio_req, &iov, 1, 0, AIOCB_WRITE_UDATA);
          if (ret) {
              free_aio_req(s, aio_req);
@@@ -1543,7 -1514,7 +1543,7 @@@ out
   * Send I/O requests to the server.
   *
   * This function sends requests to the server, links the requests to
 - * the outstanding_list in BDRVSheepdogState, and exits without
 + * the inflight_list in BDRVSheepdogState, and exits without
   * waiting the response.  The responses are received in the
   * `aio_read_response' function which is called from the main loop as
   * a fd handler.
@@@ -1575,12 -1546,6 +1575,12 @@@ static int coroutine_fn sd_co_rw_vector
          }
      }
  
 +    /*
 +     * Make sure we don't free the aiocb before we are done with all requests.
 +     * This additional reference is dropped at the end of this function.
 +     */
 +    acb->nr_pending++;
 +
      while (done != total) {
          uint8_t flags = 0;
          uint64_t old_oid = 0;
          }
  
          if (create) {
 -            dprintf("update ino (%" PRIu32") %" PRIu64 " %" PRIu64
 -                    " %" PRIu64 "\n", inode->vdi_id, oid,
 +            dprintf("update ino (%" PRIu32 ") %" PRIu64 " %" PRIu64 " %ld\n",
 +                    inode->vdi_id, oid,
                      vid_to_data_oid(inode->data_vdi_id[idx], idx), idx);
              oid = vid_to_data_oid(inode->vdi_id, idx);
 -            dprintf("new oid %lx\n", oid);
 +            dprintf("new oid %" PRIx64 "\n", oid);
          }
  
          aio_req = alloc_aio_req(s, acb, oid, len, offset, flags, old_oid, done);
  
          if (create) {
              AIOReq *areq;
 -            QLIST_FOREACH(areq, &s->outstanding_aio_head,
 -                          outstanding_aio_siblings) {
 -                if (areq == aio_req) {
 -                    continue;
 -                }
 +            QLIST_FOREACH(areq, &s->inflight_aio_head, aio_siblings) {
                  if (areq->oid == oid) {
                      /*
                       * Sheepdog cannot handle simultaneous create
                       */
                      aio_req->flags = 0;
                      aio_req->base_oid = 0;
 +                    QLIST_INSERT_HEAD(&s->pending_aio_head, aio_req,
 +                                      aio_siblings);
                      goto done;
                  }
              }
          }
  
 +        QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
          ret = add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov,
                                create, acb->aiocb_type);
          if (ret < 0) {
          done += len;
      }
  out:
 -    if (QLIST_EMPTY(&acb->aioreq_head)) {
 +    if (!--acb->nr_pending) {
          return acb->ret;
      }
      return 1;
@@@ -1661,6 -1627,7 +1661,6 @@@ static coroutine_fn int sd_co_writev(Bl
      int ret;
  
      if (bs->growable && sector_num + nb_sectors > bs->total_sectors) {
 -        /* TODO: shouldn't block here */
          ret = sd_truncate(bs, (sector_num + nb_sectors) * SECTOR_SIZE);
          if (ret < 0) {
              return ret;
@@@ -1728,7 -1695,7 +1728,7 @@@ static int coroutine_fn sd_co_flush_to_
      hdr.opcode = SD_OP_FLUSH_VDI;
      hdr.oid = vid_to_vdi_oid(inode->vdi_id);
  
 -    ret = do_co_req(s->flush_fd, (SheepdogReq *)&hdr, NULL, &wlen, &rlen);
 +    ret = do_req(s->flush_fd, (SheepdogReq *)&hdr, NULL, &wlen, &rlen);
      if (ret) {
          error_report("failed to send a request to the sheep");
          return ret;
@@@ -1758,7 -1725,7 +1758,7 @@@ static int sd_snapshot_create(BlockDriv
      SheepdogInode *inode;
      unsigned int datalen;
  
 -    dprintf("sn_info: name %s id_str %s s: name %s vm_state_size %d "
 +    dprintf("sn_info: name %s id_str %s s: name %s vm_state_size %" PRId64 " "
              "is_snapshot %d\n", sn_info->name, sn_info->id_str,
              s->name, sn_info->vm_state_size, s->is_snapshot);
  
diff --combined hw/rtl8139.c
index 7b150475f4b4138d53dd49a94cceed2dc5880fb6,8128b64a0fefbfd6b2b8438c5ffb9732bafd7e2e..436b015c645e7832f15bb56ef03c13a8f206424c
@@@ -781,13 -781,6 +781,13 @@@ static inline dma_addr_t rtl8139_addr64
  #endif
  }
  
 +/* Workaround for buggy guest driver such as linux who allocates rx
 + * rings after the receiver were enabled. */
 +static bool rtl8139_cp_rx_valid(RTL8139State *s)
 +{
 +    return !(s->RxRingAddrLO == 0 && s->RxRingAddrHI == 0);
 +}
 +
  static int rtl8139_can_receive(VLANClientState *nc)
  {
      RTL8139State *s = DO_UPCAST(NICState, nc, nc)->opaque;
        return 1;
      if (!rtl8139_receiver_enabled(s))
        return 1;
 -    /* network/host communication happens only in normal mode */
 -    if ((s->Cfg9346 & Chip9346_op_mask) != Cfg9346_Normal)
 -      return 0;
  
 -    if (rtl8139_cp_receiver_enabled(s)) {
 +    if (rtl8139_cp_receiver_enabled(s) && rtl8139_cp_rx_valid(s)) {
          /* ??? Flow control not implemented in c+ mode.
             This is a hack to work around slirp deficiencies anyway.  */
          return 1;
      } else {
          avail = MOD2(s->RxBufferSize + s->RxBufPtr - s->RxBufAddr,
                       s->RxBufferSize);
 -        return (avail == 0 || avail >= 1514);
 +        return (avail == 0 || avail >= 1514 || (s->IntrMask & RxOverflow));
      }
  }
  
@@@ -840,6 -836,12 +840,6 @@@ static ssize_t rtl8139_do_receive(VLANC
          return -1;
      }
  
 -    /* check whether we are in normal mode */
 -    if ((s->Cfg9346 & Chip9346_op_mask) != Cfg9346_Normal) {
 -        DPRINTF("not in normal op mode\n");
 -        return -1;
 -    }
 -
      /* XXX: check this */
      if (s->RxConfig & AcceptAllPhys) {
          /* promiscuous: receive all */
  
      if (rtl8139_cp_receiver_enabled(s))
      {
 +        if (!rtl8139_cp_rx_valid(s)) {
 +            return size;
 +        }
 +
          DPRINTF("in C+ Rx mode ================\n");
  
          /* begin C+ receiver mode */
@@@ -1785,7 -1783,7 +1785,7 @@@ static void rtl8139_transfer_frame(RTL8
          if (iov) {
              buf2_size = iov_size(iov, 3);
              buf2 = g_malloc(buf2_size);
-             iov_to_buf(iov, 3, buf2, 0, buf2_size);
+             iov_to_buf(iov, 3, 0, buf2, buf2_size);
              buf = buf2;
          }
  
diff --combined hw/usb/core.c
index 0614f76f4f1812887a810ce052613c873248c3eb,2641685a3228ee7e431dfaa7b71486086359df17..01a76228372dcb88205b90cf88a380c12d2151f2
@@@ -522,10 -522,10 +522,10 @@@ void usb_packet_copy(USBPacket *p, voi
      switch (p->pid) {
      case USB_TOKEN_SETUP:
      case USB_TOKEN_OUT:
-         iov_to_buf(p->iov.iov, p->iov.niov, ptr, p->result, bytes);
+         iov_to_buf(p->iov.iov, p->iov.niov, p->result, ptr, bytes);
          break;
      case USB_TOKEN_IN:
-         iov_from_buf(p->iov.iov, p->iov.niov, ptr, p->result, bytes);
+         iov_from_buf(p->iov.iov, p->iov.niov, p->result, ptr, bytes);
          break;
      default:
          fprintf(stderr, "%s: invalid pid: %x\n", __func__, p->pid);
@@@ -539,7 -539,7 +539,7 @@@ void usb_packet_skip(USBPacket *p, size
      assert(p->result >= 0);
      assert(p->result + bytes <= p->iov.size);
      if (p->pid == USB_TOKEN_IN) {
-         iov_clear(p->iov.iov, p->iov.niov, p->result, bytes);
+         iov_memset(p->iov.iov, p->iov.niov, p->result, 0, bytes);
      }
      p->result += bytes;
  }
@@@ -550,7 -550,7 +550,7 @@@ void usb_packet_cleanup(USBPacket *p
      qemu_iovec_destroy(&p->iov);
  }
  
 -void usb_ep_init(USBDevice *dev)
 +void usb_ep_reset(USBDevice *dev)
  {
      int ep;
  
      dev->ep_ctl.ifnum = 0;
      dev->ep_ctl.dev = dev;
      dev->ep_ctl.pipeline = false;
 -    QTAILQ_INIT(&dev->ep_ctl.queue);
      for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) {
          dev->ep_in[ep].nr = ep + 1;
          dev->ep_out[ep].nr = ep + 1;
          dev->ep_out[ep].pid = USB_TOKEN_OUT;
          dev->ep_in[ep].type = USB_ENDPOINT_XFER_INVALID;
          dev->ep_out[ep].type = USB_ENDPOINT_XFER_INVALID;
 -        dev->ep_in[ep].ifnum = 0;
 -        dev->ep_out[ep].ifnum = 0;
 +        dev->ep_in[ep].ifnum = USB_INTERFACE_INVALID;
 +        dev->ep_out[ep].ifnum = USB_INTERFACE_INVALID;
          dev->ep_in[ep].dev = dev;
          dev->ep_out[ep].dev = dev;
          dev->ep_in[ep].pipeline = false;
          dev->ep_out[ep].pipeline = false;
 +    }
 +}
 +
 +void usb_ep_init(USBDevice *dev)
 +{
 +    int ep;
 +
 +    usb_ep_reset(dev);
 +    QTAILQ_INIT(&dev->ep_ctl.queue);
 +    for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) {
          QTAILQ_INIT(&dev->ep_in[ep].queue);
          QTAILQ_INIT(&dev->ep_out[ep].queue);
      }
diff --combined hw/virtio-balloon.c
index d048cef50ffd2a7ea26ee34f8836ec904dc0ec63,23effa40a08b4e829e163ee68aafca9431404b6e..dd1a6506cf2a13d594bfbe7d51a16d56a3e899c2
@@@ -77,7 -77,7 +77,7 @@@ static void virtio_balloon_handle_outpu
          size_t offset = 0;
          uint32_t pfn;
  
-         while (iov_to_buf(elem.out_sg, elem.out_num, &pfn, offset, 4) == 4) {
+         while (iov_to_buf(elem.out_sg, elem.out_num, offset, &pfn, 4) == 4) {
              ram_addr_t pa;
              ram_addr_t addr;
  
@@@ -118,7 -118,7 +118,7 @@@ static void virtio_balloon_receive_stat
       */
      reset_stats(s);
  
-     while (iov_to_buf(elem->out_sg, elem->out_num, &stat, offset, sizeof(stat))
+     while (iov_to_buf(elem->out_sg, elem->out_num, offset, &stat, sizeof(stat))
             == sizeof(stat)) {
          uint16_t tag = tswap16(stat.tag);
          uint64_t val = tswap64(stat.val);
@@@ -146,13 -146,8 +146,13 @@@ static void virtio_balloon_set_config(V
  {
      VirtIOBalloon *dev = to_virtio_balloon(vdev);
      struct virtio_balloon_config config;
 +    uint32_t oldactual = dev->actual;
      memcpy(&config, config_data, 8);
      dev->actual = le32_to_cpu(config.actual);
 +    if (dev->actual != oldactual) {
 +        qemu_balloon_changed(ram_size -
 +                             (dev->actual << VIRTIO_BALLOON_PFN_SHIFT));
 +    }
  }
  
  static uint32_t virtio_balloon_get_features(VirtIODevice *vdev, uint32_t f)
diff --combined hw/virtio-serial-bus.c
index 96382a4ea164a176e5851852110aa788e8293d8a,728f218dcf29c016e3ce4169c55dc3b8960dcea1..82073f5dc2615e278eb601a2310a15d5e33b9176
@@@ -106,8 -106,8 +106,8 @@@ static size_t write_to_port(VirtIOSeria
              break;
          }
  
-         len = iov_from_buf(elem.in_sg, elem.in_num,
-                            buf + offset, 0, size - offset);
+         len = iov_from_buf(elem.in_sg, elem.in_num, 0,
+                            buf + offset, size - offset);
          offset += len;
  
          virtqueue_push(vq, &elem, len);
@@@ -454,7 -454,7 +454,7 @@@ static void control_out(VirtIODevice *v
      len = 0;
      buf = NULL;
      while (virtqueue_pop(vq, &elem)) {
-         size_t cur_len, copied;
+         size_t cur_len;
  
          cur_len = iov_size(elem.out_sg, elem.out_num);
          /*
              buf = g_malloc(cur_len);
              len = cur_len;
          }
-         copied = iov_to_buf(elem.out_sg, elem.out_num, buf, 0, len);
+         iov_to_buf(elem.out_sg, elem.out_num, 0, buf, cur_len);
  
-         handle_control_message(vser, buf, copied);
+         handle_control_message(vser, buf, cur_len);
          virtqueue_push(vq, &elem, 0);
      }
      g_free(buf);
@@@ -728,27 -728,15 +728,27 @@@ static int virtio_serial_load(QEMUFile 
  
  static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent);
  
 -static struct BusInfo virtser_bus_info = {
 -    .name      = "virtio-serial-bus",
 -    .size      = sizeof(VirtIOSerialBus),
 -    .print_dev = virtser_bus_dev_print,
 -    .props      = (Property[]) {
 -        DEFINE_PROP_UINT32("nr", VirtIOSerialPort, id, VIRTIO_CONSOLE_BAD_ID),
 -        DEFINE_PROP_STRING("name", VirtIOSerialPort, name),
 -        DEFINE_PROP_END_OF_LIST()
 -    }
 +static Property virtser_props[] = {
 +    DEFINE_PROP_UINT32("nr", VirtIOSerialPort, id, VIRTIO_CONSOLE_BAD_ID),
 +    DEFINE_PROP_STRING("name", VirtIOSerialPort, name),
 +    DEFINE_PROP_END_OF_LIST()
 +};
 +
 +#define TYPE_VIRTIO_SERIAL_BUS "virtio-serial-bus"
 +#define VIRTIO_SERIAL_BUS(obj) \
 +      OBJECT_CHECK(VirtIOSerialBus, (obj), TYPE_VIRTIO_SERIAL_BUS)
 +
 +static void virtser_bus_class_init(ObjectClass *klass, void *data)
 +{
 +    BusClass *k = BUS_CLASS(klass);
 +    k->print_dev = virtser_bus_dev_print;
 +}
 +
 +static const TypeInfo virtser_bus_info = {
 +    .name = TYPE_VIRTIO_SERIAL_BUS,
 +    .parent = TYPE_BUS,
 +    .instance_size = sizeof(VirtIOSerialBus),
 +    .class_init = virtser_bus_class_init,
  };
  
  static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
@@@ -916,7 -904,7 +916,7 @@@ VirtIODevice *virtio_serial_init(Device
      vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
  
      /* Spawn a new virtio-serial bus on which the ports will ride as devices */
 -    qbus_create_inplace(&vser->bus.qbus, &virtser_bus_info, dev, NULL);
 +    qbus_create_inplace(&vser->bus.qbus, TYPE_VIRTIO_SERIAL_BUS, dev, NULL);
      vser->bus.qbus.allow_hotplug = 1;
      vser->bus.vser = vser;
      QTAILQ_INIT(&vser->ports);
@@@ -992,10 -980,9 +992,10 @@@ static void virtio_serial_port_class_in
  {
      DeviceClass *k = DEVICE_CLASS(klass);
      k->init = virtser_port_qdev_init;
 -    k->bus_info = &virtser_bus_info;
 +    k->bus_type = TYPE_VIRTIO_SERIAL_BUS;
      k->exit = virtser_port_qdev_exit;
      k->unplug = qdev_simple_unplug_cb;
 +    k->props = virtser_props;
  }
  
  static TypeInfo virtio_serial_port_type_info = {
  
  static void virtio_serial_register_types(void)
  {
 +    type_register_static(&virtser_bus_info);
      type_register_static(&virtio_serial_port_type_info);
  }
  
diff --combined qemu-common.h
index c8c6b2ae352044e3d33f75d1df39863ae457fd69,71395771dbf4c42edb90114460d0adcdc8865af5..09676f529fce6b77345ead37107706684395b10a
@@@ -17,7 -17,6 +17,7 @@@ typedef struct DeviceState DeviceState
  
  struct Monitor;
  typedef struct Monitor Monitor;
 +typedef struct MigrationParams MigrationParams;
  
  /* we put basic includes here to avoid repeating them in device drivers */
  #include <stdlib.h>
@@@ -206,9 -205,6 +206,6 @@@ int qemu_pipe(int pipefd[2])
  #define qemu_recv(sockfd, buf, len, flags) recv(sockfd, buf, len, flags)
  #endif
  
- int qemu_recvv(int sockfd, struct iovec *iov, int len, int iov_offset);
- int qemu_sendv(int sockfd, struct iovec *iov, int len, int iov_offset);
  /* Error handling.  */
  
  void QEMU_NORETURN hw_error(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
@@@ -240,7 -236,6 +237,7 @@@ typedef struct VLANState VLANState
  typedef struct VLANClientState VLANClientState;
  typedef struct i2c_bus i2c_bus;
  typedef struct ISABus ISABus;
 +typedef struct ISADevice ISADevice;
  typedef struct SMBusDevice SMBusDevice;
  typedef struct PCIHostState PCIHostState;
  typedef struct PCIExpressHost PCIExpressHost;
@@@ -276,13 -271,6 +273,13 @@@ typedef enum LostTickPolicy 
      LOST_TICK_MAX
  } LostTickPolicy;
  
 +typedef struct PCIHostDeviceAddress {
 +    unsigned int domain;
 +    unsigned int bus;
 +    unsigned int slot;
 +    unsigned int function;
 +} PCIHostDeviceAddress;
 +
  void tcg_exec_init(unsigned long tb_size);
  bool tcg_enabled(void);
  
@@@ -312,32 -300,29 +309,29 @@@ struct qemu_work_item 
  void qemu_init_vcpu(void *env);
  #endif
  
- /**
-  * Sends an iovec (or optionally a part of it) down a socket, yielding
-  * when the socket is full.
-  */
- int qemu_co_sendv(int sockfd, struct iovec *iov,
-                   int len, int iov_offset);
- /**
-  * Receives data into an iovec (or optionally into a part of it) from
-  * a socket, yielding when there is no data in the socket.
-  */
- int qemu_co_recvv(int sockfd, struct iovec *iov,
-                   int len, int iov_offset);
  
  /**
-  * Sends a buffer down a socket, yielding when the socket is full.
+  * Sends a (part of) iovec down a socket, yielding when the socket is full, or
+  * Receives data into a (part of) iovec from a socket,
+  * yielding when there is no data in the socket.
+  * The same interface as qemu_sendv_recvv(), with added yielding.
+  * XXX should mark these as coroutine_fn
   */
- int qemu_co_send(int sockfd, void *buf, int len);
+ ssize_t qemu_co_sendv_recvv(int sockfd, struct iovec *iov, unsigned iov_cnt,
+                             size_t offset, size_t bytes, bool do_send);
+ #define qemu_co_recvv(sockfd, iov, iov_cnt, offset, bytes) \
+   qemu_co_sendv_recvv(sockfd, iov, iov_cnt, offset, bytes, false)
+ #define qemu_co_sendv(sockfd, iov, iov_cnt, offset, bytes) \
+   qemu_co_sendv_recvv(sockfd, iov, iov_cnt, offset, bytes, true)
  
  /**
-  * Receives data into a buffer from a socket, yielding when there
-  * is no data in the socket.
+  * The same as above, but with just a single buffer
   */
- int qemu_co_recv(int sockfd, void *buf, int len);
+ ssize_t qemu_co_send_recv(int sockfd, void *buf, size_t bytes, bool do_send);
+ #define qemu_co_recv(sockfd, buf, bytes) \
+   qemu_co_send_recv(sockfd, buf, bytes, false)
+ #define qemu_co_send(sockfd, buf, bytes) \
+   qemu_co_send_recv(sockfd, buf, bytes, true)
  
  typedef struct QEMUIOVector {
      struct iovec *iov;
  void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint);
  void qemu_iovec_init_external(QEMUIOVector *qiov, struct iovec *iov, int niov);
  void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len);
- void qemu_iovec_copy(QEMUIOVector *dst, QEMUIOVector *src, uint64_t skip,
-     size_t size);
- void qemu_iovec_concat(QEMUIOVector *dst, QEMUIOVector *src, size_t size);
+ void qemu_iovec_concat(QEMUIOVector *dst,
+                        QEMUIOVector *src, size_t soffset, size_t sbytes);
  void qemu_iovec_destroy(QEMUIOVector *qiov);
  void qemu_iovec_reset(QEMUIOVector *qiov);
- void qemu_iovec_to_buffer(QEMUIOVector *qiov, void *buf);
- void qemu_iovec_from_buffer(QEMUIOVector *qiov, const void *buf, size_t count);
- void qemu_iovec_memset(QEMUIOVector *qiov, int c, size_t count);
- void qemu_iovec_memset_skip(QEMUIOVector *qiov, int c, size_t count,
-                             size_t skip);
+ size_t qemu_iovec_to_buf(QEMUIOVector *qiov, size_t offset,
+                          void *buf, size_t bytes);
+ size_t qemu_iovec_from_buf(QEMUIOVector *qiov, size_t offset,
+                            const void *buf, size_t bytes);
+ size_t qemu_iovec_memset(QEMUIOVector *qiov, size_t offset,
+                          int fillc, size_t bytes);
  
  bool buffer_is_zero(const void *buf, size_t len);
  
diff --combined tests/Makefile
index d66ab196a7448d6a490f95e543fe508aa3888e94,7340bc5044cc2d12fde446dcb041d802c61a6cce..d687ecce3f495375ef75d9a4eb5a958b9b5dd10b
@@@ -13,7 -13,7 +13,8 @@@ check-unit-y += tests/test-qmp-commands
  check-unit-y += tests/test-string-input-visitor$(EXESUF)
  check-unit-y += tests/test-string-output-visitor$(EXESUF)
  check-unit-y += tests/test-coroutine$(EXESUF)
 +check-unit-y += tests/test-visitor-serialization$(EXESUF)
+ check-unit-y += tests/test-iov$(EXESUF)
  
  check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh
  
@@@ -32,12 -32,13 +33,12 @@@ test-obj-y = tests/check-qint.o tests/c
        tests/test-coroutine.o tests/test-string-output-visitor.o \
        tests/test-string-input-visitor.o tests/test-qmp-output-visitor.o \
        tests/test-qmp-input-visitor.o tests/test-qmp-input-strict.o \
 -      tests/test-qmp-commands.o
 +      tests/test-qmp-commands.o tests/test-visitor-serialization.o
  
  test-qapi-obj-y =  $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y)
  test-qapi-obj-y += tests/test-qapi-visit.o tests/test-qapi-types.o
  test-qapi-obj-y += module.o
  
 -$(test-obj-y): $(GENERATED_HEADERS)
  $(test-obj-y): QEMU_INCLUDES += -Itests
  
  tests/check-qint$(EXESUF): tests/check-qint.o qint.o $(tools-obj-y)
@@@ -47,6 -48,7 +48,7 @@@ tests/check-qlist$(EXESUF): tests/check
  tests/check-qfloat$(EXESUF): tests/check-qfloat.o qfloat.o $(tools-obj-y)
  tests/check-qjson$(EXESUF): tests/check-qjson.o $(qobject-obj-y) $(tools-obj-y)
  tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(coroutine-obj-y) $(tools-obj-y)
+ tests/test-iov$(EXESUF): tests/test-iov.o iov.o
  
  tests/test-qapi-types.c tests/test-qapi-types.h :\
  $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py
@@@ -65,7 -67,6 +67,7 @@@ tests/test-qmp-output-visitor$(EXESUF)
  tests/test-qmp-input-visitor$(EXESUF): tests/test-qmp-input-visitor.o $(test-qapi-obj-y)
  tests/test-qmp-input-strict$(EXESUF): tests/test-qmp-input-strict.o $(test-qapi-obj-y)
  tests/test-qmp-commands$(EXESUF): tests/test-qmp-commands.o tests/test-qmp-marshal.o $(test-qapi-obj-y)
 +tests/test-visitor-serialization$(EXESUF): tests/test-visitor-serialization.o $(test-qapi-obj-y)
  
  tests/rtc-test$(EXESUF): tests/rtc-test.o $(trace-obj-y)
  tests/m48t59-test$(EXESUF): tests/m48t59-test.o $(trace-obj-y)