All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v6 0/2] vmdk: Optimize cluster allocation
@ 2014-07-30  6:39 Fam Zheng
  2014-07-30  6:39 ` [Qemu-devel] [PATCH v6 1/2] qemu-iotests: Add data pattern in version3 VMDK sample image in 059 Fam Zheng
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Fam Zheng @ 2014-07-30  6:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Stefan Hajnoczi

V6: Address Stefan's comments. See patch 02 for changelog. (Thanks for reviewing)


Fam Zheng (2):
  qemu-iotests: Add data pattern in version3 VMDK sample image in 059
  vmdk: Optimize cluster allocation

 block/vmdk.c                                       | 222 +++++++++++++--------
 tests/qemu-iotests/059                             |   4 +
 tests/qemu-iotests/059.out                         | 202 ++++++++++++++++++-
 .../sample_images/iotest-version3.vmdk.bz2         | Bin 414 -> 4764 bytes
 4 files changed, 345 insertions(+), 83 deletions(-)

-- 
2.0.3

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Qemu-devel] [PATCH v6 1/2] qemu-iotests: Add data pattern in version3 VMDK sample image in 059
  2014-07-30  6:39 [Qemu-devel] [PATCH v6 0/2] vmdk: Optimize cluster allocation Fam Zheng
@ 2014-07-30  6:39 ` Fam Zheng
  2014-07-30  6:39 ` [Qemu-devel] [PATCH v6 2/2] vmdk: Optimize cluster allocation Fam Zheng
  2014-07-30 13:55 ` [Qemu-devel] [PATCH v6 0/2] " Stefan Hajnoczi
  2 siblings, 0 replies; 4+ messages in thread
From: Fam Zheng @ 2014-07-30  6:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Stefan Hajnoczi

It's possible that we diverge from the specification with our
implementation.  Having a reference image in the test cases may detect
such problems when we introduce a bug that can read what it creates, but
can't handle a real VMDK.

Signed-off-by: Fam Zheng <famz@redhat.com>
---
 tests/qemu-iotests/059                             |   4 +
 tests/qemu-iotests/059.out                         | 202 ++++++++++++++++++++-
 .../sample_images/iotest-version3.vmdk.bz2         | Bin 414 -> 4764 bytes
 3 files changed, 205 insertions(+), 1 deletion(-)

diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059
index 26a2fd3..3c053c2 100755
--- a/tests/qemu-iotests/059
+++ b/tests/qemu-iotests/059
@@ -114,6 +114,10 @@ echo
 echo "=== Testing version 3 ==="
 _use_sample_img iotest-version3.vmdk.bz2
 _img_info
+for i in {0..99}; do
+    $QEMU_IO -r -c "read -P $(( i % 10 + 0x30 )) $(( i * 64 * 1024 * 10 + i * 512 )) 512" $TEST_IMG \
+        | _filter_qemu_io
+done
 
 echo
 echo "=== Testing 4TB monolithicFlat creation and IO ==="
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
index eba0ded..0dadba6 100644
--- a/tests/qemu-iotests/059.out
+++ b/tests/qemu-iotests/059.out
@@ -2056,8 +2056,208 @@ wrote 512/512 bytes at offset 10240
 === Testing version 3 ===
 image: TEST_DIR/iotest-version3.IMGFMT
 file format: IMGFMT
-virtual size: 1.0G (1073741824 bytes)
+virtual size: 16G (17179869184 bytes)
 cluster_size: 65536
+read 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 655872
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 1311744
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 1967616
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 2623488
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 3279360
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 3935232
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 4591104
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 5246976
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 5902848
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 6558720
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 7214592
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 7870464
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 8526336
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 9182208
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 9838080
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 10493952
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 11149824
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 11805696
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 12461568
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 13117440
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 13773312
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 14429184
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 15085056
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 15740928
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 16396800
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 17052672
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 17708544
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 18364416
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 19020288
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 19676160
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 20332032
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 20987904
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 21643776
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 22299648
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 22955520
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 23611392
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 24267264
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 24923136
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 25579008
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 26234880
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 26890752
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 27546624
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 28202496
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 28858368
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 29514240
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 30170112
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 30825984
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 31481856
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 32137728
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 32793600
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 33449472
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 34105344
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 34761216
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 35417088
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 36072960
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 36728832
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 37384704
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 38040576
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 38696448
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 39352320
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 40008192
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 40664064
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 41319936
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 41975808
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 42631680
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 43287552
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 43943424
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 44599296
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 45255168
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 45911040
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 46566912
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 47222784
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 47878656
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 48534528
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 49190400
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 49846272
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 50502144
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 51158016
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 51813888
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 52469760
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 53125632
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 53781504
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 54437376
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 55093248
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 55749120
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 56404992
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 57060864
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 57716736
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 58372608
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 59028480
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 59684352
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 60340224
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 60996096
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 61651968
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 62307840
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 62963712
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 63619584
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 64275456
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 64931328
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 
 === Testing 4TB monolithicFlat creation and IO ===
 Formatting 'TEST_DIR/iotest-version3.IMGFMT', fmt=IMGFMT size=4398046511104
diff --git a/tests/qemu-iotests/sample_images/iotest-version3.vmdk.bz2 b/tests/qemu-iotests/sample_images/iotest-version3.vmdk.bz2
index 30abf217e72d38e97b1e34a5db6add15ca3812d9..619329a246cd44f2592c034cd11d9d0afbcc1d38 100644
GIT binary patch
literal 4764
zcmai0c{mde_}^x8%r$I`q+!k^)+kqPnEM!7&Pt0MQ6dV_jKYY`5yn^UE6q`^iX0<R
znmgo3iXpd(uAkqZzrTL(^LgLr^S;mf$NRj``@HXK?B=VdjdxXca^+Z!9|Mq{{QG}p
zPE7FWha=}+jCcQN%VbTkk6&v05#`NYMlZMTe{K8reAHpR?P{Ckp4`^zs%q_!DO2cv
zWjWU#%O1j{I_wvZY)VY1HE5}%n^-pJGMO?)w%DEFzFdo~K;n*HMQ21Vx_8r7x{_NG
zoiLfr%(vCi<p@wEdNQ{Bmh&G-ko^N?>}^#FD;aUSylMPq%IQv%*kK!G8>UKmWt{TJ
zgwrJ>rwCsY<wR~=PbH&4x@6c-Sgwq}UD5Xema~&>qO2n=jnT#m-B&hI^c~s3Cl;2)
zn%JPQmiNw#8e@meY}9WTrjJb66FGtAMY?77PX0Xj0%1T0uOhwyAWAf{<;_nY!3t4~
zZ~(co93x!B10f0z4gfGh0hLRkPWWX2kI8}S>k9w?I6OFD83lX5fW-$fz(JnOLG*xu
zlt_y9PBvykmt_1HWjU3J30MBN5L+zPYcO3oTM<uT0@G1mLMS$tSHkQ*Y>=7E6vkqG
zWrT&1Of4{Pju6GPBo15hr?Rr%SEjsj&evg%X|MK0H+|Q}Pbk&N_KX$AkZD_h@sG%-
zi#jYv<d=;EVwqkioQ8b2Qi*&O5&4B&8DZX-R$H?^VWAu&^O6XPZh<hCFE$3Wff8#R
zz{rkFoz6;cUcuRhJ#}gmmJ(5aL~>^>lmkF^@Oyk1$L(x#&sF_5+eq<b&2j5Vu5-h>
zjt1u2Rkw*#Rk>{;|7>?1_kAK{og?FO7hg&Z&psaixOrE@Ub3^_7Dmr<;hX6@Msh2H
zir>xpPw=xe_b;>!!J{eDC!>B^`AYg$Y1zOHzn`OGM;^(Q=I)ZtdtW0zZ|kBr_Vf)5
ziHxWBz0+v+3)x>}vG%g)AIDxbteP7<isB6K+>OrseSufhUeNh>sMh}TwnmkUdk?x-
zFNZn*bNl;i|A(<Q2q(|COWj$xtcVh#(K^8{maoS?du1@h)!>qX5Gup7)=>>kBPbjY
z7u5sNfWsx#snib7S|X9?Qb+EFBuQ%cmy+Pa>J?Q*ai$IgN!23S0o1Fis%QsVAt*e%
z_a~5gw5d@OLJ$>E;D5pRXklz@VPWb(9v~-LRB4d4#o$%v1U2z8M7Q3Gk&3vpVqyFV
zR}0S1Wqo+i2c0RHRe(zQqEf9PI0+IA0qR9bp<xc4381sRz4A!d`wz0X7y!Yh^~9;S
z4?nbBC|Xf`v~1<Mgq-(Ly)jq$MfZE6W6jN*UvKw^r@hqqQGYv8;{^CI6WvngKl&my
z?D8Y+q3pp^ADd@d;&nztK_S=8z$*7&nh#Z0*V_M#exNzVxp{mezj-=2if47^N4SpQ
z&KgE{BT`RUZ2j?z>3`za&Fk0C)5?+C?~Mk2U;2*3uZ!N18B6=x+D-eBj!fq_7Uad#
zy^t<0)_LQ4?1m>-EpIxQTB_G-ptE$|(^Og)(k#*c2Q8^eAcZOg=n0DeBjrQVwyYv|
zcWq1Qllnb($Gi#C)pnbi#P{y;_hLykZLL@Rs#^SREVBS{V^oRRR!=jrpCD#c)i`gr
zAIVMW`i{jIFCT28DxLr{87B}8eir$cjsRuO0*tb$g5PoGD>T8B1XZUZsL>8MbOVCW
z+aThnmxy)&L+i$!g+X|mmu83o>>zmsg3mo`+%<cCWyYuVceK0v$md$5%&q><w`d91
ziM~sf7B2I=Gf?h4JctxjCjdah7}w`xEogjq!B7rZncfaKW(lD{0U8tnMG!)FB*1y%
zA!kcS3?iLCj{)GstN%TkuIw>=9d_p{-?bjDxblMSfQ-^wH0-fj_I#@`0HB>P#6`F8
zJ9x6m-AQmNDofJM%sFRyE~O@RN&lir=-;;w&!i@{&0Uy3)NIP0w^^@IMRef#gv8c{
zpG?R4>~fE7zPcQOid}A=aqP%FSR3<fSP3=30e4m-h*+G!f8-`!;xOV3+dKr|><!U`
znTkR|d`)8Ks37GTP(s=7&F~+&Y@Ple2+RIWBfAUvk}l7)YdYGV{n(oh`t|k;raWD9
z&+T3OEIrQfaQ+4y7F74ABHK{Tu2wLwmjfH9+#weswdCA$i;~{qc+wKd=p<CV!f_uU
zums0&1$zMm0EF8d9Igb0Hbo=ocmf^Bz%d}<E|40J%-{KEMv4loknS+Y5oTg!byDkW
z4Ljfz0*Pn_UVpe;5%j6KqiHw)sUP5&H2;!x;F*&SB*XQ185x0+*rLJgzDCT<jB%{h
zjji_B6+E8rC_V_TCAQp|(BH)#o4OdB`!*${dG)178<d<-<=V()gD2S_0s~^A2loR=
z;=o=w@Mwn^WRR+7`^}|SZ(;_B=-H7^<z=Z^;@^C#tL$NGYO8wkZJH3vOl~9yQ(+b`
zEf0&z*>cklT6%A?n<5Rr*v?N#Au>GGU3D;@Pu&}kKZDWwbTSyXQg`QEXyDqw{OKOi
z^P!CjRi)jX@B77~y6fH;f2yzfd<OzPT%ed{Ao5Cg|5askRk0eQ{d1PfpBa(OgGQQX
zEdCBGy?ZSX+u8<2W-!^L?Go@Wo7*Kz&yQ`niWtx%`LR4R2{D5`qRG_D=fe_jIs5P#
zqH-(%i-i`I7Chy&7zdE4QUb074u>;vLc9F%Gz|y}3aEz(!a$C|5fn_r6GQ@<GQbSD
z8W8jh;#O3W5SLKTqo9ToqQ)iOp;CtUF@Rp0ML{wpnTk<QL#076{Ip&Q*}(YyON`^M
z7*><qhzJt&bTm?ukE(g9E<L9rC2R>gC72O*Z3A`o6`)-fq##{d7tej3^8#=SHuA8t
z#w$DTHAYACdyD0Xy5k*48DBn4L>>V!DX{6n=!Gc=yagz*bh-icYLbD)#X`FM_lIGv
zQ8uc9T5azP8cd)?*zsPzvk%lZYAup1bLgnfX^TFa$&_0PkWRtzm2a5|+L*9~$(A>m
zUY~3Fy^{^s=U#t$Twxp^7i`bt5&F&J!l<f!u5KXUJP#7t@hNg8rRp!nvZ&{Z_L%jy
z)FWH7&e*pmUnzi8z1Xf%*F}R6#8T7jlx^lqa8PVLHQQxn^Emn5X(jNa%|B*)d;8v>
z(~&?mS?zLd?XC4BzK1t1O6Q4F2eRYHc~30FE&)rS-?V!eciy%;WFpIK;F|6%>HvSh
z2i=LMW|bJvY!#EB$)XUFnt0S(J@4W3Mb)n2o}S>pHRH2_h=OqB^v1g@&{8u+u>|)2
z8uEy|Rr1xyfQolbE0$jVl6-?KR+y?pb88sBkWMg*D!*X^NI?k+CHU%}8-itA?l}>D
zo4*6-fJYGRs+Q(SAGziaxs5(UT#0A4<jan`$I~lpRTm_tg%?v7tdz&Ahd&#&-U|>{
zKFVEaJ;hu6HNtu&wqQYzqjxN2zS!K)ZiZhz{74p{jml>Ys8T?fS_1egXsA($R2dCu
z0i@AlFDUdLRVb)F7^14oIZA>nmKoXiSk+u5UEM6v+KnM=u;3qa1vt|oXgJp8&1{<E
zwHtNSwYLCFY)=YcKmEEea(RT<GX5$q=OS6(AK^)gqZZisU%slb{HnBCH+R){=KI8%
z)&^_+_u5VD@c-Ceb%lCDKZ#|zbrM>9oFn|d_6iK)R^<|F5AC>Jc{;oW!`0IIXDdI+
zPunU9=L_^DN3$+mjL~u1;cLWsQky27`z|U<y`6fm=&o$f+-w)b>Iz8`vTpEZebM@v
zpzj+c#Jk8oRj#H4$^DXy(u(8mZKuvv>$#&PjZ@`TGX-LFQg-}mmAF?{eq}D)F;~pH
z|Dvpj)Wcb&4!rV?xNK>J{wwu^bAMg!*`elldvom%5TEcuWs_%*nJd}#SOuM+N8d$x
ze#yBT-LC=+(&Ckx<KImU0R-N%HhTDOR5&@g&mb!)Nq4&7`yIQalAm`{1-+;9fj=K`
zw~~|xFDh)+1{DUlOFl&b<c*V&pc=S@mAm`$cm9i4qbdxYghN(asgkgWTT;6_hzvd9
z>*9Cd85DK*7qJ{a92WifFlGj%$x}wx`03x(HDvnmxx_0O{pTdn5XT+Zf^64gf4WUt
z+~B3XlS7~YvC~H81atC`Ln|J^B26h6Pmjw;>bWG5PQH8TUA^$C1wU{V5i`2cKZK5n
zmWTfQB`yMeSN!wk+pD3%8>T7aDk5@XP2NWh!k65X-o2a{g}oN<l1ybb84~2xYEWxq
z12HdoWL4PPbH5A)v6}1XU)l!$eeaBA&vc_$-*v3;r98o_@)v>|3h48%*FV=`t}Hrf
z*2x>OlJG&kf~%|Aw>QI_axK*%mliN7BSP+ygFAm;+C2Fk^>xf__MN;w6c;T2pW;*=
zS?7skJ&b{7huueNbXN4qr#&3Ab_mYp*J=X9AWPn!wrO@IW_XOpU)e9#`!e&bS>NYJ
zgIjbDK2aE9{N{odGe?A%8xymHw5qW2Xr>2N6pb?3YGRy4F%jb_L;6SiQ$PhfNUy$g
z7&&YtF7As}Zh%R-`UuEnS)m%Gkw2<uz<{Bo{B4wl!tdt|e2n-nkxmSJS|Q2&B*3}m
zwXKZykbaz^Ie`@LG)^Q8a-eNscR+Lhdnd!B+kN~30GRnn(TAhbYxUt?KJ;~DOtPcK
z!4IpzXf^QQOw|PGzu`aR2-M%9ps7mH3T?mPg3lbZiQ)u?8Nm{U7Be<=G*yH70nzwK
zUsX5_0~J@WfZQ%ptDu#w()oe@FgQxpSc6W(!Erpt8xQW%(2+RZ(RRHf@}^xMHiA7a
zXv(pA0}4T+UwL_Dm6MJ382>`K_ZD^*iKm(w3`YBF=_+Tl-dvv4&|5<&{MOTEJfZGK
z>mI1vs5$CsMB-3GU>`;4l;@r+00E*@?l;vol`RL>23^w34N8}|a^-rD(^(|z_4nhr
z4#Zb$Z<;Z8!s*E{B}O4kyLh<Y=BBK4)>!Ru-lv>&tNjjM{aw!2V8e!#zpFN7He(UQ
z6W1F6r)T;|tKQJZd3Voo!#PJW3|fU-{>rjvO}9l^%O~E)PjZ!WNTf8?LyLy(ojz#E
z{WUPeeGw9Dh8gj0{j%O3c!$Nxz7=g;Ip1V^VWYe^{@QgiNEgv69R(GlD3@6Mi3)x+
zlc#noE^|$ga&$EJo0OBhDQ?VE;~!+ndSAUG+6a6bv3T62cDwMRp|SpDP)3nTU7i2E
zve;vDgpYp&#<Z3mwVywiI~F%ejh95*h4&5mY#B<;!O&cHA6l-Nq7y&v+=jYZtJO7s
z_3oj%K=C{_D?5BSmCLe+U<Bq>zS>(oiqT4cF8A!(4X9hvtq>f?`Dp3degW&vwD&DH
z*%1wwLvdZIBxzxAiI-ruv<t$tv5rvH_01nNBRip4@A<(=XTL{-nIUnaaWA@h%A^CV
zl!fn~yct1BcqT=<p=U}XngX$b!4QI*%t=#DlAc#Z!I-m9y+MYE07Y!6pVA>*V!NOo
zvT2Un+XhIvj;$X~L-j7QmQJ@rKTGlnPpr4gT;us+RR!-Dv_%*XJ66#ond&j^NcLq_
z_WZSimYEyHpQh#lcK(a6u1ARhaBx4I_OG_~{jF$^+!m9K95(9eVP?9I^sF0rXkm&R
zydFUOw)X81bL1nc`=nO=+R>GjsA%nn6T*gExOT`j8T5>ETtX;GKUsD2^P2~EOT>l~
z?Y5t7YY&!Ps$2{hea~KM2sydC7qW)CHJ8%mdiCSxQMK!I*7?-TS2gu5_+$7(V6dQ8
z!JJ;P7yQUPC2<UUl2Jkn_YrCC#f&U&*2~m5+P`p$MKREpV5%wIQa+xi6=*eM5GhT5
zVJ-rw7d~6K?$!9=SCz&vEC1_yWrwrnkxm{@kNQ_C_fEtiS&0It2{1{>OU-acIJHLT
z^xHzroK57-U`^SIzeR4B6aXntIhl^X&xp>x672z;abrEvS%UGmBZbLYT(h31nGLoX
zS^Z&W+&kBz$EFHbbXpiEcT2m!T+Tm%mbdOIwmI5Q{(u=J4Gi6D?miOOthXqU2ByeG
zbID<%1C9AR@4KmrD;5P*4?%k+#~K;dgMhb(tgWrhlXLp6_&3~r5w=6<$4hkAiGe_-
zbD=oZFZ~;__d=id$c3-?HV2eQ-#`dF6(LH<?PmyiV>q8-VM5Yd5#}CdNzcRYd0DyD
zM&2Hk*}ngIBupTb*1i2<dHV3!tY&C;u`Gq=cINcY<EKT2rU>H!JOoZ~l)ZrbH%<ko
eB29UI!jLw&oCw7P$%+2eT%ZLN$`@p^-2MmuzN;nx

literal 414
zcmV;P0b%|^T4*^jL0KkKS-4ab^Z){!-`M?<SOa_FKX2WrKkwggU;qFBpa4(^umM=u
z+94F$O))(usK{+bfDHzK0MKX+G7S`-Q`Ge`dYS+L00uw+000t1nx~<uv^3HWP-tix
z00uw<K=hVO#1Ez%h~;8tm5}gs2_-azgp&-Agak%FkPaO6#E>Q}oWup($ZYNuP+onz
zC89&oo+5m#SRo3f$tj3j4cj-uY<9AFkA%eEJTaa)*;e;U06X$QBY(3aGcne4@Z5Q`
zOld1c2c2n5eaHx1cF@GqGfd88M9D~UB914v;WOL96@WSu-<9};viD>nCB_lZ=L5MA
zWAhh{E!lb{@J3L6J+%};gkaKNrNrxivB)qiB85a>b>(iaNAFyd9Z|7XRWs!&h*2TY
z2uM_*TOC2Lp=5yL%rudbN4;JP^)svmH_P%A-P+35?p=v$3M>tU*);6x0S=pmRj{{|
z7O<gW34|a7q?sHzkqRsX5{K7j5{vUyiDt@86*TlpddQ`yx%PYS=jA|vGbjHSaz!{$
IkhoM7^luBcZ~y=R

-- 
2.0.3

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [Qemu-devel] [PATCH v6 2/2] vmdk: Optimize cluster allocation
  2014-07-30  6:39 [Qemu-devel] [PATCH v6 0/2] vmdk: Optimize cluster allocation Fam Zheng
  2014-07-30  6:39 ` [Qemu-devel] [PATCH v6 1/2] qemu-iotests: Add data pattern in version3 VMDK sample image in 059 Fam Zheng
@ 2014-07-30  6:39 ` Fam Zheng
  2014-07-30 13:55 ` [Qemu-devel] [PATCH v6 0/2] " Stefan Hajnoczi
  2 siblings, 0 replies; 4+ messages in thread
From: Fam Zheng @ 2014-07-30  6:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Stefan Hajnoczi

This drops the unnecessary bdrv_truncate() from, and also improves,
cluster allocation code path.

Before, when we need a new cluster, get_cluster_offset truncates the
image to bdrv_getlength() + cluster_size, and returns the offset of
added area, i.e. the image length before truncating.

This is not efficient, so it's now rewritten as:

  - Save the extent file length when opening.

  - When allocating cluster, use the saved length as cluster offset.

  - Don't truncate image, because we'll anyway write data there: just
    write any data at the EOF position, in descending priority:

    * New user data (cluster allocation happens in a write request).

    * Filling data in the beginning and/or ending of the new cluster, if
      not covered by user data: either backing file content (COW), or
      zero for standalone images.

One major benifit of this change is, on host mounted NFS images, even
over a fast network, ftruncate is slow (see the example below). This
change significantly speeds up cluster allocation. Comparing by
converting a cirros image (296M) to VMDK on an NFS mount point, over
1Gbe LAN:

    $ time qemu-img convert cirros-0.3.1.img /mnt/a.raw -O vmdk

    Before:
        real    0m21.796s
        user    0m0.130s
        sys     0m0.483s

    After:
        real    0m2.017s
        user    0m0.047s
        sys     0m0.190s

We also get rid of unchecked bdrv_getlength() and bdrv_truncate(), and
get a little more documentation in function comments.

Tested that this passes qemu-iotests for all VMDK subformats.

Signed-off-by: Fam Zheng <famz@redhat.com>

---
V6: Fix assertion condition. (Stefan)
    Fix spellings. (Stefan)
---
 block/vmdk.c | 222 +++++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 140 insertions(+), 82 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 0517bba..20d88e8 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -106,6 +106,7 @@ typedef struct VmdkExtent {
     uint32_t l2_cache_counts[L2_CACHE_SIZE];
 
     int64_t cluster_sectors;
+    int64_t next_cluster_sector;
     char *type;
 } VmdkExtent;
 
@@ -124,7 +125,6 @@ typedef struct BDRVVmdkState {
 } BDRVVmdkState;
 
 typedef struct VmdkMetaData {
-    uint32_t offset;
     unsigned int l1_index;
     unsigned int l2_index;
     unsigned int l2_offset;
@@ -397,6 +397,7 @@ static int vmdk_add_extent(BlockDriverState *bs,
 {
     VmdkExtent *extent;
     BDRVVmdkState *s = bs->opaque;
+    int64_t length;
 
     if (cluster_sectors > 0x200000) {
         /* 0x200000 * 512Bytes = 1GB for one cluster is unrealistic */
@@ -412,6 +413,11 @@ static int vmdk_add_extent(BlockDriverState *bs,
         return -EFBIG;
     }
 
+    length = bdrv_getlength(file);
+    if (length < 0) {
+        return length;
+    }
+
     s->extents = g_realloc(s->extents,
                               (s->num_extents + 1) * sizeof(VmdkExtent));
     extent = &s->extents[s->num_extents];
@@ -427,6 +433,8 @@ static int vmdk_add_extent(BlockDriverState *bs,
     extent->l1_entry_sectors = l2_size * cluster_sectors;
     extent->l2_size = l2_size;
     extent->cluster_sectors = flat ? sectors : cluster_sectors;
+    extent->next_cluster_sector =
+        ROUND_UP(DIV_ROUND_UP(length, BDRV_SECTOR_SIZE), cluster_sectors);
 
     if (s->num_extents > 1) {
         extent->end_sector = (*(extent - 1)).end_sector + extent->sectors;
@@ -952,57 +960,97 @@ static void vmdk_refresh_limits(BlockDriverState *bs, Error **errp)
     }
 }
 
+/**
+ * get_whole_cluster
+ *
+ * Copy backing file's cluster that covers @sector_num, otherwise write zero,
+ * to the cluster at @cluster_sector_num.
+ *
+ * If @skip_start_sector < @skip_end_sector, the relative range
+ * [@skip_start_sector, @skip_end_sector) is not copied or written, and leave
+ * it for call to write user data in the request.
+ */
 static int get_whole_cluster(BlockDriverState *bs,
-                VmdkExtent *extent,
-                uint64_t cluster_offset,
-                uint64_t offset,
-                bool allocate)
+                             VmdkExtent *extent,
+                             uint64_t cluster_sector_num,
+                             uint64_t sector_num,
+                             uint64_t skip_start_sector,
+                             uint64_t skip_end_sector)
 {
     int ret = VMDK_OK;
-    uint8_t *whole_grain = NULL;
+    int64_t cluster_bytes;
+    uint8_t *whole_grain;
+
+    /* For COW, align request sector_num to cluster start */
+    sector_num = QEMU_ALIGN_DOWN(sector_num, extent->cluster_sectors);
+    cluster_bytes = extent->cluster_sectors << BDRV_SECTOR_BITS;
+    whole_grain = qemu_blockalign(bs, cluster_bytes);
 
+    if (!bs->backing_hd) {
+        memset(whole_grain, 0,  skip_start_sector << BDRV_SECTOR_BITS);
+        memset(whole_grain + (skip_end_sector << BDRV_SECTOR_BITS), 0,
+               cluster_bytes - (skip_end_sector << BDRV_SECTOR_BITS));
+    }
+
+    assert(skip_end_sector <= extent->cluster_sectors);
     /* we will be here if it's first write on non-exist grain(cluster).
      * try to read from parent image, if exist */
-    if (bs->backing_hd) {
-        whole_grain =
-            qemu_blockalign(bs, extent->cluster_sectors << BDRV_SECTOR_BITS);
-        if (!vmdk_is_cid_valid(bs)) {
-            ret = VMDK_ERROR;
-            goto exit;
-        }
+    if (bs->backing_hd && !vmdk_is_cid_valid(bs)) {
+        ret = VMDK_ERROR;
+        goto exit;
+    }
 
-        /* floor offset to cluster */
-        offset -= offset % (extent->cluster_sectors * 512);
-        ret = bdrv_read(bs->backing_hd, offset >> 9, whole_grain,
-                extent->cluster_sectors);
+    /* Read backing data before skip range */
+    if (skip_start_sector > 0) {
+        if (bs->backing_hd) {
+            ret = bdrv_read(bs->backing_hd, sector_num,
+                            whole_grain, skip_start_sector);
+            if (ret < 0) {
+                ret = VMDK_ERROR;
+                goto exit;
+            }
+        }
+        ret = bdrv_write(extent->file, cluster_sector_num, whole_grain,
+                         skip_start_sector);
         if (ret < 0) {
             ret = VMDK_ERROR;
             goto exit;
         }
-
-        /* Write grain only into the active image */
-        ret = bdrv_write(extent->file, cluster_offset, whole_grain,
-                extent->cluster_sectors);
+    }
+    /* Read backing data after skip range */
+    if (skip_end_sector < extent->cluster_sectors) {
+        if (bs->backing_hd) {
+            ret = bdrv_read(bs->backing_hd, sector_num + skip_end_sector,
+                            whole_grain + (skip_end_sector << BDRV_SECTOR_BITS),
+                            extent->cluster_sectors - skip_end_sector);
+            if (ret < 0) {
+                ret = VMDK_ERROR;
+                goto exit;
+            }
+        }
+        ret = bdrv_write(extent->file, cluster_sector_num + skip_end_sector,
+                         whole_grain + (skip_end_sector << BDRV_SECTOR_BITS),
+                         extent->cluster_sectors - skip_end_sector);
         if (ret < 0) {
             ret = VMDK_ERROR;
             goto exit;
         }
     }
+
 exit:
     qemu_vfree(whole_grain);
     return ret;
 }
 
-static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data)
+static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data,
+                         uint32_t offset)
 {
-    uint32_t offset;
-    QEMU_BUILD_BUG_ON(sizeof(offset) != sizeof(m_data->offset));
-    offset = cpu_to_le32(m_data->offset);
+    offset = cpu_to_le32(offset);
     /* update L2 table */
     if (bdrv_pwrite_sync(
                 extent->file,
                 ((int64_t)m_data->l2_offset * 512)
-                    + (m_data->l2_index * sizeof(m_data->offset)),
+                    + (m_data->l2_index * sizeof(offset)),
                 &offset, sizeof(offset)) < 0) {
         return VMDK_ERROR;
     }
@@ -1012,7 +1060,7 @@ static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data)
         if (bdrv_pwrite_sync(
                     extent->file,
                     ((int64_t)m_data->l2_offset * 512)
-                        + (m_data->l2_index * sizeof(m_data->offset)),
+                        + (m_data->l2_index * sizeof(offset)),
                     &offset, sizeof(offset)) < 0) {
             return VMDK_ERROR;
         }
@@ -1024,17 +1072,41 @@ static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data)
     return VMDK_OK;
 }
 
+/**
+ * get_cluster_offset
+ *
+ * Look up cluster offset in extent file by sector number, and store in
+ * @cluster_offset.
+ *
+ * For flat extents, the start offset as parsed from the description file is
+ * returned.
+ *
+ * For sparse extents, look up in L1, L2 table. If allocate is true, return an
+ * offset for a new cluster and update L2 cache. If there is a backing file,
+ * COW is done before returning; otherwise, zeroes are written to the allocated
+ * cluster. Both COW and zero writing skips the sector range
+ * [@skip_start_sector, @skip_end_sector) passed in by caller, because caller
+ * has new data to write there.
+ *
+ * Returns: VMDK_OK if cluster exists and mapped in the image.
+ *          VMDK_UNALLOC if cluster is not mapped and @allocate is false.
+ *          VMDK_ERROR if failed.
+ */
 static int get_cluster_offset(BlockDriverState *bs,
-                                    VmdkExtent *extent,
-                                    VmdkMetaData *m_data,
-                                    uint64_t offset,
-                                    int allocate,
-                                    uint64_t *cluster_offset)
+                              VmdkExtent *extent,
+                              VmdkMetaData *m_data,
+                              uint64_t offset,
+                              bool allocate,
+                              uint64_t *cluster_offset,
+                              uint64_t skip_start_sector,
+                              uint64_t skip_end_sector)
 {
     unsigned int l1_index, l2_offset, l2_index;
     int min_index, i, j;
     uint32_t min_count, *l2_table;
     bool zeroed = false;
+    int64_t ret;
+    int32_t cluster_sector;
 
     if (m_data) {
         m_data->valid = 0;
@@ -1088,52 +1160,41 @@ static int get_cluster_offset(BlockDriverState *bs,
     extent->l2_cache_counts[min_index] = 1;
  found:
     l2_index = ((offset >> 9) / extent->cluster_sectors) % extent->l2_size;
-    *cluster_offset = le32_to_cpu(l2_table[l2_index]);
+    cluster_sector = le32_to_cpu(l2_table[l2_index]);
 
     if (m_data) {
         m_data->valid = 1;
         m_data->l1_index = l1_index;
         m_data->l2_index = l2_index;
-        m_data->offset = *cluster_offset;
         m_data->l2_offset = l2_offset;
         m_data->l2_cache_entry = &l2_table[l2_index];
     }
-    if (extent->has_zero_grain && *cluster_offset == VMDK_GTE_ZEROED) {
+    if (extent->has_zero_grain && cluster_sector == VMDK_GTE_ZEROED) {
         zeroed = true;
     }
 
-    if (!*cluster_offset || zeroed) {
+    if (!cluster_sector || zeroed) {
         if (!allocate) {
             return zeroed ? VMDK_ZEROED : VMDK_UNALLOC;
         }
 
-        /* Avoid the L2 tables update for the images that have snapshots. */
-        *cluster_offset = bdrv_getlength(extent->file);
-        if (!extent->compressed) {
-            bdrv_truncate(
-                extent->file,
-                *cluster_offset + (extent->cluster_sectors << 9)
-            );
-        }
-
-        *cluster_offset >>= 9;
-        l2_table[l2_index] = cpu_to_le32(*cluster_offset);
+        cluster_sector = extent->next_cluster_sector;
+        extent->next_cluster_sector += extent->cluster_sectors;
 
         /* First of all we write grain itself, to avoid race condition
          * that may to corrupt the image.
          * This problem may occur because of insufficient space on host disk
          * or inappropriate VM shutdown.
          */
-        if (get_whole_cluster(
-                bs, extent, *cluster_offset, offset, allocate) == -1) {
-            return VMDK_ERROR;
-        }
-
-        if (m_data) {
-            m_data->offset = *cluster_offset;
+        ret = get_whole_cluster(bs, extent,
+                                cluster_sector,
+                                offset >> BDRV_SECTOR_BITS,
+                                skip_start_sector, skip_end_sector);
+        if (ret) {
+            return ret;
         }
     }
-    *cluster_offset <<= 9;
+    *cluster_offset = cluster_sector << BDRV_SECTOR_BITS;
     return VMDK_OK;
 }
 
@@ -1168,7 +1229,8 @@ static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs,
     }
     qemu_co_mutex_lock(&s->lock);
     ret = get_cluster_offset(bs, extent, NULL,
-                            sector_num * 512, 0, &offset);
+                             sector_num * 512, false, &offset,
+                             0, 0);
     qemu_co_mutex_unlock(&s->lock);
 
     switch (ret) {
@@ -1321,9 +1383,9 @@ static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
         if (!extent) {
             return -EIO;
         }
-        ret = get_cluster_offset(
-                            bs, extent, NULL,
-                            sector_num << 9, 0, &cluster_offset);
+        ret = get_cluster_offset(bs, extent, NULL,
+                                 sector_num << 9, false, &cluster_offset,
+                                 0, 0);
         extent_begin_sector = extent->end_sector - extent->sectors;
         extent_relative_sector_num = sector_num - extent_begin_sector;
         index_in_cluster = extent_relative_sector_num % extent->cluster_sectors;
@@ -1404,12 +1466,17 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
         if (!extent) {
             return -EIO;
         }
-        ret = get_cluster_offset(
-                                bs,
-                                extent,
-                                &m_data,
-                                sector_num << 9, !extent->compressed,
-                                &cluster_offset);
+        extent_begin_sector = extent->end_sector - extent->sectors;
+        extent_relative_sector_num = sector_num - extent_begin_sector;
+        index_in_cluster = extent_relative_sector_num % extent->cluster_sectors;
+        n = extent->cluster_sectors - index_in_cluster;
+        if (n > nb_sectors) {
+            n = nb_sectors;
+        }
+        ret = get_cluster_offset(bs, extent, &m_data, sector_num << 9,
+                                 !(extent->compressed || zeroed),
+                                 &cluster_offset,
+                                 index_in_cluster, index_in_cluster + n);
         if (extent->compressed) {
             if (ret == VMDK_OK) {
                 /* Refuse write to allocated cluster for streamOptimized */
@@ -1418,24 +1485,13 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
                 return -EIO;
             } else {
                 /* allocate */
-                ret = get_cluster_offset(
-                                        bs,
-                                        extent,
-                                        &m_data,
-                                        sector_num << 9, 1,
-                                        &cluster_offset);
+                ret = get_cluster_offset(bs, extent, &m_data, sector_num << 9,
+                                         true, &cluster_offset, 0, 0);
             }
         }
         if (ret == VMDK_ERROR) {
             return -EINVAL;
         }
-        extent_begin_sector = extent->end_sector - extent->sectors;
-        extent_relative_sector_num = sector_num - extent_begin_sector;
-        index_in_cluster = extent_relative_sector_num % extent->cluster_sectors;
-        n = extent->cluster_sectors - index_in_cluster;
-        if (n > nb_sectors) {
-            n = nb_sectors;
-        }
         if (zeroed) {
             /* Do zeroed write, buf is ignored */
             if (extent->has_zero_grain &&
@@ -1443,9 +1499,9 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
                     n >= extent->cluster_sectors) {
                 n = extent->cluster_sectors;
                 if (!zero_dry_run) {
-                    m_data.offset = VMDK_GTE_ZEROED;
                     /* update L2 tables */
-                    if (vmdk_L2update(extent, &m_data) != VMDK_OK) {
+                    if (vmdk_L2update(extent, &m_data, VMDK_GTE_ZEROED)
+                            != VMDK_OK) {
                         return -EIO;
                     }
                 }
@@ -1461,7 +1517,9 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
             }
             if (m_data.valid) {
                 /* update L2 tables */
-                if (vmdk_L2update(extent, &m_data) != VMDK_OK) {
+                if (vmdk_L2update(extent, &m_data,
+                                  cluster_offset >> BDRV_SECTOR_BITS)
+                        != VMDK_OK) {
                     return -EIO;
                 }
             }
@@ -2020,7 +2078,7 @@ static int vmdk_check(BlockDriverState *bs, BdrvCheckResult *result,
         }
         ret = get_cluster_offset(bs, extent, NULL,
                                  sector_num << BDRV_SECTOR_BITS,
-                                 0, &cluster_offset);
+                                 false, &cluster_offset, 0, 0);
         if (ret == VMDK_ERROR) {
             fprintf(stderr,
                     "ERROR: could not get cluster_offset for sector %"
-- 
2.0.3

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [Qemu-devel] [PATCH v6 0/2] vmdk: Optimize cluster allocation
  2014-07-30  6:39 [Qemu-devel] [PATCH v6 0/2] vmdk: Optimize cluster allocation Fam Zheng
  2014-07-30  6:39 ` [Qemu-devel] [PATCH v6 1/2] qemu-iotests: Add data pattern in version3 VMDK sample image in 059 Fam Zheng
  2014-07-30  6:39 ` [Qemu-devel] [PATCH v6 2/2] vmdk: Optimize cluster allocation Fam Zheng
@ 2014-07-30 13:55 ` Stefan Hajnoczi
  2 siblings, 0 replies; 4+ messages in thread
From: Stefan Hajnoczi @ 2014-07-30 13:55 UTC (permalink / raw)
  To: Fam Zheng; +Cc: Kevin Wolf, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 754 bytes --]

On Wed, Jul 30, 2014 at 02:39:08PM +0800, Fam Zheng wrote:
> V6: Address Stefan's comments. See patch 02 for changelog. (Thanks for reviewing)
> 
> 
> Fam Zheng (2):
>   qemu-iotests: Add data pattern in version3 VMDK sample image in 059
>   vmdk: Optimize cluster allocation
> 
>  block/vmdk.c                                       | 222 +++++++++++++--------
>  tests/qemu-iotests/059                             |   4 +
>  tests/qemu-iotests/059.out                         | 202 ++++++++++++++++++-
>  .../sample_images/iotest-version3.vmdk.bz2         | Bin 414 -> 4764 bytes
>  4 files changed, 345 insertions(+), 83 deletions(-)

Thanks, applied to my block-next tree:
https://github.com/stefanha/qemu/commits/block-next

Stefan

[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-07-30 13:55 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-30  6:39 [Qemu-devel] [PATCH v6 0/2] vmdk: Optimize cluster allocation Fam Zheng
2014-07-30  6:39 ` [Qemu-devel] [PATCH v6 1/2] qemu-iotests: Add data pattern in version3 VMDK sample image in 059 Fam Zheng
2014-07-30  6:39 ` [Qemu-devel] [PATCH v6 2/2] vmdk: Optimize cluster allocation Fam Zheng
2014-07-30 13:55 ` [Qemu-devel] [PATCH v6 0/2] " Stefan Hajnoczi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.