qcow2: Rewrite alloc_refcount_block/grow_refcount_table

The current implementation of alloc_refcount_block and grow_refcount_table has
fundamental problems regarding error handling. There are some places where an
I/O error means that the image is going to be corrupted. I have found that the
only way to fix this is to completely rewrite the thing.

In detail, the problem is that the refcount blocks itself are allocated using
alloc_refcount_noref (to avoid endless recursion when updating the refcount of
the new refcount block, which migh access just the same refcount block but its
allocation is not yet completed...). Only at the end of the refcount allocation
the refcount of the refcount block is increased. If an error happens in
between, the refcount block is in use, but has a refcount of zero and will
likely be overwritten later.

The new approach is explained in comments in the code. The trick is basically
to let new refcount blocks describe their own refcount, so their refcount will
be automatically changed when they are hooked up in the refcount table.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
1 file changed
tree: 53b14f5af9bcdbcef9c0ec8ec180b3a9586ed7fc
  1. audio/
  2. block/
  3. bsd-user/
  4. darwin-user/
  5. default-configs/
  6. docs/
  7. fpu/
  8. gdb-xml/
  9. hw/
  10. linux-user/
  11. net/
  12. pc-bios/
  13. QMP/
  14. roms/
  15. slirp/
  16. sysconfigs/
  17. target-alpha/
  18. target-arm/
  19. target-cris/
  20. target-i386/
  21. target-m68k/
  22. target-microblaze/
  23. target-mips/
  24. target-ppc/
  25. target-s390x/
  26. target-sh4/
  27. target-sparc/
  28. tcg/
  29. tests/
  30. .gitignore
  31. .gitmodules
  32. a.out.h
  33. acl.c
  34. acl.h
  35. aes.c
  36. aes.h
  37. aio.c
  38. alpha-dis.c
  39. alpha.ld
  40. arm-dis.c
  41. arm-semi.c
  42. arm.ld
  43. async.c
  44. balloon.h
  45. block-migration.c
  46. block-migration.h
  47. block.c
  48. block.h
  49. block_int.h
  50. bswap.h
  51. bt-host.c
  52. bt-host.h
  53. bt-vhci.c
  54. buffered_file.c
  55. buffered_file.h
  56. cache-utils.c
  57. cache-utils.h
  58. Changelog
  59. check-qdict.c
  60. check-qfloat.c
  61. check-qint.c
  62. check-qjson.c
  63. check-qlist.c
  64. check-qstring.c
  65. cmd.c
  66. cmd.h
  67. cocoa.m
  68. CODING_STYLE
  69. config.h
  70. configure
  71. console.c
  72. console.h
  73. COPYING
  74. COPYING.LIB
  75. cpu-all.h
  76. cpu-common.h
  77. cpu-defs.h
  78. cpu-exec.c
  79. create_config
  80. cris-dis.c
  81. curses.c
  82. curses_keys.h
  83. cutils.c
  84. d3des.c
  85. d3des.h
  86. def-helper.h
  87. device_tree.c
  88. device_tree.h
  89. dis-asm.h
  90. disas.c
  91. disas.h
  92. dma-helpers.c
  93. dma.h
  94. dyngen-exec.h
  95. elf.h
  96. envlist.c
  97. envlist.h
  98. exec-all.h
  99. exec.c
  100. feature_to_c.sh
  101. gdbstub.c
  102. gdbstub.h
  103. gen-icount.h
  104. host-utils.c
  105. host-utils.h
  106. hpet.h
  107. hppa-dis.c
  108. hppa.ld
  109. hxtool
  110. i386-dis.c
  111. i386.ld
  112. ia64.ld
  113. input.c
  114. ioport-user.c
  115. ioport.c
  116. ioport.h
  117. json-lexer.c
  118. json-lexer.h
  119. json-parser.c
  120. json-parser.h
  121. json-streamer.c
  122. json-streamer.h
  123. keymaps.c
  124. keymaps.h
  125. kvm-all.c
  126. kvm.h
  127. libfdt_env.h
  128. LICENSE
  129. linux-aio.c
  130. m68k-dis.c
  131. m68k-semi.c
  132. m68k.ld
  133. MAINTAINERS
  134. Makefile
  135. Makefile.hw
  136. Makefile.objs
  137. Makefile.target
  138. Makefile.user
  139. microblaze-dis.c
  140. migration-exec.c
  141. migration-fd.c
  142. migration-tcp.c
  143. migration-unix.c
  144. migration.c
  145. migration.h
  146. mips-dis.c
  147. mips.ld
  148. module.c
  149. module.h
  150. monitor.c
  151. monitor.h
  152. nbd.c
  153. nbd.h
  154. net-checksum.c
  155. net.c
  156. net.h
  157. osdep.c
  158. osdep.h
  159. path.c
  160. pci-ids.txt
  161. posix-aio-compat.c
  162. ppc-dis.c
  163. ppc.ld
  164. ppc64.ld
  165. qbool.c
  166. qbool.h
  167. qdict-test-data.txt
  168. qdict.c
  169. qdict.h
  170. qemu-aio.h
  171. qemu-barrier.h
  172. qemu-binfmt-conf.sh
  173. qemu-char.c
  174. qemu-char.h
  175. qemu-common.h
  176. qemu-config.c
  177. qemu-config.h
  178. qemu-doc.texi
  179. qemu-img-cmds.hx
  180. qemu-img.c
  181. qemu-img.texi
  182. qemu-io.c
  183. qemu-lock.h
  184. qemu-log.h
  185. qemu-malloc.c
  186. qemu-monitor.hx
  187. qemu-nbd.c
  188. qemu-nbd.texi
  189. qemu-objects.h
  190. qemu-option.c
  191. qemu-option.h
  192. qemu-options.hx
  193. qemu-queue.h
  194. qemu-sockets.c
  195. qemu-tech.texi
  196. qemu-thread.c
  197. qemu-thread.h
  198. qemu-timer.h
  199. qemu-tool.c
  200. qemu.sasl
  201. qemu_socket.h
  202. qerror.c
  203. qerror.h
  204. qfloat.c
  205. qfloat.h
  206. qint.c
  207. qint.h
  208. qjson.c
  209. qjson.h
  210. qlist.c
  211. qlist.h
  212. qobject.h
  213. qstring.c
  214. qstring.h
  215. readline.c
  216. readline.h
  217. README
  218. rules.mak
  219. rwhandler.c
  220. rwhandler.h
  221. s390-dis.c
  222. s390.ld
  223. savevm.c
  224. sdl.c
  225. sdl_keysym.h
  226. sdl_zoom.c
  227. sdl_zoom.h
  228. sdl_zoom_template.h
  229. sh4-dis.c
  230. softmmu-semi.h
  231. softmmu_defs.h
  232. softmmu_exec.h
  233. softmmu_header.h
  234. softmmu_template.h
  235. sparc-dis.c
  236. sparc.ld
  237. sparc64.ld
  238. sysemu.h
  239. targphys.h
  240. tcg-runtime.c
  241. texi2pod.pl
  242. thunk.c
  243. thunk.h
  244. TODO
  245. translate-all.c
  246. uboot_image.h
  247. usb-bsd.c
  248. usb-linux.c
  249. usb-stub.c
  250. VERSION
  251. vgafont.h
  252. vl.c
  253. vnc-auth-sasl.c
  254. vnc-auth-sasl.h
  255. vnc-auth-vencrypt.c
  256. vnc-auth-vencrypt.h
  257. vnc-tls.c
  258. vnc-tls.h
  259. vnc.c
  260. vnc.h
  261. vnc_keysym.h
  262. vnchextile.h
  263. x86_64.ld
  264. x_keymap.c
  265. x_keymap.h