0005-VMDK-separate-vmdk_open-by-format-version.patch 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. From 97cf5df76657bab81d6b8669607f6f13215201c1 Mon Sep 17 00:00:00 2001
  2. From: Fam Zheng <[email protected]>
  3. Date: Tue, 12 Jul 2011 19:56:31 +0800
  4. Subject: [PATCH 05/12] VMDK: separate vmdk_open by format version
  5. Separate vmdk_open by subformats to:
  6. * vmdk_open_vmdk3
  7. * vmdk_open_vmdk4
  8. Signed-off-by: Fam Zheng <[email protected]>
  9. Reviewed-by: Stefan Hajnoczi <[email protected]>
  10. Signed-off-by: Kevin Wolf <[email protected]>
  11. ---
  12. block/vmdk.c | 178 +++++++++++++++++++++++++++++++++++++----------------------
  13. 1 file changed, 112 insertions(+), 66 deletions(-)
  14. --- a/block/vmdk.c
  15. +++ b/block/vmdk.c
  16. @@ -458,67 +458,20 @@ static VmdkExtent *vmdk_add_extent(Block
  17. return extent;
  18. }
  19. -
  20. -static int vmdk_open(BlockDriverState *bs, int flags)
  21. +static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent)
  22. {
  23. - BDRVVmdkState *s = bs->opaque;
  24. - uint32_t magic;
  25. - int i;
  26. - uint32_t l1_size, l1_entry_sectors;
  27. - VmdkExtent *extent = NULL;
  28. -
  29. - if (bdrv_pread(bs->file, 0, &magic, sizeof(magic)) != sizeof(magic))
  30. - goto fail;
  31. -
  32. - magic = be32_to_cpu(magic);
  33. - if (magic == VMDK3_MAGIC) {
  34. - VMDK3Header header;
  35. - if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header))
  36. - != sizeof(header)) {
  37. - goto fail;
  38. - }
  39. - extent = vmdk_add_extent(bs, bs->file, false,
  40. - le32_to_cpu(header.disk_sectors),
  41. - le32_to_cpu(header.l1dir_offset) << 9, 0,
  42. - 1 << 6, 1 << 9, le32_to_cpu(header.granularity));
  43. - } else if (magic == VMDK4_MAGIC) {
  44. - VMDK4Header header;
  45. - if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header))
  46. - != sizeof(header)) {
  47. - goto fail;
  48. - }
  49. - l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte)
  50. - * le64_to_cpu(header.granularity);
  51. - l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
  52. - / l1_entry_sectors;
  53. - extent = vmdk_add_extent(bs, bs->file, false,
  54. - le64_to_cpu(header.capacity),
  55. - le64_to_cpu(header.gd_offset) << 9,
  56. - le64_to_cpu(header.rgd_offset) << 9,
  57. - l1_size,
  58. - le32_to_cpu(header.num_gtes_per_gte),
  59. - le64_to_cpu(header.granularity));
  60. - if (extent->l1_entry_sectors <= 0) {
  61. - goto fail;
  62. - }
  63. - // try to open parent images, if exist
  64. - if (vmdk_parent_open(bs) != 0)
  65. - goto fail;
  66. - // write the CID once after the image creation
  67. - s->parent_cid = vmdk_read_cid(bs,1);
  68. - } else {
  69. - goto fail;
  70. - }
  71. + int ret;
  72. + int l1_size, i;
  73. /* read the L1 table */
  74. l1_size = extent->l1_size * sizeof(uint32_t);
  75. extent->l1_table = qemu_malloc(l1_size);
  76. - if (bdrv_pread(bs->file,
  77. - extent->l1_table_offset,
  78. - extent->l1_table,
  79. - l1_size)
  80. - != l1_size) {
  81. - goto fail;
  82. + ret = bdrv_pread(extent->file,
  83. + extent->l1_table_offset,
  84. + extent->l1_table,
  85. + l1_size);
  86. + if (ret < 0) {
  87. + goto fail_l1;
  88. }
  89. for (i = 0; i < extent->l1_size; i++) {
  90. le32_to_cpus(&extent->l1_table[i]);
  91. @@ -526,12 +479,12 @@ static int vmdk_open(BlockDriverState *b
  92. if (extent->l1_backup_table_offset) {
  93. extent->l1_backup_table = qemu_malloc(l1_size);
  94. - if (bdrv_pread(bs->file,
  95. - extent->l1_backup_table_offset,
  96. - extent->l1_backup_table,
  97. - l1_size)
  98. - != l1_size) {
  99. - goto fail;
  100. + ret = bdrv_pread(extent->file,
  101. + extent->l1_backup_table_offset,
  102. + extent->l1_backup_table,
  103. + l1_size);
  104. + if (ret < 0) {
  105. + goto fail_l1b;
  106. }
  107. for (i = 0; i < extent->l1_size; i++) {
  108. le32_to_cpus(&extent->l1_backup_table[i]);
  109. @@ -541,9 +494,102 @@ static int vmdk_open(BlockDriverState *b
  110. extent->l2_cache =
  111. qemu_malloc(extent->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));
  112. return 0;
  113. + fail_l1b:
  114. + qemu_free(extent->l1_backup_table);
  115. + fail_l1:
  116. + qemu_free(extent->l1_table);
  117. + return ret;
  118. +}
  119. +
  120. +static int vmdk_open_vmdk3(BlockDriverState *bs, int flags)
  121. +{
  122. + int ret;
  123. + uint32_t magic;
  124. + VMDK3Header header;
  125. + VmdkExtent *extent;
  126. +
  127. + ret = bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header));
  128. + if (ret < 0) {
  129. + goto fail;
  130. + }
  131. + extent = vmdk_add_extent(bs,
  132. + bs->file, false,
  133. + le32_to_cpu(header.disk_sectors),
  134. + le32_to_cpu(header.l1dir_offset) << 9,
  135. + 0, 1 << 6, 1 << 9,
  136. + le32_to_cpu(header.granularity));
  137. + ret = vmdk_init_tables(bs, extent);
  138. + if (ret) {
  139. + /* vmdk_init_tables cleans up on fail, so only free allocation of
  140. + * vmdk_add_extent here. */
  141. + goto fail;
  142. + }
  143. + return 0;
  144. fail:
  145. vmdk_free_extents(bs);
  146. - return -1;
  147. + return ret;
  148. +}
  149. +
  150. +static int vmdk_open_vmdk4(BlockDriverState *bs, int flags)
  151. +{
  152. + int ret;
  153. + uint32_t magic;
  154. + uint32_t l1_size, l1_entry_sectors;
  155. + VMDK4Header header;
  156. + BDRVVmdkState *s = bs->opaque;
  157. + VmdkExtent *extent;
  158. +
  159. + ret = bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header));
  160. + if (ret < 0) {
  161. + goto fail;
  162. + }
  163. + l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte)
  164. + * le64_to_cpu(header.granularity);
  165. + l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
  166. + / l1_entry_sectors;
  167. + extent = vmdk_add_extent(bs, bs->file, false,
  168. + le64_to_cpu(header.capacity),
  169. + le64_to_cpu(header.gd_offset) << 9,
  170. + le64_to_cpu(header.rgd_offset) << 9,
  171. + l1_size,
  172. + le32_to_cpu(header.num_gtes_per_gte),
  173. + le64_to_cpu(header.granularity));
  174. + if (extent->l1_entry_sectors <= 0) {
  175. + ret = -EINVAL;
  176. + goto fail;
  177. + }
  178. + /* try to open parent images, if exist */
  179. + ret = vmdk_parent_open(bs);
  180. + if (ret) {
  181. + goto fail;
  182. + }
  183. + s->parent_cid = vmdk_read_cid(bs, 1);
  184. + ret = vmdk_init_tables(bs, extent);
  185. + if (ret) {
  186. + goto fail;
  187. + }
  188. + return 0;
  189. + fail:
  190. + vmdk_free_extents(bs);
  191. + return ret;
  192. +}
  193. +
  194. +static int vmdk_open(BlockDriverState *bs, int flags)
  195. +{
  196. + uint32_t magic;
  197. +
  198. + if (bdrv_pread(bs->file, 0, &magic, sizeof(magic)) != sizeof(magic)) {
  199. + return -EIO;
  200. + }
  201. +
  202. + magic = be32_to_cpu(magic);
  203. + if (magic == VMDK3_MAGIC) {
  204. + return vmdk_open_vmdk3(bs, flags);
  205. + } else if (magic == VMDK4_MAGIC) {
  206. + return vmdk_open_vmdk4(bs, flags);
  207. + } else {
  208. + return -EINVAL;
  209. + }
  210. }
  211. static int get_whole_cluster(BlockDriverState *bs,
  212. @@ -630,11 +676,11 @@ static uint64_t get_cluster_offset(Block
  213. if (!l2_offset) {
  214. return 0;
  215. }
  216. - for(i = 0; i < L2_CACHE_SIZE; i++) {
  217. + for (i = 0; i < L2_CACHE_SIZE; i++) {
  218. if (l2_offset == extent->l2_cache_offsets[i]) {
  219. /* increment the hit count */
  220. if (++extent->l2_cache_counts[i] == 0xffffffff) {
  221. - for(j = 0; j < L2_CACHE_SIZE; j++) {
  222. + for (j = 0; j < L2_CACHE_SIZE; j++) {
  223. extent->l2_cache_counts[j] >>= 1;
  224. }
  225. }
  226. @@ -645,7 +691,7 @@ static uint64_t get_cluster_offset(Block
  227. /* not found: load a new entry in the least used one */
  228. min_index = 0;
  229. min_count = 0xffffffff;
  230. - for(i = 0; i < L2_CACHE_SIZE; i++) {
  231. + for (i = 0; i < L2_CACHE_SIZE; i++) {
  232. if (extent->l2_cache_counts[i] < min_count) {
  233. min_count = extent->l2_cache_counts[i];
  234. min_index = i;