From ce4ce6411ff28fea9c6582fad12194250177b610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ertu=C4=9Frul=20Erata?= Date: Sun, 6 Mar 2016 08:05:59 +0200 Subject: [PATCH] For kernel-4.4.4 --- .../kernel/files/configs/kernel-x86_64-config | 4 +- .../kernel/files/patches/linux/patch-4.4.4.xz | Bin 0 -> 200972 bytes ...-Intel-Lewisburg-device-IDs-for-SATA.patch | 44 + ...ark-HotPlugCapable-Ports-as-external.patch | 45 + .../patches/mageia/fs-aufs-4.4-modular.patch | 231 +- .../files/patches/mageia/fs-aufs-4.4.patch | 9511 +++++++++-------- .../mageia/fs-ovl-allow-zero-size-xattr.patch | 31 - ...-positiveness-in-ovl_cleanup_whiteou.patch | 44 - .../mageia/fs-ovl-root-copy-attr.patch | 33 - ...ttr-check-permissions-before-copy-up.patch | 65 - ...e-a-minimal-buffer-in-ovl_copy_xattr.patch | 89 - ...lear-PF_NOFREEZE-for-xfsaild-kthread.patch | 39 - ...st_modeset-regression-from-Linux-4.4.patch | 82 - ..._vblank_offdelay-in-drm_vblank_on-v2.patch | 64 - ...redundant-calls-to-drm_vblank_off-v2.patch | 76 - ...umps-1-with-active-vblank-clients-v2.patch | 120 - ...rqs-after-display-engine-is-on-again.patch | 57 - ...Align-ata_device-s-id-on-a-cacheline.patch | 39 + .../libata-fix-HDIO_GET_32BIT-ioctl.patch | 98 + kernel/kernel/files/patches/mageia/series | 48 +- ...m-arm64-kvm-fix-ioctl-error-handling.patch | 51 + ...lock-initialize-max_dev_sectors-to-0.patch | 36 + ...fix-a-use-after-free-error-for-trace.patch | 36 + ...yed-iputs-at-transaction-commit-time.patch | 238 + ...fs-fix-no_space-in-write-and-rm-loop.patch | 47 + ...ut-of-bounds-access-in-lease-parsing.patch | 104 + ...esponse-processing-for-read-requests.patch | 72 + ...acy-clock-domain-on-superh-platforms.patch | 39 + ...out-wc-from-bo-on-unsupported-arches.patch | 46 + ...et-a-default-value-to-blink-interval.patch | 66 + ...uniqueid_to_ino_t-function-for-s390x.patch | 63 + ...round-for-ats-write-permission-check.patch | 78 + ...-device-00-00.0-is-not-iommu-covered.patch | 92 + ...otify_removed_device-in-hotplug-path.patch | 68 + ...ause-for-missed-hardware-breakpoints.patch | 56 + ...-x86-update-tsc-multiplier-on-change.patch | 56 + ...le-mips-kvm-fix-ioctl-error-handling.patch | 49 + ...number-and-return-value-modification.patch | 94 + ...t-retrieves-struct-pcie_port-pointer.patch | 78 + ...oherency-between-d_inode-and-d_flags.patch | 100 + ...stable-vfio-fix-ioctl-error-handling.patch | 116 + kernel/kernel/pspec.xml | 46 +- 42 files changed, 6779 insertions(+), 5572 deletions(-) create mode 100644 kernel/kernel/files/patches/linux/patch-4.4.4.xz create mode 100644 kernel/kernel/files/patches/mageia/ata-Adding-Intel-Lewisburg-device-IDs-for-SATA.patch create mode 100644 kernel/kernel/files/patches/mageia/ata-ahci-don-t-mark-HotPlugCapable-Ports-as-external.patch delete mode 100644 kernel/kernel/files/patches/mageia/fs-ovl-allow-zero-size-xattr.patch delete mode 100644 kernel/kernel/files/patches/mageia/fs-ovl-check-dentry-positiveness-in-ovl_cleanup_whiteou.patch delete mode 100644 kernel/kernel/files/patches/mageia/fs-ovl-root-copy-attr.patch delete mode 100644 kernel/kernel/files/patches/mageia/fs-ovl-setattr-check-permissions-before-copy-up.patch delete mode 100644 kernel/kernel/files/patches/mageia/fs-ovl-use-a-minimal-buffer-in-ovl_copy_xattr.patch delete mode 100644 kernel/kernel/files/patches/mageia/fs-xfs-Revert-xfs-clear-PF_NOFREEZE-for-xfsaild-kthread.patch delete mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-Fix-drm_vblank_pre_post_modeset-regression-from-Linux-4.4.patch delete mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-Fix-treatment-of-drm_vblank_offdelay-in-drm_vblank_on-v2.patch delete mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-No-Op-redundant-calls-to-drm_vblank_off-v2.patch delete mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-Prevent-vblank-counter-bumps-1-with-active-vblank-clients-v2.patch delete mode 100644 kernel/kernel/files/patches/mageia/gpu-drm_nouveau_display-Enable-vblank-irqs-after-display-engine-is-on-again.patch create mode 100644 kernel/kernel/files/patches/mageia/libata-Align-ata_device-s-id-on-a-cacheline.patch create mode 100644 kernel/kernel/files/patches/mageia/libata-fix-HDIO_GET_32BIT-ioctl.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-arm-arm64-kvm-fix-ioctl-error-handling.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-block-initialize-max_dev_sectors-to-0.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-btrfs-async-thread-fix-a-use-after-free-error-for-trace.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-btrfs-fix-deadlock-running-delayed-iputs-at-transaction-commit-time.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-btrfs-fix-no_space-in-write-and-rm-loop.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-cifs-fix-out-of-bounds-access-in-lease-parsing.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-cifs-fix-smb2-interim-response-processing-for-read-requests.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drivers-sh-restore-legacy-clock-domain-on-superh-platforms.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-amdgpu-mask-out-wc-from-bo-on-unsupported-arches.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-fbcon-set-a-default-value-to-blink-interval.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-fix-cifs_uniqueid_to_ino_t-function-for-s390x.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-iommu-amd-apply-workaround-for-ats-write-permission-check.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-iommu-amd-fix-boot-warning-when-device-00-00.0-is-not-iommu-covered.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-iommu-vt-d-use-bus_notify_removed_device-in-hotplug-path.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-kvm-x86-fix-root-cause-for-missed-hardware-breakpoints.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-kvm-x86-update-tsc-multiplier-on-change.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-mips-kvm-fix-ioctl-error-handling.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-parisc-fix-ptrace-syscall-number-and-return-value-modification.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-pci-keystone-fix-msi-code-that-retrieves-struct-pcie_port-pointer.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-use-d_seq-to-get-coherency-between-d_inode-and-d_flags.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-vfio-fix-ioctl-error-handling.patch diff --git a/kernel/kernel/files/configs/kernel-x86_64-config b/kernel/kernel/files/configs/kernel-x86_64-config index b6092c88..9a624aec 100644 --- a/kernel/kernel/files/configs/kernel-x86_64-config +++ b/kernel/kernel/files/configs/kernel-x86_64-config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/x86_64 4.4.2 Kernel Configuration +# Linux/x86_64 4.4.4 Kernel Configuration # CONFIG_64BIT=y CONFIG_X86_64=y @@ -6625,6 +6625,6 @@ CONFIG_ARCH_HAS_MMIO_FLUSH=y # Unofficial 3rd party kernel additions # CONFIG_NDISWRAPPER=m +CONFIG_VIAHSS=m CONFIG_RTL8723BS=m CONFIG_WLAN_SDIO=y -CONFIG_VIAHSS=m diff --git a/kernel/kernel/files/patches/linux/patch-4.4.4.xz b/kernel/kernel/files/patches/linux/patch-4.4.4.xz new file mode 100644 index 0000000000000000000000000000000000000000..f8dad41478a481cb1cea5f43fba73f8f86673ce6 GIT binary patch literal 200972 zcmV(lK=i-;H+ooF000E$*0e?f03iV!0000G&sfakv>osMT>vr~NeROI5q(hJ3QtGS z!4;|pXZW)T&B<2$p4WOUgooq0_Vv0rFG*P91JyUm^8QPe@R=`8@V>}kdP%LjYk}Y@ z3Aj=Jqr9%ju_6QT8TqHhoj;x!)U;kzw-2)w6(AOjXeo^*lLLSjBte`*z1k%)`|T%( zUfWt06qL832-WD({99!}FFF_+p7?FBn8x#zLNdE8${e4XoW*hOwZ|d*K1q4sjI+^r z(LniuLFt;^YgQ6L&Exl{Gah}6v&N0~4UioE2uV`x(Co9?OTqfob))wgj&3-xSSj);s{y@2~do11(r9y>JFOpP0mB%QAjegFUm_?!j||V6{W$ zX`U(3P$R~bL~PKln`Za>Rd7aBn}S`at^MwT1w(1y?rP;eB>qj&5DoqQI-dQ!fG``! zNh6VuO~U`C;Gb4t>eUTZNT$eH;D^Mi;TJ8?jC!1`^uz3>F{(1M)kAzw{hBnntLK$paFR1xlP!G$5fMGWO0ZtHT<(?pH(4G88n_cqdVq zs*Z7GD3EWqR;1Q3VghF`ZX7xCfmj5RsMeaIAX)0|JiG~wg>21F9U->BR$YF!L?&tm zj;#G-0vRD5_BfeTCS>1MOSBBCgN3uLU6-xlqAC^36K-3bd#5AfP>Wi04h+vgSZV7p zF!`GQaFwkA|M*C(!3Fs2TeF7rHI-0mU=twjWPBK?!E}q^gg~Kkl_8KTwDxapdGbI-TlnBFu75$!>}vm#SPFY`IF1S)F0yy%aA zB@*xPvg>%5e)SM|kQ2pGwf8)FWXr$XN`zc2019w~&yl8Aer znwPjJUkd35D{a?@>cmM1K0EH!T%V-|#Q3O>nPgQq4l;Pa7!|hUpXH#FDi-uoDKl4; zsU?{7cObc62GZ0OGQ-4dbI;^^+>jBn>6o%CV2vYGloOLN(W;zjjODObw=np?jWMEH zJ}uuxjT7?f93{Sb*D2Oui+hh|Ruh$4b!hBtk_aLT3EyvC3Z9)1Yab%?>3 z;)e3-&B4u*?7>xB)s-m^WyN%H!k$WbKTPXo))(}58ek#I{~Y-GR-l>ld9<>whL3Z^ zqel?@G9~52#316vDmV*0B|k>hMgfGK?eWS*CqGl%yRqwX$40+E85X%AxT1tJ^Lpw+ z{KDs6x<`!_BFo?h-M#JzH&Hx1Gb1WNu5kaU)i-yX^hOt?&;KVEr}!d$d&BmOAL$@T z05Dt1uJD7BL97y?-6QoW;=PFa(a|GJ57O=DhI;~oW)BdHLrXBvfA9d&6cm_=TjK`8 z^C(Mb@UlQPx`Pw;(5DY9DHnGRA3v)&tn}R(CBXJfPbFD@t*bqPN6g(kio*VGQ1U5w zvqwC22M6%?fypl}ZOyN}|3Oygv%0y$FY8}O6mr{+1h@9{N0Gk>yoDecYcl`(` z>%OlGY-UU9$7_i%JvM=*CLU^nYQ)vbpR5K(ZLN~U>vZaVQd?+;E63g#pDtA@SSTAJ zBMlt!i~o0^k@C)RM|6Z3b$LB9An-WsUy9~d80$3L0Lw%+mUG0ME%@Q_syq3f;DiQ6 zJ1|F)VdSqTd&S{gfY;IsneKP?_Wzr5*LL$}?v-``D~Tf(qcK#4GWpqF&ht!>ARXdy znP#tdc$n`I9nlWVNQ)k=3D6x?L^7^or1Ua!B#L1AxyH`-4eWdL*c308?^R@ED>xTL zMz`I;Gvi+c%?WeDR~`NJMt)lY?8*yPp|gpD+vV{KZ%-@c1B0QQvpg?qhT*#K4LiSt zF_m=CB&s}GD5$dPcVy`b4mdq`AC?GLO(zr&&IaMjMxigH{1@);ce0O9YYN7C#M_oc z3>CGiz9qesf}EK{kN)=HWskc%&##siW-+NhC!M#WOtrkkebXhAx|UVKIj9qgZeVlV5$Xt;Lm*9qf((VC~)Rjk}p(yfU55d?SesSS`NS>mg; zW5|@0qB);=ykh4z*w7=tw5bchS^1ERE5S_OwLA!i@fm`WlD z()#QXa{+TSqRBjQntmv{QbJE;SpL;nl{#VqZ%_oh+|JX%LTU7Xb&P zS3N5w=OsjXv5=1;p-8fP7An9x;K|Zm9@toe?RB?UsW?W{ETuEp=|OF$R6>!x|2?ex zjjRIt)9Sv(?78vX&uhi6q6e7@A6cT-rgRIXtcm|?v8BJ!Lm^a;3lLiUU%~^5C%u)5 zWNfL8Pz=49S#UdpmOV`~I_cM{x9Pu!z8~n@7(r;)MdCk;gU#)-*3m6(f+WGfG5%ViF#FE5&#pJw<0Y|e zAMM;8BxuU%6DI9TnBFJh^Y%z%Agx9Yf?!yzb&~>REBgE24J;hA*NRJy$ff_$?5$C4 zg!tE*xu{s%T!{#_)wUPY4bhvf!=_;yO~u1J5mdr8S`Yl|q=nUg(hU;NtBG&BZ~=cN zB!{2cY7|Ta9S_p`$5=7Ihsr_xR9S-Z?DCg=63p29y#?4r6DqW)GliT6t}la8-dRwQ@R z?-sLEzeampFl0r)7R-qar4QeD=I*tKMaoD*}gc-Zu9}s%S3_8yb#4nG_SRiPhHAwT-joq zRrmmUd6%uQnT6LCVhAlIu`F`%&4SeB^8u0f_d(Jfv7> zk-4WL8L|kvJczFPC-5wm>jp#f);hANfx7_@RL1#Mf6ik;b9kkn5E-GCfGmr`Js2tE zO}`^G(3Fx&H|5HcOW%{gCeu#XnTUD_UncbIE#X_L^!Y;b#UV+z7F)T%NeWz{3;he# zS6i%OJ)R8Or&5-Cyi13sr!+cOwI8Jg2~p2=v) zHj_2%8DRGs{hPrNS*0W9y`_|_DQpA2zuZAWT9euB!e;VV4S1@}{?(KV4hyPE?c)vq zC=3$o@)Y$|f{Pt}B)@T?_NzHL^8~|TbjVFvujd9l-e;MU6@t7sEdY}%0tG(UrvmPb z9gpE{4~2mX2GnGScHzQ1zq2*zwNG{Aqnnssfa}t&yt@CfPtHEQTmy5a*mKapXc!^m ziE4(YfN3)n)z$n;dJtn_18NY7Kd@EQ&{r4D9z1Cd2K~JlC_!S-IP1{;Kk`xiZ;Rye zltL~k0?>|qLr5pCI0hP2$$oe_t?}aSp1SaZ!ND(6Rz zSu{Hy1wYL{zN?)DZE>*B>UJ=Uq{OJ2ASE?EQF1;$PPtgvh7=QfCv+=R?d|&c{i$O< z8gMejwgKWd-{m+PU!>*u<~9a}QjLtA>4?8Cl+Ex`S^+ocQQE2_SlwO3N0a$emOE#9 z;+J#g@Y=mt^|GZD%fkJY5{BCim>PfD@f>p%bYKDoL@F7%s5L+#ykj+3L!P_Y**sUt zVv}ZPT=5GJ-9`1*jOGPFuCOL`z^IAjCRIc7C~9)2W1}43ewMF#Gfe`oqwAk}=+G3G zF?pG2xw>UUQ`xIHZlHHTO-PU=EV=3r`F&K=m%cEr!$4Epw4QOH7~KoYvQfG4R#PX{>| z|9VvgzQJ2;tOA0kT@dE(zA?(jW#BlZsZzhkT^>Q6Uc4h{LI6maTpX_|O#X@I(VQyY zQj5!{UqWP5E8g-|g$$Se4{_ay9W)0D?#eg@`KTR3G|6c!=Z%1I%P(F^%C<X}WIm#Y9!cIh_~wMMsMKsCCOo;jCFDW%BBX)gr(J`ReN#njA^?>`ALp?(0gBR6l) z^~0Cfa?Z%Sq2E)9Y7X(+iBA_9>~jhtk5&1dQs4y&xb79TZEbO}rJ8@7 z(vZ^E-n|8DxI-8c=|*ZsGlW>MrEr;&hL_SN4FOE$unz^J(SKcjZ<57fpH$AR)z>kt zrNkball$pCa91_nn5Mw+A#*fY?gFj15;S}bPq&hp(zq@_x4M<1vtjv=3+lA zY-|z{q4ddR(K-;wuMlWJ?4CmZ1IS1XHAKu=s8ae|abnYmiNSc+_mhec^M!g2pPR`U z#(W`ijbr;KK%&hX$r6syfFq|tA8+qYePp5wxMOgI%ZvVpUUsRPa%5jyp6aHMDZ_=d zn`=`L&hG+ZQ$o*}>U;Y@V>=`dao~+_jMo1THkLM#TL%1Vtiu}0lg@F( zz^WUZg1!e^SF|cOW4Zc_@2Vf1lo@xW5k>1lqZIEzq0b^}5n&bSpGI|Sr{F7;v3-}! ze)df8;a2dHIvBh_W>}_Ts5DcD9ZzGgy_fOab-dU{|6o~}0Zz?`ofRL1>B(=u$@o_c z&#oxPzQN9%F3EO$06_8&3+yGyupH?zAO(b!M9OKiGVy54yI>y(Aqiz-;9WxXQM7DHMFi zSAfSc)j`v`OM7hP!Ai4Rb{l$bN{nc6Pocl-&Z#07x_gxSg#wvm)d(*!e2rSW;e@b+ zfco?E3!ujp9zri7Q5Lp3i_ciHG7O9^SHX3C2b%|CWn^RVYGrUb{VwK)jPqaahxIW{ z@1Tp6X8SQ(J^xL~BPxIz3QCs2Q`wjBgB^}1$1iA-%QSYQ>3ZH--~%6!QS{lU(~7j)7UPPSLvk zK(h`OU1S=+T#9@1bQfR@xn~9VAu=B?Sa0VGZ}6sA(Z(1aHToJPPd7(iI=SUPeG#@K zgF@udEN94hvKOsWt6QNmTZCf^J~(>>oe#M$X6sPtX$T3L*Urp`*ol$#Fze>Xz=CF@ z_FWw%Vt%lOa+*oP*At@0REk%~?9TmNxSjih-#W?b*6l)iL_mj^9J^*Tm`>7tMf2oV zR;_=QT+2de&5qfGMR%p44Mcmi$H}iGas)kGuy}*@pj~@-=6%o_m>2R?R-3g(fDUw_ z)aMgt3%9N|LQTI$f_py2bzxyIOUwFGUOr^*Wq7wD%jP5rRV5W;_5uB2+p&U=b|mxW zvzwgb-zj&7ZDy-X20SHFLmQ!HIFabELG$DFM@M3ywCBLuGwm2$Sef;v8Vu(PyQT#p z+rX&V;^FOP;r_7iEiRl|a0c>F2o`V?mx-J>NLWt%L8r5`UeAoMHp!-wd~B4>d5zn# z?pyW=Q@XDZ^SnujB7XP$#BnT(H5`J@m6llv7bTwo>s0$OaG(myhB(>KSB8;)KlnNd zN;dW2BLrY3+b|k%2uVa*Q~YoAAoGSg*AuriX5KrF4H1);IF~li&N&C6xCdKbfN^DS?TES$^uR1vuv zS*wk~r;(CjWrWmThXERcd~6@eW{#v|(JG!7Bt&AD$p#@Ln<|zm{dfi2Cz-qC`db99Sih$;??!o89vjPt8x25>#~x6OF(1iSed|95vg+{697 zKIaC*--^^QcCt-&ZtrZRxhm_`QL#KmMi+8Ddm8rR_j}R6LHML-Omnh-bpjk!#$LDS z?je%V=6`ZDSS7k^_szPq0{G%8AT_aj0i#vvQ1E%=y_;UZtk%{pL(dE?w8cuiG%}>q5Ya>BT%FR=Etuj*j>mVKx0rAhr-VNH!Zia zONPmRY2pL2q&$DfeSMZ_Q)Trz;MqipO@dD-!io6CUt<4lVfw3Mz~J(~om!^U$T-<4 zKgaUC8OEntI_3006b^Je^A~=s(p4YioFz*rbG9@l0EUQ7OwG{LVu2T+;3Dhb39UgY z$)BBxC!wm~(l88Rk9T%&leO`7N z|4mOYZyN73z9*EC;qgS{kZnlXQT(Ca@_I{%_}&fM$KKM3YD3*m)gl%zGKOKBp-p^a zMbPolE_>_y2UzBG{Eq%e=zyab?xp0U#Y`X(TaNwZEEZ`03EvD+)7z6D`VWU^?|X|R6vM;y~^Zj_Usw#x@84IJIy3XO|PVAY<}H5NiKicK~uXs9qM zGI1URq?u6nSGxUFWlB-6p--M#MS@kpIm>Qe5bD@ALC^2>ba6N$ zBLUe&^#1Szh3nU(6d(=qKKLWk>mGl1qkSQ?n2&iL&Fpkop4~g$UJJia&_ueXuGOU5GGp}35}$<_)d5Iuc~qXYjR27JPZ~KQ$8uCAh2X@DXv~< z@0fj+PTqfRZMJ4L4%i<{l8AaF=xev^xJJ{Ml)%XJiK;$Q74;??5_#nZ9(>7Oh`HH$ zWO$9#hle`DkQ+c4v?rFrro;te;mYCaofS&OaJ=}d&V+hK~D%UwYTfD&Dh6;s3OiXogKP zGrcpRZc;?~jC1T77a4O35;0HUbx`k3!#Pv!X__?kd>!dnmc$AXJ##s!LGoRhcw;L)CB1ExVf0563JSITY4Fo63sUHud! zEsV2FHn2=dNk$&Sv;OKH62K%~&ZDNjs(c2dcmAKjx!`bC;}>}^Ff+57*hcZ^DLs>% zX>wZT>@QkRLyC$Krh6qrd8WfU1(gDfrWO{y&!wC|$pyX|%}MYBYf5AgRSP(yH$k|q z*btWneSE8%zyGM9YudzX^dWPgU2$Jnrp3xaa?d}H>97x0g@>NO=d{GipGe!{3x~Uv zlq7_+rmq-71K480o&ZsF*D6)vL_cQ+{-eE2SX1+fSFBvZ&E(3w%8MtP71 z9K-aJehQd7Ov{OmOX3^GG#mVFJTn5L-Ph;oOL)i-BjqomVs}|^eL%|M+qq+gP^B_{ zqr7ttz60WUwsLS8DRa2{G!G^h&T&M<(?RbeMUTG{&>z7Aog3@$rurOJ$g@WWfG+(@ zingLmGX$&)iDs}C&AP{9Fl{s*!jYe7`|%cL_r{xqvp`mKRr6c28=XtHH_oT3f+B`g zp2=lRpPR^z+@k9?9v3-==7m_2;t!)(OGE_H?&g#;6Zx$}_L4jjxtK`6AHLEM)b(a~ za+i=AfeBZ#-+ydeM2Uh+t&?Lye+s6irP+6`u`Ul+e!YDX7Kiv=@q8@^cQ6)?B1WX3 z^=sU~M1D+eGoOZj37$=!m*y62frA$|0|cw$lql9h&;m2x&k~dgUqxvv19-Ql&ag`T zH5Rj!n+SdHX-$7tLzt!Kty&k@_hBNSv(P-yezVwTMx?j1gNbOQ`4AOdQTjkOs2y6c zTC#XzBFPM-Po;`%7Z>;CG~J~SHfz1MQ1AhU#wG(sP@@Zjq^e~pN#3$Lkzcj!xei&c z$q_Wa7e*pVa?EDT_SR*ixe-qF7nDyCR=g~gLlnj|s;gztYR7}Ez}9FK34_clTtZoH zNh|TtYQrINQ#j7vi;a%oOr_8_7xox3=!xnNuhN)-5c=J);=&Qxm1{H3CTF>rpUIqerh?-5 zgXvT?B=PW-v8~0A`6@`e-&tH@tJtCBG7b(?71oP-$;*B3yKco_r$tg5#HW(F*kNLE z%x+8b#%RL3x5i~tzFD_y)$ONqMN4+LD~;3GW4ho3xH!=b)?n8Ew@a@yu!6ZX-!QB$ z!?U%#zAP-rTF|Ln)8r1$Lfs<25UV}f`fdA?QO2M2GEer`fR6NKT&f3-csQtyL`w@8 z{o6!}B#f0eRlTLWo)y(HeW9pkv9;H$3?eK@=59Qd9FwHsV1T*weIoZ{Z_WA#_5HeL zD5kW<{gkJ$^qDUIgb)3&u${7>d;sHFwl7k+G?wiw!W`#t8~z3XLn1Yt{_D|{HwZo6 zodmSt5abc-$X(`3OprmgA56Hx4%&X-ON9GjDVgk=CmUyhf2P+r^-tz3VIqwY~mQktgLbQuSc`{$?^v@l}9Xkf5IZqo5Wl zUg#*wEy9Asj2FQejb#w3S%z&rcgNUeu~w}P#r)v&(%(qx^B%nrRyHQ$;7K!_UGEHN|p~c?~vbI1RD={_+{(6i64x+}viow(KAxGsM|R@ z^Xjjc$E$L1UJrjCW6=;3PC(0vA|ph-S9f#!2`pOgZ28BmvQA-zf$wyD%|rjb&tRtz z%046n@FGQa2%TV@U6f}!LC-wQ6(d=K8DKvKJR@B1jwZ}qI$8pNzo@wc2~LjKjDey6enyqp3n}(FPE132w5G6?jA|xgqNo9(CC7r1 z0j~+hQD1*CA(-^(ZG;0rXw(;+ox4dD$XPaiL3`+kOTzHKz42>Wdi^;<5aCZdwdtg( zw1bQKopJaSVdba3qutwjoc#6P2fxYAf24_<3oNxuMv~`oaNVh=+3Rasu&f&hr~$&y z8qe-XfSaztH5MOFP+`$PIu>Et%J^FOdAi?`(S{a^7l^Bx3k#Krr(ih}?fE9qSFVP8 zQ@rsUc2q&O??XRx3ot1`AG;Yvtbr0TXzB96i#doOIGd<>9*Do&G2!5aXTqegY09>Q zlC9QT#q|qWRpAcDqpm*7m#oU6tD6G&01;5*S%agtiSlVJG}G&^S2Nb6K-uATQ36o9 zbd=ja0Rtu(IXRG~itepw$!oTW;IZg32(es#ClApK*T}h+e3YC7RKGRv=B7}hbX_Cd zEn59l%&ZEYOx!3fY)$e?GXlDy|j( zX?DUKyEEs={K-AYRdpLW;{A0Z$G#ft;42{SPSENygB`{~Y9X;;Ay2D>B;z`*C$#cu zw`Pbv5On$`qXkmk<>b9^%j4~FH0iVSX>r#GWlQI0)W|SQkO(Mr6JAvQng+^OQgvg2 zwDtfkUT%bJ-^#YaH^}~p@G#06iLxQ46;+iPnK!D|5?MMCx!i|P7*fo(_32=mgp9`- z1mRSk)Jwg>;t;;GfXibKy7l3$y^56T>8eqg)_Si zMLreup}U(NU*-g-119KoO|$}%im1&4#(8QO2bzw(EjiJ~uOpnXHraAe2m1@Q;B#Lk zmNj{|fB8QN@KHSf<#nlTf!txSYUTgPPlXkK`xvcu{LtHnxc8IB3nvQxrnofK;~_dr zpM=48JV&QbUpjsjPxy(2sF#yxH1fl;M%+3u*w1O%SVl@Ri7=jbAyqbDPmZmm!Yo*{ zGrlK1b}V3l{pI6fdr_E0%rez~p;LfTc(vqTWS#rYzgVH!vh_?ZyLt6o(IH>p6 zRZ?y&&ZL;Ekd;LF$EiO{2`4ig{Y@%_f)_s8$F*i805Q-Fr+ivMhpNI0eJ;xJf=TME zRpjMPB5;}Q8{!^hzt2llh_XM7+ZVGmdxq$f3@d$nNW>@_wM*47$i)TykrEhNHpw$p zA}2$Mhezt$l^K7POZ5^VDR}SNUMfvmb5I{c{G=00R_UWez&PPwX1Q-xx5E|U`;^M? z6*?YsmuUW2Gc+?G(Jvm%*V@`;7ReE@KSIbJq*@u-zISa>>r%ugpA>e8A-@f5o#-A~s>$nuCyA>g>!Ay9?5HMMTdvn}^ynMyAgqPR>Se-O0N>MQ!Kc<{7E-=v8=_Vc z8o2v{YGyVxl^@DQ2fSL2PT?VY6F|4ff#Cjv7SDUBC3e)Yd)E6~@|{*BNwt)KI!h#i zDstb43=aNImBrUl=KfP4y=Ly+ce>Yo{HFP5SC3A_>fo)vPG)I3rA6A@1NVYc+|Zi> z2!B^b+@Z(pcq5^(uf6p>B0ZW~8@b zKF_Vn)mxz&611P36Y#kZBx}Q8z&+aL!B)Rf-KU0M$^ZJ0(%N3ABlP?qAyeScllwOk z3<>}wX_DE8aH|Ee#_ZFU?oN1++>@Sg!QjER!kI;^UCXr7^^@V%SmOQ;IL|~?8RNx* zS})MHWx6g`WLu1an_+?7$0^^A0+LuykFK#u?Exicx}k4mxb1R%Z}wK2#yqvEi#Xs- z>-XliZD&}EVqy2NMeRHK6_w?)C9(dXKdyH=*2sec0A#iI-Vm*SXws{A<;8piYafT{ zW`afXCpM4o!b)AyDiJ@m3FC~NFfmJe*w{)G^4%iluZJoOUCRIxY{Wdt9lw%vNbMZT zM$s0|-3GOayo6#eRa=6E(@txDC_hjHw^HWZmI1wwmx6vk?aBRgKvf-aRkS1%FS<+7 zZ+VgJ+Fx5JPmux-ip?+&je}~gqgoNcx{qMlaw2z1Xp}@xdi|#gKhT19P}Z9 zC36($;l*sxcN)HGb^1}4!_X*Ob4i424iZagH<7>LftB)?i7feBkW9bJVLh9CxG3>d zfbNe5XiC1*J>v{}vsCbSoQWcWOlIPkn7-H_8wZAM2Ys~nIG3<4VRmBQ`#nXslhQ|| z9sLTKU#v$MhaW`h_~P}onR7>w<{2siqkI;3H^gg}3`Ka4IMfj!oobXx>1Hu-L^CR( zr_M(1ULaTaeb^??9YLX~lyU5q(6K$^b)%fDbj_c2m_po}9QA%A`)?lku?;^_SU${F zW3=6ums90V^$An--z69^WYw4LRgc^`?}?OEPM9Hoc-Y`2n}v<*riu)E3LHwXfv*$& zVtRUJi7<}Eia^;W9&K59%t`qg`gue-#=m#iB5iDQl23?!>AV98Xt&`$q7mF+`s)*F z=;PjHqkrBmp~RpN)OeVR+#pRzgEO&GbX7BJiCo8EuTTypzWR()u_U9Qha-Jc)G7v? zwLu_Xwc6zQ8g)AUWkQF@M;#A}n)nu#8#D;R)WFGIVx^3n{|s)>%ka=q^O_Y{HllwQ zZA(}B_^yiqZI$}K%V~a^JflsTYittnwYSWkH3;7ABN#q(#O#pQXJ}*E^MB z(^U4MhF9Dy;U9ZENIwL5vrZqV5J}46wOOfU!dLbf)-vmrWM~_=kAM7K>bdkmMI&UI zy0kV%yDMjLR-B(v&DWejXD`s@PbkX=gRVup4!7!DFWI(d6s(@p;qu5-H3nGX0WXJH5a0aHm5hG zKq7c6gwh?Yro?_5Le}?$%?m^mqB62ZPXTiX2_RfWlbA;67@)28jK^YRWKOoe(G4)e zUXmz(aGddA8hPozv+WhsA^tCwBg7MPzoMN5okWV>JyIe^@iJ0NljBg1fLv>@8lAkg~n{NqbhH4I#j^ zF{7W{$A8hx?f=&NF;CR9Cw4m4DZB_T3rsSdZVm)4nSrvO8X{IeTL9b<0rF&TX(-;{ z6vk4yjt1mb{Y<~`^XP~V2n)LcEzAKT`brDWA(*(06mgRtUEfNbT?h@~0ZWmwb9oGx zPGvFYloP8Fe8#610amkRxjfJtCYY^n9S{{;+OOVUJB-1&@t;=*`xVXo!7@p0#!oO& z>g1zr3hoZ;TO*x>`i4sk^hiS0rVXf=Id=YO!?ib`YQlXpu}uKu#BH z=rF7`io^9!__xz?bO!bW`(gF_vdx99@ZK9I`@l;ax^&GHLauJHVw-IW*;ry_Pa|tv zhO$m;_B42nOl}~OW^y=-tZ(MyuPce$bKsJBmv)C1nU(d)`D+3tvuaqDvHzz zSEU=YAjwV!#kp_sDf{63+LKn^&3-Tb4JmQ#fhC80jEPwI<0Tf=e%vdz!wq+4U+7nzNPw4NuWsfIhFSE;G{e0f?{{#R%xm?TRwx8kaJ*H0lEl({ z8%(8#0IQmLi=U`EPhv&xt~7d3c5-$yAa%Wfs*D7<*Ndk$Np3{qIVv^P-yX3_AOyVy zwhH@4>Lg<@AgrJd-%4J-I1Ra=@rR7Xn-8kcDejrTc)iS6WpcwL!hG}`$G*WV_MB3M zLPbI0OJSyJsRCIo8vIc0+4l$RBbf8!%n{;Ib;7l#D>|4d~4DL%A_wG>)pz0bK#Ga z$374FxERiBsR4Rgljs*DdNbJ&b;93B*P9_ zl78K#$Dbpqyd`WLOp1|mY#mxhZ6!3<8K?*BA78Q&OfMH z>nx$TN!mo<8yi*htXUVz2>(7ZPUvDWOeYPGh(JYp1p|Ux+2QSeJ~;&bpk}k1pspLf zK_cgXtb57a9JLwgi8c+9LV0$(;#5 zLzP;r8UUxjl!fVnK+a&ljhVbrER6Z>FnIG6H>A^_h4AG^ql00_mNHswPZHBZH(#w!b=5$zv99(XYRdVn0JF1I2&1?L5 z%Sw0*P#nFCU$Z>gj1gA4097otLT`&i{1&}_XOidWogfGDR#r3cAgOD{Z%L#{piMhvemQu5^9=z2mCnRoC>dlOc83m~@ z^(04YVlK%4n%{mgEevK-acm!hHzB57%d>Bp%o;RE5&F1S;o}q2xh#@=S)GWsIk+Ma z>lKhy7kd6m4)v~3cqX!6A7xrrzAjlH0w#-}=NWx3WbV5|Inv>KB8Vx;&6&oy-kfa-;fK(!U#WmwMF&evXP3`N#!LBlgw5 zZ<8c0wM)XPSI4#`@^Co@J7-+1CX>|(rU8V`hTr08Q(>UliycYgp}%rDY_P)OMTSRp zl64P-f&+A}!LOWFq}c2Ut>vEdQ4mwI_C~>RL7f(`%0Le0)(=n>{-CBUK+*3&VN3kR zsA-(&!_RuW5qLU`Y|ZsA@{_a#p$6(SLo;ceZc~cUo8$8nJ>t=y)RuPV_s-u6_!JzS zvl$gdCdB3Nc!F?m=1=38+(KFg$80o$D9epG?gBRa{XK zK3o!1RCLtqTGo+tCg2`@$SVdY)-Mb5lrVl|bIa5(2>IWDPH) z0NWz3YiT!DcrZRcPyvwH(6}>3ZQMe<2}!yXDD&soz1SIa=aCDjeWRrpQ@PU!I36V? zIrboFW*iA3 zTH%A`du5x*8Ze%OM#WC?y_Aa(a?)ZN!?3=SRUp^ivLCBbiD*(CLf2Lzk9E!oeRk`e zLG-&xZ$d}N65l*t+Cz-Qq*fy?ZVz)-K{R@MBUJC1d&<0s+A7?iH_c}F#-3e~1z$um zGZjPO+bG^CMZY84*s_~t*clMj}NbwflWmr;%Dka;pakl6dO&}mxibJhdL3*5ME z$^e!1+Bd+*eKb>|L2#;gh(ln=mm33nBHGm(N2Af44*lXJp}IF0x3!vsGtzhlO(AJx z8*H81um&GPcA;hYBc=U&h_OE>dlfH&+R0^6g`)#((3Pkj9Uee`xOwSf#vhvvo)7vz z*P5V}B)65aR?33kBdTkW^WC9`!G?}GDF$-8L9*WY;Vgy}Q^dDJnLey#uX)j8*y-!D zz2wD~DNi#C9{TdOee=dkf55BotblAy&bJjBRu^u36Ob{Kz0pL1)iF478iPOD5Bm8| zQp6qS){FGB0ubCnRT6^~sOfjP71}AIBnatY`i6S)o0(;3@;&M+CUe$au*7xA521~2 z=$SGNvH(YVuJv(sZ($R>PewPvgX$kwNb-M`l%Ik1!myX|Q{j!)v{5~FU`xMDK2!)4 z4vpG$kQhIGpu`|biN17q(nVITfAc$(b2ax|!%#6D0ol1@N-MW(`x!uLPFZOJ-rk=d zrnJ@9i3aOfdcuu5>6b?ObKLkoj4+yP;aE?hNnE@dmV4pTr~F=FY>~mZTd07#hP=$tF39zOw2=Kh_5%Mn z*$l?p3UfS-)4d3@s~>5IvrY7Pah(!Oas7o@$I{X9>m43Dt1k!w==Dq5>?Yp*z2ehV z-CJbD$*Q;VkzFKJ+R|9(Kr6&{aLhg-$@&>hMXiIXDZ#Y++AsbLuJ2zEs7*KVZ`WIH z2UZ~rhK5_B1=r=2$H+6A^?I)>Xat|nBIt{l{{me_O^)je4Zwq1W6y| zh7ZLximnPHGAnwOzoY$SxbO|x{Ww^9_T2fe<&;$fG2kuN`^yEY^N9sHi)gFL+|a$R zhBGRZM7#MNT0^Fc#x%d4@@spP(^-AItPR;^n|J`ZdP{Ea+9(g4AZKhie0{~kqVQM7 zuKWKEg|G&^P~4UMW{M`A5uWOiEtzjY)0U`r`$1tDiLbXEd|UZoura0i6}%KZM&X}{ znHwAUt=I8T(%arl+Bx4qa%Y#S<-&EcL#-`Vp(uq0 z80?4P)}=EDq!Y#9+bXtNX{skFpt@#wc8w}aN_#vFUi|eLK+c_m1h9s|V!$9P0g!D7 z^o1PFc}T#};i~eRStAUYq0x@z!BvzfgUQNMsJr7~hphxBne&S(Qp3%FF0A6v0(33* zpd#lcN95!yy?s^47VB3z&bYadQfdNyD(CrK0yRP=0N&xpuEW2{-EO}!Skvvk)QQok zV>T7|rn~;hEkEQw)74XUm8b9!-20&$2P5Ns%YJ?UOc}C889pnK1FJS(l6KK83G%@= zJ&6Y24n)UzHKFl7wMLXl42`EzUf`BL?D&Q{`+ziH%}|1ib_iesQH{D-Bl$=KMztoQ zkDTc|pg+z!77Io{qRuHsrLx|iA5Fa1jl5Cgfyg&mFy@{Q)^h+r>2qfx{`8s-du{bfd(<#C8%(3wTP&TGbvzTRb*Ay;TCK>g;32;a%9~ zYun>GOHANJWdh_)2En#I$j|n9n6kArw%2t2PH)Gloiom#Lu4uQ`*8tI?;J-q!8Mb# zvROnsHdFf$O)#p9FSV>00}38OD=h#sK+M0AWQ(0<0QMF|?RPW$sn!Ic;4ZboB2R5% zrjnTt*Wr0Fqt_HSVM4YPf-e!gkWrXl2Iy=k-e$ef)aj{ee7Me>L|w0>)*F1>LL;nx zj1QHH)8vLzZB;UVl{nMPkr5l2ThazTOYEboYeFWtl+M(%=_2J5EZR<~y*s)nFG zByorCv#Tshk}9~z8Zgc!Vv;^Lt;=py5UNBCFO<>-RQSjVbfRo6XPb zK=Tb#VvV%aON(C4)z8o730;U`lR?n0-%H|eB^fL>IhuA!kjD6Z$UT++LY_e7xqqmE zS_FC-?TG#fTd?Q4{7<@q!H6hA@Esk(18@`-`?pstRNkqMwdSe|BZU`;hYj9nP$`PJ zhU`km^ZKt|?jng-i(H?x%()#NPlY7^%XwCm3>l01kKMLP1;ApIZN!9+mPV-hUi!dy zBSzOmVw`7sv(z$VFp29-oNfK~_^z=L%4A56$Z{piT>YR44J;eGW$eNCT@@^B-9`W2 z>29&Ebg*kECfeY|aO@o{72T!|kmjxF($l#UrQZU+Ly(x1(SQVVGny$3Qlwiw0*1ja zFXH3=Q%@BzFJ6wf<#wXnHnMxPhyjL;4i@FeaN@m?YzR?@W~wT5elQdEsDStqQ3V9a zc^#nxp$_rZCKCZ?Ap^eATt4}vHakGTcHye$;0}L{?@)KehtXy|p!=0Lzoc-(0&AiV zTg8->prHOelk_V9Vt2bQQL9W9m&EPda=$ECr^beMD%DYZoLfx~(rN&F@E^5clYu3u zxGN_Ioi*n0X)NMz)T-~vZ+QZsZiKGdGQ<)C9s_36@^7S2$rt-D#HDGgC);Iy#|^s6 zb{$3oLlG~QW$@OIXpBT~A2puHE|JYqkg&HRwy7w_B zCPuV4!Z)2ZmRo6PuU)z&>8P}SveE9m*pj_9_!I5lSoy6?^>dPEGSGCANd3g!8~$ki zp-2aaZMvQWZvGA+-E*&c;sGoR+6f3NPDo+z9{T6U9`(AKs7#jO77ut5g@oCq!Bx~Y zGv4&dBv{=ZOn$J;qrwRhE=Y(5sBvMW`xpl4e|LQAFZPz)RdS*d5Y0DuuW8#EoWo#3 zhceB)+}6Fsb8%8th~dx2(+2VM?=pyxs>GKyR{WRwQG{^fN>w663l;J5d zE&)ZgmOV2z;pkUJ`=Oi(+~8D1tIz;CVLPJk4y{cQ@(^*%^=QmuLcLWe?R+G~Bp|3- zweDXpPjT}S|I#1;PYzwFPD2cEI2#G6BPr~@!{(Ne9N0y8i+t?tos-C+UIFUIR!>{=NyZx4eq9x z@FbaB{Dcy+x>QNCUeai56L5^5d0&^x!6@%fYC5Zs+FjFo?Iuijij z(uJV5$LJys>=yKsF~?~$_RFkn?z7HqPi2RlhF#U*7>icqo~$yn0w4LsPMqeMU zaIml*_(8^~y)>bS6juYFGkr9e@q>u6f*Hg3_`*iP`#%2gcynvw#-(lWTmz{Vr?g;p z%)|7l4L!UBd1X@@lQ1{x6wtHj*`E=ru@siMM?B~=-VhaV9Tw0G67wNOw}uhzYH76D zhEY63(+zqz*=+B4hBWe9Lzmi?XM~XVGbo9H-7kk6!3ro0F1_(C_$dN`cxF6JIg@%L z2vDlF0X#!mcwnqTYvJ41a$J(f?j7i0se|B9Kg(s6pCm787Lctf20knvwIh0P%mIr6 zldH7E{=#EYI!;R*yR*M!XC_XNF}*sgCe*_7r#u^l$idH@{MVFTr)w%qt(X)^d6(us zetUFu$L#=6`&VFOh7?+E3kfK3UuchA<~`d>4jAl=_WcxX)mAm72%bOt zqo=`kPba5*W?9rE;|x`5$2$_Hu5JIv5Ep|96J}u+eTCjAg%Jl0E-13?3E{^&ApfD% zlEAtCU7G#d~F{h;D;JAlUoVY zrgd(=urVxM59s5g7x{duNqp0g^?CMwFZ1>A9idGu>(1ohiGQr{K%~Dki5+wJj|!l0oSaB9ra=*yxK*Xpqse9i5s4gy1*vZk$((V8d*m+749*N!<15V|Vcvm;Z56^EY+0ZqQ{ z2mSD^#N!+loX2>~kubg!BSnfC_@)UqEOv{@u;LePx1!l7bScqP%0dQ8B3+m9IZ(ZR z<-~5&{(%36K3X*7;COi3bj%{j%o2*SQ(oYUOcqVDr+u+N3&HRo3WtgH8=U#MV*Sz{ zD=-!6mP1ws^hQNS^AV97dB*)?D%Q4SE9 zgErlN5YhwN^9H6AP1BNnB(|_tv0nw7AHYaZukna!GY&6|t+Bf$TvT#EEa_FOhIJMb z&eEy9PG1KvUW0`A$z3P=k)-6kCR!#K&YOGiYU zzRZfO3b|Y%qChDc-4hWI4LEi#Jgc9BRC(p3k^9ob2f>(%EdYwb2JgyJh};+SaMa$_ zeyUi*g)3ygxtxRiJ!ANRy&{5%$!x%FQeuc%8$@(aW!#k*>gwz*#a`I6FbS%hg~J-v zof2Dj&ff$N%xSUKIgKNVQs+AtGmj(95EEjlI^7;*DAK&`yvb!$Qw~hMOp)%aASEQq zsRrn)yxT|kjL1K%fu@v?p(dOE91$su>!YNyb}Uf|V+=fq`w~Z>D&UX+ne%3PuU|BC z7LUWufWaVa;LFqvS~#N7zOwty<^==ZG&*^nn8aB7`DiorOZUY=8)h5>A0Le-(w!Wx z)vczQ3l=c5E2O*@yulC&CRm(Gr-VSGi3CBlhiAg9Yb9#)_`6#DuW?#QXg*A4th#lq z_HKLOEn{ZOskDtuvd;DY4Pdiv6d9`3J9??jxzayNm!Cq!IT%U0}zU zP0jx-lb9*t#TLL?y=^SB#oV>Atdtn_kAHzMwb$jZ1vr`jipESPDeA&gjA#C%8W2Z1;L7SM5L8!VHeZnRDVYxYAImYpT>1T?7##VG8M7a+!YRCj}r#0 z%}f&OC#-B7A-DX}Il~nMWW1q??_f%^iNpCkYek4}LP?RLJit`cnFh7%MOJl+avGeg zm|ond9SGP>J>Nd;`()8>${yvSK0KN*cN0CrQQRJ0Ur%JAc(*oPG0*uyE80rTJHqU< zis%u7ZqOW6tgm8y;Z~FOx%K<#?=Q>k@M+i%C_TW`rwzPNpjy)2)X9WCS6MGu`B^C2Jh%{5(1#&pPl`;)Xh;%bre`CQVxTqz2H2>z8K7W&@~ z1FVNV%XjFS8Yw8S#vKP;Q~d8lY&Sff4pEc^&InKkz>|8JfQ9t}H8G&6Ok@)Mh0)j3 zv6r(Ne0tH-wvgL7_Ucra%N5+;=nF}r$K9Hcw;*NNrtADs98Azj@`Dyf^kdaVZ(6Jcec zcsXJ$+mK-z4=T${Os2t`aO|4r_q}+NERBM#CHzz-^o#PvA^$6b5ML4E!yhmMEsbB? z5oKWMzS?+BVhK4afSoj8y< zPq_7gx`7jY694RUX=&5P|GauGU|W>s8U{tLQ^*e!Q#TNvllyBHtsY%i*9M!HxC!w4 z&`B*Mt075EiYs+Rg}dj2DZ=si05+`pNaH^eG2Roi_@^k4Av4WgZ1-G|2=yV~~!=bTsq1jLabWVxK?;IQ{m`k)iP zs)(@x|==*NS<(pFl6&R2}nVNmEqINtNe zWLYx%)dst>6Yis#VMAexvsa(_f95~Nrc_=aV<9AcQ<_PbC10Q(eHx=G4J?6|ot3tD z^(KG`76=Z1sL}O>Ta4g*btZ6 z?C*p1)%AeEIzo>IWrxmi@37VR(|Q*ZurY)|4trhLhpO8<_t0>_nj~I>aVv= ziJ>;v+WkbSP1`+`-Y0pC>LtoXGjE$i*udjnUJZ~JzI{**`#SMQIDKS_;+9D;^@kuN z{zz6xtxnY8EWGn*myFP1t~s$IEk>%rv-6N}J?S&QzAaD(UGWqF=-ZGN<4)DUpHd~l z#$vX~fC)~cJTwt`u?whuCgcPm9HLMuavF=eExX++0AP%Pg)xS^`9aYF8DUOLOKy&18Cs6Oa6)nH3U$KeH{c{vG>?; zsdihN^lB&OQpet(=Z=UPN{@QqkZh?@Y4D|LWtKAC@g~~wo6f!)j{^(mPNNLLdC0@_ zf=0R#dBh6;?UenMGiZE^o(-(7F#VScxi2*KxS=n58>Z==Wt0o#{SpgC{N|fN&Vi38 zP$@d;*Zu&s^NIU%_HfTn?42CxBrrk;K2FD!ph-|v!skaJl2X7{Tb{5} zM+RqoA$w&|P;a^X7+Ug$BoSsm2}vFtx(^nEc(;~|nq3xbgyju>EKHznAWyJb7fN2s z@pKwzq}_1g;C2El>eRTGFsbKQVGw}1tAeAAr{XR#&~JE5Fau)rPR)PeL+mc(Rq3RW)muF$||g zl_wt4{56_#^wK#7f{Mdr^*!l_r&+3{{-D)2C#$I;m`Yu2>tV+l5;RK7eMhGh90Df9 zX_vW-me5#N+{g*AzuEVNUl2}*q3qrOw|g(dy7LOyOCDijn>Rky;hx4vKYA8}-*bmP zfL5@g$pc_ewoY~?B&d>Lqujzl<%_M&4VlKCrV08`g_ zdLp$@zoAS+1OnqcbNkR}LIS~AAVZv?lraC6682zvzlSWW1|fV;Z?@<@kmR6&@d3&;vxO}3P^ zg{gj|{WVxc&LMThVyzrUEF#`xFaa{!a9{wHkbPyb!>7Y*I-~C-R%~x6iAAK+WW=I> zL&=mp%T_)&iE=^fa>t|2v>zV9WJNL)S1(pv&Lycd*ro9VBPO>+v}`p9Pu;*qK^4Cw|f=SIh0pKDSI0AY|A zm5=2HCO!T`tClvTfZW9hr7CyDMY*snM8xFf9aAS%D&-}vB{y9L6MmY}gx`KMjN9fQ zRzY^~MI#A=-`8yc{JO@5@frBeJ9Z|mkIK7kB9qJZ-nFI8@?$35vk&Y#tuFNFD>zVF zzc*%8OiiZ~w}lK$U9EkT6Qrr!{Gyf(oMa%N55pM_+c3pY~Bi2BIkWAwOCHDLp#T^>hmMg@qT z0c6;LHnrKZ$AH>LXcIdhZ32MYsqMmMtcw6_a5J5xk>kp1$PcdfEDU1Utj_V7R8G=U z5=7HEeO(T2y9C>{@r;n}L;HwTZWl%omSq-lyuRZiOh^h`tHU9x=uCm;53pMw^ud| z>i&Dq@k9GRsGmJZ@F5O@)NuG~z3m|m5FKE7-q&Zpye(*S-;ak3h3sIB-4^UnMHj!c zCP`rp_1<0vJt|n2>E_EF0LH?m*8B`Y&c4;ZyC%Z7itHmRlM^$ zRB08!O4*!=Sw7;|nk@I=pb$MP4*55nuC(9d6QR~F3o|JyI+gSC=}TLvGv(=;=k*QI zbdu;cJ?_A2n<{=$<<(o0r(TK9Fl@hl^og3gnNzh(kBuPaW7wYP)Gp6nX$PkdVkCMQ zp|zt8!p@4^Fq$(us=QBbK9bDnGgInj3jS0mb^)Q=kwG@(%i_pIAlIR;=c7jx9rpSm_`^!0tDF?HYQDiOZX}HZ7f3U?9Y_- zi2%MgT-uO+*{;m2iMd~yTYMG%jNvXxAHfiP)%{; z5`b3In^3|L($>lmk@B3YC8cK54pBQYZF*gWtNdH3aUMTyZ5c|K--&NFQisjC#<;fcK?e_$me`f zuA9$F7659ZjgBaQ@CyNqQF!Y-=)tbfb5djWAJ7-Nia6}R$O=UePD1|EHoa9 z2dTXRZok26f*!H-ErvXv@hUcKRNt`oY%pdHsT>X?rP+XT`J3JJ`6WzVwi2OC*z2Afz$JHfzU~%~ zKCk5*Awiu9q@@QCF&SljUH_-M?Yzm?r?|uSA!~!G<)~ueYRFD_ z9>Rw{L`5uzNh@F8fS=u_`m#PX$sI74P82u++cO`KjFAAQ77*B9x1Y7>rU;WWxd$oL z6mG^xgE%c4eMW>hI!8m?RM^&l$p+!Le}ZsfkQ5k-U-KUn8}f~Ld29nG3RG6|*{Ccz zA~Z4-#-aIs_;x1V+yaxWNt}(4jtF9tSpdyp|9+7A`4gM3w>0gG@bU5c#@AZdiN=eC zzF*D3+BPkOgAOSwxH&cDs_s}RSqb=*1l%qsr6u<%di51DU34g{PMYhL?J1(FE(;FT z4cK*&_P!4OFk67}wDB)8G+q?|%F({8*e7Dyyk3`A8ceq25P|dfP=d9|(cGF1zA-%u zvG0Ai^_}Fh?!*+S4X>lMG-R>?67U7={BBLPc0@;HtSpMxVBocjL+nE+aKDiTZBoqd3I#It(rZ6zCZlK`e+lg zx}-P;V(a;kUGQB!`N!|Puc`qKIosScbh@zkZSBiZgiPXY71#hkE=^PEoS@n4MCf2q z%*3o*tlvA*o1rbp8J`}rY#`2wu&uM|ompFHo?VgtLsguJwT_^}<3ZNvKNK{ROE|aT z(zqJ0c7)rby8wN()B$-d6tk2fx5bdxM6`P6Y-A`iJ8{=Zr%?EYXnqU>1Qq5+9 z*B%_3=gT}L8PmF4QJk%NI6Lzi@DM|pU@z`F*L3Wl6y9CZr7Fwj<$Baso;e6&3B{Y` zAfcqnYWX*Fhew`t{JhYl25VMiNrsR~Uubi^`cJ*%i~n>DPS2bZ0D-swR#7?uLbj=*q?aD($%CZV zHvR;G!5I@2b~b9vJ#x1Fj_+{T5``m4?tZ<786@^)FWD?|^yA%Qrr!tuTD&zlk1Y-r zeSgVYsdSN(l}i~xCX6%_|6wP+AY_6Y4cm%|R!q75osQ3{Z%&KiZR_p}k~9TT#K+~S zzU76IRNkNO#@QH^#u zeYB7cl2Zm^6^BtRMeGy0n0yj>%bXcWf3Y1&XLB((QVh6mu>b zg}0(21bpC!^UOS<$e)#eXB`QmI1?yZ&Vx@S#8!us?_;^%7vwLHs~AbG8|A%wG1d}- zT^s#MrdZH9DNnG%o{B-F+R2LHKP1-4tdzWuU#U7DU(GpkFgea82jGMB4~lP;+i%~b zb|YwoKJrI?het%Ds4Rp!+nJMQ1OvL}oLC58(mt8mnhsV~ZlInBiDN013hES#e!U{@ zz)uTiv5*~aWuFfYXXS-bU6|0uOJ|TORW+)_whcq2WoAf;V(XTh4jpifQ@h(-gjE=$ z&5)Vq;GWmG>H?kP4LfQ3_$h@MEQ?x3h3nYxavluQq* z0sj)LnDu^PWsV%nl%S4))|)D8lo`5s`tg{TU&q`ewxVzNj^ihjt*$}Q8mKB$>RJRu z@9_P;m?&IN$o62rm=8h8a)c?R-uDOyrLZJ-;{vxsuZEkqGD5RlofjJ(V&mF{;wf7i z(~!9Wh8SL_fmL1e5OkF@usRI0eS-wPL?Ag*{2XNW0Ou8q`ic)=pz`8ih%3 z#PMNAuB;;(8?>14!zAS__VQN}DYhY2QE^N~z|>eCP$6DvFW!dLC15=In=^B6C(0#< zY4Dgl&Q#djL}ilr7vN^NwnZE7x+2`{E|4>~%C;XZkv*M%F*KT*N6o05e?yh<2?j8- zQJLpWZ)umgpxRBR20&w(JxJj2x^S5Ma}kOVDe!~L70VY4xL*73jc8Ctdd7q;{k&6F zbymDr{fI=*5?8~Tq|MC0qgT$E1)hBP9Tkx4ch)M5FmI9;*2zw9Rf**!q-H1VRKL9ZsceOO<0gwR-ZI_sAv;sz|PwI!>{4` z%7Qa&Vc~2PAi3;3xYm(gI>2nmKoI#-=~}&^w_y$45mN+<+Lffg?cuNApcn?@ivz^g zg>8V4R8>-e&xkTYXB{iEB$W=RZyA_KiCvH~Qh9i!_xt;Y9ROW##D=djU4ybUoo{a} z@S1DPB)l90fc?1v*G)LWFqmmH3D5=>12wry2ICf2jeOQRB9lK%rcoR- z$JJGV(GnSVdzU0G)9s_&$O5$4o_jbLcoOo8UErF%jFk)g@259=rjBUHFu??4B%w!^ ziE>nZ+1M#?S*IrHBx^0?9aC>5hHR#je2kkSJ28AOZ?(qrS=jug%(4BbCP%sVH(UK1 zS1T4A;UAa#W6KYqd@Y2TKl*HRI>Rgnb*5)g-ZFa{<|160qWaU6J31g#gV+O|R0^^G zSQz|$DM4n|!jX0K$04D81*O%lRLOWwzsO^F$H&U8=Go}lBV3Vd0FTMnYEW?Eu~DzZIj*Be}GZvdZ= z+y%@gFWsgdj&W$&4oA950SVL?aKqRCD(>%vBvc zzHvGuzK!3qe)OHO;mM5I6zmOOlbLWyN0jZ&??2(EMfBi*b@oN`%jnt{En>3eKX)yB zxWqn^WNm5EvpVT&{;VRs`rfIuu?a zHH_K-D5?tqE`E|lI8Z4mr^Z1smGz&2kT z%A4~HE;H(St=(~REj7Qvj2gw`|38HYjc8C4=5iK49PTioPLZA)W3Znq5m>;DSy0_u)X0il&`pXKrV^mB-}F~@4$DIu@yPepQRs`_26kK22_ymH zC&qGbf~vWkh~(p!yVARSspK%q>|Q`%7FL3P#s59>s*AJC4cYGAUvOcIRII-@r&Zk>^!gzq(N}cLK4Y~5&fhCz!FiM zGDe9w*;XPUEbs_2T;3;_e{3TL`?SvcmkvSN;FIGu7LIPF*RxXWu^e5lT%~g+ zlP`vx;9W1>uZYf_#GNUYFy3J*1gB{Ngwxjmy2*l!v#@oGMcyb6@$3TS1RanpW^z84 z3}iJ-hHFq?A8NdEjIdxC65gY~U2;gCQsCCzmG4M3&QWvbO4v{WQ1jO#dA~`gTcEKI zFr#5Hby_^$x%%b0fM0%soQ($AyLEu>KDKegaI%zZFqJ38@yq3FsnBuIt2)V=SqhCB z5DM9S!*^|&tW3^ls(=?~3<~2fWL?~rBf#GLpsOfUI1@98xFEbgZHml0D=kfStH@}_ zC}2}m>q7yH5-RD;E4-a^!!9!JR=vl~Dr3iPharTK88r_`k-MF=7vL3{jZV+b#lM@oaU&Tn1$cn3M+mPnI% ze_Oz!8oQ$kHvFCGwDL%reI*rB}_g7HRDHG;f9c7{{{wJz%1mQk!{ zm(PXy8AJg71ZF(q=;Wv;eop2#a>kE$)%0qvr!$0xTvhfqeFh62)4e>m?rW-cyOK1w z3uJ0b%*g)XSPr?n10R_-JwBGVYD*Sp-;9)<&5Tr4t39U4S==qv@F*FGs~m%0Fa2Jh z6ce^`QO5h>b@TcZ5zLTKCOw3ioxjDL8N8O7v1=IR^BwHsgy=2!A>|~8ik`%CQ0_S` zeQ7ZW4gHC9IR+sVH>lI+mz)st(L#wyCI&EAH6Ih* zTFcgs0&_09gxI|lK|bxQ3wfsTJ$U(wQ8XiF%>K4{nKLFWG*JL>Z26}HoUHg-)vAgr zrE)|ENq}KKX|~qnb>M(bBs2rc6h{s9X0GT(_y^U+55Cz?XtHC-Ah+#DRvR|e6QW!#1DXY+9?<;dzi zTqh3m5RsX?{ewp7wamU$#@^-d4zdhOqQ{5Ap;)Hhth&@|^get%u~=;)6)k)a{O z@i;~zuS3ElHjPBHg)i3ujgmdt^eroL-E*&QuWq-T{M$D58^56+X zkobp@G+Ud}oq;EDD(v47naM|ElH28hgzvBZi=(!w!s2;{;(TDP(N=GpQgjcs7=)ab z?c<;Q4&m8z5`OP#Rugrm@H8cyU?D{97f8K>4$(fmUAa5!pD+081^{(erfN&Ev-#a`K@kd5 z3?@GbN8}lZ8|SG@6N#_L4VS$|+5-Gtpq|@bUc}K-mQ_3(d6gDD;!A}wlHpo~WEsn^ z(^(Smz|%36yeq9q3q!sDamFM${f>-+Yh{3i#f$5rK$+H-55wrQc~3tCg~qh}tgY}6 ze=)p^wOe=~BgD^4x-g-VaM?@tHCysC=SmPyAE^?dDDy#Knu%}L)_TD}QxT!Kr@sj6 zYXLE#Rj_x{dV>5KxR=wXFIcl>Es}*D!#bo|kF41z>IpbGSi~+fgSbByfi!B5SUA}> z*>jjaL<^Yo>V>ZUhyEVd7fs;zzK>i4N6>{G`-4>N8b#09A#YnLbM8Q`{+N zw-1!Ll0rSLYMdg%So^%J@e75@?F6n1keb$NpCaHDSZdf(A{zM6;@4dY<)Dy(L?bM-pA#f*I(0!`5hxz3NO zB;z(g$dxR#73(3jzd5+GIv47$d6T2LII~pGL0IjmIrYkEZizC2(+;HQ_lgIp*@ z98FDZN7K;Y;|s31J6`J-eoAW-OiwWa1GYlapp5chO&Nr_2e$)HNVO%wWpmvIVH>;u z->J8fkF`K4=~GB4;6dgAk89oXmJ+)ikr#|{zSJvQ!Mln69E zfWzDulBNHaa>Jy3^lRw?g*iSD3Xkrpe3%|b$!AoPt%<=TpH~3(SDt}2ar1apm<0^= z^Vg3mo`T7B_D%-^oAuT=j#m-d18(-vseKS7h=)^O8(db%B#=P;{@y2{@JUF?;-C2= z4-9l(h0mmP8>H|ku$)>PrAyd$V-w`dV?j2+5RjMm&s>H7Znngarcc(?s*T-|gm6KC z(G+4w|CHaBNx|DWL+;+U0%ut7rk<+<(R7f0__6^&*A(Yf67gh4_in^o6CQOuS2D|k z3WVcaojzk^wu&2Lk1elZ5gG;M8cj{?RI@cXBDzU89I+6q2)QAeVgw>tK<;6;{b`4G zHH26NyWjCn8%oRY=SZG?_#APY$INM$){-CWpt;Dx4jIS|_Y?d3w|B`PZ5jSW7)HP2 zc3NCJ07V)jW0A)h%QX+wI6R+Sw?NB#7(Jx$XIro92c25$?)bnv5v-u4>mJ43RP50I zGgqsDEkq_WH)jwbr0TjcWMoyWuBu`gNOj4oMf}0s(Sy{|IKPtYeVWikwKK|}@Mej# zTVZwqyJ;IqYJ->#!d+y`s~4^zRU&Lzb06lxHTc88sn=$oB~>=Ge)C8JDdhyT9=uLLo6Psn^NX87*TFZLCvaont z%_`Kb9lN0IMgD$}RUN=quydlrhD1@CFIW#>JG(&!6$Qw`q7NNMUFO5M(Q1}YXR({L z)*EM<%HgMSG=_ufV_Bwo2BS<#ssqibs@IRlfzlsx1cGo#;GgLs-g%%ag7{wqhN#QA zW5Q~qZ~9zn$zfh>rt%U!?t30|=`{fiVTU`rxr!#NC%QSQM@WP{UF-$%VakV=`K2jC z21$3kfmU<`rF9VcO{ephzoKMxU790bqO%{RfL+MVZNn?ezLlr}xoRkyx?Kv`e9*u1 z#!zvLAewC47ZRdAy8N?!|D)*9*bLw(%n>l7>9yfj?VT0V0#vj=ix1fJifHsVzIGf?a)h*>ilbW_Bzg?=*Bx^HHW26Z#T0CNj z`7Pv+0SmD<{rOjw*1DS$?&G z={Oli>YGDpTaIY6v&>K613s0ob2)`vRUVFY%U{8L}MCW{D)36ZTqbMTi>sGix zl{ac6li61r=dQ>&!I1mrgXOJCU-hW1E0$r9A28eO30xYu!vBmj7v5^>#OsWveYAeV zA7VfEa9XhqC3&YJM!mRlkopE;)1V4D_27Gwg=8cEit%_@1dbKhWF}0S#f0;ENXZ#( z(_e8$h^9y~H!}aaRsd|Mw#^%(;qU$Hpo{|d+_=qH{|q+iyQ@W6C{tsPg@EkTiwYi@ z4FClQ#!9e(J$VPVe>}w!${McqTd03|75hrWZSfLYE1Zn5cTd~Q{A-#cB5cL(4zjg% zyp&e+^hM1`^N~--FJkAgt6ks+spm(mHvlIuGCLW}LIt zeI-#G1ZOUWrdp-50W-r*scbe$L1gfBw)MB5B)#kg4}g52inog?>q0pDBMR=;f@qzh zBs{K7m3~Au{#P+SNP^9Gfu)0&1<>xh%2?MZd)>^4wIAF)O-EAWw~U$Nl#kXG(*fq0 zjc+DKMet4eQ?k(GzjRjS&*%ilvRsIS<*S=@0s9%ay@U5_LckGUKQdiN3(^YX9b;RZ zf9XZ7X*G%()t&YGrBP{gzl|>ma_H!5>W>oPpvld@vQKP15XCbvOOI(`YOD>oNX~f8 z8Me6*nqx%ch{Qehv<4cDPAK$jmV0(a*);DwF7ubg+hNL13(c9NLS##NBiF|Gadvnuti^srnsFJ><} zrxHHl9cdD)Dw){21RG!Hnk|soEM1v``PA0olj4X^VwLO`HU(~8HnX1}H^xx<_=(RoabNU4ow=P{9pO+;GRU`foIC+gwi+ZofKMH@u4I91N; zqniB;&Y0EZSKMq1oKwUs1MFb?H2zhr;rG6^X?qHClX^a?9;{kpa}_*g)j8w6} zEVjOO_ZDK3%ha97y)7(L!gLl(ISUeA5T3l48(hHBK-+2#)y_^5SPpCc2HH_hsT zhE)RE5Oxlw9{wiG30SbNT?&3?_~Kgaxo9lq*4%Cn8nLx)RfU?)?*m8g2)q5OjGJe= zzQ*p&;oh$EDjGym+PW*;GE~N>+L+d2BGfv{+msTGp02WsRgN#mCct7h4+iOUb7HFd z7Y$BoVPyuhcw_Ldq#_~~>WaHiT{3{+64`)l6dzlP#;3Fzu?4si2AMN)`V)->NBl#c z%wDgrhtL6;3k7=dS)VH5n`WnL7-o>BA%<>k^<^)8HH!4jh9Hgqid3zbA6Byb@|MES zAnKCWA*E&*!INJ+!M8)y+xzcT5me`(rHt5f3|El0I(ol0>eo55EB3pSJCi2#7>3M5 zzY~B^IZpbw0N?fw(33z%NAuc$_uxsiN;=gv2Ez69R%S}wf(jmQJZ=+I$Lm(Q4+`H; z=A6H8;G)b#ZDLEv_gbxyI-e%G zn3Z*!En!pKvo6O8mZ@aOCL~^Z zv&sAgi|R&fa@r{yz%w6n40B-Zm&nhrMxoK^a(>Pz!&(l$V<)Cfa3{EXC>y;_TYc3% z{0mx?d)OA?ilf+9sO2g$wWj|77KW6q=h&h6?Xz$>EOxJjUpK~lLn6?KEY|iw+~Im@ zLh7Z0R{-9I_N}LrO8w6f)O?feYg7pTX3sSwXhd6342hGA+dZPAry?Q-J;G1ZM2DEA zYt#?emtLJA5K`ll!&cwn4mV|;)aLd#efXDvlS5rTiXGVADFa>&WFCul}Wlzr&xA_F1u<|sZ&Upv*&Nb z=X%(eKUf3aaSN&tUKSKYbZj;*7X2{|2tW5QWIFdtwC{trd@#f2Xb z^40A~60pEIm~qd*@8;a%S1%=Eud@9I|^TQU`h-JZ^ws!@rqengTnmVq9^G$ zCT35$oD?q;H#d|3)sWcgkq0HLe{g#27dQHt!9M!*mH6dB*8LieqDjSV9_P!h>QSPl z#9vqsudpM(8+gR?lVJ{zObWCgD%0n$m&9SnIbSMQ#Z(F%B{dW8KiQ8VRHt8zncV>} zftq7I(uIEo?iYLVb5qII1xrtkd|W@8=m>#YmK7hhGzb!j?I)P`gNf->DbJuM|0M(_ z-!`G$zsSZa8}+~;62qnU2fQ3Mi;kYVh_|yaDG*>8KDIIl7EsyE5P~aM;ua1xb}8q7 z?IVdhLsU8MZ&p%AOXDZfSiT9%_*Zso|Nelu^jQB$8zZrWYp4-igp342vkQ1% z$$$}(Y1)6?=@p872x9|VK%V@@2M_m$z4E3@K6D0i{C{wDND@e~Am8G~?o3r4t5h&S z8Q=d);S~VD5v2b{HCg+|8=~kfBG}><@X3`flUCWV4i3^4ts5c&#<@ATl5cXNP#Dbh ziu^-qE;%B{s)51bb=J~=qN)D?u;<1r$8&%q3?=+uSOW-rV5gcFYClFlF+DMLEI{IR zjL2+eyJghVMh9CM^Au?5I$~-aCIi^*@Eg()T1viVYXE%5m9BVGz;rYktw6BA^f*)+ z99n~1`Sce2mY#Ti4v+MB#e%98e@6gKK(fE9?8?|HLf{}s<4`|3K-Pn# z3~+tu{PVSbJc75(em(V|OJ=;+x?7F9Bw#E|a`nYJ`gU&!46^cQWURi^sA}Wfi_L}0 z29FGGk|aso9~uDgz?@k9h|mE^Qz0f7Lz!Ql9IiQ=H-?j^T(%TN%-+;I$Hm*eQWU+||{V|7W3cdOv?Tfeoc#O<@+l zP3iW8)w}iJjvV6l!yHv+1``^^o zzOyjh<8Di38%y8GXN3JI5#KP_2zn7I295W~S+me&ahOFSF6B~B;-?K|3yhq@&J83!pQ0C&JB8MR7QfCqW8Sr~Ct~tapb4l9+@~76Z^OZR z@cV0oD_srOC7py)axM_OQUqr_5dw z3MW=s=L!bc`k1hfvD|8s;lDi(e2#={wclo6AzPF1@|x0V+IrDRW9g?I}B#$iTCH7c=&+7q;AP1Td1JOaEz*jissJeSRIJT|h_b6fO zPC=Vz3IKK^gG6e9^8h7A(^%L(3K-wdo*2jqe1(`X8_)UZzux%1OJKVD%<`qu)UfN= zv>v_pS0CyJ@HhJU4cu0tcVONn0Pq#osTygoodU8=2yzI@Pq!832N!g<*nS|V*%!Lo zQujqG>u3E8$k$SQf>eFLfSx_^)dWwbD0IxOs=q=MwLXh@q@Ud5-d{AtkyIxA+{H?x zZSCs=V2^Uzx6@C1A~>2H2WyT#;yDY&nm2+JoQMZEoiCumKVz~v zL`UsR_e?O>A?Pgv}oeB^8Ws(kpD55M1?<1n-r6H9y-uxR{NJ2OLu4WNBtNgcP&G^ zk2yDqKFVtf5lzu7#LT@%o8{s^U~9cHiWYmm12D%`gwL&as@d`#JsPZ_a1KWnJnCZp z^mIt+gW)i*KPFUx7KO(x*yb!7zKoV8{w1?yII@&q8O@fO`^r%Br<8|ALtu3F;( zE8P1DB1ogu^j`m|t-+=`q*ZmQK<^x#GW2Z^R_uS{{Vn}ZZkB!`3;l!MqXMK8yMv4F zizQ5`@taqSqVK-6;i?BfqgYnwS+p4^&Uc+>tx`o6(y>OpJtbaTo#bik%;!DoX^Peq zY>6rWE~OB|mUmy9?%IS1>~7%T*p^pyT^hq|0d;Jg1yPDPJBjz!ve)bsZ@Q(*rP(EW9qt(sd-Q3U~IkJ#E|nJC$?`C|*{I4}GS z@TQIXfsQGNOF$Fbny!cCB{)OT7}g2xg(!1bW-6G>vkl|XW0{G``Fk4LkePYB>Y<)U za2-C|3<95_K43|t`DEA`J>=F#t?KIy18Ai9(>kv%Ntt#^pdx`G-Wdil%Dg3w3`Cll znnm%k#5p3@N-MnTw<}>;?E(ncfx1XPczzGQ3m|VunK82P<1_zWzUSn`&?<4N2uTYK z0IOqSOKvrxpDpS}O>UgjEXzQ#D^I0>I}ZD=p9~od^UWuN*Ulu0Yh8s~WUe{twOJjn zKqI3oS&}YwSkT5St*cM%!gGd;;`fn;R(KkY3FW+U>%L^4(VgtzAZSI>HS38`>ofy` zgccha2iyGRaeYW8tfKy(CEAE*oFuC#1mAJGhPIYGFTFjRGmF|Mok0 zHg<8U6mZ^)h{>%T8b#Q|x@n#8=G4{KIW~~Wgq5}|9Kf?&ZzOJGq+TgI(VjiXjGS0G z4bI7kpYXt4j~nUwu)_86wXvrDK5A{oGK5Sr!9=CEQ7ECvTO=7T-1(=myJ`5G%F~Y@ong{LLNV>(112#J zs~bX@(d(_eU}Sogp%^ccL%uMLf{~+{N@9y*p$3z(K6jFX4fX80z+!bHM4-H1q>%r} zkbDCFOpF2kv+#a5cdTHpeY_!P)LM-9&Zj`gC3)e`ZhC)aK^!q#nCi+WLx@YZX$ONX z-Ck~+i^JaL34Val{dH)52t@>P z41!O#zh5JA=N5h}{oC7zf}>&;vrGn{+DF2v>_sw;5Tsk%4 z$Dwr5ps^EnNx_(SaC7oX{8?d}yJypg|I1V(4D{8W(jGj)Ab@O%iE%43$4$nb=v^NI z8)YeNOJwRTkTNT~$iYW#QX&TT)OwTLI(l4Vgv3mYY^r!vlp zjlFkF%>4E>Zz52cxmnz|?jau1P_M`@tOnzM@EwxEp0HFGxrchEqvNs_qrVxdsLU{$ z`w$d*5Czxl@=qcZFg&Z@(mSPiXU1p8sT~*Lz?q{G$`^Cz?+1GaC%LqljtHjpm4dh= zgl}zRk9K0ky$M76NCk80eYRq^ExqkM+^LwgUNw!B_($K_olYp{bA~JEH7byiH4BmC zP*GiUf~J@r*ebwH&=@x~;QLF3(AjY0r|iIgtt8dbd)&e<$98T4WrXV|G1; z@tAlMRw-C+1pG%ge_Kcm-IPp8K>(YS&-U7c_FuE)Vg5xep(G*LzF{+e`Ary%+O2uP z#I+*W4>FRqW%M~dGMub2zjGV`H`NKOw7zW}BVOdmwtqFx6kjNo)7r^FA12#LZ~2s^ zh+}rRZWm1Le~gh)5NL1bgHNiW0q9cAzUWG6Xp)dv47pZ)ByRSv(`Or5sUw_{K}c(- zzgPYwoPd`D(;!Jw2~&%z^+;7Ir4c%y7~zCqWZg26Co)TDZZ$d*=}{y;=_DGG=CS0{ z-kt(R#|Y(ggE_OSVk{IIn*<5@M$xV2o{}fz z_(xQ-08yt-6?*ffG&0X+T&_^?>R{Ls^owW4Zm>(fYXUNkwE4J6oW=sZQB)4qXcAAb zS}$DH#DXX+vDV~1I-KM}5AQ>;!Utl84(vW+(?Y|(&TMDH3hzA#Uzv%OK|jPo za~n|K$e;CaD%;CqYcn2E1sepO>=Xk8TX}^Ec`WvtdZVG{r)Van>I(eQ^aNMnjH*V@ zg4ICK9MR*4)t?%}rAFQuqR!3o!WV_b)^I1o!w4^!U1oUbiH(bgjek(JmTVJXW(#ZS z#IJd8eGULWD)Ioqr&uzZ8VIqoio)?t1^#$Ar?92nM`bVMeIeN z{cMobT$)fy_3P*4AJ!M;RVU&05CcL~*LqSM3X_!5XkB7-@BJ(8#dmc3h z?uf`p$?bK8&XwEP5!-g_v_#thWy%J{n@qTuP7(It*KC2M)}PI)279@?*7XE=#DgwY z1mnCo?C?u7DC9zAs+hOA-8dFyWEk89tiBflgIz&UOeNT2B~&Dir!u0>G$PFs>2|1N zXPWIN|49V7DREzckl$jsVIWh*90gLYsoeB|NF`1 z3P-v-EEdnO2?$#jqHPoLA^d=i9^&(inJd#&>^C4&G)M7iA=8{GyNKSa&$(3M3Ahu% zuPkIsC*M-q-yP4fnz&8dR9Vxlm9vHc=))AoAOv7K=1A+Uy-eN64tRQQ@byfmRU_A8 zTP`ngzf^K16I&dZHGfd_pI(6I&|&QDgqlm?p5U77{6lHz5u$QS0a_U2K-TjDB7y`{ zbCXx=4*}!@oFHVSr+y$oblY3B#q|rJexW%a8ca}|-{*Vve%og`CpfR|UZ83ixu8;D zNGvn_TdZrPX(EqLHKN{?@3q%~FUxhDBG96(vAHAHsjJp8`YE_B#eo_4yCP^iT3wN z)>VS?G_=M+Lo{NmwW$r592)YsT%1pN#g6zmkU+k5?zIQwpfwFGGQS6C6Q?%TQCc61 zxERQp`ASxX>E`p=y^-79*B+%&k=3=OZ!Ni$714m2(QU?HZ_G{_h6&gqa%)|P4f(E1 zbk))GNVmTi&~$t_{E&CUGYbW2J*4GnKgvnA1^##w37kVb zcNRq{y)9rZr;uWoo0AgdaVbw0h|06o$+j)OL;4V4+Zh%!B=+*)0OI0i_UOLLBoR5r zCqJ%-(!XgVSJw|Xcl2b2jfMKY;00T|@1S61jS~NodRP_2y#XgQVD+K&byUf{haSo< z?|==$H&g68^TXs}EmD^CI*C9~UO2G+IJ#j?WoG#0p{Z*d5`iRx;};&;RwscMI@D+Y zbr)S33V@}$6OO$ti;+|;2!LhoGf{6XTT)7bp6BA7K})GfLVV-rq&EWjAy*sN?7 zGN~WEm1FA~>}ExlOxeP4!|N!*GuT`2PKW|k>GeweTPN$}8si_3gQd=Syp|WZWOg+B zBvy`MGS_LQu%R_!0?2h`cHEt@Jev!gG87ac6287^7@ep#z?xWPoL80o8Wnd;P(@UdvX?DUS-QV6y`RB;iw)Smdb!fi;4FjsX=NV=y;STyDtG|^&MFxJ4#=f0aXgnn1#kQ9&K zJ?PNS=r9WSn)IA2oi`vvy|DTL>sCkE{R6lM+;5q;eZ=z1rVsS@T3IlW5YVn;XK;~4 zL^g27x0qdkGqREJxsK5MHs)g16Ow0XX(ZzcbhF}kyu614JW*R*^Q~csjoBZ(aSI+B z>?~lFsTYi+1-zPfUnJ-XeJ!e#4_&omv93`n_xoP(BC1O$_AQ!wiL+|#$WV^c>4Uf? z<!mx$-7SE4UP+@m#Yd>R}J=(Iz@ z{EZNV;Q$>Uj2P5Uopi*6Do(gTybCx2ZCU?n1mlBo>&zy%yj|5g!QFTriN13greLd0a4)96#oCD{4c-D;H9=Oqc8T|s z#voG$v3oN4@Qtpt*R4$QA~Tid+;jELJf07<7?xM>vg9O!imD~0n^IZgbi2bIn5AE_ zD-#hGru*WVq~4!}z^Ra0f0`|xVT06*Es;(`8h(X{5y2_UO?9Yh-?10N`6)e}XvX;H zEJxad;Z|DR7B&ttpXeBNtj}|8&w6AI$TfFo#m@*;{Y1+k;ggwUZ5t{r2A#+?M(rZg z3jykK6`zGXNHVl37}q0}pres!S#XDDbU8$Y^@-FWfD3q->`$+^&@Uk1Cz}sRdSS-4 z7`wgRR<@q&jfzi&9m#m`rGE!^g<@;jh$`=n|PJ z-?1sw?ucKOx20^j(-T0=+VO)EX&q>`4zjuDMszxNCx0f@#c83k1UIW@-}d}l?K3&wrZ z+1U4>+g64`Rmm7eDMZ_3o(@HD0|;AR5oJ`5a;(YQ;wrrtSt`ACXFQ(q zwyR27B(!iWjKp3MsD;}lb0hxs2SO_oyf){zjn!WH5+!j1_0TK}vJp0yKPZun2U;Vg zH~?u)2P7qn;ri83SAo3Ekt^}?b92xfm(S;%&X84zMg;pv*UcH`Y;R!)ZHk`UO8xs8 z4l@8?t0k=#L-QW_ZSAVWb3EzREy4pv^_Tflz|Ec=>ulHNoy&+-AQHxo34~k#qOqwG zV+Y)VW->72@N{n24oebeEjF<56@MWF{s-M%i|rJ)5i5M?uhFjuzTdO|7WeCx5h;;i zWiFy4FoGIeBq%e+PE*zq;3>Ygn7T*#zUp?6 z?JdjCf~G-6>l6I+>fY6p3Yn=Ck0ld)kq96!^0smUoD8KV=&SK?hs#gN^wg)|x8PYi zmgh5b=-@2!vXTy83UeY*Dw$GyfxV&0mNKK4YeIVi%SJzoU)6bBx^$ukm>Qnz1phBA zk$u>J^p`ip-xJ~*vT<+Na9r6WLi?agrHdy8HXYhSC0VUr913%k3tN&K84{l71o(>R z&m+*8>9B{6lWt@^N8y3F<>2U(a=VMW3fln}f~7{_W}j77yP8&A*Q3R+NNtNRWZBIy zt+_2Kv4p@k_~&%ytn2bt~Fh{QpcC~!6bjtm_}=Z`q!ski z;+h!7Tk`Sl0d?}VO4K?v)|nEeAv$bu+7tfJL?!B@2UF=Ioi34-@RY`A`Qiou0o&UA0)?QgNz*E?CZ8?%tCHqx&f`L=cQqNE$TqDp*-}V(NSXaW7ZI_{!BRN++FUSU zeyl~t*4{#k8PPf0)Ys+CT$O zwxnWwLF;%ad|6`M0Mna?3+dN%-MiZ}Bog=S;%`_VI7+|p3nF}wU8&!7^-D5XM1<-^ zmZ*`&KHR09D#+m14uMad(un9~yt7~poc}JSI4g1M6(}xlt``JThvx5)l)#J#ziV_; zVP$D`>X($(dB7V3SqEz7e1T1Aj=a5xPCdhs*VYS5u*|HFyFB$QwNH^%kN&-Rh|Nyx z=PQs?C9o&O(PD9O)V<7NF5EaLXW5eNtVqrY$x1=t4U4PZ5m%Hz2Vr9q&eXpCG3q{} zQF{3_++bpO(99`CIk!8(4~n&<;0|PQ@5xSvl>C*Wxp$G$(%Vyv zslusQW<aoBR7%AJ zYO3uXu#ZzesY=XDX~Uw$d1(^_EWy`a`PUdQlyJ=M!DcTTe|9*_!@1v&V_n@Vmf&#iaM8&~jhvbkVHNS@9#|`iKZ2k9p#g>d8hp%23c;c3S0=n)c8=B03Ja!88fDc#v)z5|JSP2=gub z4J(Orw1=xpwTl(Wh7&cKl9lv(sFfc{?FqBJ7*90GD+w(~Xt`+E6a!0upFKwj?_ECzSe2OIJ z2LxQA<`AVlxfek(SleB%1-L~^vdB6n3pGI1)nK5Qc{lO&TVSgp|H|vCapPg#%KH-B+b*(7r9I}xKzDrnXK^NwR zG7Xog^JRQg)bG5r#87*tmJ|zR)Pq{*aQPYiqa70q&klmR_FPDi96WKBu%R<@c{sYq zYK3g^?STbTF_H+9Gvr_JREWN$uRcjofK3TMuAsWnxW4#5vH;%X{{Hc#*yODJuq<{wEEA*Qa!cRe;-%cO zggwP(MVz`?UBFI5M%ra%yc8*q{osT)=3(1b#-+-cpmo$1dEES(`g)7Xg4sN6ob2b) zhc2X>LEIqjWW+CeexTE11qT>wi)te;+iv{lY=-*eR*yj__=%* z2|AHFu)`b!^Vg`RZeTW8ir1@Yvnra)FuPV^C#NnDRbxjBCxtU9kq;y=~-y!Ltlg(1T!*{3-1}30sAf+>UX;w|5 zED^FZ-7^omSuyEN9NVTHri==VC&Z?QJRGld3$|Ye4dQ}W5rPCg#`54U@HN;&tXx^3 zRBLqG3Q}t}F1NySzxjAh3pH4b_`F89xV! zsX;s`=ip{%Wap$DU1#{#0Uu?Ft4=;h9teK6gN;SqEcO~^Bs(+o)<(nX&OAY@UU2Tx zmgWQIEGHkNrfr{!vJm^IeqArzQ+Bw~#mwW~43Dl~EZc<2+f}1gYW%#ny4J!*??l3E zh{kGdxlm?%wb17raSt2rKN}sfj|qlQZ))ih5((UcxoH~WmX90@%Jo7v)q(%*6I)t{ z%gr3z2PE@M%9Prbn6Au@?VZej!T|#KH`jgL`WB?;TvbE*?R%tN$(~^SiPyTo-pyo^ z*romX2hELmX_$<<@6W%WZvp(O>X}xB!DK+xksVk;Km0^;V2cWrESkI@H=g_*cMdL3 z>u9-C7K6L(*n94gUW*yXRY#AM&~-V>&w}Z&s(esK$C=RXKsMR0Q#B%GK3)$U8(I@U zb%3b2zOv^&^y(b^dbCPH&TKZ1dAN5^6QdT%siY4(gKsF00IZV!gFIvZo5aP8&}#R0GjON}LrX$yDZChExqMW2{jz8{vPPq`W&yBN#chD_~Wl z5iDv*VsAlB@e~s-??e<+i>qc-Hhnci2`0rJlh;zz|J&g5+Cgkt%6g!j10prw_^cQ= z2q=w6#Y^=Ki3Y_|*;p52-2IDxOeiLZd{(tzA68)Ga#$R^qg2w7Ckza|(YBWX6FHd< z9@crL>9+xpOK7 z=}gkU(^c@{7)zRZ4j?9WQEO^U+oXlwDx9s4OjynydP4CwpU;mQZlqMpiFiC43JyG` z@x-?LE8$1csI(=s-J99&EK;LL)5lG!@PWC9H6J9GX;Yt~H7$p4&J|M>;i6o+9I=gu zF*1afdcKM6BT}V<#0Z2U6+~yNILia{jY+>^Q0c=AquZ-H01^OeQx^p_eJ=S*3rRp~kD)fi)0jgfE8stG1}+a(*c%k(A`{ zx{Y=tn<9JE+Ek^)xzf{>lZ5{n{!-+oHs#=(P#+;j*dE&6Ne}Tv$^hFLe#Hzk(3c}R zVUGWpFf}{D;nE?YA@!~08kbGp|5D{u_y-eIyU9+F3aPly&Lz7Ukx1u;i{=4~+09bM-YiD<&IdEWqlt6`4MEq2(>Dg-YAjKCnRv>grYasFiOLvGb6Z(qq< z6g=9!bEMz*EmxfxVeMjJa5FRoB`f8_ZRl(F4CA83V=Lnv%DoSPyz0;Qm&cH8XyZoH8trLdIE#PHWh4 zX2bf|-z<9;09(kM78?gudtJ*K*6BGBhmwq?;W{Y~ zHiF$Bsul$=Wd(sOW%xz9>4%V?4EhagMj$Z){$4yLa`}1Fi5_yUPY7UjFO>YTuOux5 z;I0AQtUe$xYBt@7xHI__Tw}& z=pqa?ZZ(XuOB~(GSliU>u9$BjaWvxT#(nB~Tl%~ctUwlj(@1c*`)HY#wOzHHtC_Q; z@MvL$#dhZo?Hy)2S$pFC7v%@TCXajPkeyQbIP5*}c`ScCC|NqSsWzXy6dZu`2{3vv zYpYDM3*tX1v43vsStr>QmTl{?$Uep?``dYUu>wAIKBJp5uQ~Q7cl+7I$ulo2ceM9? z%^u5EMGvKhIT?r7PZUowA|{<5KrNhX?AHAFco}@|xmpr~g7Uk-M{RNpaFf{$9Dbop z6(juZ{)Q@7edt2aR)2XN^2(U(&%BqT6hRVQQvd3_xi$=L8^U;~KdRm4FBaiznV!nv zsq9eqklh2+f)z)3N&;Q}Pu2HX2idncNo}cHzf`+StuQ41=?FwdVWVD=`m<30BNdez zWPrzK*+j$!FqX>~{**o3p-8Le!ku%x6}C`g=7&R;pd-%2f0$e^WO>DvClq6Zw=8=8 zoJ`B&koW!bNHh7el$>qx+;9diW0DeJ@6fSoys*+T$>lp{bI<}!Wz>GP!hxtZC6USF zPoYlvM4k?{kLM>pP}3nP#W<{D(}Yq;c57=kq{i>sG}ueHE{Cjz$m z*|?aimOiNfz+sV5tgLpOynE0OAvbs*Yn5g|49K07XR5(Gd!ta`{BatPf{GNgYKkyr zLG7A|&1LcND)>+uMtfo>)shkmH-4KN&HEn7CY%s&jS=snl_|UF-bNgt48jq%g_Ptv6TX<$SYr8@YOU-ONp-j4 zB#Q6SG2h#SkB!Ts1C98st z;G5bMJr5Tq3ARbFBRFdwMx?-Xbg%fNIttYLg0ipVTEQdAjRRmSEJ9TyzH04 zzHjpggY0`LK^@{PnK4DS3t6L9OWfqZB3O+o^EvCBLgxdn|^IvskQ?u(Ie<^ z01j4{oi^qs3)gka0PL+YRmA*zOm!pwCnO_I~I=7);DMr zsP(S`P-CseKk*j4r%epER38Hm0z+CZPjek_>xb{;aOFX2FWihChv2HXZEWsQ2l}|M zcSvN8l1Ky?wM6f-$b0KpI1mb19Qt$H83g*M ztTpxmAja~lYM%Cid*^Kh7RAI{4uulp%WIOTa4>5BSVV7|gY0ZKXYVhb6$}w~snC)u zj}&(J)4*_-Q6(w1oB*f9V^f;pOf@Yh$p9{XTRSJ;Nj1=uL^k(uYqGGiwA^-9#)vgl zLq--sYp;xB0mJ~r;)Qon6<`#?Yp=cRKs-o2XESH%0va$-Gq+&1*}qXD3C@Y!Zks7< zIw@1)=XL;n8E~38>fN3Xa8N~&l)miVl?vwUJVaT9uaNdd?`yM{EAA;9cj!s$@v$t^ zO_fophqki>a-R1YW6q9&ODbRTarq=J`fh$1UMzd8WR*Pv5m*i>DG2G3!@qX5G6r`K z<}647UkTaFWlb4^TVLw#SjPira|NQl@8Xi$D@|rBgVUP>xSJBxFhO3a+{yOCYNUFweRHarVTL=2eI=M-sIM(UPKYd?dFZU6J1Xw%D9r7O{mwowY2Bh%^MG z8|xG)GI`KDHAFKlb~3fLNFG~e;P;?rcffJ+M}NP}qaiJft)U_5vX;mtK$qVkBYjSd z_|E#npFj_9Bvj_kQ$V4g__LSn`xN5upd_9pU(bXGVilyHcO|J0Iw<+xmD`t~cq7T~ zXoaL1={HQ>0e7_%TS(MYF&SkdfDo(u4vMTl0e8dL)CGjS_(?px?u`@d*L}aj1lmZ# zE2Q%p8(>9a>FxdUlgt2Fn76Uw=i{zCc9agq!D_(l=yIp34tn zOcq7EH(pHcCm;Vsmk-hL8(-K2)v~hu{7w)G0@zaMlU&UdPjAB)1-(|~KR4Rd!FxRamDKM#sKP1X z+;{BCpmnrfe*O`qmBZY@`UY7-)l+76>;pPQ%1(wA_wSn1)Vb~EohAusaKcl(erq*1 z0acV9;MCmf<2+?@wZk5%>jHz)E~L~Vw1F`7ke8u9w>VTC=}w}*;QjFU7gQ;>D^P@J zR5U^DhPlms^O2^8PE6-N$0Qt|ip$HVW#<>;-*W&bx<55YX=4Y(Oj~_kiqBZz$f?ii z&L&k%=7El;8iZj=<#z?$##F}kfQcP_*9tK|1E2NgFF6=7*>bbBb-s4jw=!gU-0XqR zUGw?3cF%v6{r<9i`l)z)0PxZGSPL74B9mXEJcoKxt^Ee6uArD#qpqxjfoXNP+lCj( z2Z{Engi)-CfiuKKTcitiQv>93QX3ZbCqOx+J(Y%#GBU|3@QBL`hF4302B|0l|E-e> zfx8m7>&?lW6!`KC`AtWGaU6mYE%%)-*Rl^I2abWRU{b{y!AFqG*mNPJ)`)j8n7DhoL*L!$^5`YUM@Hm z+0cpbHgfB9$_{^JW>%}LW7L=NmRa-#9GfsvIJ%;lXyB~Q9}!g;u27GrvPp5Oa|Vm^ zA>0XlG_N51(?DgXBYA|kNk`4#3Z61%kQla4SXBKYWP-G*OfNGl zCW<*D2U?$KZ-7`!@d#9926sb`F>bs={ek_FCZfzcV3?Ky8gE$K?lP|IN-J}7U+2R7 zZ2%B@6Irv z6JvqA;`@Z&G`c3J!U}aNTQEuJgXDcqgUc*4)okAWL>lEWiBb}pM#Uvj(M(FLWRd#C z$8Uh|qoS9^lwjJEyZ-!yzCa_i*-5fhhyU~@4+#JqogNzk|C8jYsXVuPNz|RDZhM`6 z>t`@1RSK*wG62St?*m1w#IWuc0gJ6@0N;5`%Z51_MlsRCwbd!oi*}DSkuyhrLBg4B z@m&hrDK0By0A3OX=Mjv;hbwX+5z9Tpcun|v`XZ2%w3?TCVDpwx1~bxs?sQmne>vkz zqc3AS7%LCoIqY0|-H%s3Cv52Qb; z7v@kcu5~E+cWm_`iMoYZLPcG({NjcNZH2jtqLdIG{hVdeY%~inG~}Itl>zc`Cb9U* zQoPySUqzz%a+B=evlTj6E9_VBsErxt|Ao%o&Xm$DwYzC65plQ?c`F{olia>|W8lmh zDn_z8W#|+=M#}{xt#D0CvpGLO4awYw7+X9#nPP7xN?55O*b5Qvx)0dB+yDy&bCzQ37tb^UIR)zbNCo)EW1{OxY!F zD8Vr7N=DInk_{693tmtP1aROK_KZ7^+SqhM3yye7LW?!8ckhp@}(B`E!C2b3mNVj}mx z;5`?S(!cy)>b1f`Kc0Y^clN(6w|ob9IoR%qqNtQfe2q^XK#Hvj&Go&>v8g#V00Ea| z50Vzmz%LqBsiKM&a`joN^uZ9G#D8VNRY*=x#$D?A0DEeuNa?(uGkNp}ahI z1MKu9;6wE40OtMZF%o-HLgKOFLL8kJx4?8BrV$a@M+E-_w3aQc4zC+iKrn;1gU1s_V%LG`C23 z^aZtnPM;w4V#%AF&tAaZY#phNUS* zy^K>vSGy+0&KT*iV7}mK(F*e z=Tg_XfPSw(&U28{IWWbV+H8P zM0CuRn~)?-HI_Rt+mHDG+|wvLl?6!;MBH&P59q{^(V8T;b07w6xdS+Ta<%8r(bM0C z`UgB^g6%WHWy|(|u*uy_=_g>Y`n_8Oz*Qge-PDcxpmILVBI_k+PvfJY;u0&7=VH2+ zJ91%ms0%@(yCJ^eggnz5dG^)Hsfx6J4?#83(kLRSAxn`HgC+^`DV zuyx;L7$?v(KZq3(s6W3c@;ks9Xe%_BiYgbD&w?1bKxy}=+84(Uk-Dc~i_!C6ire!z zumrAs7<;)9YAMQ&?buYj?Vr-6|D4!7*mk_do}8k}lib$-cW&Y{X0owmzpqtF=#eyJ zww%Z6h?!FFihUFlG&asUSWKNe9|fX0Xc2M>=zU1%V?tzR8b``T+NSdz{6C%jpYah) zFpFI)Z?gx!QiqLB>a~DdF&>|ut(f(#s1#TLA?Qc*!$Tf$ec=7ZwqsqstbwYv$SL?O zI5y5G*y1hy&Wt5hS?ErgK>k7UO`n!@^kHBY+fcsWgK`y0TeOtxy!L188frAup!b3f zDo=UMbgMm|%5ZPzNkInLbG`ACc~Yd{L@QTw?CO7X+-eR=qx=1#-PiGgmo(0S4Zs5+ z*+*l>|ERY!1AjbQmnb@2GrW!M*Or})JCcEAU+LjZggskdV-{*7$mug$P^1PV&RR-!uM&A+8k>3wpCq}I0 z05Tg5w`zC7KC(^F+Y;Ze*`d!HZWx5^Ov3#X9$BN_S*e13@!T2|vr78+eoEHzjgKin zH_~9~1f$}v`njOr1g2PC**z;AZ$4ujk_kL8l%=IiI|hkqwG}*qJKF@FZsi%}QlPS$ z{kp%vh*U0_4^GiA$7+G+%>t*uO@4(xW7^>PE2~X>77Kkz1H;Cld|RJ1qIp#}URXTQ zcT!GxXd@DeLJuhtG1v!OG2IY66)UkX2|h}hHlHAnFbbIVdA*<0louJ2M(MDRoMRHX z$%PEk5P-lK{kAh~_Qhni#WJridSU65T4aO{ z0I0^%g~LWL+y4~?p$fjxSU|XnG`v5IS#O-^#}&+gpwm!Wi85Hv4t}?0A!+<`ly8U@ z+=Ls%t-VoHYh8X@08>D$zvGQ8k>%R^876+WzCw^r{CX1Igi|c^yp(3XpFDo?S~eO_ zEtmr@&6M3>!@C$&G;{D<(>NDsv|?453p29L6RN&V^t!{^EHy;3f1z2z`PkUw&lc5h zIP>O3R2$6+cYaQ^zh}j?4e{qCSJK;;InADO8Y!xlGsB9*oG5HEG_JNJ?AJm0a zl>_&GWapuaof|)p2&{UVS?vYNqb3oT?HrpiN^?qdW8ktcMq6~kJKGe~DZ4pM7LPg~ zN*bGeOg&%aGNTqK2P18ecx~R9`6poNtHMT0dV5011VQv-PS+w3ozf*mHDf(;eVzwg z_vW#T|4h0%F^H#S4asQ|z3ws

xoZ!bgy(6!Hote4Y>G1yc5&YL*Zy1k&LLBL=O9@L2R=wWN(DLK- zp%I`JwD+J{y=F{GQ5z9c7~}9DRITwNt*SiFOO6dS>LM8@oYlqpW10mztznBpfAm>0$m9<} z+2@JM?6`12<9>K)QiX%h7SR0PWsvsvECk#_%%Z_wPJ&^13AF6N*iZlo*X*>Lnz82| zUY?bE4S5Q^J1#yi*2YsqkNVJf8bf0<&P`L2KTFtE$ z6u{-QgmV;z2jq6#cH$-y5G<-TiK8P~Y7#Sr1035O_Afqu0p42BvDg}Y(h9E+s z0ICqbjrS!7Ic);R_SD#S)<)YuTNKJi^cr_ZcT`=igS;;lUJ(@eqQB{V98~$PK@WvX zOcnFKayW=~klwcm_-{;mXa)Nw4xqEtbIgpCU}GYk9usDXhM{#ybfnREH4f$)*UR=h zMi{y$)Ad+UkJj#^GtMr4^BvEuvwt?*hpIHrOOpD6YG4!sCwX~$R@UvXY`e0|Xm6_$ zj`VLSZ(~#LO!BU*L<0MQ%Sf|L?g7~+=1;}3)HW#-yMwk=mRzw?&0rPdtq%M=!rg^X zoe~a1NR@9q0RYD;{y5w}_ZsB9NG5 z_u5WgaKwNT(wQ_wV;2`H0=vw|RxR2`EdNxED8TV}DTZsE1@E#n7IH_<99R`ceXObU zjrZCtaG&)qwz$)g8FlTo9eG!k+p~gxL%8Hr+G?Y_)wT<}$1m^Z7a`Gd3d>FOp!wH) z|74NIJOSX3)uu-PFwr+55DYh}hi;-2e`TG)CK}H>9H*a6;4>K73wzjj6e13IYy{NK z+Is00O)^n*s^0|90xhFXbalTIwL~tdm~!YWXsrn2dBu(~cd8UDl@@5nPeyctg(A*z zjr*h{XQv`O^M_cD0>-)1Nz?mvh37H&Wezk!pnf)NYBSf5ScHfBYV%?Fdjl%=|M^`o zImh!Hzq$iGG6#j+3wG?fa@AL5HO1N>rY#;lT~hVg96Yo#pl%57QJE68UM^kn73 zuDHuESi``xb8+wPvq6N%Y;~mF~K}dD!e)Q&vJxu-F513l9mh7hnHZ} zS)89izaab4OkGW_K$_|@Vdya)o?qRShCd zoc{g|>TX|@PbJ>eKW@^_B+Kr^0MSG}(KNlnAcWJ($zCBP17&}HVr4N`hPZ+wXRC>w18+gY>;Hm%*OHigIzI5G_Tox*@ktYAp@;>RLu@P;EB-jW4F&eqA6 zgl@1@7KvYcHe;6Ut{>@*Gj4;ZXpnT1cxzN>Um%SsTmA}?;Ro_=3&zJ&2LDvbvKNy~ zABRy-V!ofzz&2i@bSY?Ml2wW?Lk)IeU&n-+8r*ecuV-}jw=Suj&eieifohE=IFl=x zq%g)~uzGVL?nqBo64yZ|%Z6W?P`7bce+_HxS-9 zzUk(MTkk1De^fe;>Bf&dn(`1s_1%}S$-E=NOD($J!GnLLnzj8})4t zTF(FlWp$W;;|suZzAEtPs)^WC=V|*n0U95b-yNdBO^>G>w;E2noF~`1+WImj^MJw5 zjp+KzonWh#w@z02g1b~6cA>`Y(R8+Ai?cXMjA z%`@CgzkJWIW5!+v7_)6wUI(Vywh^i|0G3@2j*McDtGm9~Vk zRDS1Cu;lwAJ!#7>d3~}rQ@h=0d5pf^pNnBoU95GYw5m+L3IwyS*>yxoF@HY8FnT9R z^;MePy$tX&@khl2BI>M!(Y8X zooX9L&SA>nea)din_R)*KB5@zdL5||1$Jd^CPyepS|n2z0&JD$jeSY7W?NL4|J0>j2zhR| zD99K)FzPc))mgs+w36g@rj(+zXi1uk-=902U|e<}DF-k%as+^c1U(pH_0tu;r^cVw zW(0*zP&0f64y~l~b>Zia^-`ihSt8+wW!x}Kfzd-#CSr~N*^7^CM*0L__T!$uK+wF= zS!AOsb&HBMXKT#BR$6oHVc($bhQ;tDn1u`LVeKwu;F?|@aUrZ#~EqiJ!{*d58M+-WAZ%)i#6N=Y)$Ct75~sfWFH;R ztVnPz%TcQ|dBAFv-$g*^%pWiIN|gHEkCyyl^)VM_br301JR<8a3!GUeQ;}g&HRRN( zM?f2X75YWl91C0quS*|c)B@Yb&vyJhNB;2i!-QwBHSP|%(3U3p2ptl1Q~G~;<8F&q z=QF5W5;-6kjI_&p?}ux@q-A?Xp{@B*VQLt{<=IC@uG1n3_9B zrI<1Tx|zJTCT4fQX4eFWrx zPp5ahT+a}FtVUy_Zd(CfC`ZLD;3+|@fH~*zZQ51!2AVql(v5PBdifR%uAoYU0Q&A= zb^#DvZYou$)41Q>n-YNHNBZ^NtiGh%r$B9N^h@T3&rW?z%SjK<0_e)U^D>}T)`Tng z_2q8!t}~&STJXC(T#$3rsVQPT1n!=(V+$?AN3*Cr9H18A^|FG?sf=c@L~+HX5>!{W zpSCDl_^F5}Shk?6Fz==nlYIVBsDl?*fB`4+Ehr!06Is|)R77NT$hkOxR8nWLVt-Ke z>GkIf3s`!y(FyM^q(3789GnK|gZFW0Q7A5Y(MX<~%T)?jZP&jHfHA4(W~F>3y?;FK z=PnnaP@$&G61dt$h`1&$5z|NnJ0!L204AaVb;trPDuv6A?@2SWx2uU!hXM!*Zs^h}V?QbPbSpbNE{oDTPzqeo;IP@p?v zz+ZZTC!)S5(;o|8kB=)VR<5&b^NVhjno@b8hIJ<4_Lyw3FA=D)Y01~)op)$~Qut7c z`T*V*SBb&%YYNP2%H&4S92G94)+K7=^V`4QA=(rDh)l{Dq)GK9%_2`_E{mz&-FZOd z2_uYH7#Rhnh6wJ-~|3y_X^ zmN~syeD$ZBX&uhOxbP9MExb-yxL%COnr380Ijw;dfA_@uFo)4vKm4beC=B&{N!`*I zR(g|eFeVZEgaJ?SBmN`IQ(YOmY=hqjAh6-XNILhJ76?a z9`!U!8|jpN{5zG0NrXC2TGHwk!q>01-bG#w*jCTIH6kw)`Gt@Ul@3_yCp#)9+-@6?Aj z3M41pC0kL@{`2iJXGHArd}rb5d}KDq3i1QytV=+VA!8Cu&MDZ=!fElcqL=3my4M9X z!qyLD{97Ma<3CZ;f~gokOT#H6n;cUbGfp5|g3u!?Et&j|ITj;Kd3%LKCZ~T|UKQ#( zC5~ck7=#jzB(!HmZ9m1Ty zIIEk+GeY)wShd7gnG`x!)NQ;~{XF;#g7@kb#F+g;1HJslaI#{}@2+4S-obsGal>M{mNsFhDY%OmOFoIc93ss=EjVbqof4*2DOQMa^@w85aodKSM@RSdu<^`OLYg7eM5~v*F<(IWjwoZ6u zG2uEi22x0lrBFc)Kycy$Q-gT$5SU6M%z)g(W`ZU#uF52G#dR3JEJIB*x;!l4N9;`Ko=3^!Wl4vGulfJv?-kN|n-uYly7U8+M5@bfH1YAGH}3v1 z=hTqPBWSwfSB2(XHg%S}ZOM#B{IY9DIWm zJ2x)+UpTLdZ*i=W5tx4PBImOwiVC&Tz;Pj1vg{VJ;}uzA91*pe2Yg#jAM}~rbMM^G z)xvURChJ0BmO~k~&k+;sp$`KTX*te-^W<0Erd{XTgL@U|;fH@Q@i?-`>hgI&L{16O z^6*(;5d(nc#8rV17iGS$l6F`z*)OBFMnb=rD`4yr8V$vk`ADUp(=2nc$DYb8^pW9#hdN zrV8N_iYnZ}=#AfIDdXo$~e`zjOy#(R=#kR{kLMt zVvJ|ptdot8od_x?NSyI-knlCfqDVdBw0w$8cI=Mti`B2m(=&F?QLEEq&0%|gNlwx_ zw{5%i71XZ2;tU+cGKwT&IwPv$Fn+fakAd_5w|Ycm1BNGg)m1$fQdisZGEmS#te-ElJibqVM-dH1Pag=m#4emdcSe3vt*_UB1u~M|imH&Y=nBw+7 z87i%QcK7n#%+bh;fJhJmm3N6Hl7j%+(&Twb=A;01VnEGd4J^iN22 z)n$6sc0yrzFyd0Z3n&&#rl&c2d}#|EJ`jH^!SmzQi1=E)>)at#V&>BzS6Ca6-n=U- zKPCvY$dn@74l8kDAo(EKhysJO^P$-(;-*W{Wj2J|tG+!ORM(ZX>uv*$A)tSoRum%8 z;#39}>Ykc^_{_YWzrN{SZ~9#BWJVF2Lvg9;PC(N3w^8Tu!hS=w_R4EM8b8vTbZ&0$ zc*U%WAd3&bjH=6HO{HAtJM zPa(Tl)g>Hy`1edz7kRFW2$>*%Fq8DLzM?I~eE2~ZVK17vjjZIXUQ#ZwvR>xdc^GBxxa1!w6C z?gUF+-YHX!*#3T{g`&2Uy6s?gM$oJU`E!|2t}tfv(#v!=nz6#)kq5$$Ssfe7bZ~=k z>fL(3FSX2HOv5)HVE2nhg+6GbgrlU>Q?3ZBJRJ&x^&QBv=g-|$6E9yFUjh~XTkFfp zI1ZDYh+m4$0nX@wv&Ckf4j%Zz&~_jsD~^kBCea+KJV|(ww#FNla`K$(_mXo~5u8bV z>#2s#JTGliSmV68Waisk^4}Kaw&i4|2sp=*s4p;seAWwe71XYrDr1XJG^i+6>yG_@ zg6rh6&qpgB)k=?2kA>|^W^&5~p1zWy(E5=XjaA)rJlPHAP7^j=O3*S!mF;_PWv#E< zki-z%9>CU-Y4L8@86FD3F*5TDp6-+3nV`qNJaK^kIL8_ISGM)Q4f~M#B^)+L2jmpq zNMly{q5}X>Y>0YQ=EtOao0SWeVp?KTRS{*3{%!0-_$SjPX6?^-Psh-|tLH_eVU7s$ zf5aRCXkI0{B{lWwY_3> zrF{1>G4EvkCyIuQF0)?u7CP+-2CDp;j! z;!jf*2~zM&P(3rQYpE6p;=8R+Fvd_Hn-bhb+6x+R1X{^#rlIeJA}yxXtjY!{WVbkk za55{jw;ne8DkQU*KfQ@~mPgoTF-jrr!0O#k4Xa3SQbHCj6#qbPxHz#F6=;u_lP(bh zdpEonhxRWVB9TA7(MiYR{s+2K$o4c`s+3Szx{u$U;E^rvOyf89xak=@aexE6i*(US zy2x)OEVA7_8hdFknGJKQj$!LD$xmtqsB(>^&gcl{knPBt6?A~&fvS}bp~2?bkz}B$7D3=60h=@Uj z{}|Zb1QBhfu)cj%lOe=f6srk#3{fb8|L%@AdPVn?BX5;|4@Rg6j+DJbO<_)qoj`}F zXnavLDq_Wql2`2M>f;A!R(=Y-Qv6s@HbUFMGMnQ}adq@?%SH%@XUcZ<{DIeLX&5;ger<@ul$O<2y;_E)Iy5r--ohW9^qUPe;^pL)9F4fs2vWJwA6eP|B1y2I8qQ5D8B?rV zo*%Shx8T?-SyZ(6ip{Rxj4JXq-O@#oH0uQXAVoLK_kS9_yerOxqt9vxi91{A7JL`lfg zHC*;X&|_=JM|iCb?+WNKz|tBxyzJi$Pm$jq9oS#>S(1(Rn7 z60M+Qcp<9vUed`MXX8|-IGNneeyhD2MoHHV+xdphMmW%ylO#dV)1xP+@S8@$s3p6@ z7|{Xq%>HnVr?I@odnr3384s+hD)OKrov22vN}}G3#mji#0V3`Yc1+m=j!j8b=#Sfb zi(#Chi&_=0CqBZV(`2@8sUt znKkQI(?9e`gqTU%J7yz9tI~Yx($N*a1Bg8`b&CVK5%yc|w9*o{-MK+RgFws$YtRen3sJsgj@Ud_VuL5I5r^^&N&~En(e4 zHiZGi;54YqB>1f_iSSY_b;`-+?1Ch@|X*X9wjcA0%>p+m&5Y^^FBo11o%PBPf>i6WE*}|<(3gH!al4bKfDai;x&fA)l!S~d}j&SvD&d|%#bQOS+y{8yPf$cKut-{3A5okqad@*zXf=4*^ze$FgSS7~zPXb)Hx6coXZuhvZzbLAg zcCeNV!$(a|jz=JyI!zKd!Q{@^!%#?6zojHzhtRMgrakyQM<14T|1eFH5p2~&^BR?| z(T&|H8CTi zMnP))_GXBv#Vyc5@0pkwSk)!7gA8FZ;>IB_nA6;h0Rh2$NOTbX3nNiKE{hSv5=3zN zx1WN1SuZ)-0s1+gbIr&^eb~A#?e2{UrOm3Dk6GBfJ}#-JKr6r{-CG+v&}HR+%_BRlI8L+^AHd7nxa!Qo*L-vZYv(d4 zxH^W-F=a5Jn`zx>tRt&2+%d>wW@xF@8lgvH_Vjlf$vgV0LHTA{>boHz-yOVFf&k(j z8#JWDBM;s*{JoG@ffiVq!1WH;0`ki8lZarbrEch+XYC#Pz~bBxU83+~55q_hAN#0O z7aV}LSo#g6+W`c|Yg6x=^8|NDHI6+%#1R9lUXw!Wef-4Rhrm7$B}Nb-(HUCW4N*+m zfEufX81etZxfHLm;Hh%07Ar%aRJH)KF4BM#mQxhA6JFsYmcR$*Te>qFH4F!MY@#XH zb7+@kbfySJ$T(4kh*Jan3a%Ig-Q_#Cs)C|_%n^p|)Mh+84ZAr!KYnnXw zwEU@XEW~0#=sSAWkMG33E}d|U&+hVx)r!hIroi83b$|r^7^Yj3HIP)+Fy{7d3yh}) z;eZVAaOaN1g;jZd#^zQ=kc`2hIPf`ell)+!)E!QdaBGH9Xc6qdb54~h*Q&}AV7#r0 zv^)U1I$c0*N30mxl?uEyBjoV75xObg#GA&r)La;W+H4mUpmwToIFAreXw|vkkv+qj z8K1R0|0gK2MI#eigG3=$(2Fp9-!cqy9)S1KpXSn@aB5Zx#9Us0VUy&;`~r;Rp{?f! zc=2rsACXlxowrTo=Bw})V%u7i2YdG-H8i6UlS%cD5!=h$K`?$RsV(JC>Kg3xzZDa} z&Tf0D-NQ7qf!8i`nJXwi_{A8Ql;NcE0yCrm?Cp{%mVX%o4ADsAlHAaadhqOsKNJGgTlU;xGtWfipX@Nk&v+6&Q9N` z=GjL+n)nH6ed^!RwmF_)C2@B(I=A-+(fU+Pb+@NM z1!jUU&foV1$fceMKqd6S>;@FQO|BzU|C^wTlbI2qZn+n|M+DZ^s33QK-?qDkU>?TY*$W`oj-9x}#bl ziUJvA<>x?bLag^)iiJ;(%45Y=^Tt~Zndlzs|A5TP=y;3;T*cJFz6+XEQ`Ky~?`G`ss|=cyEMWIuW~@hM$!h3XYatOo4@8QA?6ISpyq}#4`~F}^P@tZ; zICDrTfHnALLLo0XH{D6ZMEjzM%_^f{L)qq`&mQhbQcLtJdTtx51Vbg*ak=NA(aM-b z^ytns59=<{Qg_tTrz`wJ1<_6Yz%4eD>OKMAE`#gvUn6q0Vy?}oA6F`QE5%5T%QQ*K zCWS1Sv6}0m@{%V`I9Br$M{|v^XvwlPK@rzb;8-)QGw{_0O6@XWlz|fsD)cvagqbVQ zr>~s)cAzpE8gKw7#DM``AWd#IU950!=*b^~d(EiiamZ=%K21Rlg2nI9c^7RCih&(v zhrIcgGI0@+5zYDnn_}=%J&P8r7A*`dZ}Irt&^Yok?LDuqXC4MrdJbWaQhnDzw^X|a zhGOId4KKV@j!z5v3o5|r^!+^s-!<5Co>jp!kMcNQYsS0a*efYG+WuVFnvC^b+h7`q zHmO_Iiq5o+l0B@J%j*t$`T;EiGkinE z&N)>1E4KCtXWFyX{ERIRR9Wqv&rdvHr}_8F`_ezBKy~4f-mYD4LQSIQ!C`JjZl0v911pngoCr_yiyc#9;-^QV$m)87>n z6emb6n(|MQtEVAfgoKB6xjUK`j(bjR`}8eyR2oUNaGv3B#9B0<&?DIkmHO(dpz!(< z>3#igr5UmOF?D^4R9ld81!N?iX%gnSdFzpc0W|Od0Dm2(D1`wp%abVJ@IHBi{!uUh z&LB$w>)*0^&$8K+38$=2M~)TonLrQ)BU70f1@o*aBeCQ%sovpC0x2l#y(xsO-@QAo z{Ut0=8v1iI{$E=$I*A5dy^8$*!2T1)O(*Gl4|w`w(gY2N8+m&Sf&`7LABJcXv}H1_ za8m$8gte5o0RhW1)7!FDh;%z38F~m$4!v*r7ZQ;&dz_&BlP7nC--=a2FhIyk#;37tA5tsp?flz*}_t zpeRjAwRH#yAj%c1F5}QzAPv8_ASUddd&Q%EFL7ge9Ix))`#D>eA>TWIiHGyQksWk2 zH>ZKwC%b&Yc!k{Kh|U{jc$HiBfRHNv6S?)80d> z2P@V(eO~MNAg{b{gj$I^kScgfZe8PCKmCdH4e}cFem8O?c;~^CO`K`N*@09bW8KqX zKPSI7Qg2Sv^Omz`>GCAdx4j|@!Z9cYyP1C-2Gahis}0%~E!#CED2Tq^G=d|3;9fpI z1Qm^*K^T3us-OZM<=Z;wAAd+UZiJ`(AO_q*YC&su}`4K47cK6BnD@ltT8#=wXpPRws-h<>nfaZR;?NfQ~elW;)AIV1rJ0l z)}|OeENS-|G!-%ROe<^wY|50P-l)Vrj!N=*jgJkn3+ijIeUZ82LlZzkCUqH7z}ZC3 zZvIZx-O)uno4kvAND4~xRbnj%y3u@8q9Wefz#5}pMc}Jv*TCH^aHt1#14ca&_U>j+1#Fg`M4TMl`)C;6TmnWteHytNNwg|b zB0I-3ZYoV7@+mw_0MHAbbnb<6_g)z5eJ913J^4{6_SBhri%z4WT~=HKKsUjk5I~Ui z@lkZqrba>p>K)Bf0g<8w*2 znSua5! zL8Qpd2w8YGpJDU4-q1xKB&kv>%q!~?^xz2ppLR@OCg*29);MZY>M5pgbD~V*AHfM^ z_3dk4h}%dQx;!_S7th+Xxb_(1xWqRXk&C^lnD*bTd*B^i>#Xt4byPw;^J5Q;CbbJ^ zJ@;CJw?_`n56J^o!!5L@(@8jR6(f14?qxCRSVA)gohq16Z55UIYcwQ3y27Gp!(}Z? zg6Z!z7feM&;>wFXwx<@6Ba8piM6@EYyVp%BTy|vRBYYZadsmM@{JO&Du|6?+LUAc- z<&O_U{d3K~g6UV^=RL!Vh#SI$Q^SpgycwUlZManOv-}j%CpOI7e6Nudypc+(NbDjw zTbsed?hc47JjIj{nwF`MibOYgN&&u&+$WB74Mk|QS|gCLi5jL&Mj9Q#qcnYuhwQS9 zhn4`)`$1$azDjI`-fmarqyc_!3McPcZ$l^SQ9Ec=c1}%2HFb;G2d71n%Sm0xtD?p9 z_XDXUxMz8P3|RlKy3&8frso~p)Km#lIC@K^yH7p7ow_fbHF?5nrIhNtZ|=MNSgx>-2RlAIJf9^g_cf*qD_QAcLqPt$DiUTE3X0^i0RfQtzFKqbO1*x!KwV&R;mdJqvg(-$j@#vpKc;T{?>!3Tk46OJAk~vDA3Ky$dQd%r1jFr*ZiclfYyF%9Ge`w z1Rh7Om(eqdTR&(9|ImW&!DH330#$Ez?c-GT#_jn;IBMkwuprNw(p6qOmJ0CT#H#mWD-6gYfqsKD?U)NL5dwaa$J~_E?pIpa)c0eb7etF$XeqS1uTu=1c zk<1(sv-D43wcy;KC(v|Li|ty|8Kx_aT946@wF76nX>H zGKBwWP@19F;ry6Hn`!RjK~my&-vRHMayghKMCHkdo#2)@6BW)(QHLdbUv<@Jf2yA`kK0B^J=x8JEkQbTYiPAvtrt`ppBrQAWWf7v5nkiwXX&q* zG^ru>4inrP0PKtl=QSix+->W=p!KqV5?3Qer+*eE4;D$YHnhLp1cj_2UzkF@`=%AP zmbYJHl0*GC@R^gKk)+psqU8$aB*GoQKS}kC#~o^(^0)z%kqCZ`O&3+{vQ=HJNy@uU z046?nLLK2KecehC#!o&cFhkeZEI95n7y{QqJh*vZPUuB4XjNa%&|HV@ByD+ei^2@U zCS$5d1GxJ*@7586;L4{y`$uM7NXZ^+-p-eWlAVp8UMZhCC2N&bFr-h%5m{}Eqj4^R z;q>rGdR0t`+2F>OQIB=6Vu{bHCC1iht9!LH+2o;_eP2}6K#N$6YYbQ13J-?(n;+?^ z)FR&M)$3TOpC$*TpXBNd>Vz~;37ANQiWRD|t_R-6%VBB_;4Hsq%lV9n{}FREK$XHt zYXLg-Si@vP2V_Ag4HCrO>}o3&=s&)I0^o~$h5QFKR$p6Mfqhn-u1HHk(X|F|JHaQW5FaEuepGqlQBmMc{K*ws$GHZ? zO1`Uu(|>{pm(>qByqZA@Z~?r??5Uf&8Wqb7g=+K@THh((6n=W0-GXngv5bET>A<6w zOIB(u=3EK|PiA)=6^+qN^q8m9W75_H}tzaAgImO2W-omtt_I7>*2?meItDr1Vc8R@X;( z=Qn{RP>u@3kD^fh8oH~SaCV*MHE}(xh*>E*W5|9Z&>^MN_3umfQYIoG{XfmULfImR zuntF7;dZiVGK$QOHI>d03zMEyuYF+~g;aNR55*3T3fi8Sb^E%I) zY_8f9x*kK&YZ(x#3-1jt^P``wTQ)l z;{q{(%Owt*>17E?x4xG%D(v#xVOJa}dFfGLe+~WKcj8uyM(8SN8QWsSEh?F%bmOl^ zk)s&f7w!0v3N*AC}a-y*UE#{r;j8LnP+OdV17k;^dk>IfBL=v}6@x^{aRO?;j z>d6ffIi(!1_4U`jhg*Xx)U(zd>FaQ{%^*h~0{Kxby8AUkz}^`NxFs2VUMO(8tZev> zq+wh+Szhf{$Z+Ii_Q0j`NHxd5(B8f+*D$30Uck4k5# z1Im2;3m*}+=2lk~V#wm@5ZNk;7Yhl`k5Rvge{hKytqI}An^tCqZd`J80XOq7eCjCi z<@GbpU{fktukc7$nCsp_wqa1s`ZYf`hqvEby8lFo{yu))KIk^9VVR_1P#Wx~V61ye zZF%Ae;Y&a|Pgp{z&$Tu(ZsukPQw8Nl`(W%yN`?*qlJx3hq26s{@~pxCzpKQ}*b?EE zl*5$-^9M}Nh&9KLch^xEYzd*?y0QYPsiwWr>@yk0BcbIyv}v|`K)=$HLNNhLu3XDu zr>R=PZTYHz66fa(+iBojMtJ5Kf4I+OWir*CmYS`FW=y3*ZbVXvR}R=#%CHCe8;-+& zF$8d%#`tjbU5pC3x_B~I#cn0lC^#mPrDx=X3oWD8CGEb65yhMN%zj%$j2edQ_t}bI z=^$W)@c{WycN`X6y169*7g&XvmYp=>?u_&8tJtcDrcog}*wlEdrbtU9aNl=fa{0v> z9Tl=SUOtXENBoA+(1cVx&S;DL4VDCUCN9vCPt=RfP2enX@YFqKC?tviUPG$@-tijV zOStL-;YVGhHo@Eqq1?b1?rF@Q@{z{7?=gTQM9-=R!!jVTD6ubL03tjeJ4D*xI(DW5 zdgXV|iU0N@-;=S2$-RX46J{rJUEformLJK>AZoy+vIC~dyTolE`6^Mu_< z04qS$zfgF%R8?C!WmTq5huc!XDC*1ZC&pB+s5%X)1?;*j((V#_9D>dF*%CTvgW@rV zG(d*XfO&UNd%6;Fx&KG>;ChI+XAjh~YBfygyBUak#zy^D?Y$p}Tg&Gz2^y}r=!CaF zLBQ7gGa_f+qnMk7ohuP$R=OorMlTJk2mHD>jw#5SQI9h4UStnejIa!r?HvvFFkqVR z1HPCmmgnQv&oxJkqa#NxQ)}b3BMrwRk&kCZio*w34UIr(+7lTR+q)ndaR9vafY}2B zE3HN?PkHw+`MJxZA?h~S4^gly?sFl<>z$Rj$E3|}bBze05`2kZ{NvIIlMIO~>{g{; zP^BI^X)kH{x!8X+T{g@)Z`+sou``%BUBvgnABN9&)?IM0p>K+P_b9t91l*=Co!ziK z>(yt;SYbUBQF*0v^xzI0IS=hOOC?{}7-SD8yc8ArG}<+r#?*1* zZ^AeTBM7hN2#Dqq3GYv=*^HQs#V~u}+Fw9Hy)G@6I}zT}$YbhMh&EtpJytZ9$ws=6 zOw6I%s-yQ>==Ts#YaD*4EZzpcqZSnJJ`3I(JFNwA+HY&4_w$pknm5~ONm@ZdSU^id z?`wRx7boD`#s-28i;ooVu#$mg78lY>S*G(T8Xp5W7 z(dCy+z~<_f>qkB2ErCR4U2^XDq0P+!9|5+a$LtlRqc)b}Pl15a+Zs$InfSO577ef} z8^mIrkFu^D8&YvW?*su9?wR#H_sz^RPRq_ZUA||D3yd0a=cfy&ZFkryGs4p(qqSg* z;}WeB&UE}-HXFSxsLsDCZfp%Kg5ZC{0sbWl{{9oQ|K?%Wc1HPIy<&Gx_RP)$TjS)P zDpqAX5)LZEABrg)xF4cP+s=PwSb_{gorpNEN#|C)vB*0OcaOXv^K~u=Z^6+N0=3JH z*A2E1szE+iEITbQPh-%jmt(%FwP@9{z_>g|h}|<;ARR?4$6|hlE-uQ~609In{YG7+ z&c`Skj%B)m1TZCNa`hj&u2Fa4YfVY`#ouE_tKU=)hB0La%TB!8V)?O(_UYT=6EOqj zD+R(@DU&;DtrZLhY203QgGNhM1qboxM*49OH+;0IdN;@hVdnIPx~7@JD=no2Nps@_ zzF;@97)@ZjMn8p(xd}ugfY6|l&kuUe!3@+3SD}N9*%qF=;EGj|qLNu}6D!n4w`3ka zMO}ivwm?mzbmuS^Teoq3>$(v1>Z+a_()r*AV{^00(qjsAMNg&nRiQGGoKc*G4rUU+ zEq>`fwjfxyCiR)pX;3*X{>pKKCRJy@^=7u7E92(khrPF1<2%E#o5O6K*7GqT?p$K9 zd&dkKN^~_?*{EDBgK7C4x+~KHf1Ig-eQmY5`U`3EzF*k`m#~t=MoquVdJyYP}P7Ec*%5U(mdOY6?cgQX&ycpmrNi=3_R-Aym zCzxTOP$6`Y?Qwg+4(KW}$+qW@Y>j4??VKFOt}xj6jlu1ospk}35xuvz}*f5?5lA_s%!L5vurE7dQ!m_ z+=!XU{=YFaen7Rpl1_>C3D{?K0>@n<(Nmj6f1{8ppKn>KH;g*`h2 z7tg#fd)2H1olvO6gmOF$Wx?NE>YlQ2#WGnjH6}lVR3y7~Q{>a}4L?`5iLo!;tm3Py zBgC5)d*WrUlkn^vm=7ZCO5RBOho65p6NX-9sTM&)pKINOF5im<9q)*PmJUQpOP;*3 z!4`@=RoZKB@#^7H3YZ#&7h`qZSSOkDkV>jVRsCw>Zn&~Luf$JhNY|ibB`;iy2e-5F-Q-<-NeCNdKl5Q0YkY+) zoLjj2>l9;3kh_Pl*V2M_(Kj4aZ4g=}O&9WCb{xaI**x z(&43`EXtd}yGOMztPdHRgmcf-ggi3zrqh$Z?sIoZl{6aHP^&+W?$h4HZZni^U5dbs z>XPIa7(d>O+4J5t`L37T#g{)uhWi>UPhIs|oD2SS+B7$tedJ8De%o>F%;!JZ``g;2 z1hFQQjb4`ZBF!=Z-R>Ea{+yv5Pn;zxNfPwg&_qFuXa=2~JI%7WRnRz!xB=_*q<8Wx zjc2ku_DuExGU`57t`QMyV#Mmp>5#NAaiA_|Db@#oKq(O`9;vMtQaJO%6mW5MH54Zi zI|Y&@vg5uPP%zR!6VenOUP`zNGkiDa(C1tp|vMVT#;ocC{wWHF+K zJ>xU#+3KC`=Kvblnpi@FmV+eLe$lA83f#*%l{Ho=$XxgZNJ9zO^h!)@x zRF9v_Qkb3s__Xfb`|pEAHEug0^iQ!-kmrSp^MHBTSz6F~Z2oRpz0>?zVj?WeG#Mbp zu2B~AA4gk&Jay~HmF4olC+;PwT6|9hER86vEvV1dtOmH2ldaaOQA`Nd#wV{KY_c|g zWC1*7w308|t8L~xmP=89q=)suLqn@kf=MX8$n}^8+@lH{w$Pfl;W!oFDp2|kskvCz zFcHGSQ725}B-H5EQAbv<7DwI28hlGoQlK6Z7+89J-usV#kjE`svTH$X8kLZ?!amq` zxUaHp8^@$i;tm8e|BT&rxmGUpwqFW<2^llo7v|>130jTNSJni5@q($erkc|pO?apc z&4M-%HSE;`G074i`CTp`*kYii0oIbm9Bg{jD;#eUDf#?{G)|q5wr6nu=up9MS?Jxz zyq57&^dgb9J=ULtTyPsrA3A@lOGHGs;S%Jk2vOY<%oXX;7M>TcWQ zS-Gn_#xSR&ArKPhyP^+dyd4qU4En`DO`cAeFf@YMZQgUh9KWLE_VNOC|1RZESm{#n zf;jc-&rq-;JUV@D>@;e`5g7elGf9VY&ipq;sTXs|Mgk8{96uZ&C~qv^vN_*vu8n8E zczF+#uH7G4`}Yio89s~!RQM1*_}1x=ZVZZ@u_arBpPA8$Y^fZPaVSCyz7#srTC)6< zPzN52=QE~Bcn#alTYa?m+crKEdC$tV8ek+mf|%^+glA!Jursna#`3KdXTfo(s1g1| z2ZN)KLUL3aMGr>khinh(Rp>5ijVv~6qK%(K0?IQ9J`xPbP>Gpl>i56R)pJ_8<1PL@?G% z+o~b`zBXdiT^>JGQh~m2n;Eu4E!MVr41`Vz*gyHMzPPWZ$k zjzGv4q07IgPo}Cs3<#fBm1i93(fL{)85q)`pBn6^!>Woqaut3>mn)O()kW5SjgwEF z|9*&@?ie{PZl8)t{)<)C9ih2z$$!tN=qt0(N7FtrfR;m{PD8?hIXOKRJgLpppSvtn zh-vV2mniODiIk;gl`IYdB6wqtSzpl3W{~7W{Z*nmxg84b(XVbtOw4?G)R;wSZ!$XH zd7#w;;wXoN+nb<3KK(F)$Z921JeSbRKmA|xJaeB7w;M-o0WeX5*k?W80~V6ZFuC*7 zwMh%e-BHmL2KTq;?%skL?^}Fl9?+ky+{!FP{GOJ;i{oK!lv{1#i5ZBD^~l? zdjB}Y$l{OHI{*+f^mu*xjcx-cS;J`pETZ@|xh!Yu9X@Zo+XgG3W>&9L$HcPp*Nfaz zE}!qL7YwunP*knUL}fkXM(E%B*HN!1*FN)c^to3CkQNBAFrOj$mH>uHvDj)>^42}# zuwF@cqwTOICF&#KpBS*VEVt5R#Zvr%F@HT@bf^dZcoYq{c{E(18TdH;(N9j*LHXO2B0KDQf>Bj z+a+Pl7`fTiVabIOUaD<9)ZMSkT}orQpwEhn#!;M2)&kZiI^!jXxw+Ng*9EX!7hCa0 zadYabhWtyz0#Fe{M_Gj(+qT>nf=_#bs@vwC{tmc+tVn|D-|?o{Gim3Jn_e;GiOPKd z_xW4kga$3PP;D#;o5tXQ5A@F0pcQ?rMB%r@F9!YesCs*E$Ni_BQCtrxpT)2NzO)Bo z>^0orjoyb|nGqnhz05(hw7x0gNT_4RW9r}6M1`E_Y#W+h(LU!qaA)5rmm?@h?@?qO zg4hP7Wc2e>wMO@WZzkRV#bxQSBZhRTOsTE4BLuHcN0 zQFO7MtC!9j^wq|7G^2mm>ot0O3mz6iWDd+4{u%q~rSA~-UqXL*6CsF(Gr6#ESn;Ua zOg2XttbM9UmJ~x2+}R{S3tqg!TcQRQUK%4MB8lagR(7}K_5YDXOL_UOThl{?1R3wwrFCV_Y@p&=6jHn zcBXP|zp;0;Hmipst$_h{DA$zoZW@z?O69kjEp?&YykcC%zWvsNv4^p(m417rxY9I1 zRL?}P1atBl&duVt66K88~?nw5WIr_cv z92hv|0sinG9o}8tN^}v$HZin96CRqI17R`*+We`JUUqzxE$~9@$3xu|3DqxXFLC(j zJ3;okQbq07B(6^a%D{VfB=VDAvzb>Nn&1?vaXFrwgN41R4-hh}tVpq8LU$5oiXSBU zsV~l73N$y05c3m3KalsSy0QdvQkzlROS{X6PpjcXw7CoL-tl$-K&DxlQtpm+8`~J{ zrvbeeJvZxA-3&Zxv4v-Ylf20Ofdp3i2EW8(B~tv>-nq1#rldq`@Y6hxm`QB(w+h(9 z4eQw*!}UmfxaLMtD0>d#S*b>Pn=Z87C-j)hTWvT=UCt(#MvOZ)@yqoqPVDJx*BFef z8q;FR^le+cCAv{;Q$IZ-T1FgbwHvv6S<-U2rAjHO;DP*ydPKbHx|nuz+}!Zth{60c zd(Gbd2|_#{Q9G@itIIUWkgZH7g6peXz0D+^5TV(4-BpwTl z1dg#r?9hYfJZ?2ofXOG@3ec{A>f02{?=d(@ac+UB|NCVul8kx%p)>czmMR<>B+d6H ze?DI5GzN_6Lh`J}Kt5qK@a1ItsRuvk^h^p-O?g9YB4)Em6wjo?^4+E^eHg9bS^6 z+MkMMD#DqIBb=AR2<$o|aL$_1u$B|}YIv^{Oxl(PY!CK0unU zy2dmy^%;5OaMwV%$Yk386QLQ&n?wJdXw)IMzED?w=O;Bth!{Y+#8Nu2&7M9={9HKz zE8W%f{K;Xw3y7ADs_YDZ{c#YD6kBB5bIKy(;2EJrSj|*-jn_%6ZDI^s=2Q>;L1&u^B^C(>iL3S& zxC}odxUON^Z~p7232%blZ#Ahp!s}%`PZG?4;>V%KVt3f=v3YO$cnc9DgmAkDgmSfG zV{^)=gIt^w7{2wSIsyvZ8?EIRm%6Ih5Vg|DojXsuLvvaHBQq8cqRQ;29@i(T-pQ zHV8-DJPl(Cy4DvR$mCn#pBUL_3~Q3@GleWS1;vLH+?SulduvKj7XSZbKq4hFBW}*^ zD0;szc(~#Q3t66v3Q=N5zA30(c;)bn@^@8GOnIk4A{r|#q+D&M--qxUw7SSgG96)~ zG|wsrC6+|3M_PX4tk=SdLEh5F^X_%`*+;`;rUtc-8G*~>iy>S-K7{BAzSZC`O+x8B zPRSPZOX3KLdQE^?Fl6GHk^srPvM#<5FJND5PL!Y)2|7`T_RJ$sstIM%5TFW5uM%`_ z=&L9&6~Cu)B2m{*E-Nm*@!*#koG1}hdfx|^QgDaK1ez-(2fK&LbyR$~D%n$r{P|T) zK_j~T=WZd{6Sa99mE+}s-E#Pywdr(5BvVqTG?J_;nv$cr>9GUzjkh~|9e!K48R9el zrSOFaL`&N>RQFy49-Om(Ce}wkggqyz5-m?s6dR&2qH}E8--qhP9^xGqz(i}-!K4U) z=|!?V;Rd1w*x)Oin(^vy$75f8Up~u`2Rt5S)8IB(n$;f*_O;u#oQAtrfs%mM?w?Ul z(Z&|Si3+71gXhXVxj5xPo&fUf-s}q7M;TJbi{S9w+F9J9ZAFV9Z`XlmnBf~H_Y+w7 zgqI(34eEBPpoB0=IXvfrtj);sQ|S4`iMURN8bn%c9q#bSG3w8|nogutlvl@n-~#1Z z^)?y@H?>W3(o4F6w^24CBswWthB6tFIcY*h2q|kKn=|#W5urgrDg+;wX$m5n7q(T< z6kuROWC7cz#X~`L*};nf$6kzUpj|a2A#)wq0Wh>^Q#b(#&0IvnW)-kb zc1eF_#^~EXX`#i6(kLPTK!c4EG^g=I6QfcpX1opA2>s!oR0LA!x))0ihNTn;w7h?5 zHwjw6qNHV55jyPbWSTj8wHY8rPWp=v>$mejiZH$d)XvF_25Y=>V6~D|Y{b7kTUkfi zmFLN-oD2mjW-m#{EX4h4p(t7slM2=?MV^Guq|J2XmE*l2cqB{zvuo#oa5Q+sbt+oQ z@Rjr-fXwRJ^pEj_vV9sb8fv%ndd)*z{Mp#!6mAenjZT8DKL+^f%vtbly^^pn`#XxrqRWN4C8h_c6?J#YA$Tz2~m2entXeNO&@ zP-+AEruNuUy~FeWyD*mQ-U6faXZ9pACWY`r{@Ln8>;@VoA*y(Z9*x~fk+)>AY_w02 z3MUx5D&r`YiCTip>LUoa3q-EeFPx(-pfg|gvHu`d{-auVcD|+vPT(Ko7G7pAEp7k5 zVf+~oeZhs0PT!VGU6;Jf7L6bZfKm?v!rzH04t0It&uwdyLrzV#=-nDtIo@hOEr`6Y zu3zf1Lz?bhy$cgcLddM~<(n^v)_UP@yUDp1t}uRBed%xWd}fSR^S`ZN#c30YD`VrYERpzEi6qOrV+uGv|^UE7YV z1gpbo(zs<_xr(s7+9J0_)S155{t=Sh8bBrGYZ!0P&c9)UxHN~YB0%)gO|{OadCI2{JN`SoL^D++vxvCi^7(l_&*t4# zq%G$CnqmdPD7xTeBXt4by#CL$dOSR@lVhBC`>NyMs+>JXt@!VQP$hTv=`N%NQd5el z`x}gKwRARH62zd$jH~TKAf@4*ZO(T;SxRdDce;FB&)jG!2BW4!X)SgPpnxr~S@&gs z#6&>cIf59=&$a9T#^M8t`OHf#t!e|sOniKeb5GZSV3HH29=08D%r3=JV0=Y!*NqSG zZX(7`)HlW^m}R&}q6Ve3aEoDhFUId-PrQpzG#r25<>6cl#hX;QV-c3ZT|9uZXQ0kD zNx|`jk`HrA9l*YJi!)OHpa{jpXY#BnjrU*g-q#q?sZ-9;JINsAc7y$GZwzCQ$HE)9 zW0t+6L3M)$osTM^4iP*-Vo=IO2;Y_FX-zNB0BtOIjlB$=GVqj;hGm``8yLoe*Vuw0 zPhgQJ-KS+;K2%;w=Q9+&CR;BhGvL{V3>yTkn{k_;_+5t{=FcgTki3PFCcx;< zkZedKZeBid02nGG3mm;5uM=8B41Zty{nY5J_h@>B(l4R(xKfa*F*Pf!E(}E*Qnph$ zkR$(?#A<0b)9^&IeRfTqTL9sqn(E&HA_Q3U?CJ_QYG+ZkEWme~;AAO%g^nrcyK*PK zkPc%=sV?ot*o$SHUDO!)8o-?qzOq4;ym1rxPsskc{?E04g`M_T-8T!xUp!IO-XkWR zi7l+*g}G08LIc|O2$Htnm7*+X2@(4@klv+dajS5+06*pX;t zx1h0L*%VAo#J75sa&bfdSZrNY_&B&zXEspWpmceogo|a`D79{w7`Q#?r`(SknS> z3e>^}x^sVI6YjZcMmTm(3;;g^?*FLB{#t1L{^g-*A8R9|Wb4UvM^e0G|8DcKTbQVx z>g@C{T(iO<6($`i(4rGxsKi;(*gC?zEm@8+J2ggi6l0X5%#26{ zUPE!KC5v+2z&!zOg5lqE*JrqAbouAYRVcC(BYYIs_By@wU5foJav<#5G-``$-IIB~ z1=zaBO1MAQ=!hk!I~Y=7x$ovE>X=d366##dpX7QI~7eA};x$7CD-K zGzykPb#>HUy~lSXL%;+IuySPqz4jdp7v7tcPD@Ft}Mnf$ffa^h3<9^xJpGORqT5$23#AmfCF^u@0K?0aUWlem=K1$>Zhlr`$e+HU_IW_u&NKD`a6P^GF% zw$VS2BnW2FR@+=WEKa2<6vvWFVvdV41HyNN_{-3eIK!c@Q{k%IYPMgUHsSfs2{65S z3juM>PA4$oTyIGl{=I5j$l#DXY>wM0TJH)h8jugxRkQG_ex-ctLxNML!<=$D-@I># z{~Fj8oT_bm;+YNmD^|zgA{PE|2y4R`JugLZ==KPph!zX8a$Ni)@+>u4-hHs|= ze`ARqg$7lrdxYM;!pnnMQA4kvDtAFOx$QE&^_fsMAG~3~oE|Zx?4&MI%V@+ZnsaqM z1RFEMHgZ1!4GO|O?ti?aD6pdQ>Bi$dRBL)TvA1iC2$crLY#0V7wahdpOld|wYni#8 z3(5UbF{Fce0Hx703k`u5gY%kKms@}KqFMrPQ}+>q%Ebq)9w6DOtP3ftcuA^4!2=ely~P z47yHqQ@fNS*8(|_4M-DTJAXIpp{iZ6)mlK6Pi$St+p@1Ph>krhpqsfG5Nu@)Xf_*O zK(gTU=H{9tKa}0|?I-5En(jyIgN5%lucVw&TDb#%v|_pZ(&gD8(*yo6BwMDB$#*!9 zhNQ5+yKK51Ky23T0ZVH5Ggv<2W=Yv#Py^>PlvBi4bOn%T;!socOGtDn0_N**86g4% zDK7^mfC#1^^A~ImHicL9Gym7*;#NhlKzvr?v4LZT1D-qg=pClC_r zqP27bNfrM36DP}^RdLv-^SM)@7RE+}#Yw#F^PtatGQP>`u4EsmS%Tlq7MEgVJg9*( zGiXbjLmd9+foTN&N1TJh#D~0{ifB5Fl09 zB({smR;ME41ChZPscVjGR?PjTNHf|78TP@8v^}ZG(Q(?}Gx^cn1)L^Y!DgLOoGpRj zM|mV|J{*w}V!Ol0m}hm|B<&Iv*L6)*VLZ#@)mYff+zdL4~1`B&8EF$k!LlfcknhU#8~;# z)p^-pFhs6Y*ex-B3)j2Xd&7zaVyRS{Kw}^y1U7o^IN%N~etIFt%st)|9c7WWz30Zm z6aHuKjf%02N_4QiqX{XCP;PLe$>i#-v|J%+>4Z1W_~t*eFwqK0){r~Xe`5`RqZ;_o zb#vDLvAyF%IV;BEeaS(nk5)r=DNm_DRIA}E~oK#b)S}@jg9s&M)PZZ=63(6fjHlCs&3h( z=I51Oo>jx%(;&RGOk$YGYKqI3&{n#g) zG-DgIs6*1*QOV*rH093Hv%1Vwr~>-pkD~1C3f8h z^~DuCovfe*@DMk#A(3F)neoDEQidfqUvl(m{)SI6?9!w8Tu&KxzYEa!e^Np&8D>N4 z&KhoX=s_0*0;7>W9v)9`NB^VMa)-DqO~5R==0^^SUCZ9@WKU=V_l_l7hCY%g;zF9? z67*PfOd50y}6$v6qV!ko=z zTUE25G}g?Q1xbn3_5yfbKV{PyZ_#`cpeq#gLb$c|RPG$@(T}EJqEl%nJ57!07?x|r zvF@Y)ed)Tboak$@bJefBWCB&Y;)%^%csl(I;BN)>pbw=z8JE>_M&&JWh1-Jk^A)b6 z2JYc(p$%{3<8-;Vxe&4-vQrxI+yde_W2Nk5IyaQ-$b&nNGACnAAJ-yheISJz8>ofy z`h95gMl2j#^*~UOy6l3VfqtEZ74+SdZsF+v^krOtS@k|=5h=SE7wk!Z?{tj19!zJ< zJi_8eG9?l3F;kqLo)H>?1KB_2dB@M>3EAJ+1a%tm1^Ms;Ge-O(c#u%H zB!Q3e6J5a@;qMSfAEhY5jvRlXBq!3AB6wEPEw>6I&I4m`cQ}~vro-44YmqIf<4d5I?|sr0aQvKGhE!6xHgXL}6zE^Q_j3ew zC6dr8obZ)}V_x-;A4pqxMSCmeRznL>eEjG?p}U~zBMhBjO9mn`Z8C;i;h*dm=5uyD z0LJ>Ynj|fv(6LwpjvA3WCLkC)BFy!gh1a4`DytrJU{RX7*l}>|Or#A;%EQFLd@Ue+ z(J0lKb`yZ(;cPNjR#GvR+!ksWP-^uVauC_HOC*Us$SB%)!74|yAIdUEhxK9)t!od4 zOfo6*@%izOs-dB=18cq&A8u5L>u)ian@)OlJ2AR%de2HPy5OnkE?9Tq!Mo(QmOpug zxZITo@<}l1G(?hEOokbY_4(&n;MtXL@|I+d=uDBn&8McQex+=9yB-g83!5e0RSl2Y zS~9rl6i=-R(v!E>yx%p(5QNNBO~wu;1Es4y{;GoG?5W`RqYNLq*;#y{n>gEH?w z?BG@P3iCz{Vz=XE{<5g3dC__1tAM>Cs$NYIbIOcO{$$wMTov=ld0Z-|zG_ALxR5uj zJ!tp}AzX4YGw)MM?m>7nB!kvI-dHu?`(M%V&jN^RQhLgSTT3^cCQL3Pd1{uXy>@gx z_{a+jd@drt285-r-mdwv3*4L!aF}kb^!qiV)jw6Z066J z^ldCet8md@s$2K(7Z@9-lz82A=r}}lN1F5F^01(Vh6@UE9BdjC>=x9QBQl6u6*I%> z%aGGlTrmA0dBs#xr=SD;!Cx*c{Ta3P;eudM-I^o02!RYuf%JrdoFsz#7d7Q~1bZk? z3iw`uCp6=riJ?@zDVwN{oOCwJM*%WwAkO~xSAKkh0SBy1w+b?7;bj*wmy%nmw{vltSG*gq7(+#Mh};mCl?l`&t%1{GiDj9h6HlYvwxuTev8 zq6LqKRz`DZ|3<2E_WLZ%AD~~hxrs+L^{*RNIHDPF3S!dyNd-m_j^jp1kv>q0!T9zz z;YjX5Rv~Re<8qdSB&4w4E{DiACA*96tdKZeB#xewlxiXNH7KO>B?tV4oN47cUep|+ z{zN(!K`+XLeEBX<_E|c-ltx%l#+r!vGu_x@iSjQj(LfK|8CR7$Y=F~SIt>)GiZ6%M{AUZ=5>>!tD>3ruTU zyNQbLt7DP0{t=b<*UUr-)Wz|q|0Hi;Mp%41P(VcU-dwzMoZ=f7WTl=OkZlo$!k8{Y ztH(R`H*}NwieX>L46ZFMR=Sx`ykgCAFLP(UXljPogawe%c!Uy5PxGj2tzAUE$Dhb3 zOlMOL4<7tXro2%9twBc;0LHs8Cc64zJ!&GicI^2KB?MZgDJAgPRBvR4VBk=ox zU!j=@LLZcrTV~a+i(umFiPp~xV<+O!Blo;UDdk~g?L}z*XsN-gqVp{5!fl}$I5O|H zofWQ-S=*)G9gCSxXd5Kp1;eIk!8-J4_R1t`Rq4j3zZQrE2Sa(H_TftN*)$M1mB`WL z-O=OBER64`pYK1~DP;Xd2x^^*Q!`}^dnL?Wl;}*F8m9WHpNF#2TVO>~H$}TfD}&Oq z@;M4uBaKTnMMHZd*RF$>D~>WzuZ=86+8gn`CsB*T-Z9zp1ikzE?=D(!-$8x9#dl+6 zG7DR0Q4${EK`s1!qPN7@FQe$GTHn-+oo+gcHU}ZLIu!NQ5HKr5;w%vLXI2m!C*&su z|0&>L3KsrD_c6m&y@24fG-Nd(&+JR@4$=IXxI3f*oRuGxE*$^fxU0&g!`zx+E0|VqY=SKr*W|@E2m{}+%Eb;B;UWZM7?#19=0kj zVwiJQMB$-*Ia5BNx>ERU=oS)xn=}${gnU&X^9s*c)a*Lc^>xWmh-=b z=rX-1L@f2!)ghEbdFgNFbteio%&@A(&0VYbO_R<>_TyjOPOvldhk$bil|?U?4#S5q z{Y_1IeHfS}5lxHNxvF}-y5VMyBr0XiKNU&w=oD6P1NW@hx<7)7{^$euh6p!Zrf1p6 z1*+QOiStq^m^9WqPetflgj!s}Z&G6b@ij$}Sz>X$Xs_zBVa4Ez<~Kea z3;JMQ0~ueL?;aRY@yE)MVZQ@0(~32190_Pk9-ryX`w2iVebM-eQbN8bMH6IfaWl3k*Bc^WjNi2aF(s>pc9cNAKC& zAGXQouoN5LBnMGbW{D&W+a0zl(R25ydJD{VwUXZyEY^-zXhQC^?iSFe>ZSEt7(IH8 zAup6fFVIbhyPeEVmm^N0xb*8tRS$skMo^OD?!b zFY1H$u1TY!$CxQDc$U2E4^=mBL=!qV(9v(mpF+Y8L2P7Nu9VY2}MGNkgdQi=oF; zIKMj%u~k_JJkJnRNx&498Q;D;W&4Y}DCk&cJ%O_lGuEG^JZv9w=LU3k>h!b+fjs-+ zeQwijCN@z!`#OYET?hywYAFiYNQxKm=f;JfgBr_i8M(wY7Qg58gOr0p539>ri76P2 zB;C8l2M64|hk)Nacu~{?DT4oB6jG@g4_XZ#THK#eK5fa6U*g>NxFnm3c}FA)dkn#( z_j%X34_}wVy+nn7ZVH%P1Y)DV#34IHXUHv?m5lI|uO?;trVAhSqt7B>w6i5bF?{ARtM)Z;uZ~RKejJHpIA(K?1o>vsbZ!>9r#g*rSThkUJikl`BoIeo3=g1N_9!APTiVd4Q+eyD}_uNZz0$#&$(-2&aCBn0e+{*1DNy|MGEs3Z#j5 zoFX*EdZ#O`-id5GOn)n9M0V&t3t0~C-!oS#0o!U$|Lsqt>Uxc`)eJ5I?Qt_v-> zTmX3&pjVs&^OB#2)9PqKcTC^0*|^E#Q&2X+)e3Shx8qZuL^@}nM{1nBU(*-+PUYxE z9k0sc8M9VtHiD_t?h*tZi#@AZ@e#-e%PC2Mo+%gLC25hLXmb(4hRcX0!9~$LWP~ix zx|S$EUf>DT5OhR-q6BPSK2rjKFI>(zr$p#ha(W}IVt?1C?4{OknEx&`fZCEVN{k2G zGOQeHF!f~j-qjkNWfDq7j%A{U{5ar1tDA?dhij#B5mV1Xx|$H{jils;^lu%%YoqMg9*#FZzHgL-D5SyWuwmpeiu(U7xg zeoEpthf`fu`Ms({I3ap^@C^-q6W8cZv9r^S)% z8diIih2e9HN!pCD&k80bIm2FBB8voJ0;g(nk&Rqe>ymqRY-2`(u>CK^W7+_U_#(1p zl9x#MqCm+>M2g^?e5jWpdeTJ8R8xr8#W!)fqdZsZ5d|c}o0Qb3Awq-l2wA^DXW#74 zDimqlIezsO?eV#HWg|)he(Ctk0y`_->X^4-)A(96MyENU59QLt1qq+!YeOrK3f!_w zlS6fVh-Ng?c>I>)@Na)B-(c_hq=Z(TCO$4)&{*qw61kyyTFNaJ3o$-TsSla)_7jY# zJ|ywUrBqZ_;{v77zHKZtio7&Njz_aEv@RBt1eaC16A20jBt^jsSX|mX3^%Oh49}Ixf0X`b*wV8AJ{#fC$dNc(Z31xnC*sH3B_05qwi1BVw_~ZlB8IMF zOrtaR6c|57-cbFmql4?$ZB<1R>y~R3H$Ol7&2h+^vZb_S@fCKV8p(4S7Z0Dogd^f% z6cPwkU)9MJ(+bC_E%*7a(bL=5txYXAsIVc)`QGHhc`f<&5qsipINS&%i0SDY=pp^Y z?*go_&P*#AmM~wSg{i+D;611uuFq`2?TAZEwL)^iSZm#Inu{)~lq$OW*d{}kd0_20 z6z0sV(|#;_qqYz1ciQZ^@s~K5fTiHEM2}SV&)A0~+}*z5mZyk4CQ@;#ma@ilkSE5t z@c{;&X&|b4st!VTw?05Y_1rG{CZC-uoryDawTO&f8!SzpNJAr|2Og?FOhPa7dH?agjhPrh1|~z1^{l(22qH zWVN_n7uSZ}QLtOE!PECA_5md`@wi{COxM+lCAiS3iSplj>D4!@pi!hUc zghIKCx8Hv0Uw07XE;JPTbD7mxw?g!QNvFuHjxTH`w+Ss7AC@ zhh$)^Np@#9$fWdR#`x{4eChgh-JIB8{)uKPz^O46NT4ds?ZYOjT07AubdzNpT(dsc za^HX8@`7?1(4$}yU{hp60>lcAOFN!++si~e0dj9=gvt7P!z1du>HGmh^KO#-F+frOtzms8h)I-R0Or_Dhku%{85xE+tp-skhtBIWUE1 zBc=2t4IoB^a=Yc_1*5ledYx+JEosYz_e1lJ;ohxh3de94{d?-`1V@#bNiKn^PFv zJxl%N)YWGPvzDF*sOwSx>k@wT0?M+gH5l>%Iu!QyU?!_*bU%5KvCVUdB(d=%QT39N z44n!6nnsU%3jVO4SeqrT@G*u3`umfw z7s=b{x|bdt3(j+g-5W@0SY28QC9j`49p?wDTr@F>d9aW54n$?}d}F68g<9%=py3*P z?x5uEou(q*L@j{+;{3sOimb`}xXKg+_gE3Wp~2hT(W6epez+;42b@$hyT_?NgnV2^?6(N{*AOk~0jkDB5}UVK+NK(uw* zQi*Ij-hYC<{t8NcDsQPeNzF&Vn9_4sP}~X=SUCo|Et=5$=_H;jsta~P)g@M02gBUYDyNP#uoAu*dXmKL<+dUX2YR-PZv+uS;WNe!Fq$snS*vXaD_j?O*@48dX%+)mb~AB;Iut<@3#rLu1>r5p6nF%1q&uB z07XE$zh;<$8#ulUhE-*e;O$Y29z?fOK4aI{(%=yraT+9=orkdDw>&*Yg0GdD7VzcN z7J9ZCG|?^sO>#)k|EaC1g&R^Ds1e*XwSC`rdRgrSz>c_52j58I!ah+&$YR?~5 z$uBrlb|(sQE<4LW@LUF0LS^eP#<^Vl2qomaN9B&zhVOV{RuuXRZsqyHmD@!ZZE;81 zK=2R&$F-4Ho_QJ+$Q~I?(C3B$s4Lah>8gL&s)bfL5G3a%aYtT(`{T=K8)aEB1X$NW zb1PDfo+z=vrC44v0@lR@CpK(a=5+xg(FZX^$E9UuI^%w@mA?({<^)BE5%Xq*zgm(~ zE?-%%BUR%4SnZB+8Mr}8r`irzYONX~XnTnLhnl}&N^{R}K6T#^Q#5YYSzBFGcL`xz zsH4lAEWG$k{}}IDSo}+m1AfQ~=GIrlf|dD*(R2cU5LXBA0Eei88c2vsRn9ks+ zJE*?#M#!@_JJpz=d#b)d&D*VQATDM53Wo#(z#Se5(Z2(@m(9_`y9 zF7Oryb38~H)K(4i0sOU^syzaI2Xh7lp+=>NOnjAs>*q*5sA$Z0Pr>hTmfvcwF(QO< zgVqeHic*#=hIc-=B0D>%r18IW#D4B_5huE;38f*kpHsLq16(=Di7WZLbKwW5%~X3I zP4_!Nsm4|Q1<;7ko$O8Yk6KJfYJ8DIQju7-m_Z}3x^@9iMD!B%V8?rW8A|5`{9t=b zIlc}YTWi0ls*=(2fNC6J^1aDPY(LNZ=nk#Js)WEb$xzQe|;my4)pQ+l> z54#^xzCfNdmaJB~Lb1S>%>kKWGle9B0yP3y>q)ZheMcWU16 zhpU*TD;I0(Becrb%V1_Ike@bq3dt*j>EY+4%DX{9ms^2FQSRdn>0(D`C(%W&Cl$&! zp&q=b6xK)v^NV=7wAR>frrYRArjaHaV{-m}!D2Dx!Io}X24zrfJ82mG=%m(BIZ?;! z@E1=Lq1#rUtD=3%VM&s@c>3?(8cHH_l&^<*0MwFqGy_s?+JTskd-y5c>TRitMPb8p z%JDCM29n@7F3Q6OT*+%SX3q^^nY~t-uG!yhHy}?0Z6AB`%>>Ra!!}U^80|>>;Z%gc z%eDd>!XM#Z3HWS*Ef}R2t28?jow{JKM8stqO1aGzk+o9?YwMMY&!VQpFpqt%iqKa5 z>cg)S7`-=Tq`lizsdlXtF~8R`8}~)5P;M+-2JZ3YKS`YD#etF>14NEuUY? z!FZp*Qpy=3QL9uOY%5ZerRMLCogyMV9B^t)iYh@=^n)7XF;%iTKm-SOa0-18ClJtR z^9$tGr~`P`%-HXx$ccMVlrTN`524c9Mt<=$E^w0IB7s85$5YtJ7J)?=p#yBqGS|{1)=U>1UCAlV}H}a1t%DQ&Na|?b>_LenUgEknO!|$qltB%d`pZiA{l{-XjDe zzKOq=EAUJ5Tja_OKnTLFMg-^Slf$`UIm}yKeR5bwU_;YP9R0-sDy|;!y+OwB=7a|W zN=r HAev9QIg<%`Wyr;9BSn7=i#fi-#)z>ok4{};+7$K zn_l-8UtpXBk|6HXG%~p5_=Ed~i*w24@P_D2pki~#m1>4WViI>rpoH!E%%98S+ynUr zQ*>n^bbF^T`X(yy@4eHR8e5K>wg;MhS(mQ2m>z2t>4Vl3U&NXiZSAM!jVq;-MI|l? zYT{ESQ#QmOb6YHo#2X4{FJ_&es9~~bZpng-Ch7c-fRsyD_GF?JF8?R6w4AY%Rz)w9 zZL5xg$TE;bwicbIq@c(kafScW%95U~TpI}`dgPsnQ~o$}KN!APmY%$w7M^5!+bHzK zYsWF;G+GF=J!`|MgFJGk4Q}H&S#sxR!~A&lP$4p`(u-9gldTgZdUp+L>k$VtuW#yU*!IoJ>IPe*_SphW73FLa&$pB zAY=c&M;bmz_#Y2OPgli)`6t21*-|YkFEcW~3i))WYzI7*)*>=pX~Xe2(pmq!gn1m) z%{rBmE})vCy-#CtB;d}RNtl{{Dz1&9r(YrIVSNX{=UI<=&&N#zbJl1lyVUm`!bfe1 zVZG*@_?>OKDx6pD)gacqJjmwDCPI{z|NDT)h9o9{oP zHwt0?1KgkUsMlm!P5pYPMw@aq7K`AtqBw`-eW&_-QT}iz41H-bfZFbINHkgKGkB=` zsmU)Rq}cvSY>hkS&$29@+Q9~(G7lNfBT%_Yx1wEXJ2gUKnqJ>1Us=gcZ-LGl=$&3@ z4N+gW*b+70@7YGAHe@YSD_De&WJk`8DEg`h2b~YoXhshj)!(!aL=T5&rMMxh6lA79 z(lJR(Rs)vRT9;e|A$LO^OGLOje6Y`8*51H}Lmc-{#7xqDjJ+-%^LXYbIbe~l)|FWj z&beH7YIrn!_~ORnf+^RWB75Y~aF(RP3tMzQ5Tg*`II>{dfRv>Uro3lMi5cDl1o)j= z8l!jSNbbFdq6wCmqDl3npn&_ar7?KEsDkW~X!a^v!CjcjKHw2~K(3$RvpoM_O0%9^ zUOhL9;o9UCE(LI2@#zl-Ign(+bN0JSheIBSDmx(U4oL)Tla#)Uhj1~-djN16h)+{D zsDo-K2x{d@4_X4l6r}#qS;YFd+}18eV}36X`<)Ah-8>2)nohMq1; z9@lsIxG%c$7d>dj+&KBP96Fa^PNbAjTxTdo%bMCeV77W}30*6Vtgt?_90JX7$4MNu z`=CR$Wq#-RhNU?snd38kprVRGS#yiIX;Y zTP0Cl#LABjHRXG|`dk|#qkb{=rhR1nd{SB|qd>mUEw%JqFor&&>JK?`o7M2=$Ix-n z<21rJ3u_$1M!F>zR-_m`dbRxp(7l&h<;of zAX?aL7XgV~yESz0i}N$DSfxlvaK5K)+3+l%41`kiP<=JU@B~J>Hom{pbhLGUKAbuo zuxl7W6JbpZ6G*UPdi=;e4cVM>$_k|Wc+5GS{nfQBVek7X<3hH6w!gM}av+#tM}X44 zun$M?sMTX~{l*)w9wqSpKsOk&ZKLI@lGm(0P5OY&)lapx=@SPppEF5 zd?_!ZVTT(fk zx4{|pIG-)fR(Pz4!`2PB({3Gb{ATp!-cg{GU@vt2MI(^2(zo?9oLjuwCG?;5$fPQM zt_b5%5%^`vWZL!#waNABw6dBOuf8X{hY*yabrvKOSEdRP_-HJ zOf;z$DYAT!`H~qocdmt7xZVGRvbN8G)SXz5_NUholgU~u>)DcBWPyC6*4Ckao`G|9 zQt_2>l&$;y*j(0QU;D>=+s&6Yc90c}mekEZp?8$WN858?;bGJLr{97GlvR*7r>df@R5DM~$`aYRO_WaQ~)ztF7 zQbIq`?mUI6w3zxt`hqJSyK?IIL1-C5Ld(<*8uX?##DoW{fs*d|iU;2Km=v!hWg%2a zU}yR!VL%}MT%7(Ln{0uq>%%pAf(Ngfiwi7>5+>U6>4yz+;MzEipXL5HV?vR*bGSE0 zetcxT^`tswzRP1l3ZA|}s6y0sh!EuS>{>F0rWS`EkOW~L$_Dr2XUTM<3Qd!}c51o| za62{(*p#)$Xs`(y7x&-BnqWHXoDRz@0l^+>Q|OQZ}h82_tOg!}`Rci)XPDUI7u? zz=bb&Rsffl9hvr`1Arcu>1Cbkd}!7uQZq5GZ?~USg%fxpS!+h&y$aqdcf8YV#PJmDkRl-8lr#Lru z9FwG`WP0c3OJ!lx`cW)uh_n(LjhkhH9n@SO^0cXmC?2vwephfnueyRV(5|DAm%QC5 zv!w&gAt|VPqA};*`Cm-@+fprU5J5DQEP2d*rYmCD*hoX!WgdcCp3GwG<0xu|0IEy6 z2m|a*cMF<~Z{wM8$Kni3I-hvZiGSew_Ykn8#5qO;xc&-8i^8`~99QQ+45i_HEX5l4 z*r#P*CG$|=N;eZmzi$47gdXvq*pYQKV??S^@qei|O7}dDQXb^SmaKcj{CGp^I41?= z68b)k-feG*TF{a=qSj4V7m_U~yHaa}38M)VFjsyMEsQRhTjrpw&?@mnp6Xmn zBJmyz5nhEV=AcL(tSAmSb!IBC76N#CD?*WU3yEIAn7I8Pq3U|YVr&~MHD`~k zW?++cxPALBpq=Ieaq0m#jL5a48r~lZCA3S;cqjo2f@6g5R2%Dcy$f`+Pu*;_>c|d& zOWFgUBBsz9!x6c zrI=4vhyQVM)zTOc|8juYm2+pC)ybf#!wQ^M9%EnK+ysviVDB^Gp(GsjkLnQan1(${ zhrU)SRZYt}yGX`K_)Nf@la(6#%7(2%Q+KCiV$Tl^mm+G9E=5y}GTr)RQ`z0(74;J4$+2p8x|DGt6TD@DGgVEH z&GCy7!OVC{Jv$ypVr>1ULnfB?x{rB@=1H6KowF?0yS%tL)djxFVyDVC*(socATut^ zht*8iNYRqsPsvGG8v^$Q_0CZVP;jbZp!Jvrg~7&5k{S&vvu40_YoQ)1k=x~CVtELq zCldQLY19AysUSoNgEvxd=_7ReojL;52DHD3vg=ieg6cY|oC~%mqrK?@4)!vlZ(3}T zwDr}%j7Q<}4vWV;5IWc#vpp_Spv>}xtWHRmfJ;?!l?slLvprBj6&dy%7gDjd{bNO6 zr=QaceoAssdJ@hY6)5Cw0uy^=i-m$w9G&yB5*;AmkABp>$&v&CzkR0*$T&7Nq1k*| z=ObSW%5JZq;AUN_Avrd*GdnuXJ3h(p{yGJZwy)2jSHLsendUU78!K%HciHzX05Jqi zD(%ofZZJQh1DqQfrr%n!)AB-TnYUfj6`uk2c>>jIz7o3`YQ`(++$``jwJav(=lfvA zLE+{nb*I$WPh^~jSaTE|%%C1C@>^UsMVe$BLV0({XB9(m$6x(usmQCY>lQ$6ku@i>`yDJPGclkgjo1Dy%N?eWi14M11i4omqZODHyWZs_;p(AEPn?6 z#HqV`Ce6juPMLg+fS2#V0aNu6)|6M6O3uABaJ}yA=royYg2v#SG0t$|6-+ zZDhg6KABkc~$drBa0Q|Q1y_`4U z>^tmP>?!a{;5^J((J2Mmu3njq+34Vdkcg_(*HELKHF1_QhzBTh@$;~dm>mc*$+%J>*?bt`u*A7*#@O&`+v_f!I8tLXW6j9Vsww3Al+jqhM?C0{c2YzPKgMN0b4S7;=Mf!iTReH3*A-KCufQBpf1$9Vx5tx@E*fq144Z`2TJ4#8uL@e4*)2y; zp8N*v_6AJ=^?N^Jyi!!Pi0-WV3K$O+kpR1n2i`=clH*U@bvOy=5x0*Fp+sFGVKx_< zQEtWzClBU>TvYzuVvqsC!r`rAtREL^;4a|BoSqp^!Zgp19g5RP>4-70vp6PT8TCJX zd3r(+X+cKOqg+)>`A{Hg1b^K<(&YCnhrw?)TX=bDVzlbu6KilJKT5{-?04~%OWpu1 zx4mvUdJLqsilIu51&5Rt*%p1}Tj444aDs=D^SexiJcwlBWY)YIfkD(`F$3HuK-!V{ zU3JjA-8r6wYw~)sBMSl6%hiOTNG^Dkqdie3n9COs->Kx6Y$VniE7Ey`dmj>zStY*% z<%zNh5(om%duOut!O3C?T|m7*^<*_(#q+{!)LI-|D)BGivH(3oWReI(D+=)RL%d<| zPV%Vxste^fvy-ytvnjC)3JZCgcszRKxfl=ILvhq!b&k3uSOO`#+{a^|Z)WSEWwQ0L z*M5!BHmVpS5lsSHAVbvZB;Zpsqy;u_q}I)Q>IDbXdt7{oQEV51Wk!j@Iqn>Yq z=ejZR+}+O9vJ;{sn4fR-!#g$J=FBIz{Taw&ftaZBjOas9suxVqMCAKYQnwj~q9s7- zw@!c^-iFxWHBaYtIibjXg=V~si%VKf+ZhQLnaq^wpL|}!FJk}PcnB=({mHMojfsd9 zxGc12{zc6lINKv*cH)+mB!JYNE0+(i(t(rnU1nP+V7|Sb&ZpBsPDl!v<8d*8`Efnk zWnO&GaC0jP9H18vv_%gO%Xv;?ZdK?XNXhJIMK_z0hy5rCGcx$Y4DY%Uo$2@jKsp&XDQ&4(z~>r4WTtsjlcCgLuKDk&Gr`?pGC_ z!pa$VBoF~hs^j&6Yu>HlmeWc0c^mg_h0iOS4;1wvMU4sz$vq*#wbWtU!tDtR8M>Kh z+X_g;*WRzo^M-8V#hqDRL}Qa*X~KEGq4i`)NRl4*f6#dQ;x*x+yV0(kxnZZ``vA*3 z)3Tk!`4HVD?cf_QTvDN}9@Hq~&S+TknYO^DF)Nmh*LzI8JjcOsEWF|IG@2bbUpwpI z0y>Nl7%6d(a7m&0%{8y}EvWbGTUy)Wbx%_qL`KfOk|%wx6zq=1$PQCOB_}Hd zC)=oL8aBEBuH~LER_J{76bXTGkMZ3xBfLGFI3C4wcXTHL(>hulJBoGXGmfwpSTkNO zmCh2{zzICJjEwea(Toy#o$;;OJp6hSB|-h!Kq0qQNxiF57rOX-5(BbQPYT!r>l%dN z3Gf+>m@iX!W?+*ird*#_dkxd!W)Y(k9=9eCFy+tkn=wnzApup{YL6L5MRptvETQ0h!*TCra?#Kv6j0wsDj=jYk9>p&hb{&m z$NvI$pxwSxXG5^B+_zP2jzgR3?RhbZilq|8Jt(FDg{6>P%?1k8nQBc&`Uv0V30b&8 zJ`L=uZ|S2DCQf?e|7WwuC2bkT#1cMXSZ8Ts0c&7!JJHIk2-}j@xNx>-!}`}56D$XK z$#49XE&^YO=2C}`xExmKL|TTIwL*Uc%|TH)6gUO$_Mp}3UvF}vA3*QWIfI@&#clme ziSowE-Jk^@`1+)r+S}zNm>js`!ZOUt_Ws-fSc0h$d}0Z^I<97#9w2&TP`g4tz@xA7 z*gvPn(7xnDEA{dn6d_!+t?5SDJ?q1)DomWbXr$M*8c6*ilIHGWjnt8T)?M*6HYL^lq6ovSS6ANA83?`^9ZZ)HEz&`h}1 zm92^yqE`eY*nl(4w%I;CAvdX`RgAC73Me}w)}X#P`l1T;n*I=J1%PA?tcOEDcbuWU zTUPpd`@UE4I%(|1?hU=Xqsue3sXXtjnn8NV!POFbG-q;nYu2+n-Z&VJ)VCApe8+N* z_U(YnR8Bdd*kg&a+3=+V%OoL@!fpu9~@#B8S>via%uFZ z#BGEYT*@$UOG4c>U8aK+OYboFigp+*cu)bj7U=18QJHekV<_^=PO3Mz*Cmfo7urMd zM+@yw}l}a z4+0Ib`DoPk?m-;E?1yWwnq$1s`x61N~Q* z5X?aKONUWgHv~3wcJ)HC*BR6;FhOJG+g;< zF`QYomq#34x|ITWS&2(tZUhU*YjG*6oJ zVki^(VR%8cVtWtT^5--$$DR^4PoxkMx?>0Ski&3>@1(pd?x?bg-Ixu)lN>g8d0@|o z5I6*PS;6yKPBEd2_9w$u1@k0M3Ha$@3RacFRi**@>f{w@@g@4W=!IG!2qe=QKs;Ki zk9kD%-HbCfeZNbpVI#wW<>rgscxjB0A5#eJ1R=Np))M>bWFt9yS9vfPBCDh7BO*N0 zfCigRIffZRBqY91*+>5Yx;!)q@pHKn1pvL2X-ckblfC~d=D!EwpSLfg zkw478yIP6+xN&uU)6_8yTK&PVmniV71Gt{jd@!_R$jFim+(3~+ULJ2fG)V2hun2Er zo472jg(C~;J6OfHBc;v{b4t6jTA*)ZG?P#M?xbfT3qDAWpnN3+nYO?z__5Le3oBBM%qh~EIm_H z_~+1dG1z4^1FeyqOYAwj$HrbbMN^+Yal%HLmku0;*pMQVyt-&1xfE+uq7gq;CN$Hu+oZ9~)J9D#2ow6dv#x3X1KBOU^y`}y zP!yQv!%}5>nWkBf^TK6X5Ps8~Y@Em{>1*NJO^!K4&F`d4NX^t#p^(fXq6s3FYPh=@ zR^w0s@gui7L&q@$5cd6^1n|ES@g?$!=I5WifL~q6LSaN@yjXlA?LFNqn@{|!fNhkl zcaxt`qSTehp2!1oX&mO(ZYt5B-lGA(sM;j4`OTFt{btIyl_pM zm^!GhVzeI{{kxAdkP}(P(XaSi%lZ$sF73FGJh5%YjpY#8WF7_?JN0VjhDtwkrC@q% zn_f(XYOq3UkNa84c?>ogU?z6u&#Ym9MjC~7H^PyrBhPFH#n?GeVx>B&Avi>7urOX) z=Sgp8ZiV))9T@n8`>nyB^@$U$NS-WSg|pGO{U;w@h|Cr7lQ%yM#`K@AqgUc%7*pZ> zU(&J3eR%apR8mgvKQ*lMMf}X>U~8hYP^pg}M9LuQy&ozKP^Iae@Vk&@vpS}Z< zPz}52B0ChbzZyx=_dPD36lHp{cKiXiL)!sWaE}YF}veovmIB|b8IDV{DYanv1?Pr%6*x+dj#fS7xeB>Y%B z^4lk52b2ETYsxs+E=qI!gt~!Hwhc|Vc5wTyUPe{0L)#PlvM_n@g_#wPffQK-k~%%$ zE}axWlD~1hFhD*lLc~KE^cTcHTnmg_iIlb>U7799#ooDX>g0wf;8iCJ^BkOHBLyIw zWpE2sp#y{S3pfHHW9RTFL-ZIopC~87@f%)y%^n2^tKbk>Q#p!l$$ast2DyCSg~0`q z^x3l~?oX+Q+=3xZJzhu~TKGjbHkP{=!>fB#et_+)u(o)oT?wb+94yy$-UgZ3q0)f` zpMinHXbfjQ&QCt)-WxWXhJXu_VF-MNG?qPgKtT&X)UY5zQCT;j&@`wQ4F7eF$3m^xiLNd)C?SD;R3OQ%s5Xz z+UL)a`JHJCRsT1rQU%h|WBv*rGVda)Kp=vdaKdnoHd8}4juu<*qNcW4|Ae6ROw>OBT3w?W*zDb$P}g+mftxzoF#?TDH3Z|#rA>C= zU4KB)q;OR<;cpkvBS-cADVq|>e-NUH4qjG%_y)Sn@qP_H0;7oftNCb7zd2E!o7o3D zL)5;=D6WElUT&Mc>|At}z>fy&luKe?!FfU~xpDnh3;uP&18$yFIbN7c#J;?>spsuC zp+uLl-uUH17QU95+S4SGY*XsotUyDZmG={j@EtYOiolJVgE`u;cr0I1&qmW~nPqBb=~Js|o42*)=^lH)-`T;^;xV$Us*R!)UZNK`3(h2t@lw)Z85Puklxd zoaEJTYH*LBuusyv?lIB&DzTr4kd(zT#Mrma7?jkkDCKw9^o3&gQB@>C1 z`rXR0Ga zB#hXZOlJ%asr~V-oz4tHNHSAxBzrwI|j_*^GbT^XLVm@@AXcU86vy`OXkn5V>K;+p8 z57+oz0tkr|l_Eq_B$;qoUx$1y;h@@lE&ry`I$pPEwEqgDP5t8cU<7+G4AI1M(E3Nm@9R}AQ2YW*(x>7}S4+qUlV^c6A~;aORM{hr8Dv1gJ2Y1a8B zG9!WA%X)|ezaRyoyf0i@7E0p}Qb+2tI?xB+(r)|8OLnDmMn z*V~;uGG$UZ2y_kW->PHIJSQh~Ibg1A#*g0ybkuW!wHv==*&NA&03-466q1Xl?^;eV zUn4$b!1Zis{TJ#3$=$^j;iml3Qx9h=lXi?QB&As6uter|8_G9VV8A+PtBR2c?=tgS zW{TOr0{^ZUlv9z?GfF5V4%zdn3P?;J?o1{!=LjjJZL~|Mqyadcr!r%mLRh;lZE*1> z`5b{@&lVQTg@%bxD$8+=Z{5Q_xf%08l9}$`#zU-?+f^7Z(sqsc3aL^oeE*cNUz*^6 zbRZyw4#tjKH<#5*FJaJ!g^ax^{rI6|{Lm(Y)^-ug!Q-7&bwjk9F2rqN^6pryc>uy5 zd0d|o*H$U8?XFO@iTR52PYE)27Zw@+#BX*5-Y~w{B3>u3EHbLNoFqOqDTO|0#Xeua zS;~Nvf$oH^rc2;`5IRV+KE@WZjJ+Rvj!#Ag zf?OAIQIo%%gMowNrb*G)}6U6e*+zp2m+BiR&qlh;aBS&Az7Ol`RbS zSDH=82VvALt0M;KAu|PA9q$Md!z&K#FiPby~H?b8>8zmaJEMZ8Xvb2A!mh zpY#rp(5X5Ehp}vZYkbg8(AQ>#B^TJ(3NjEz-eA_MfcqzidJ@A-RrHd&w z*2)GmlxU=G3I6=#RNa^8iFOJOKSi`a+N9_4-%q4OAps@pVc-+NRBdU#W+Q9DfNH+d zbpcw$1JX@wUh5Zcz(SG#DYtr+^QvA#H*UyiF2@vD=k;a7B~Fi&1uCL&<$+!(-0;L6 zn?n7GkoQ{5hM+x~;&X2GR*`4Q13WP0Ao7}#PFr3BJo7x>3HM@x1eVl1Lq~L3IHU`j zm)v%BlMN(VR=IR8O`=x%oFvdCVU)k zG(gMGPO_}VMRj7l8rHE!akO;Lb^jsA(_^F(?cw(T@|{Kxil}k;WoM(TCtU%|L$}?u zS8H2tZxl%JQINlJ?5FS{&Mg=%apq=Fu@z{T*N!zz4=@qM_ia1LVgxeo! zC)0X^ZcG!Jfwi_*EoF8o;*_0XPP^_o@cy)YeERg^W|M|IaC_+cN-5Ht5FIbyINzv6`NZ$MH|_VnX=GXVFKUt#>oHj|^K zFK^&SB%KYwCiE5)+HMr6Ubi98Jam!?ycGxmA? z0=pl$6q_SFhWK*zJW&^-1S=Ri^PP>L@a2`w;G-?G)4!1!e}LPR0&l0Tj;8LHesu6# z#+I0)rmrgbRaW_HdFMuqx~8TTbPRIjZ;rbR&5Q>-tDxcD>FTb;t|ZSRYz_|*e#5hC ziagDE*vM;3j%Kq>PATI3a%c9lh;@85?Jtu&_eE*5ict{Mycj`CxkVQ763%98;!WN9 zi)e^IyO~cy5Qxh;EIgoPku=HOj$vz+LVNwuVz@Kyu<5b_Kqt#>plnom0=OY0;op2pYaM zeGc5PRVG10GadE?&_zqnRd2YriT|JcQrnY%KDIUG3(S4LCCscA$kuhIp(RzK+xjP| zr~+Yt)Gt{uf}M#jeuNGF;SfT|SY_GXd#<|9FAgK@m{mIfM^DzYRH@BYYma6%5Zozf zw$cD&2Tsf;<%_V^IwGuxjcC$&DT46E;rX3!EQ=KO7{Y>y7mII3;-wM}hxGd%OOigD zW_;#8O+!!DlMQ!>)zG$X_-|x(pQHI_#v5aG6r+{}0fNPUQR%Q2f2(a-vD7e8=;*h; zJ8Amg`^Nh=9|OjK?rR^zLtk3V&UK(*jBhwc`|-3l5^8{9nKBjD%^V#nHM1vmD@4qy za8;y}wjL5)W$GH3x7l8Vp>^5DDGMy0MAZs}^o-{(VH?lOwb=Z_oEPv38e(p_#G7zA zzHlMyG7hnD2X^2`3sJ-xEl@Q9#;4gnqE3MyiFViceH94)UZI6CP)iB0JDxDcijb3D zYkd`wF>n!=3M?#RV%p7Qb&WATJdpQzHsx>7(I+8i3E_CVb^!m$N&W=#q~Vjd>C42L zxS2({MXGk^t?oE@sDI}SJ~gt0Oc)LB&27d6H5ray{JNQstt+`LWA#AVu;~mp>fwSwC9&{lN>H z4$T_@6BDvFI-!j@!BGWYa`-Zc?|@+8drk6`v(B^Y?JZ@b$bS&3?O|orktG;5U3vD> zXvQ!oCWmxG-y#A;C0g!K!YOJ#LC?|5N(H;Z-qq7ME?$TeD$|q#Yhmnxrnb7q$=V<7 zr8z(dHz{8qu!P;w7Y8~aY3zO)Eh{OWIX*CZzr%#Xbd?6rubE*3nMSE2tLN)TN~G;z zzBaw#A**e+CJ&0H^8hp83|Np;ue7YJc7Q1JccgQIi3f00b&kXsZ}DSS+Kq4Ix|c%X z-Z}tIXN#t&-JbVP^QfharD)oLrZ8+b`BYE)$%iD>qv|JjxKcm=&G-^`UErY+!^7WX z4#9ddz`UOY z1{-{4d%`JrbU1OeAl|yhh2YLZYSzc4S9wjsPHbGjZN~#O%odok@P%x4#%MfcR_rDa zYL$k&e-bTN-&^qAExYlI#-1W|yjnSz#OCiIBc_wt<1qH6Av0764O=0>p610i#QyAa zS75IAqys@xj{=Bj;dWd2zk+|HJM5ZYja_&KVl*D`@^FSoxlN?28mhc&f<6#nqHQ)u zSe+cQ7>9Mo8=^DoAF$$iy`oyh?BMyIdL9Bd^AUDS#}1bb3jFMfNS@MO6@-dOkW z65oV~GW;*K4O>}rcFezvc}<)u>H|3Ar^QVs^!NW&=?OePOZ^%6!E*YtwmI3;Lq^bf z1GrNz?TFYoE~2`6VdJ1nOKn*%2FOu;IK8F5HWm>d1igt*B=wdD*7J|QR(+gCaiQ2> z94sElOID8@pKE_)j6azw@PPz=0#%?NW>+GH4cV^Lw5o*-N4vYPH{R$vZc#GReOf>E%8 zR$YorxKy3~QKrsr5*SY6LE42mV`MKVmv_g9HOm1DF+hZcQLYZFSZusb!jvv$Zb!nZ zwZad&BRxe!xlwZ-q$PYqzCgL7JELf8t&bNsrq2T8o=E=Mom|H_e7B`KK|9qkM_FIM zebCd9aOVK2Q<45=Fd(nNKe~aY%u%OM(xesB!EKW7o-lw*XZznW%hC>+F{m@qh~lX1 z!+j80;5@JF^K1w+&Szeh+!L;K@m0x18|T=A}*yY1VJlr8m+B z#i;4A15TR0Q6tz<>V>TqbjX)xN~DkPbQH(eF(J`>tXm$-btq?xFCBQ&)_>2soIl<* zAOWV271@qtK~Ho6pSHSB2C(=&=P-SH=gL0x5qeTm=4#hre#MWDeBox%Xxm!=~gHD*I?$5!cpz@8%y^q?`m{*{IE(_vhs`b-tvgyewaGJd`yT`QDZ_v72s}5 zv|^k;fVsP{XvZw?bnFDTZc&hk%67@Y?uv=61p_Q-is$JZY>MEGOZ{tSF_-{AjVRFQe1bY_*&DxK!Hg0US^pEG)II=voX!6~`amhWkt)N^J zw!-2_aR_pn+yCO|Z^)j+^jj`cm`=s2XfrzNrj!YZ8yY&O=4B+{gigr+GZ<>zFR5Wb zebEQgHysYVzlXn^oFO6D6ZDP=rejL*u_chgi&RA6DstDvle_ht&Y75UUM*C2Ps3+x z@Q|Mwn{*p{sZmO;mn(HSkC_!>{`Uw{$Z2U7^6E-k`khqn`>OjLYwAiXV!#M_n{#*i zZz<97p&|xi|I#ZW=l9N9EVP zW@H7zHW?1j@)PPRT_;5S?2awBq3ze_Nv2cQf(0JNywgqZ5=%{K0vCvolxsFqOPpM%I8fjd<0h-b4b z90-~Q3AP**SFHtCQ&+Q_=#~9yw+uY;UL@QzV_^jgXh2EO?$>DpS5Df{A$f|zEWz}4 zX=lBQWf3Pk9${6Xp?LwGEJnP|$vaC;zA?bFtj_WSFQQpi6hD6jRb3@*#f6^e736MT zYUmR*_EsQLnMd*9j8%@pImNV4KXm;_Z7S1F97@Eyi2t{=;}7q7S1gDdMBKrW&lk$i zB(Xe<_PFdL`jU6H` z%(gL!yQtSJHN!-9oz@FVj0-Zv`|SK}KTH5WK)}EGmlY$D@ho9>=6mqc_YS%=zQ~5c zv(;kZ2_t`@oz;wYF1n(b-j2ZOgX8-P?qi)-Qk07uf_IOUrAU1q6B}YLnCpq zMvNEGfKVy&;dQs4mUUcIj4m~pw444sy{J|BbXi0(F59xyI_U1gE_d_dR^JV9Z2}Il zx;AmF+3as}`K~Px?AcEyySxg&xe)EEnmUH;I_ADk`tZjT{(15;Ms46N@U9%(N=$92 zg)L{#&l_!0U(F%H%Y3C~Wsywnf>%VK%op>_hI=-<|Bs1iH^0{cc_@hTk_ z9TB|b_eXtdd_KP^y9w_bUL!JiSz(9a#4|r} zY_^#5xd#$DQNe#@?Wvq|>2Ztr-CT2@TkpRO0lT!_8a$iqfI%ezV>M&&b$G6cZqPX|g9?5X^sqb9mWUr05XKAzlzV%;t=6tDQ@h zZQv~ab`cr=J}PRa%%kzA%M)DHGk2twmvCt9J-ZFdIIXWO$q&l$@P>EGsG3cZBM+md zCK<@{FxHZ9(U(m*@q={R)ub+JG7hxx$bWxaa&wCfC3htV7_%^5$oY#&ISs}O6-)Hi zmsnj!g4?RFGX&t~77xQXhsSvFnxS_A=U@+Au30D##Cy0(vi3mcSo3A&^e%JZ-K5 z=eCARs0CK`M0OWW&`MZEkgtWh|6+P&UCcTPm?$oz)8ShK=mRLbMl7M+ApQ2 zTyL8A&r$20w15lC@jWZJ#5qG&kp29a&_&Q>ieloEcs9o6n7{9|taK?}YWeK8$3m{q z5txbBuguFDh}yKaY`@UhXh6?0g7jfaZiSrMJ)+X_slQPm@twm-8%)$}~xPg4(G$=_OS}#K0yVG~C zisCYeQE^f>IedCDmdnBYFp}D|k;U$)))QGkYWt%1t*$)pW=oNU%mh+w34IzFxSH7w zC_Q3~9w-5a9gDjsx>@29gt$jFS!h9Mid`-*C2k_|(j9Mvqr(igg<2UP>#fU7+|C+; zIPOd|mK31wuHqk(v)8T$lFiR0B*LU<0^>|ct3i}%{_*Y~pS9oau3j^H@o2%>hlPZK zH)YQHITdjmGYA$-(*(CC7rd&8TahP_eJ#=t9*n0#%k@!>n_P{TvD-#(wNzFUs9Y61 z!tw^rXwMX3>V+%4(vA$qN&FnkB}xtsrkMKq zo&&w_QaOhD%g7fSd=23H$FqSNc!;kHoohd8DtJU*4lh`U1+9>#q!i82KT_<>p#&ic zAH+(!eV;U_CdimNY%G1>8KmN92pI&m!2Slw)deKIm0U@+&C|Vi6R0J+*k4h6?rzDy z=M>ICm}djCDgf6_W&itkmJazM&=&WQ6`eDyUAhSF1wj$Ux9nE20jL-ARwL!S{jJzv zYR87+T@ERSB^}3Le0yugv~${E0*Hgp;;S0=xP$z3Q7Dph zk#``p`gUQ=pF5-+SCef(Vj6c(&n6(QccXs`Bl@msMdqCQT6PcgUrB?r6r>ZxdbbO9o9Ah_@xKRrZAN4Q*EiFv;rrC#zz;XI{ERXoIC$fK**K!pFCVXbzZb`m4)^-W zN&aP*Z~ye^p#C<0UMFploy;(frAL}rtt$RQEtZLcvf#-jV(^GNTfm!KaaA@bjkg|G z*#1U9+>#n^U#Ly8s^>CREu~CQ`G*3R3@^ET5l}}|&!Ron8yg(j#g{hVs8Rcuw z8T!MLG-8qu@E6MOtPap|F6e5*PmF@W4i?F<9H@Y&?sAT^DAcI&ij)ZM&ww8K_M{B)ZO~TW&y4XAPbxG%IeTj{AEqft^ z>+SkdaQ=_{oljrb?Xyven^Xdo#Uxn7aBbyApvG~92tWlDh_tN??o^%spQVw`ARwiAA{M+y)N_iwxtmyW!%-@hC2JAChKtm}=Y*Eew}%S01U=ylUx}*rVZ|@h zxJCE=9;ZKc?^A~g5zuc#Jus*G{LORkfi1@h@`Q^GX{URQQJB}*dYRq%Dh?& zg?|?_@XuiQAnU4ui>&D{$>DX=v1!w<^xc}l9ttpB68CTacwvH5$Mf~DzwgnMMg!e; zNqIq?;VMS`h&WiJghzI+ z-L0*_1`6w-x{zghA^YJ>zAGiC_JTaG%9*XFhy!}}6PBnD8Y8ypwlMlS6+|qPi6`wB z1T~jEST(J%GqY#^Sxf!DVvB+SpYTGUkj|@(hJdwh(qQnrGNReVI-9tjGfcJ@qQyDX zrexd-mIQpfa)ZXm{{Vy+B#gd0a%(B@q4kYlPks?t8*#xRwb7=;K)A;%$7?g9M*oW@2`z$D=FzxOBsHXgW~ zm*(m)Xn;>zKPrQs^UU305oO>1Z?@8iJG`2#1ycGd7T1K~N@Rs(Q&;PQxPui*UrQQ` z8!nFId@3!dBju}Ht5Dvn^+@q~6N@BXj=7~_u;GMlYfV1?^HT!r)rqzuyMF2pbtj9o z>i8v?MUesVxh|elH!?$3-NsV^l5otEV?^-(D~>sk=Cqj_S(V|rFdNv0cl$aQB=GPH zLtcl!*|tv?zPg(B&AT7bA5;WJY9KvgEWzNCloqX=(?P{;KsEmZpO4t0ViJvFDNr`D zITZ$@9$Y&~r{4EWg^QsOAX8P6^dbl|QbXtNtpmZ5rFeB>da?X8)3+sI_`0eih6<&g z{a9!5Z$c!4|H0wSySLC%olVYow~PCz3#Gxm$}V#>NwG2@K(%5;wDN>PRmM2s@V z5N(p?&tfnVeT1S!t%;6@{|MJ(+ZiU1RFFo9sO^D@^`llIJ^?cV{LucXswP&+RU_D|@Tu&~-l;f~ghJ=9?4v{9=;*Jz*^1L%qy(dp;P4%Q8{R zF=tb}@wE3v4lXU!x#N1v)$&h1OX)DijePBRIKm+mX*6{J1_b}^y2-MXyUbtG{eBt7 zoeiEQoHvkWUjL1>=uNbtW=9rTv{FpXGU8O~>LmK@V3-|g)4|X;VVVr}C3YzwQo@2f z^+BI%KZy7(cgqWOt}~T|_#m0}x;2q}#Bpi*0&gr6uGk4?%d|h989*}g5nIFgDun(y zCpcTIr6%E;L8x-E2uirq9YF5Z^e`ftdBd$H=tV$=YaJ2eL|VLxjqZd5Nf!Dm-@gF9 zU)Jm^1mpTCzR}oP#J$rBQyqs5SdD?3ri-aSo-K=Pj|b`GB8a|rre%V$wHPA$J8r~^F0vo)+PARjHQVPcEAMd;% z%I6(+x=i^*(+DO0%<<1v@BI!OgB7BMJVyzif=L6B`k>$vEP-xDa@j2o#UIU(YNVPC zYzRAih0!${3(aHX&W2p~_W zSgXUOEk(ZUNEXH4crE$-Ev>;mQ|cl&(R>Q?bdNn$1JXrui`=mj4I>leFtrjv3SP)` z))TY`4}nZU<*u&IT>Ed@IYm3{BiA1UxeHex^=ix1UVcql62`!(&TU&}(=z~EJbf@| zAxg1s8SurS(C1VM2@vGy(0v_xgKj+?eyeuRjH4n;L*OCe;vRCuesrWTHzrN8Ftw2{ zZ(#VObF^40<8BvTSHYA(Ze~@}MiEGN6W^hrhapSuYhXqE571YU$_%-`_G`*&p&f21 zFNNM^`TZlpO-F8+lgu?p{QT`!G{H46Sbi7^$8sl(Lck-t|gfG7t0O7EUhOZ$);^H^QJ$syi#&`iI5N zJ+VVw!;!d|>Oh~nxFW5rMvg}KCQ>x@*#5^?Z$8ukka40Kt+%B-_z7GG<-ouL$RxcY zu5bd)4#*X}|M~L4Dpyp@4fd|)DB&FokFfd~!t??`fMd@Pd^VZ=()deYp|xJ%oDu-A zf-kM)YYlYJ78uKpQd&=|v!`+;nAtHQi9NoJ9lXI<Y-XJbr&w zEXKNrAvx)$AB0m2lGS^^|Gt47mD6f5>qGfAKQRb@c(MH>1yH=@GQD}N{WS-OJ@I&H zAzX@WgiJKF)E#6=Xx-)+a_5EUkiNZc!1(d?lV{s0eOE=h4-*c_9cbU?{w*W}fIfnK zNEm-NFS|>ilr?L1oS4LHi?0?N2+~UB1-@)9Wo^Ya4c)w2a420e(pK5@&?_*GPA5OT zo2D`rF3}L9lY{>7&MbPx&RS1>9mAG)Z$=cGu=+p#R_?%_d0@=7jKzsJe~DLySwEu5 ziPH^4YR~2QvYlGo%QFe=Gd`2T$MVVYSXYe0n_rAJ`l3iNPPHX}A&SNTX_>5DAiXUq z>ZK$ee{yXfD!dfSkKKBLs8?$>&Tqwad|hLrslKzFaf_Z_EE%`^P4LZNGO=O*f0C9O z>F%UPT9s@LR_yXV&$_>ra3X0hB$&cF!QimpY5e{h)S7q1?D_qEE+$Hm8I+PYk_qVB)?Y~xQKzf2c zZ^3GK@vxDv$}*bpR2A+J<9omRlbU=8%i$=Ou6WSA+f6G<`!?8P6>dfwX}XldoNg{c z9CF^%%x%F09%`7-&ILDD%#Gaa{=aH zi}X6r=QojwSc+m5rCBE4AD~nd9li+gd4Hpl%d)Gn{RuxM_>CQ!6c#miV^w@=`oEj0 zEA%}G8hdc)RoC!g2Wj*qep9$bY_ee+VQ`Q93jqIe5l(_XhN@(2Wo`%iqB}-FAL?ihutbPrJxE%o*yltZ?|Cu zk4T1e-KR8z>$1x8kh=lxK2muDElwaTfTa@WmoJG)*37V4H5d)UB8i2~-H@430Mj@DBLg%{X0KyJL#LOge z@dx88&mhaZj+@NKY;c9Ofc5#10*S-p^v(YJrWnTEq&-d^5`MTH<#CVbJ`GNj?i%Ox zT)~u|AV3)gvnq(t`sX8xQIqL5rBQa(&l!ND8*u&=LL{#Y4Wav(>H%uDmKD7W-B>WhE!tidxAq5n`{ zbwsg72h}G1D#6<7seB$B1^0(I7I}B;z#TB%>F?WI0ZZQ)P(=Bxt?=&@f^fsZ2xD|2 z5&2WoZR?Po%lBO!_<-roBG}W&CHm=};3<`_Tem6O@n+KwAFL76k>^pN0+aRM17JF6 zLnLj&v}yntd?vZ~0`h5b1g&)eYo+5|<~+~V9HbLx*E#Ql2wTQkC;5uUrz4BdOQoB- z?lEf7TPKzuZ-JUT_6!`(?_{xZ>UwtmIS@ZslIwlc4uk53l`bc&PBLqR2Utbn>`&?v z0ZGh@Iym(K!>**Y+hu0(SW(a0TE$56r#b>s7W57|w}-L6Zxe-kOcGF`CQcdX&YXnu zKOv9_JT>!J_9?)FDksK8`@1@PX8o?RSP|+BcZ1@LfNel z^O`L_>4aiCBh>S!8SvoB5yj>`gfz>~8|N^^1@0h$e?N_t($YSKrB`HJNCyKir}-Gv}qhmsoJ1(P0L9ttNY zKoM5zuFQ$XT}0RQRtmeRV;8)lJovu&4>5()P{VQ>-AF#e8QKP61@hGNX8BtdW#aC^ zcXKd_uD@men%ip)r(>w>*Fzl6O5BDSf)lQs8y+8YAvR9{|HTV9g2J)IXpex-!m~Vt z!_g8{fP@hfZydY@MG8+u#E|V0c@aUTe+dz?B2|79;Mj(w3pYA&|`&sw#i;0`CH#M5#&l1I@ zX)bjk^`3ke);$*B;=m!eJ7I9SJz@n=_EH)qpxW~wX(*~9)%eZ#W-pNOY_rk&4G2I4qYZC)hw|*AtEs$wdwYsIq+O&#}0rI-MAzi18BR z|1)egD!tyN55Ycea=ElsG_QTc7581Xim^7fN4&Fq(x`TxNfYRoV2_D^+n{tj)*n>1 zw-hIdY=S|CLxY1-n9dNvkPMoEO+&i(^T{#jy{4|hC!NgxmuOsp%AM#6#O&e@@>tTg zdU3Xr^xIKg5yD!s!W*0R0H@MPQCCM7=2XcKz8!Tw8c1~0Gx0inJ2PI>@_|S}bDWsT zPyQm!V31Cso#@ovAt>#{3=5#-Zu44Hpbe@%y=liEY($as#eS~JmG2$#QMO~fl-<{o z9IE&*pq{QD_O$HzQ-{sLvNc8o^5${~3+k@vVBQ6(RocPwPVgdA6l$1JTFJw7`ywQ+ z>mQP$*iFY%`n@F9g=O9LW!AK9wx(AsZazhmPpB79+$6YOBk5sfGPg*`^}P!>n$0f8 z&v`RDcfUz@f(QyB24$Qq*;Y8On>RtsJoX`NmKzlpD7H71_LUJwf_W4lcaR6gL_Lq3 zM;rjS8qxwD=`|92F$;RrO!cC2I?UeEHK-`U*?OR=Z0cKsVH>nqqEM%r=tbs_rt;m6 z7zjpTT3kCl^02K_PP54Yw#eKaG6C^pc79yH#<^gYZf|uZa_LoJ@kegxc4+;@cZV?U|Gko(rk=JTs2x?=$w~x1ym_TQ z*8;o2Kw!BA6-q?vX4g8-JEOBDM=sBD2g&pv8DH-Wq3e7O)TTBnp^poB0l6>C!V;19 z7t8Lp*~|`f+DtR&)mJJjD-I^oW~%A$S=ZkF&j#BmxF`-!kXJnC57z|w(JsNJrSw5y zf&B=cg|zc1tHV=gcp+%Cv%) zWwI#ddM4YV`pMId>9BYDbKPyp;3S^Rl~r-Qt+rE`1ziJ+0Yq2Qo@4S6k{}12OiK~K z8x3TNT7rCzIb#f zfk8v$!VUmZ66odsVIqjFaect`Z;x1P80H&J&|Xbb%@a)aL!3o2Z|hkv%XwmMVQora zlK3-BYJ{+c+3F_C;>^KpOGAqyLMAH4Of06=&Uk z{YoeBsHF4LZ!1^-J^?JsAu(XeM)9T~-^)wTLNaF()7>BHLpR4CHu(Dowy8;Gfg+|$ zI{Qw56yf-K9)`YgG*#KwqpeZ>3xLNgbEK@_cEI*VJr42lIcu6CvtJu=Z^CJu`^;nu zP*LrOLTC@iCBAiOguYzo=`nDzdpib()4UWbJ*|*n3-_(N_fRV&5v?v@*g*==W$ugF zjR3j``W*k5CNN@tsHH^8Hpph9uUz}kk_sP?<|g`J%XmCD)x&ebr(Be$eoBdZ&=$Mx zMMDmhCJB9%o)%+h`d#S{v<|1NIAuk+M}Yro&5J84<`ASzT8I*u1}+I#QoOWA;R&`) zK6>pIkLe!aM-AR+%CBy$!%!}KW`P7;Y>8g(hN=Q8KDTSM`+ZV{$P|GCu#G*`7XzDF z@ls#!^>Kn#6_fV-D!l%-?Cub=1-Hf%ptoyxxCQCrx)dYB&0nc(F2B%cm%D~y+ki^6 z9h5N760Q9=wiV_>ZC1mET>f-_vSae*TbLr{jKmRqYR)*mb%$hYXxZe_r6ZE_!7|!X%D`RdedPI)JmT;NHI${&r6QU{$yr=t#F&4TT4$*ogZX6Bo(}aXr1odSryc}^ZF^~oN_x7oq zkLIR-?ZNw%k3J(W7Noz2kQ~S?&$$?DRCNv)vtnL5uk{U5yV7wD=nVfkU6()gcpK$V z^RcuUAV(J$5)h9%Qy^~x;e(#{CtM#p9anJtm}L;azd3WSJYq;fz7@SKy5F**meJe4}$8B~ zlziT|)b}miDSG{E;{YIGIKc2%WJ^NxiKN=9>k1b}EKW9`A^N~)+Sa-KK7o2FqwMvU z4yv+;e*}h;um8R1w88@T#muv3k24P0b_=b-u)G*TY-T9{`o8~XSK9$XA1kCh80z~0 zE-rm0nAfgaj$PSGc1re&9(2XZ_o9WY8@o-!(0q%@2*2=E(t?@~&FEXN8*tWy>v1!m zk-He}ktcm+>Tt1|wu4aT=qquqXTA6&E%o@V%D)F`NHXvxv%_7?m!6PVyUPMU1`Jp`!x=5QPjEsB-`22+y); z7j$rqi`nYec#Dt|#jX}7nFD7uq($;hl?{`lHS^<}Mlw*rv%`QY?23O1Z?kG%!5<;)+7KFiJP1V*ngxAYA)Nne z0>-qhK47Oe+$|?^w=^7Pcz&MJ&ekk-Ew|gXRSZb8VH3(x3QK>Fz$<$LuuLmf&333 z)SZ1crFNpO7U$Tjf94VUhaDOv0{QEsLn^pxNKxu^H=7W5Yq2v1Hddap0(@4}8#MaY z0Ak$8A<2t9!SuK5o<7A7y|C_@CYFP)(`e3iHMqHdbT#*iH1`NZSg|jzPdGF}b%rF- zpjjz)Nb9wHp^(^UVsYGJ&C5#jRUPnzo}&W~%VW*yZ*6DDGU~_yIyE=(Gkf|2QBr|A z>`HCUwj;f)GqOAtdB2(JkeZU>yhs642jO?#x za(A(a4h(tz$M7}Oe7u*Q=KL-RJiuGA?o;1R_d0z6=+ewdK)$c)9=DND$OS3AdbBllxlKmFvmt?f2>9&Hg=WzRG^$(e{?*Z^JDj9a{X$48J-ZYD zSG<>IjPwGTfkn1yG2RG@O#Pi|8f=% z#}N~qbdW(kXarIJk+NX1ivg)bT1&2%KS9Ghe5?X8%FOy?Hu2(qSJK}QQ)MW`+JgCs zxu1^_I}~9b!Z0NjI9$mGe9uWkQ5^+a-aUFBOh%|?*{S(N8g#83oY2OS>+wa^?0>VW z7{PMWKwgI&N$YguI=;I{+TZ20rmsdr%hRVMJ>w8MOW$l5*JY3hWAbCICNkbT%_*DV z4{y<6u8N9t{BE^A;lbDfa_)Ys6!NbuKh<>@8$q)va>9k3NHn*Ht358274PA$vtzh*wv_n+ASqtP z)WJ?%@ z5L93{KC5tLdho6~a9LnVA1@i5UbIz07O7AqS=|)tJp=aT-}ga+{HcK^oENhqo1y)n z3w!_R=y_96ioNFs)?=CkFkHX@Z8B%YAn1sgJ})VqkrrTcOhLF&EwHC8!83e&hOl-b zKU%a-lI=KB2d~Z9KRi%L`IwJZbK`16KBcHyH^K(9uz-}r|2U{p0PSF5>##IQ7)8gI zA03cXz`jAYnTI-iX{SIs5s7&4fWmGPmL2zky4de>3Oy~rm%?fT%dq6=~Gy}gjb?}JNRxP<$(|!EC<@=O@-&P zPthTY5BD*l4g-jghbBowN_2=d(79)@=~p|ZpvTkS$bp0KWN7R5IJlO zT*PKNY#``@R_;LX{YH(T8H6*D95{fUC;6K9ySS^Id^Nk{EMW53O1z8Bdn7mF7>X9? zpNU~WgIm>wcsw@srX`ng;kIsl3j}8MAbjBg9VCD9rw-t3>LDV&hxaj=(d(j~gEx#+ z3$LPz`_6gV-VkbOihgGG>6LP*Z@=DVlQkXlHr`OFm!gCfUAN(s3;s)vPKV4g9PJOk zXY2hapw@mKfhzY>d&mPeYljG+WTwT%@d?d5eIdav7@leu!L%TP(j8}W%E+=iY->gc z>Yu(Z{qznK4=D>CS4Ao8>{nGd3(0M}jb0Rt7TF+;a2kl3OFGpdGHFDw1#Lu1Y_g%| z{CR)ro#|DXXLZ+2RwYu$!_TK%{nmbS2PZDHCbri1)^9uE>S>DG(O zd70}(09Qvl1_xxKo0eT1J7CNi$@7`uKoL%{k^(Z(epPa@rfJzf@u&~bD&{-0Qxy(O z4Jr8A+2-$-_!%>`q#S%w^f+_>bsv!tmPmph)8FClEb&b0-eOcq!+WtsLpGc4J|-|Q z`U$p#4i7b1=U%A_Ox*ZaM2DtZs@EF3T0L=`B1RvRgM=p;cd6rP9Xn6baaZ6joylS@Yy)>%rTd$eNozrftK6_I5Eq+$A?laFhkhx%W*?RV()*e0)1ZhOJiD{>eiyG?tko!vojX zC}yf_o@w?L663))mdLs_I=Z$|T$0v*i5w`t_Q$t~M*UqD8DIBl!NDNJD zKiJ9`fOdnr^W!xRgKrccwY0dOaoQikr=}Kq&-k%1N=#4UR?>#nt6oe-g739%i9Z+- z?LbEa)wo0K{X5HSx#sw0Z#;*bz$Yp)Hk5vl#FIOMv@uv4e-qbRn}*Gq-$G;_pe3}- zO^t-N@YNU|Jw0Inz#NjAt!AqIz1&Z?AK>zTl8XRjPhXu_ATuOmC7SzU#ut^4tr7WG0mER%M1WoC z{s~waGlO;5L7TB~kd6B3#kBwK0Hq9oWpi>bC)#myK#r3$2u)C-7%x|>u(1OhQBK|8 zA&Fjv!z2-ih53lSF^KRGjbkNel-tA@bv66H+jI3qj(Vy-ow=GUnj>VxxSA1GjSOF3 zQsB2#L;4s>D4%4~8>eVY-N=NP8YZv>&UR4cmj1lt}B9$`L=iThas;k3@a3^A{p{W>5id1YExD&0(I3bjgK|NqyLR649sbDte3Z zjS5;=E3HB#2sFK4WXAmN)E6hD5n&Vx!^AuZEPRcNmb>rIuJN)V`2u`&Np`~)W}BhW z+pS0lU=I$OBu%c_UDrfbN-^Kx--#<{Y?h2qQU*{k!)}w~@!t4`*(_U>@?>FG- z8W-z-ikn`jE&{5NKU~B*OA;2V7*DHT-)KvJZ_)v-3hNL%?D0#;(S%jOc8_MA9;j^h zEq!0$H}PL#kR;0rpYUQkoH&f1&RgV0WP|Kgpu?G@Md{YW6Vg0qD(~quDQWVwmJdWP zgZQga(}H8U!nV@uMQKaGgd+xR2t3s{MJvDsRXvqe;c;!$Wfj5*>8 zcz96qk|Gg!zXW9$clc^&dT>GNN)IZ&_LX0vy$YGkMsyhc)W^snE+zO*WP^QZ{Lb(0 z;u3fF=H*TyN}R)|)F<7lz?g4&grc-Z-}7X}MigX*^fUkyV@ds?85uE9*L7 zGeAtK)rZ+G2n*(UUMT6-cHo%wR_*v_ZJX`njuuBnIoE&*JUTeYbxuH%v5?bienL2q ztVzKFX4PKWAJ;G)B;@?n$GU&Dtyr4U+&OxqnJ?dy{!)3QOs8L^x*Y4Ld^E!7g=(5; zE8|>dr}_Y%HW4a_fNn>2>(b=tACqOE*OK#|p{2Z64YflHy6!CBkwb&SCu^=2*!M;mBn!+xecS5he*-$$=D{CS(?V z0k@=7GkCNBaa)Bl{7jB@j~&5Aa$=bjNUvy5B-q@DhGDcunqlKiK;0~AH!;n8aFRUF z@8s*QUR*8Q_9UbZtpm-y?rKJSiV|r`pJEEGVh6a%;@lpGSB?VZucK9Rltrn7SATxI zh?T?P#dUUJ;xR(>>2e!h7$|!5Bo;pDEP=^jw(l(v1YC(dqxP4WBqcm@TR-mK?FcQ) zFq5+`&l$GMuz5HEHfUnnidNrfU8qTDVLcM+I>F^=eEa(lQA*}DRY$M2Ea-~fDHj~M zH$Y)q4^$gL%XpM)73}?OXWOT62mG34z&2{r1!%ZaX|y8{u;@} zYI8^}n^|}Av`d2ATC$xHQPCpcWB6cC%MEu&cLMj%hK4~qn~nS?_FsY~EWD4`!g9fW zBt2TQ5M#9|a z&hiei{2)20QuNHdKuzP-F*6GckajidN)3mr$qs~LovrP{=sRdN^z#W(2$THZXm7e? zAnjPQx0cGR!S!cI$s2>vl=yYjWBa|Q`gL+ja0?cYwb49B>uc>7y&=`NHNudM?voB7 zkgBI042a|?f1~w3-9m{V{pjC zwBz`DcdXa@%G$oxU`!fmwWjRok%a7;;SCcAZ7$ld+NpgMwdA6cc>w)`gR?R+cb;n2bc`Vwl%*y?`YnKs>>W&&Mdm zBBpU6G?`SMJ2FPNV^>Z(=0I>BUYZBx2hN@&nMAoaWIpq3h-Y}tvirbkb#5w9p_cT* z6#d|2;8a*uOTz9$T7UkS{)#05m|A{(I3W}*MkXIgNOUxzDX63LIyPx#Zr!=7N)`(L zi>OC^@Fl{v+U1}f9*>p8e8v`_y-G0}MiM$o3vFy;eakhO`!V3cV_|Su`0Z5!LKxyW zTdhCPDvM%ey}OC849Ezm$u6_zjriG7vw^qEurA*hplju|Wn9WdMO>E9r%uJVa-RKt zgFrq^U(0;E>HWRmcBbFCCy8@A9Q#t?FJNe91d?1v6F@a?O7GcA4E!jV7@xd-*9nR- zBW=010QvxYRc!D(DO_#1gR&J9@FxbISrzJ&n1n_w-5^Ki=b^A5-b%!Ko)I(E7S&I~ zB-foNDeA{C(8GfPJUA^*>}`}n44Md0+F<<(Pq?A3A(6J|J&wg^C~Q84zDB@4cz0a*aS-pAe6~)Llr9ym_bZ;< zZ-q$hSDX%mvMCFNm~yJ^5n}o&QO>73@FgCyaAdV#BZqKRAZGXQq*A>1Bb1|K`_| z(~ zNCeHq*!1rNJJ^>a+p=--1RGE)f$gWR2t?qVF;vA^X`$j)*1#KHw_DT#?6PXe5^0Of zW?OG;-4lF7GKUBBad+vE(xHob?LL(}q@%yA^>YBe{3^hY>)st8AAK63&_GV2G=r4* zq5hCMr)f#A_n7F}zvao@XW538${sI=zrE^WNkL~hU=Jat1^AXe9*&5MG?(nDWZbD# z?2$VeOX)=|T7mvCeTh*eDkC5)K0$$HKn3p2TZuv!k3jynv)v+{J?$(|fY2A=et$=Ku}NY4;pdZ@?9Nk)T;? zR`kGlhtr7;K}*u9cHEO5l_%95cft`>qra9x%kL(q_tc=?Fgia$=%E$QLjK znM=^-M}m1x)crQbG@-p4f*T>suhjjmg_oEe$V?ni2fX3l5p(M~siyk6RqgdA87TorUe?17YQ|^KJaruAH^q+|?xSO4YH#1DZ$BVp0 z|Heh7B;_qgEAk8G3&KxC8^D?8y%8ng_K+OS%4~$9C1V*p9pbd88P6iin&jJTO+Rte zu3;3^=Lgje_lVaaox4)U?jsRVLANVG#-v+hJZv+-5bzsd2CrT7NrX8U@ki?DU4l;B zK-zo%if?iUA5WilLt|>dXNz=U_({F|%U{@`5k9wqg12QYruHN!*CB1{-w9AHW9cmfM$i4d2*RevF)8?&lDaNY+kTD?&x zn}F#6Tt8Z2n5t3=k(;Q8z75KfF(opnq`j=`IPoaU;pKui;T0$K^m+$HGZm_RO)yP#G8|6kuR_X?1ilyTPHn9qTPWaJ~LiWTyKDjRY zG?jw5GBZ$+2pJ)}T8g4@^tZYeqD2Hr?GZ3gw!LK+M0V zi0I;Tx}Z$5^|azduFUVwo8^wev?Z62Vo4Tqk;GxI8&uv7UgsR~Yf0?~q{t8Wl;W{X znH8TJy4qqD&1No7$LlxeA9k1{YK75^eG!f>D zDB1^2zt~q&8ZqsPvK_GmG_QxUHsf6Id+`Z1)^i$AE;u}Dy{}l9>~}l_HkTO74juMf z+<7Xi1$D{MADpW!Dcw%r>$4r5{a{k}R0V7b^Qv=pssgWnZ~j(*U@vFSJIqX{P6>ah zREM{@5728!rRdZpk8HR`VF@(vUiXN3(*56m#*vCvRCd3eD7 zBsaSR&`4grY<9(}z!rr0j>Whj`S=j&&)8xjox1Y3D@*}BxO(l&i|m2^(8DGcZ#8Y_ zAmF?@tGp}Os5AVUG^WiQPFqNb*@#8=t;=DddBaS`vvT|^*q9{3;SuKkI z=QRpBRbHjWIe5K`4AS{v#Xx*$C}%A;ealTGeMVg~B1%3iz7O3lYM0-x>2<^JGK44Q zYOCGyTv#rXo1{ZhGjidXsLEycx(XeJos!i$!Nq9bK42|@=3p37wX z7d~}};NCR;42<58ahfspow5|qF`==!r!)FIzzb89d2bRSt4LhMwg_2CYaR;6`|ob!~l3x{H4Y;!F>EWA^1>sL#>>N5i5)5X`ZYaYh}T7rJ> zM@JclV#1(aa>N*p9+s^SV3VIYar!(7%NdAWw7HL=8G`K`fSmJuC4I5=Ny7+E-gj}2 z<<9iry?!Z*IOnHsrRrQ-BzniE!qS6*q!2;qD$4GOcLXi0i3kFi2o(%T+l z2s>=9_N=kmpabEzbXb}1TPth6nP&qsVOe@1Gaz1gh5fS0d3Kqy_=34lYlp3AVI-29 z)4o@z`75QwdtU7B$v_C!lF?y;y?V-YfVF2?7x*2vB(HF(Yq^kVYp7HsFHj~793gQp zB%`x!r7L%LHkN;0i1K1baPS1^v(ZSFU;kQ@88S|=|AMI3uFjzB$vfE|(0eCL1eh`( zZ5D)NjI45}s66R)-m1dZUd!2O2E`gQZn?oK?D9r|Fe96sx$^-&HVw$bNRM1R8-z3q z)5F$7&1KgRy4^KR)fk1bD57x7$*CifxnSUHf~Vis91SXo)nt74IJ^#VXILm`Llkt) zSa_R*Hn>^A)S1RqN#lP-<~~l%!9?Z%rQI|8jOrER!bI;E(N?ecMXnAXaxk?1q~3jC zR>-tWH+qZ@koZfCub31ueywb8T)9HW>+DT}#_E8=GeUuvg?}a~+!k*j1W`lTNQ1HG zjCaPGLNr5jJKBuWs{7jhUFn5(aS*w?VN*U@Q&S;pK#~_X_8EK9Hjs9WXEP~N^;{lD zo6S^?_9l!q9@Yjx4Q1YZ@r}1Zj9$#8w#35P=9LN0+zu?EdyU44-0K2l9^Z)7VV?Lg zTHDKG%#F2IF&zcUe&fsQ8L&4%S8Wz+c#1gr8KbRbwbV@7`d0jP=!oEcla8E+aS3xr ztKGcpRr-%9t-D-ST>-W4iFv3NIe~DxqhSum1Px1oM9lL4ZX<}&eQ5C<$F7|yI2GiT zB&<034~k&Ng~dQEQP zvRxvBymX5E;U$UddT^QyO|lR>p@Vw9d8r?}$@zwbmI2DcdvFpcpuBJC{$3P46Xv0= zpcWw9LVrk)MNtRg4aYU%r^pK;fb{DfLSWm2Ym#PE$MHm8kn^8zj&lPd7!OPQOM0O{ zKCdyK7rwAU9It%M{3(5zliF^&dyERYLO`Co6`jsx--)|!XxO<7zVN% z8~;?pHexEiU%i9O;PMb3e`8T|5X-;(i3-R!x&65AV$6Y>)X17Ow)T#Nl&qTdsZ}v< zAJ4TP%aJ8%wO=#ZK(R~jZ}}X@*DI1`5T!moY}z@n(Kct{uYmilUM4E> zx|nSo6{{9kn?n<0dhQdy^>{jC*KYEu>@yGgz@amHIN%*#=Cac`NEbDlfJ8`+pFD9OI&#cT(OhI_S zzSAVo;p$<`(r7aUJC3=43MEAB4A%J}$#ue|9Y<|xNJk$x)u(-CEVB5kB9lldwEKGs z&*rEskIx=)r-HsbEbVrH1`%YPq7QP%pE+ZSf`t8&jSm?SpxFk4U*{pQ@_hM*`Tb+) zBh;5X&de>DNyo5t@&tuc`ptcsTX9@K!lC{(#$X^PA%%Mc(#WLh*0%RoXfoW>Cg_@C zV*)IsVm!L=+1>@4n|7T#qS7H&c6GpPsw9*26+Q1ghH=x)a*rTN|F17?4Rfq6y)FxH z4~dZQvGxKCFwbg+hXApQY?_TqHi}ScPKnZ&z7a*v1hUApiV8#)gTV?zydq5)!ebha z$2H2g0 zCe$lTXzwD>9@RNNCe@LkaQ!PD4Vvog*2#MZc}VQRxqmZs zV%uYtdKx;HOP^%nIV%Ja6s%XdZM5e*N;II2iG2Z&^CK~MoZNW70;RkG{mD?H?6D;l z1}F11$`x`j59Id{==wlGc+5Pi>9xsokr>%s```GM8&!2oVn+Q*BO1n;H+qX?l)K=T z(=tYARZs8z!C1W8(Y1b97EeCV^ z^R$RcY}R1m(;xD!sw||Y9m)Wvu>Y*2Cvg{WmIo@>_Ys_u`lwl-7`V;q|Mv+d*f{wi zqIoAcd80JkJ`i{Qb0UNc9zFy^uSBWkM@ z%kO80mI909%wh;j5wKEt2XHz(qJgf3j5nGT#p?X`GP@2KHNDiF>>NT~gBlysAxoua z2vM=}Fx+ZBSJd$X7h*5oJj`xJ9P-r1ydJS~ceYndo6`phg&3NRQ1ilbwt7f=mcGvz zHP85lfmp7KhOzZH->uJ-9(3*ONhVAA-mz*o7g`_?r(6xRb9#goT_5j#&Kje$sUz;@ z$R&Jwg<3)}haorkW-rJ~gYem?pd2k?o9W-4XJWY|ae?-r_=wQ1He*~B=Jq4PU`$GC z{^(r{h58F+H7>~MSsT8ixbPLAtHg4jA9&CZu$*?bmj8X)!gS)^<^#Yugci2bcx~ig3Ke^EvmzV^$BgUcUWw_5ea*~eb;Bn8qa+M$nBn!UWU^j zDVb;`^t1lH^vf{-sgw?K)t&t$H$peeX2qx%7OfbSE2|7;XqglqnHQ6*dyUk0Sw5H8pWPp-L7BTphXp zW09$Tz_oUdmk)_M`xp{@ddK2a3Bxr~D!}g%KF?@iz{DBOSXd-|Q%(J%PL%o7Er5S+ z@W6NN?g)=;XDI@x8pI$4ifCVMweZ7*dEoBV16^MlUDr_YCIO!g9ft)QFb~re8(^!H zC&xGgjM%i2z2M^GT9d0zJ(L2cKIu$$R(QB!9wkMK*z&5Bb&p)G@cCIvFs6ZXHlSSN zp+I-$E1^i4jW_%qZnEKLOh1a~LSaKOq?MzH| zF7?O4RHW5XrS)-RM%ni{X}PCpcWe}P{OAIUohE`plFS#M!-u9gCUsx zKpxE_&RxPij~Tq6Ud#guT7O5YTTik!h*?9u2f{`_j?p21vnADY!GTKBrl_lr9Sw73 zOn-MM##Bs>6R5JyIRoIir!3{;ej%Wn3ggmoDDlIvqnpI&I1*~bVD6tg=N@v|BQU-` ziztW!?&H^p4P)jvag7&@Ufirmg4QNGDvP6*$|1+cSSa5ksbK?OJuf`=<|!P+bLzWJ z!R8;x-?lan8y5cP79ruU#GQ{9=#9y(;h%7;Ofa*v()%G`_JMwJQsf8JF^*LC`h5)d zAg;zqq1Bo(IjDI)4U1x#;;Bv+(8uf>aA2H)G@Q=K9#ua~Wuejhfx~uz&SS|#vT$~u zJ&}GIm)P6exG}@DOSEI3cbA@ZW&_CJ$V`xeO-_S}@(w74$l4DV&Y8V%P&>)-gA_=X zajsK}+=@nIJ^=I1#|(4}{M>YjQ-=10kn=cq>C>ZXlRr9?ek=JV;4~y0r6H!)&93et zl6Th6zi?PvvJ1ka7Ss~_UZ5Ui8ze&O17te3lGc3`ys99dB&mc+r#N5^Ze#aS6SN+e zA@F11m6uQWT5L(|e&<`SDwXcCNo=+&KW+6u zHrlwLpPz#RCVeAY69hteA15X_D+RyBCR1UG4*oGHr#Q$$48 zFLE~+Tqu&&=~U5_xQVmURyvncO1e1)V^jXMtblT->g|=~YSN(NY80g>;PL`crjoK# zASij;6H&M@(`ra|QJ>t3pLp39mHmu*!M9eV;zac*u9k@q>Br_<)m8}_^t|sYk!s*D zh0AcD=Qf6z0{wUlkA=ty1IcI%3w#>s$ZymQ#mx?NSD_=TuMn2whyx7oV6reJfyIX% z6qHzylV%qszjd3)3(Q%1HPi!47YbXZwb~QPNG%U|QgI>~iS=RUc&VfLu;x5zsYr9M zTVG~ZT3ogR3G~B2qpA-!lqVdQ^H!hSz%D@>NtB)xh++ieh=s8) z&l7}=C50ZpZl}`KcF5jGV@Bjdc3gqmkhV#3=$!CaSHz$C$*|9GYOm*S`)a4%k# zhAj0KCJ43hptRCO+}rF4Z=-ka%A)YnjF$vTE0y)mZLAc9RY;YF2#g=RBq*d;mB0ub z0fc#ZlY$WbTuixBB55VS@puK+IX%tzmXb`#cxkzr9153pE`P`y#I97`y3*SJVly{;Z?2Q7pLszl z?n?OJTvUZLn1;3&GLnJUA#_sEn*wg$#ypRxEt#sFLsla9I%6@0e4WoGi|dZ2;_c|s zzW9YIODH$DOUjJ4kir|5(RKo+ToA{rJHpvx6%XtiT5Y%?#A!C$XzCqLzj4^x?B|L> za1{xT;%jBddlJ#k@4T(^&pb-%RL2YLTpdj1ygOr$w^&N}=V_(ke~rpt&u~0^!tY|b zgC$L)gLUv zW>tr9&i9T$o(iERXgqvlfvqJ(sf(&l#jFI&{}=Av*T5SlpcgWiymcImyT)Er#rjNP}=c9wH-Ii zF&b?xSAqk;@WHcIVYt7$0F_?dq-6}RWeAH8?!f5VaBxA6{B5SU!nv*!DmvEsVj1}q z(Yb_l8xFoaWZZRnxEL5rAe8%rjTD$Qvala&JcY4`}3kB!M3E?%Ed zlc2?Dfr2tUff)G2b@dav@xz&a2DJo?vW=#AvZu;`TQ6*U9BA~T!E(T#d1W;1N~I2# zD`IuHtOGQ?uCEfM4Ye>!QE_dM_;S>%n7AjS^s?%(UVH&3q}{^I((Vls1Ha_IGknsX zu|}W|xn@I}O^W#+5M?E>w3Zi)RBA)ib>avP-mjbiedwC-E)KZYaV1>PWy2t0B;T?{3-zx{mAsShoVN@jXIr4Vb(kJmLmTSoO~ zI$;7Dk8+j+9!NDn9lUCC>7I=E6&^_+Ef82d%V(DRz*jZByaF)x6!+4!kc6A{v_r9y zDLBdt*gop;1Y!X!G1_~Z9pgbSSM5VQzd-zOe$R@D-HHBPMfKD42b_?p^n;ASaIliX zVv`OnaI88gZL5tY)7F^1Q&pF^M)6J*8{qMZbPNnk37gF;aPHQFva9-{=n(>`XK#t} zTH6^ZF;0*Jd3w}k^keuh)4CuqiO)0sNmq^48KC+Pt9}ZT4$JTdUib%tjyoe&n1}~X-l7BS z{+a-C9JA8Yvv@u(TnTTq{nd@cu3^j(C*EeFn&|@uq^?Y#30#p7k#@fYrAH=##t1D! ztJ5Ivh^gIiwQnNCXr^8BRafsoWLMm`p%{HtYeV6PD~1vZd+ByM{s zu@(T5`5N2G2=L3KRY8Mz(5qr%g+a5HB z&jYszR~c7UlACe^;aK0ilwm@MYCh<3ckguFI`g%Xt;P^?qW3yxE`EBVt>(T|2&{2< zUI=yJsH~?FUTVr|8;>xOu4CGb(l!Fz9^8nB8E;3x?w;7O!i#2&l57oY&A?;g=v%fC z>3u_J8OMC0xdS<>Py;8FMf6xwHT-8KP5u_vz|nIB^l2K-G^O2X5i5;{)ejYd>~$TA zjKJLhzt9@d6j@QI%(&!#N^H@UoVo3H3YbU_Br!o0hi$q4N}-JfT`KqI;bQPScM})h zwaCNu>1z}A4HFId*S>}XJ`jYjPEJc=e!nKr=arDU%wEA3!7tDrMb$8tF7xE-2r8!e z-l?uLeAgOX6fm)dOrKI2*U$$dbhoF`4k+bTI|PvtjAADcMv3?YO_-rQb!8RUmW;jw zQp_kUh;2>P0%B2uK;gk3XR3i4B%_qAMScVM&;Wz*YVZF5!>8y)fJC1ll6^{;#G0#$ zt#J4PLkqT?a31r7bJ1aO3>OA`DnRAdfd$p&qqNzv>R;qarq~yL=t%f=n37G+Q_}+z z{On^)wSTB(d@JzU(cc?%#`sMb>&Ai<*K$^s42V7Ypp*kEpy0m*=w61Ywcb`7Il@oJ zHv|w2*Jhxl-((rA>jKOzt`#Wdo*nDY4eBR$;RnA|_-ripKJDi=&r{A`1bQBaN&_@1 z#@pM}6TAkK`Kn5*wVj__gO)J_(@Ssr$G|fHa_l?90se8D9V#!-NL)m@;2d=ZA)=}7N)|XCW#Nk0Jk>y{%oWFC@?M+@ zicK1`pUKJ@)aWqtL-+^TFU&ZJc2hP_D$Z2EsA3+HcD#xk5^xb6H$UXFFYYpEAl~5? z^`zO|-YpL8EH-}_4-DjWinqrLSy1y;d}y4poU8!PLxy5ckS3VFKWLDx0uZviC!Wd+ zCvM8+M;6*pzY6lPp-6uNzJ*g@rdf9ws^D?ReQ|wi_qql!PMLq$C@1Col3)5Hw|YqzDcb{ISoazE1#!!`m+LtvkfKi zu+@;hi;FZm+-smbD~uFP@IL#@L&AOpGTg2GK3wRZwhKKVkS~DFR4@xytE`Zx?n#H# zf46D$mnY8vEMYYpRp;U|;w7p{!VR!D4;YcDRb9t}OfSN=^5I=LXCru|?fwP52_v>i z68t%p_z>Nf)!MfKHLwpe@7XX>RTrgEQGjS^R>>mU5UY7|CU=5+5iO;6IdOR>mzO9x z+Lb$&UR8t1bt%W|qE0RR3XW4eHSVF?3*^ux&H~9RsGzVRb8goC5(cXBEm%LM3u)Lz zNWxoZ!>Y{UZPjS=3ns_G>!@Pf)mzS2L1ga=t-7uBNeOeSW}Gy@+W_gnuI|~A_=Qw1 zF3+qIFq7Kr;+f7!*_FY#F(T2tG6L5?0{9J3Fb!TW2f># z&b-zg8eOANKgfVPht;^}bO6uBVVp6B5n`L^t8-NYEb!FOP^<22-YwLRe-!vP?`?v&H22b@Wax_FH8DiB@m6) zSaUa_cC-dU+^sS*-T`F!2Hd;B;p^496S5BXkJIw)+(g`_kDWB1Bxcz<;$;VyI~j*5aR zFaZE516o=q8k$$OHenO3|s1jRSn6+7eS0H%_CRYTn}GUIYb)3&wNz$fU+b(xXI(J<{%9ZoN!2YB zrZyJ(;t)$Z{HOTtio}Qm9mcW2DzT%0+*adq)s)jxe!Pvv2t?OFM%_U)W3?=FH&O?0H0H zl)bw6GD$qWYZ96pjcqJJN|0{rt27JrU=2C)Gy~|)9mkv+48_Em-qnW|R8MQZDKs?EkZin?t}JrcE}E3ocr6 zY9_ESEG4foo&_ru`KbJ%qQ(M-fnE&2{GsF?2^H~;Z`Mei%a?ez@dA~(Y;7ya z309HeTDG|H{|#p?OH5w*bZ5Sq13Gmz5KacD_(+MQ)x=19csO?NI_E#jou$wmBJV%H zO+4q2brYV+%zsC1Hkbf{s>VSW*6T8FRvwrHl9naGM>w|j`i(a?GG^*muVU3xBT)QlllKG}}9T0^m@ww1zJxGoVG>-k; zXh;aT(FSX(-;i&?okbcEfH2#aT}?Bxhpt}7*O~?lFNLS|E0a=%1$3j3e%G4;*vd|T zT`S}g>* zm17%iNQs!@u4R8wfDz0>STrXKmNPizFBZ4y7o||l(lwnmY@fW5sfx-q@6l zkRGQ@c3{uOQ)usn+&hF4OPxHvMT?i~59S7&Hd^}HD6`g?c;VP$=)2t=Ch}VilJ-Cs z0u?Y`C)R{*I}8%z#aaa~t`K@F(W>$rDpo+$jus!mjxM2n;_AGWmDhLwLIN?s4gI#-`FVoT3@1GOaS8}PS;`FtIR<6_obUgeZ6j2FK z%Amj>gyS05@RKJ_f>v^JEz@ z7&3HS&@M28x@Snv{Pt%n|Ack+#_FPws8JavGOXrfrLw@Efq-dnrRmu%o_NxHu$D6l zaUc*bN=zDXTPu5SGDLtp0U)caPAd@^jC2Qf`Q}+Dd_~(V_9>aQTh1Pa4%wvn-M4Y| z6V<;j>lG;$s`~})#te=`gT$o*~+&u)_@;a8oysL4EP3w{v>D34e3;{60mNlygSzUYb0`{bT2- zrlo5zK&huth_Dxn9hh*^;K~nChNh>CU9-IoYpF!A(cEM(sUlY%k+t-HRy@ZAQHV&D3*SHYZK5uCJr6LYoTdXY2MX zs8i!!#FpLAl3yo$_c9-nedvRyq~8>Qqk}C4cSP|dBK-?hA^v+W6ovOtjmY)r9lQB#8i=oMb$Qrmo~=Q@Gh}Xu%;*Rjf2CbGC%nUyVRU z5k_;9^eK!dIf|SfG9(qQ{nHwvKJKRj40`vExeOt|-*#t5No2hFcOG?PAyW0+M0itZ z=Sq`EYAO;Sn3W#w|2bPY?D%4UZ0;r**P)yv8?;3Sydi zjWiUw5PAKf(j6rY!!l@D!&dJ3MOR^^$y7n^wstA1u_zjh^8{p`a`GM~}}ge?5ufA^Hv+ zTh^(MZl_do%%8t;>h9vsjgj0#|MqyILUMDqRHJ7c3YRYK@3^<-wm}5Sm^;xAZu4NW zQZpPVH4m-rLhcaEnKBKm6S@V+8$FmXgZmuV0UbMjRg7rZ;rI+v+9-_lJa3tM-8bAk z+xKsx)tb6Hjmn@?qX33l#0g1up@?a<>~D(4F8Sj}LC&0~mGY9OPm_^0%Q-kDuyS9q zbZsuC&3Ei^%#o1+K8^Aup#4c~znYQ>SVbNkG}zNsrB3y)GVN^&MJ>+H!_$yXWX{#W zu`tQQ#}pm$@9cuxz<4~7v5!(cT5i}~y;k0kL?OA3Fd#9O5ABq#b-z+#^o=P32M*1g z4Z{>*E^$1I*}InvEod%zeeJg6BVI7=qFRy@Gd83fePe9gYqKH92-7z5-vm2NCiF22 z|8aG(L;)blVBD| z6QXiKou)?|G;N;&U|pG~$Kt#k?DPgHq-IL+9e$SgqLr4i5UFyV5>0lsU^&O{5&}I4 zjAikZ>8$l*VDH#`Bq~s(KkS%^BB^lL&GYxTJCjaHXzbq|loC+95BCCikIKgDA1{XIM7n_eFSqt z1#>wl4pGV|6?d7sZ(AV^Osz5HBOn-pCzAG0G(&2Pij%qm>82VvB4vY8lO+Wmm zezb+XCm0RRcK^GH7z2sHIRO^Rx{4XOFh$j?>b=_%J& zV_6&o*AS5qO;J95lEuO2G%c(7skiKgwSj+}f2&09=4-++cPQK~!Ugl%@Qifbm3dn< z1nsiphKV8s%;5OP29ZU~K&kaW0#_sadB+^WH`-ext=TR}meMYK^gbU5WF|XNE$CdZ zv<|v#^D-7{Lj4k*spWkEsxh-K5bJXcAt2tA5wvwr1Hu(U|DNPX z28N83TW$oZ3b(@EqHOG~DWflDKIe|vCitwf8gs3?t;mpbUyM? znZ7e3m2bUYnPovqCR&}0&2uTGC|HjaLvuEZ z%+kDgWEn@`f;aS{8%q`zl*T7oh$=~@POH+vf=&vW+rZlDBJmK)65dXW<^wi*sG%s@ z9PK&2`4Bypl?+5m0m5_=FdG>%T59h|TSVb7tJs8UI>uwtFilbW0Qd6w*Ei5CBga@v zn8WQ%!xbH?iK|Gu&n$!Po1X*(`-*bb(hO_DVtO+*{NNf)<1APCv$@YBh5F1+a=S_eA>JaB3vJ;#Gfi#0nrM@s$mgRPhn55?PiSJV z3XciJTqQwt*uLRA50W{9U>7%Sgk`!Ehh%Nanh&aiCQeiS{eT3jG@L5aAucDnW3MPp zzYm4?V-VjA4_|!e(5>9<4*mdn4y-}o?{DeV;RS!Hu_b})q#7(T3*r;n{hRaj@Em%L znhU`yFlDEhfhu9c8K&fsQ_;zi0Ijw7PJJI zjhqcl8L|aIj5U@~Jn0Kz6^wIqiYQ|L-pY>UHPLrUj#hc`a=tEH({3X~cOZ7c z)}5;rz{GY-T$E?LQvO*Pe_kf^MpvZ1MNlZwk1(sXiImhbYeT&kFR)vArS%BeOGuhs zP|dC%Z0RvGZWWySkLDx&ujZBL=StodI7ftb{j&wjbY)$olY|OlpV8dwn(I!QD(@nN zFt=RC7BOBl-WaLn*FHe^Uz7gAS&YC-rPbpl>uxqkUt@}?Y&+T1A8zfbgd?-sSbj2( zbsT2P*r9z^L?YubvY3IKULWk=je75XlzBUqA{SKHp*3OQY6gqa5KQ}@f=F`OYJ=Ak zIgwrn`yECSCkK=`;&4gwRc>RAK#4nq7&YYdCZ1MvX^iJ!VB`!YM#Q&p*$;tX0qVK{ z#AM9x6d_IIXX$sT`xX0w3ko-#B41uDJi3>lxopc8vamv*umf2jpc{V(Tm0=1t=5R2 zW<@i?19Zs|Pt2XdZf7ZvIE6uf#kM!V`hxxTXKu})-cL=&jzeMbcFkkmAnvo_c;b~^ zAX?X_)_o%KX}X7xhV&VDlS=JflM7*M;H2|mJLf2Nfm7Qck_Xw1;M*mm3`a7EqbG93 za-18ZkJF_sv!23&Ornw`d=M3m8PoGZ{Ymj;wCJ85FJ4D{ZutZviA-u$I|F=tU!ew4 z6pF#Dx@GM*L+~sCG1$y|iEWb7k1)amWMMN!J z$ta4@&D(Y{(wVO>(dWyM#mKg3DAFtQpL)Bo%~o;rl^#uHM(GrL?v?{caX{hP+@?P>5 zv>OX}Kb85JOWfSZYJIhRg|PJ>FHE$lVf@HZXLg!H4-?dpXH}HJ z!Rs?)!BRs@0tB8g~%N)8kUa6Ta)E8AOq zpE2CL%`v7Her;~7WK)e!>Cw2ez^Cg+Hk9x6xv_NdY4U?YobzHGFo58(MGlL6L=zxnqvu)#W`FRr>EY4dX*L z&yLjob9)eAVQUbHRDML%$HnZU6 zrdqKQ>#FwPViMGTGa_v>Nzzo8A`@pZX7wC3s2a&rVO|ZM$x?-2c`f^Si9`h#Rf)7N zOS|hVd1$dI_V^+=HCw)DJkXys&AT|W4ecljoa5k{tMWL6IeWRBVD~TG*e_$QP(7XD z)fV&>ZP^K3RJ9hFN5c$Gu8E((lJ!4Svcwbt3ly>y(fzG4t?r3&%+U%Ph`Cr4xrfkK z@o^n8doA6oKAQUV7iD07$XA;fS$$J7yl}SCm&%5oz2*zp@~V$T7_{T*U9N{!l&~^D z^iHmYs*>VIoj^HMzc5zMXb>h&jqO}>Cz&kV$(ab{r&S+F&GtOoHT8e$pOR#E={mb-Ry5=S>k7}VCc`6 zxNdmnVn_brc=vR6tWB}J6XM8w@^A}GnJr?NK~^Q(U010Rf(R#O)(M^Va=QVq}VP$T@z zmh?FMZ&Od+OxK3lF*e_%&o#y})nkvBXqC7lVR_c=f}+?#G|-VtpRU?Jt)7*jmQj;!_f0P?_De{c4;ONkHkOUA z4$W@abjI(}ER)9=GZJh{l3@ryTk(z^K~?FE9u8o{6<}9u4*Lj}ED)+>@sn}XDl#(i z#6l0M7%%GhldgWTKphz-HI$gmPL0^AA}8)mcV<{$?;>(C>r<9Bq}H!z0~CUyp#HZT zSDvNOjw_qdgn~c1732|V8gaRXD7FTU;24BOg%Gl$P>pnXX2yiU;n+5WDa_lKR=(14 z61E{M5?87gx!<_!?ooy%?wh{nE_IK9xO1&`-097hh;S!jv)ZwPOIrL`4ztPDiUO|3 zg!%vL>w0-V2fxK#>Den8@*{bk?a6YilK&X7r9SwDYpI6x+a|z6qo#(_E)55V(g;9~ zHZ}k&K-9m?fmWV|8cGx?qZFGwNI=QG8WQI@2uFJRsu#LAZH24OofoslbRGSOB3;(= z5n6fEnA#}{H^=*y>NxR@8gyTx)L_WMOH+!wGn?-|HQa#W`5Q|{pUzewm*}<@-XBg8 zWgN7D(Vqc`mdH>9x;9EUK}1~u^;N(KE@qxAbSJ&2_d z1b*WV5E_!pckIW=V5D_%84C^+$ByNJ{O_z~5e@V;K}S6HEqIj57O(Qe$H+K+W?6~k zA*ei})4LR%J z)&L=5YdXt|Nn)Q~&3oLMxDg(Yy8*;cwO7UCj`{c7_#?%y`=f|YUPcgJl!AH;Le?tN z9j=m98JQayryDtH37|{amY+x_&9(#N(JvrS#pbU^>dyF11z*}#Zp;@(JP*!or;qTy zzpcma!K#)?&Fho=Izp+0>0}~v*8DZv4-|~v$1G-#%H=a@d^(U)(%&EMK0059506i7 zj&03}4jTJwX(&}S-RU)>r;!V-K?1ST8%0G;jW;$4AHl)T$j9!oW=VR9hbRT#bD-cJ zvLyrabp|b?a47U#z=-HhOv9Ei?9mubym4*0Ue%vB2xaGG7Ut8?31CwJ3zkM}h~XZ8 zlU7s#rB%_Kmi2EXxQ^C{%Q8w-w%!B%r@)C@*SFKEu#4|qXEm9WA=;Vcow*CEgkd@f-)R ztO0Vuc@US`ubTsrCV>*GMN6u-$)-vus9Y1H*|*&ihOYyy0)4oNz)v`LWSF#)`evo3ZB ziV+=nNjh{52>(U)$=3*jw-scDF8sh5eXc1fV(@?bZHo#|qp5Ly+cNpz?;TT}DNgpMcubw5nelYm$n-A7^LtW6D30;%ZD*FN}Z^ zl)Tjew#!_$9$kB77#2yQG?}FDFgW%BcGEW=U=((JkKpw7E6AQ!ZeU1)%H1Q1lHAUPkRwT+y-!K3ll>7C zHl=7Rxek2!L^JNwyTYawYv>|vlA|h(F`Hmf@u-ThMn*Fud0IKp4x~3Z*odbnb$0IK-1*kVXKOY;oR6v>QLLuk{>4jVz1ZES=RdvR9t&#)CPsO}OdQ8Eo18qLfQgOSP}V;ckb_a|#Q*q<+$;%w{OnSaffxpu*srnXmI5bGDPj^{YAxikrU>pb)Pv{~ z^tXm;l+JwUN#JlRX1egS)TX#j5`{MbDZwkvTh!&m-x=gP2xZ<-sE54578F}pEj`s> zYdl><$|0i7?QVJbI?2XiNixr;Kv&&McBtqdyHm=aQ|P3rEVSAVW}a6}zvTsN=YS`2 zqT&GLHG2d6&Wb}L#o_7@CXg~QpY?W@fd9Y;9B>Alz-a^_Q$upFkeH)WO{;Pw^<2{v zVXbEC;ZRTev1^ZeQ;cGd5)&zF{N>zI!eg}wnjcsNiak71^u-`w*!LYX0BcW(DpgEmP4I zTLGST3oo0LFp%Kpccn%mnRbwG9kl@XD=7d^>24@D-#V{x2)gN0yWeM}fyr3!Q)kO# z<@H8bsG#M3Tlk!OH(oR_7p1*CdqxY$(zq8&eyv{H3YXg?n>Vk7zs|P1Vs78FHa0@w zWQF8$C1@c@!qPsem}ZxreYvZeh%6qe%43W${j}*GgLt~Q(4um{><`{lp zSLG#}E2L#;P1p6F+)Dgh0g$#EhGEAB+T$4gY?UuTsUoQ<7t}d=BKfuQ6hMcjS89x* zBFfIepU2+~)M1XeUvzMfFvrL;ri%oh7I7Q`@bp3*EB}K6PeYQ)pi}(oEeLunb+w=zd%e+;9~MXJSxim}aviQh zF>)7mqz)rZ7t08!ZBQ)2ksLP3Pj7$BK0ks~P;TPQi?)^`k*G8AY3k{4V%{JIi{1K~ zP=CDT*%7Jzt%`eCHD2#kPqI*-V2zmOCfKz;$Qde*wEhaol-n_$h0CH`*hU;q6URanodm_yX0AK2`49y^%2uVhGy!Z*}`~Rx&o$Nu*5qd-e(5BP+ zGYd~u>$@>%Tj~Q;*Wiv#61%sa%f}xd9}@av3$JI0__f_f44a#9X^tGP1SIxJXCL|D zt!nIZY*(|f`HgLWoD=>|)E20m_d^}TlA}C-@6A-Y| zw2qft_9QW&HSM{a!q%y9V?F}nBL!t;K5xgDx>11xlLc57_ z=Ov8PI4rpdv1*w`HgiXhAz<}Z?}LrwGPOziRu{o~%o|(>{fpX3|;cqJu3LA!T0Ji z`^Hao>`7$lP`HrXhs#Z_y&kWAlGaJ)kQ?LtLK_ zkNbF}pgP*bSA4Be_>^f&@2=&`#l7{!hX9n;i_j*gV_cPT=_j{7Pw3iSOd{HIgl~aP z3e=)DTbl$(`8g&M=f+hhl4#Z3fp^g-MwIRqmHdB9I2D)9CCzEwopy&Mb+UMzk`+uhjjW;{a^YtRIy@2}{Qi** zvmf>!obfOJvN@nhrv3(hq9@pRYOU>lb9(S>Tc89iBD=Xi(~!v`^4MXFxr}o4CzV+& ze5VQjMk;V4>-pBK!{U>~-lO%R{JrI=QzO^fAZt&Xfc;`jF-1=;hw4dN$5?xL-3u>I z7J#>v%en8IM7dhhDC};o>Qjrc4Kt|%EHg6qEX>2Sh{;)e zG}+MukLam5y$?rpFd$6sr84dgPkTIf?Yz*O&NSq-2l7vyP#6g^hXFkXUjeDa!Xt~7 zsF4NdD{4(3LVLD2J5ap&fZ}8|NBo>LIcskXf$nAw%mX#OoB50CozXZQg{zSSZKe<9ic#ud zgDDEe(pP&w#&TrcgT;H+7j-r2Mo+@La#%D}J}zmCNm>?BvK#DuU%Fnfj2)W~gK%)@ zdUO1-_ZLpW0YG&Oh@cj0RfvRHphY7YbunfbVga|+1(erQ2a|67>+gnL@)r9A9lnE9 zaJNI9OhsL*cdfXu0wrK7F&2hJcrcVEw>h8#9$z^v-LPqcn%k;KPuqJ~)Q0E4L~U~V zI00EuW50tQN~Rwb4pvThxny+zDL5u(%VM!{6`Vk>t0TtYequph&aq;ZUVk?)iF-Nu z_dih>ILs9Js)(xo9OVT;;59;Vy$8gg9(F6{< zeq>tu!A|wb$d4Q$==y9KG_(1-W8NqZwrnE~h9Ej8`&s)1v~N^4Zn;RHM9ssgvqHYQ zs9=-rj?0a1MC?hyNUaJ!%c(K2nGu2@GFQ`V%P!=6n#TWW2O5}m1(FbH4QDOVr0k!X z3I!p}oA0$9O=wrdxQS^LN)i|3WEZhTVP=GN;m2YQIsV>1t&vjGQ>#RjxH0Sc5t*`= zLazj@Ib;^(Dsrq-`uI4}q+-v*cpCdaZu)7<>=z;u?N`QdjmhB)23 zh9y`O@tJ&bskj-JxRXG-QNw}i=)#GI>}8<+u*@|tmjm1xp#g+q;JBEB_~~yeNSRop zd4>-b)H!o!Dz#ZA4uGeV7(1{s@XfeL3-!%e$PCC^R?W>GG&@|$#flmJzFn?@5ke97 zYFilHJxb?s;$=1zQWa1?l%0Q>j4^WZvFzOSZs)NtZwB4pyk7iW{_7E3joGbUh1Q>y zNQ#=JCZ&*&);UbLB;}Jf=xSJPOuQ*u-`aTZOO7$RGsK+okjsdZo$5(RDpt^fbknlG zT*YFI!~5fp=2P{MxqUPa zbKlL?7xMT+MarifrK_X|&ylk%QQtnIfT6NwU**1C$LlGl-dr#$aBXGP3n(lHsFSYu zGwZ7_qM}Z9RXg?qbN>JmC%@6S@BY$Z*l7s!w6AXaT~VolM#$^AXaDEWw*4EDK~rtY zxe8*1dwf664!T{87IC`E);+lAJ|wtHm-lx?l`QJMR%d$5LUNY<1w{VMnrA?X*()-H zjd(5HYP`fjME|8}G_xD)t zX9U|sT+|9scI^F&KMqv$D(->xaQJ4rAFtdZ7FBNamWkb(2B|!!BVO@GbGuoAcL#u2 zm>dO)9h0xgq=xEqRfuuoX?E9(eDEW52k6+T1aS*FjLsfbPp#N$hX@k8?(K<<$C2xk zJERG8e~U3R`JFFGbb{$rd)Q2k$Qabs&-li}#yrq9%&s~=SvVsp1`xxPgsNQ(!4{(} zoIQ>RuEe*30Ce3;ps3f3GXcL!NV66T3A&HnBT>NWozPufqpQhQO2~Rb-A86GbJ>QTprJu4?<|?XC z*)2TZZ;agGw#M$J4kYsY$-Z!M)U#DCBAoZYy=lNy9L2-N<#yf#mRWqlV)CfV6tMe# z#4vMa<547-kUhi)$g<6iQg^BENmRY6xF7hbEIR$VE6_jS zt9ZMh82WF^CbcjoT#|UaMN)&@l^|kV?7I7WGgMjZ9(qk}1+)2*UT5U$>ibDN6iPQI zZ#)Ue0)k3es2>S$(jY^(A6X z>5nEQ=v|Dhx7McN<;^YSFrTNuP@Tk&26Pe=1~6MU>-XLT;keLerML9rrq||y9yQ^ofa&r3c~#W^y2 zGn_>%r8;gY7MIbP6SjX?BC%9{ZQ(to5~3BnftZKg0dCOUQj8jc0JS0zG<0R;nnI2? z=azD`czmHi1x35M4v-aqMIp^`LX780e)|nz6uuMao?}FL`MNOpChUcvwJH$}npQ{A zEH#e{g#*{hg5?y;yONkQG=}F88iKGGyTjf)U4|&^Mt!yPf#;b|231W!-|;dSKg-jRF^&B3OQDUBK80Lj??Bq&#!q7T#V!sc#jQhz?*Ch zGw&_<0m}aywilIUc$bxY0`X8_0tvnU>Mb^JbtTXTr_8C7wRNJ05_Ma-hhyta?S^w7 zQAd{o2deBCHms?Oo&*2dFGrmH{9Cy5N<@;-#cprgNWkv?NjP$sw(J`xI7sag?svRuev0orOw(GpZF(=1-pfQ4Xh8-=~jV(H zTa$Cjmuc9D&c9-^1w?B@s9K>elX1Zx5FoX7f!c(^FFaH3CIj2YF$u-71%WQ6rXdD{ zR;|#^C?nL4q|mb{G&i`mwa1l-qb9vj*k~7+0L_+G6w%EI2u@w8Lz*+5SHO__cCb8G zrCA$~K*MV7>fHokr`i$x*qb3hXy^095Sv63S+0s%4I3b59YtG}VL|PTI+hPwqZ^9X z3av<6S;>@PJF^-zc0{IS8*Q1ZXSS;uAyH>?0M6N5DMZT!E(G8!+-##VyU|T(n{`Hs zjSCJt4}M9uZe63NATr(aY(Nae7RfuNLbwf3fc(d&;=cAx5D^0x^V>ryxtV9`m54UA zD2PIxo8^hpix~t>w&{N_UH!%u2|udB6Q-Y4Lcr%ByOtr366}+_AF1dFGqjEmgp|n zH_FgqT2-3Gj*@?g9$j+)F1eg$Ns39JVSYm~41Af9M{pw`N1MI$Uq5O_vAMXgy096B zr=3?U8SWga5V&+bn|u#uUz3dq8wV4EniNVRA(LQNbBMX-pvPTS53QS23{RN;fT7(> zdR3&4r(>$fJQ=xGtrC3?FrlfkG%h~{ps4Vy#|j;^Q@cWgeM&DR+tY&YW<`#DQ+_jy zD3Y=z-Gfcwl4bKt??ER@4q+SkIR5oBXz%zmx?j-X0F5-N^X^4#6XX4&HtP-NkQm1~ z-p_3(QYM(iH{r*pde;TvwJN`w54u!Q-QV)s)a8t&+Fc|T6Yx>;0p;FSxe4%3fFB%> z?~x?=G)Irl2NSE)cGpQ+_ccrr(rIV`6Z?O*U%F-66WA5%+j09!{*rI8Lda+45D}bSAcfYFj1&kA))V=;sv+6z=4|}7IM$bEBVAmt zr3V3kGgY>eJlnwUJ%c858}wis`xfuad}7x-&N$srJBdNPR>&hnLjzUZ*{=ELuTlEW zEGsp}n22Si*`l1C!85pa<0}i@@ST7odpa2IYcC@TJ?^$wGUZPIDymYiIqWH=-Y#dH z6oAqnCtZahxCnc|(WsjiTtW`Q)HrJ@?dmHzYka~|DGP$>AoFljlCmC*M~yf!=w5S+ zFav{+oVl)-!fWF+!M+Bv;Bh#$yAM_f12~_I{&P#Do0dbk6mE%Uk@FU&8D7`pF?K0& z0)0DH*=ShCtUYO<$j##6gkMkET?)9XO@~6mwMu9xv*?hCS|5ta;EmmP(j z%%~G8W!37=>$p&`P7-_ zqJ}ImDh_jEkXPYz0}7ElA$2wyxWgF8=L0nTQ8U&k<$G)%n{a_22vN=lp;FH`Vfi_t zCx|E9W#*Uh@{G3~LRAho@zdT(o2Erwl>{SX48z6CuHL9<7BafwU}xRck*^Jg5^p)V zbJKCS3j(0^de4)#CG>+W#FT`G5*vVE`4P_55_kqUHnY#@$I2e7VYAlQ4n=7Sg8f{x zuYoT|Z7_k31(8Ojy5lT6XhHPf)VeSwfZ+PP{8Vj&KpVp{t3y=?F{&j%5<}AznOkJd z5Stx7wjX1y0of!=#6`M!0N*T_8z#F>`!hpZQ#M4?W{~v6%d1$OB5qau8WLE;bH zh$(*s4wj(@EjIU4P8#Uf3c*bZTSxQHX@vc37uZn9bPFLOC4koJ05#{2FY^fij%|q( zYE>Is<{gYTe2zNCv0{>xzJOzRuN$VXc6sU4yhKc0>6a^}Y4k5$#q-Gn>u`9|wQRNr zN4^g3Y_1Ln@nWP64}P)cWF3@_Ry>MoNgiY;FzL*#=>a0UM}pgc(Zv;U;SIV%{H8^? z;CZlBZF`s|L0PPF z7ctLBtn&XvW`m$iyCq4di2W8WAEt9@-Dh<+vfMn^d3<0Ko1}z;XduyRajCA(r)x$u zt}$xgTn`X}g_R35xFPVXX`-05FtTJ#6KpChC;9(pCnG}$ZMpF6bT}>k&+7&r-{%wf zdb^K=ktJndc0Nxta-XZ@6b)1!zp;?gGwC<*hJY%AAg^M-sJEO+s5F@N-j8viV(hou z0<2hFblH6JNA&=@Rii!II{C_nEt^)H#!PVGw1^H>2u*VJ$pig#aBPc?Ro)U2BDY_b zy{(pQ4HS41K?N`;QQKCwa`RT`(7us{9MVtme;)V&z$59YXRQ0@rI|d>Ch}KWkH{_}Bx4ScIuoI=! zlLniDK+EPs29)@MkaVH&JTc&P0qD$cWeFJIsXzq5s{v1PpF5K|7l1rhr-82(m<u48WS)4}Q|{N^S|WBgG6oq#NlM>MVePJi!3OBVWD^DVoz~A%@nKp9Ha_XZVm2 zCBu7K6g3~l;A^#5p3rz*oJAkK44gb$p}v1|NFG$nuhJ!LXcdy)^LGMXwr=`!j>>?x zp)b|5;WxTuQFYY>ZeTfOEmC=8f-b#>%XZQr?Am#&eRHN$t1M4|ghUcZ)QqG5A2pH_ zB7s%2({@c39R@O?0(TUK=tDa_E9Oa#9pN8h$9|Diz8vf>wo8c<4r@Mo+ntv6)j22N zPFkK-BMsu(Ld(x^T}>R_R|Oq20Ai7m1b5PoiG{Eu0Hojkyiey5iXFndyNQV=L<8)> zP=T%?Ow55IYJs7;q)~&w?vFkDLKi&@y>Itod%KPN`07#ZLCdIOomCeX{C{tMB@-qe zdZ8VRmv*LUVRQx~g5g=h&%bY-c+oH($PFanl(a}PU%k))EG{I5-16R3`KBtV=;C5Y z*rv*=v3~Q3NcefiQJ3{#}a)p4=N*mVz_)ad!%Z+N?0gSFHlq?Lmolq0-F(FIi)qeLD*S(718G zT}UI-0d{0GH@MPl|9d-XkbToi?7j53EZRCP$GM#uA5bOyEaK4qtdHU$vd|;xmYs-s z5INo-#tI#>l52{iv&y`gi}?8+AfrAy^Vj55E@J;eS>_CN(k62GdwU2@#}zEy z381KxmfZuB5Q*bF;d2to`HKuM-}x)k;v5q;D`aeEK{yaDT4H0E$R)hw-yRLb?$O&) z2eqc8E_y4a9R-^&A+XF$=jKNhaA(RaU|j?fy#x`W`$Pvrs5wTS@H{Kt(XWF#vZZD5 zzL@5KcI$P$7M?idcO%zlZ+Xry?(g*jphAwYZc!WX3w~?r!p2nCyYG8Q2n7d#`m`n3 zY?y9(TPt(@5T5E@`}_A&xiAf*Vn!wg4Z5#ssLbl<+vfaF(Qf1XQ0V=@zQW4kGYjx< zik}3WaI+4rfXFRMgbY_3?oyg+^i2ytiE&&nrKpg*s~s*=xiKR*8t=rBIQ&y&ez1!m zTj@ZxB#bx(=;ZL(2PP3v2x@A2-vSC_qC7L)Ko7bH&pXEBW)M|}XFma?Zd@N5*gRij zyKi0!4a0nuas+TfZ!hm4O@x$uX&7T_PVJ@<=FM15oA-h=ycS#wrdDSIfM-fB`C5tz z1`%z7y%tlV-cR5J#MP57mYE>Q77?Ig6ObjCJv1bzAdAfbh3=A|c~=E}=cXywUuJ|g zp3WYL9+oB6A*DwsiO2X(ty(&m#|ArWCdBg;X0bNVEpbW3tW#XiUy?>yN$_qN$vI>L z%ynm6+7R(=W#XCW`oo(4c+Hc5BFyaVp=W-4bdC&JyZ#r-_FtL9I^hUtT}FVAAR8@? z4W{_I`4$`%;iO%>RQ%&5!C(>fuXzbbvrcY0~)&099I!92Z4_LbmH0A{P)Gav@-wcO+ zS^00JeCPd+K2VxXI8rJ0w;?n31g2?a#akZd#hg?C6Ce=^Y{=n?^^ z(rq=O^{KpN3ds?6MD3se)itsXxiORoBC=d^1>F^`pl|IdZ(CU}ty;bkd zDtf}*uryHA(^tPWNeKmK_R~(8!HFH-KN<+@R%iU-rW@ks-$clnIr%I5p4ah8Zsr{k z8zJNy!!!Pn=`yrD{Zgs`s;J&82$`5kUjaU`G#7$@uppV1WwGld5?P8v6FbQTAZ35w z{4Kap%y4x_+KYrk5*_$I+#aPEh1Zf(BSPb?v38!iDIrgHR5+4dtmZ)p8)x@1U<6-c^VK6E&mu^3$})Lm0^LpPRD{>dVkR zz?He;;`LC6&Ig4!5vSWNKBgq%-6_QsGCg=z`+d3V2$TponwYo$8cNsQ6_Xxd;i!73 z{>r58Bp-i4-^dfcCMM`R1jrWYi9vTVWWOLYeC5*bE@xB%){ z&WB#X6FvML-e3N$fdjYBca7T%HoR2vFBV``l2)e6jq4pu22*Y3RJ9+w~( zN19^k+j~MjWaUAlgsokeE?20h(0=_$`LK@NVWs)nP&{9C`OKL3??nh|%{3pj2@8^# zErvDGdFr8_)hCbdtWhqvL$bb(4LZ)jr0G*2V)EQ08wGE(P`J{2NB zfFf1K6YsKu!SUAXbY|0*o8={C?_s0!mTC_^Vx!5LT`l|Yz7aC7sh89)dH1xF7es$> zHKJ0uz6w6~-MAsmU{KAsmd+Iu29_ zj=I2SrCeG0g^q;e*7Q@8hv&=riYz!&SGYHUdr;fcX73q-H zo*$KqV@ZiDBg(i`qevNbpuph`ub8Jg@xWZ)=koU*a$l6&^-zIxst<}{sx$usnC|k4 zAlWQGkTZ0C()JVQ*S05eB_;Z%pBrO;yLnFS+c|=x3QpKg42!kOD*~>#C;IUZ%&VXN zz7!gQ^t0&pfI$Kbuffmro1j?lPAoKOtMfl9%VN(^1XFGc?pM2Oqeghb1_r-JD+B!v z6{BP3$>MG&FeIHQ3YA*CW7VGC?5kQ8*#X}SbwrUTA6YQy@{TA^PX+Jy$eax1^Fo+i zigq8B>st^_fWTrb&5YV?OeW{E1qL<^`|8$bp(jV0Z%pR;(Z(caoM?80OS)~u|D$K5 z_Am5p%ll=!o^h6_jgtR6zOgm}?-@nTwGQE_o7#QQIbg-*%%{#sSuFSPY&wY$9Mi0> za9AmScxWIAOsO-rI3Bn0dqIKj^==jfu9d=DR@c&-(Q%u|eSQkm&dSpS03DYO#Y{1g z#i-Q)yWfv=z8^wzA&(ZLI@X6y)n2r`PLPv+0@gY;>7IQy?1Rv!4^2`M#JW^C`^~a4 zM4f6so})QgtCf?b5*6dfqY5jDB_feUwv^WTT$ex)%-Z~GsNcR$=g8z#TL3lGU({!T z@0ERO(9-$^`EWaPu?W&QOa)>VI6drfG@%*`kok!a@B-Ei@F>$5Wp4YstB8)_Z{UtJ zaeFLVLl&F-0L-(N_%7^F4T?b*!AGold5bff9E7`eQ+bhjL#F<#?N5Q*<`*aRvI{-D z`gsi?5oD>ZG=f~#{z);}L2&nQ`gR#wBaNDD2MV40op;lRTx|2P7-5022n1QT*dMpk z(?cq@66na(qqIEIH0D(U=qbK&IlQC!(9`C9c};NBOt6A+(YhVVLY@0H=L^}7cV4RZ zkd6WTR^ynddghV=4PC-I-`6uAA0Sb@{>Xbi*d|CS$aiEYrt&&X9&!xBWI!!rRq-`H zM~9O5+w5%=GDtd3UD98oF?HdKP#1A#SB2*$U}`M`Z;bV`bQ$GCrPK$!4hQ5&DbZ>M zNz1xk09+2)82?i(>!2rk1OmJRKu?y@h-grv2IvJE2G37=WWF5?g267Fa|c2D?@T4d zu>Z!E@265R4tNYqibheWL9wvi$>E&onFUY<8`yk2hfqhLcKDO59DqMT8#5}#XVp8G z2(h(zrw!8dloy@4IeR(0;fM~`ZLAJA&^6E70V$Ao^dnAqIIv7To0kLO@*eLiTWHrr zaQkL$z6DzoUOkOjmC_-QToLO2+$T-o(*39DC?j^dn$njCspajS7jd;nsq3b~12i*& z0vmn{e*_tfDrplf_vzRL`2sqH0gYX>JTDp`>pfwY;bZx%UN8W1#=Q@MzwsIf1vN zprKS;y$p_e@s-JJsb)(qeFPz4=zLjtc8S6J@>ioPSwuIcH>Hh^SWBnKoxRDY3!tvk^lD3E9-F6yS3Z)q z0M#M}GEIXTh~QvmiGwptqBYS4`QbNa5el@Xeg5qLV?`2 z*k*LUWhWMfjJ;9tS{6yUXu(uE$vVyU*c@DsrsWDHxzJ67>)cQ;IqbR_#my0RJE(C! zI#`y1U-(Dp+;-4}Ff~}Lb!dD6P~M3wasX=pyoft;7Bry4m*k8gscJer)dp&fomQK= zVP);X6!iFy>wf&;&TNYNX+tIU+D`~Y2*8mmAl1OhwZ65R2*om%P%BSW_>y8FH4ZXr!ZHO5fc{8o$o4&0N< zS!>G>bN2?B-;R*{bx5)lt!Z@l-DB}Ur}7=CTIDLT2i{tNfMM2>>@2Q!S<(QKY6P~d zppFbwGs^i_*;wX>2(i3MSGBZ+YeYnnQQ*f6i?@t=cYpgWU1=*u+|$v>;SFflkj?IT z`7mUksI^owQ5hUY&95 zl;7Gt#Y+0~PI~5(N2{Xwn1rFAg6j}3l|+~ZG*IcR;ZDS^9t>G=UfbL99aX)EEOi79 z+7Vp8+fk60_V<<3LNf=xGf34}p#gmF@*IY{m(kjcl$x)|P%aT3S98C@n#FR&qW1-DnmuZG=K=Or;uR=MzTFnq#2pAPPbJ0E_Q59XwzcNGc$)U+%)Nw>D|*pLE9Pe>)Y(mA3iN(!_^TH%`(F&J6{RKAoskE14_gk(epnydkzH8XAT3$VCDXl*x*mbVWBFFvA$cRBE4zDA zzqe|F1|l)xQH&{4Bk}#*UiZ9hehWs5FW@dmcv8Ia-7f+eDe*)GoPb0cK{CY#b8fyj zCq9K6-j{kjT!!^fiOm?rg(3*iqUy3}khFP&C*=Ni+?0_Dq;Z!!OdIo!#Mw4GbIRYN zCMVb}&qKK~_H#g;Q2LdT0PW=Zdi>a=M);XH6 z2kbHKtGh583_c4mE-G2Ct2nw$eb-;K=T`ZmbgPV>+hpbvty5E3=~-&pFDHf=^tg8( zt$`Is6kj^mM zBM)!ShJg8pmcOy$o?SDgclc+Nm~yCv&d#v92JI%$7G=jkfL<4{1IOPA^yewK{}IIf z|LG)!$4}FT9HzU@-%HL*9{2{WZV8!pgM#tK5(E|c6MrM!Zt!1%T2I+~c*Y=m%iHVI z=sNv(0L{pq8%S?d&UBaw?m)$Yh`cac1e5HaH=J%xGGnZRirRX%(sB3sjYTy6MC8r? zEkE`>4Y=EHZ<1I9Nfh={y74}(#e$nLt*W2%I~6+L7V-V$ldDym$=)n(x1a9s z%qYND)Z5XT$TTcA6j;NkIW_fstKV5eiE|=ig(Eaj9XqXKob0*&u?k#~@;|@wR5GAB zZ1OKMP-D=7A85y_$r}2lZ$fR=;}ItS1vTR|JiGsn$tRA0DUX0_ZiJ=*R!Iv#smH%F z)Qpi>TBoT=L!fO>bYBDx0*4^h5X{>z=G(IKTelCkTJ>Y;?zo^zl#}-1KNiyIx{RHn zfOPqF5rsHHS|HSraxJVjHC3dAkHtszJ98Lol}L+~I-!F6dqYf2|53fd5S{Hh25#Pl zIGIH6o?sy<_a?EME!KS+Ad-bX+wu{wr%d^gz6_A|IswcT4Mh}+k2g=U)45J27s1UK1B;Pwa5Gj9qXc~7}E|b*_vD{ zdB{yRlO;=$aBxq`DqK)AZ6bw;If2doUx6#xJOJPnTGh_k8a5R`4I8+{4DL3AfK_lj z?y@KZV87*1$|Xak9p*-3Z|d+7YgxAeM-Q{80+ZobrLL$35Jk7;5Jd98rUoNAg1OYn zgo8=RBh|YDiKs18dYk#ez?3m;9Lw7Z4)GW=Q?S`p0PpXo0Xl3dhqLBm_Gu={eg77e zN&oU)VASc$LK8fATo+2Cez3h#dg2s%n-GK_R$6 zdsg)69s3yPNTj1kz_Y3zeSI;ya0^$Q2!n9 z+~-y>%*NgK#_VGZ$lVjGkeZTCgN*|tZCj7&9 z)J8)@CnYeXKp##=gEiQ@|39<_v_P_Ta?@7EKS`7>AM%aK3GPb*6*}w}#Ii+KX7u>I zp%vZ19;Q;(&k2b0TxtjSzgh&54QfBr4GpBGIx*e?5Zx|0AtN$o_(aCPbZpp`wQdgc zU#Lgp^HwNeId8IYL6XE6#J1`XgPed%sQ%n9V+MbVwo-z3LWC8s1%$qzZ8rXvRGG~H*m}n4k6XAyRJ&`#p zSVNwN9ufd`X)T%B1XBs?2S+O_R+$EDs8MoGryWp@CYjwZ{^W!em_~#J_ z@gh)LDX@CruMlUMpUPe#3Q50c&D7qmoq;F(U`Njd;U&D{k!yT z9$`<1RQjfBS%FLj;*=VarbVpQBpop|rtGp3_{M9rw+wpNamXGn3V>XR7QZCEDiDr( zrR|$#{Rf>v%qOL0w>fTniUKY5)= zIFM8pNFhi2nqwPcwGSEh9SV8?^hagZHj)Dd>gKtR0x1b0;V+=YnQ80$-5Q6Y;N{G@++MmF4s!Az~t{4Tj zRH8c`6)>Q<6W#0IltG1`A3ZTM7AD%70abH-9!|YS3uUM`J7P?t35W#bPi*2`$9Q6e zEP4U1I?On#aDx*KR6N{-GbowgYVRm;k%1|c(t!LNXsl65C>nVoO#&bG62Li;kG{-s z$al^hea@8dGgi5)XifW|KH<%Q;`JrbC@tE9%3xujkIRN%s~_JyYCvTPBa4|O>>+Jw z<;1_s&UzG?z}?ngUr2ha%scur{+I9bzZEm+o7p4bT)-Sr0}x)LOF3Wx7MMg*7uimn?gv~O?;0k>~-%y5~yo0<#TfBduFsbM$VS0zXarqzb z2mA0SeOp-hyhxWk%> zR9&oIw-o3a2I_fR(8_&#b+uI=>qfjoxz99(zjr_jnVNfI7&ThY$usndc3m3v-k<&bSvhKTFYRZ!iQVJwEe3X#8ns|Xy0T1MmXnsAsRdIo;VVx0oX8gP_yI& z#{GT9hx;h|zeD*)MYe>C-_XY>fsq{L0AH1Hz9^-Plw7Pb<2-iP3J@3nq4O;91Gh|q zVGeG?)ci#|{}q^H_OYzTyg-`S7)%oqiW)Mal%}t5w)kfPcq2#HSbBhQ6`2|Z@&6=n zS*&475&116sb?9F(DSv+$W+dK_zTcy7MyG&*~^@1;7wDoCuxhvZTje9{l8IR?9@N! z6;?6n7m*4&L=UhyTJTKfY3=mE|6)Bobe~H)_wSGT#A^d%Z;(Tj99kf~sF>XKl1+t@ z23+D(p&^-{qdMj$77yD-r)z92b z?9b3JANuY)oV)flfnG~*3xv9wxc@VSRs<<!dP4t{R&;VOa{9B#kyg$_f z>T64O68HSHMU=GLL`w$h1ha0_bG73O7Dve5>FqQNt4#s-q4-a2Vkf3;)5tElg8-%d z=&o&g+&3wRm<`8=MXP&|h{mNj(ZTX~tCJJOIF!wU!m#A_aFWci_mhUqx-wCRj(IC3 zMXRuLQ;S?3XxC6W!a(bIWm#&2Z4-%=SK992S^*-9p>%l>K68KtJFC1yuTSZmU0vK@Jq(QVUB2Azq$C==mv#GW;{%5OaV>{*4P zm>6pVBD$A8x-Xf8IRJZBn!(L+rim9=)dbCFM?RZRAab8Iq{`z5aKgDObv0rq+=f^m zc=v4P6*S8PUJdOlSHI`t|J_TciKOw?D#1;lZ}GQX2>jz09mhe5KD|frq+M?_3~z{( z2;a_vBob|8)w>k7vbHv-F3ifUEG|V=vi@=&eQA6D zs~&vv6Q`NsA(YQ}5FEk7t>(gcQ64+d;Q7j-?6_qlK#i-jP%rdf0dmyAJ+b_#b&61~ zbm-lNm!vy_K0*aw$lBf!7@GnDF}7=il6w^mHaI?r;;`xyAaN2a^L19HpY|jkRJF}p z<^i{zxU3hp-D7b6rv+t;;Vbv{{<9ONT{@j2~qEGG&5dR6= zJ=S=!QYh$PAOLQL=40CP{$B$>MT0rZXc7rkyeEY2!p~5CoowpQ)4KNZ@hE-A*e;Hc z{;)v0UagLfooSfgE>dLg@EY>SZF4{h%3cD8062IQ=8sI>iz)4k7?}93cC5~~bpMtN zq*VvVzBT*83~ls*P1N$erz-{6_P?A{oA%K&UP+k|b8pZw;*O#fZ^c?gD#CHe{{0$W zb<&}kO84;2TN~a`Y#6bfR6lt+BorKX!-02KVoWU3va2DVf@nlkEyBAHSDq#fT{;#x zE-A;IpYh!NKwOPAci+xE@dP`0ksnA`i!PTu&+$9@(054pJ-M#`=1Pv@IFvLs8=`n{ z=upI~BA&j*3rgbluZuDCF5($waoy`YRw2a4mTUPDIv~+CO-iStHP{5Mz^ya}J`N5{Azq#tb#5!t;Gu`6ym`$~s?uUQ~Z(jeb$)H?%KC%m6S^4DH85!lc^K zjbFCLw#4o=KOnvU^1ByA`7R0bxg;ZlKDUe~Kz2JN{DAaZ*9CShbf3~Lt{Om=+nn~z zId)cFLdMzQv?Q*VIg|>HXYlLNIEDfmwo&NTCZjC7G%3LfA(!Kons8Ji>4gE4;vFG) z=x{S#$TQQ?0%D+g9|+_Z&g!X2RB%!Bgj%U@21Py~@3`BhI%9{=A8J~~B6ErCN!z3$ zV>C!|>vl3+^tyWqT5-es5EgFwb+afrHNum@C2;$Q`={W5^&5zlTFlSFFMYWRRfH@Xsauu=jWP(OAZ;rLzIW}tpw;^0FA@nOM@_or&_1b%qD_&&2jF& z16(~_K+?q9R4@`zm}Z?y!Q_kKRy};y;JVj$tzLNXr5J3KkxNJ!?$Uusx~I!zhL9;B zW}>PBFPmIbnCIR`l3s28Jp0-O(8zRbA@>U>&hrS9aCs z+&XlO=*u5F|x$=_CXB*Bb>q>7daxg?i{Pwlc0B_i!MSUh$)roX8OnJ;6lD^h=&!uuv4!i zj)Oq0Gova2Y4q$VhTwQdjJg1sg5UC4evIh-Jw<_yOE;YPnKp&w8XGXJt=pseBiwvI+Z=z zuHgmCWKl8RrJ!VFlY{qvB22+ImP79>GN|Uup!%->h7*#MBn+fnzE)fVzLQpH&^x&y z{1Hcq<|2cfsOj{KMoCGkR~6M?D|T1~h)+^^S~=IkHTQ0Mr3Z908j7|$QcUZQw@6EU zzPFkC_W1-~cP|tw>gUaf-E~5!xOzNoSQw_nn8znWdz45p2BpSkc9PcvMi>@0;$7Zk z=eqQ+5u1skl1*ktT{2Be>96^2naSJEF$7cf?oVZO2q7msEao98i+W?Jy7njL)XMdoPp3Zc0sZp@A4Kk17SMXrZ!dfHdL^+%J6jzf#-d*K>$hMy= zJt_iv!z68acsjW8f@Fcre0eY(AjC!okkv3I3oy!iBe26s(gW*VWs-N!%y&1GN;k7) zapmUG4(XuJqGPSO=0OPWi*-o2PJihbtz9_zl$tO$n_*supEbOEEeWOwZ4{g)gQ`_a zmI)2S&*Xj4931x476!GYI@o#VEHd0{gkEVJS7n3WHzLXw(EuuP*?w#hJ(=f?xF)L6 zqr0~%cLy7)t@iyf=-qBE2b%rO>v#y3-l95f~4qxm!+a&C}+Gs2m~V2Mh3*w3VaL`#%d_MOSRa_ zyNPJo@%|ym17aWvT1qKy8UHj95^$c)Xk5|Sn{Zk_pchekC!jrM|G(f)Th|g%o{Sfm z`Wm6f-(<&*aO0cp*}S>r{_o@4ju4ibkWz*dTakChYt-&#{I{^#J3ygA&s{>R_tBRA zOk=UDYwIpdeLFD(bZ(#9GTE*Uw-p4wQ`UItErggd)yToV|D#EHa+{3MAqEuFfX*~M zevbGNBq$c4YWIGNkJwq>b{-&dd5`W^On6BFtUctVWmGCN!7%f`07e+o2EiWL7K5#; z@fCyjo-V(TYQ*Xj6kByF+>VqKI1bctNVCfCOCsd)PbBD%&mu@IrWwy-9{2_5#+&I* z!9xO^E(32cvKU;bKE~HdDzyop9j!qR>BI?Bw|>+kB>Bgdo`EK>Uyw$U5BoMl%t%PW zo_4Qj-||_Kh&19!q&D}*G-_P68i(9f9(drCmRn2Ii*>3Uc%zRJ%3|8ON<=c}BA?l} z9CSI-RpDJm(-*m8_iH6E!umaYyE%*16y$DZjpbJ`T2?hoIL~w}onV(zY(OpJ|19#p zM?Su0{|n%cdN;Ot`a-(o>rEgzfaXOqbn9v_+wK}X!s2`I=c&MzKn%e?fdhqxYZ|{F zHs98`p;4dzY5cvA+CMd)=fe2l=)s)<5nR;;Vs;>EuqdPaXe}++ab9T9UyVgffaf z?>hB6&l0wjVXPdxJCxH}9KrK8DGkS5h`EJ%z`(M3v&fTEIUbtXDpE$*3m}BessY`4 z^%BERiWx-%KTRPG`J712dN_0Q(|x<;-3Gb$Ll(v+5&LFTswRBBw%%hNpRL1x(Bw}& z^2G=8&d9I8WSd%w-rry4DsE5!_63WoV#d7YRdLBdx$->nFWYGD`AH?StIwuvNA5%G z&pS^`k#`%&*nr{Is6O#@*F1mBAB2jUMjm--zbIVOKx9B8gg3Zs_mR;QMbz2zNCx?< zrsMShoPM=fF0@NHaMspVhj1(~OqoPeY(7GGkc+Ir9|W7h7bb)Buzp_qi_(wk>Gb;O zGc(K9Yf7!NKfW^KK(AUKJ#pw-yo?-nCcchMLBv(UZCie)KcUIXK^!bUEw^6p8(KHb{5 zS7o79FpFTk;kmQh59^n`tJgT_^HcJBn}*NjL5`#={SwAd zIkz*sW220=n=Dxl>nJmCXXG_jb#E97ImGdZ*mtIIdUYIYUeIL4Sw>z3V6nU`U^nS- zMq1jj!uz1-J`S$1AaP|hBwl?R&d*%gaoUS?K3#ZlywU6>S=$={sXbf97w+0D)l&82 z>4k~D;SU%L)lxwdCGIO_v8G<}iydjsEgov~*xxLWi>do%ApDfIOa% zD@yyA>!;jt^`p8F1Wguo)T>!E)+Djwj`h_3E8ntS0&c!@_`638T=$abhB%d0KEkjJU{>oY3v@4GZ( zm8gLmtC*4C*G;HXJSIUNOKTM^o(}Qr`T8^ZW>NB(SR=iki9N{d`L;y`MUyU&7J}Go zcTiq+q%^!h-)o|wG4{Jd&1}g9Z$xeB8o2O?#>2l{S|j2n{M*Dw-NvX%BscwU1yBg`QbWDPED!t{b&1ccU7(t2H=Qm(#6_EG{cwE_@+y3Xr4sI`#wW9Bl7cbf z=B;Xjz0(i$xmRZxoql*I^Ct>mkNP!dvtYGRadU+e$Ih}Q5It|`z$oBL0(d=qB|<&t zQ3li%JhlAV1_!nhCSNKuAg_wRyY?7S_rqg~&!wQ0|Bi^sp=LiPGP7V^^{kg3bne>9 zK69J)=|eiPCqH}WR<8Lmik`H#5F`4qzO4ZoC@o7wudjWRtKlLm7cNt!ME47i0d?4X z4A0{&{+(Q>;tra0^m;c5Jq#vXd{{o{8Kf(f4jx7V}u>C34UC z%cy4@k7J1wEAAxruD>L8`eR!Q)uUgOsf^|MI%9wuJsvNs(t#Chq-+~n>1kRVS|5Y& z8y%A|01R(cM108UqlEq!&~;`u`PZ2Xw#E#dgwA^Sn7?7LnV9FnGwmO((q&$7)Vk41 z>T`{qwQ?-pV4niIG&Ix-*Kb!|1A761-Brt9E$^qu6ctFC)09$-`qy)20kvXkm8|AT zx9c(4J~juJqS>l7Y=gIScPuCW_Mnt^(1Yue<`YT2q_D-M!Tasg2`w= zBk4Yq8pPQ7sTTODV{dSrdq``Ep5FCZ+8M6P*UEKL|Kzesmq=IUO;@_rX%zC-V<|sQ zYY!wubcXNA{d$@0`z*6)I1uI-;WN?Pm`C9sF$+X7FHFjy1fNy;4QgwLhzvz`yHNyzqfMRQ(c^=>pG30XJf;Y%nOm7O1&lW7w$xi;0b zdJu9W9OrU$%^S=)Z#4W+O!jlG-k^q_FA41&-eY@^?rJ(FwFy zdPM;tOZ@B?w`cb2_(hZrp&mBpoidls0CL?6hUvsIKIwX8U7PS^E@LnjWi5g^8Ty{V zJ*cYQNVtsvL>>dhFtC(#yckWq=iEhme8*r@cI_^9IO6qkb@_vCIh9E&%ue{*B14Ly zaqM$+jwb@%{T?jLkGqSN-$hKDZ!=^1soU)FJ3gXr@g|dH#JHN%_P8Rh`zyF!Kwbtm zz+e;u`b}6w>U{9U(vspp`tA6os#`*D5}Lg+S-y+x@I)$2bZ^C1ZtGzY?GI40oreg> z1I2blQ9kuGzwWu~>c}u?9qa04cHnyn-yA1BeML6Yyz~Yz&u#UY{ijZ=#5q!|o<`G5 zyhaf8@D$|?$*Hv+#K!ouT(ZM_UZ?twX5TwuvvLukfa;?OxgP9h6EDzcWReZACV4jk z3=UvC`7L);k0yGxvp#SI+5Ye;#VD+9t}EUfpO{ymfGl%KaB`$kapaDl!FbT+k-TjX5vSS56GurbC zz#BCCy+Dy!*soZ;bUVp(3mXo**k^69qO{||O~NAw5QY_g#JPc~`<8ShN>yOAWSeys zOibBZP)MA&u8TP5Jdh&%0wFnG+owYk*~!qV_EgMF#uf8+)AquUp5HM%oyg){P{xjJ z&_uF+#5TF?gQgwCWvKypQxQWqT1iaW1qfgA)uGzOC8ryX>x_gHVw51c3B_#ds_r;} zyLf&w$1WEaUdVi&+<_K14%q@ao>c$Ghs_SiSh3ll#uG+9n9pVeO7<7hqSHS7*5~e? z-MeW*iCKl`+>gV@z3y34_PcWVQ~+uuW*&C~gta+{Xzqc(2gbz4yG>@o_wPIl2Xwg4 z?n6BJO97hn4S7Cr4MhxZyF#9?F~fPuL8wGJCpO0`&VLa8BDT+N#(?or`b)CY<9kW~ zIQ&XV7tQLsbF)%mI}WDp{hin4)1o8%?I>S@oV6dxqd~0$9VoF8FSjG`o+e(#QzTp@ z?2OnTM9(m9se1oywHSfDBIx=(IFaR&sh1n7_kVxrb@QpuWyt1WYL}L^_kzc*C$r*V zZ03V};x@y_{3VOBVM_aZTx1u|V>8iC=Abe7vdi|jS+wUDZ^4`h6J7Ew&R?5jnjDRU<&bdeBp8H;VRmUs z^G{aB+LE9rlf>;(0kU;nj-J+bm&%%f2g5z_;wKAq%nd;zoC&I8N@gq)?fKKoY6+S5 zlk;MH9ge3$rR_y^z#S${#td*wAbVQ);1{OSKNcic-`k${O&|Mkc(V88 zR!oel6+Z`|&~9G_auGOz z1YVt7X+Mb`TYrMTijj*Th>@xMNAUZM=y95U*0sb(_q-o!3~H%NBK?c=$}0c60=Xa9 z3}LN}@@_AJ7Dym-uBM72mO3UW%mb;n6iJwTxQ0}MHWu@9sQ>yEeo&uou}nMWus(v2 zyFPPa^Mv~vusH(i;~g19p6_>)+xGe4TB!S&k%)%wKK`>UXDn?!er-ugSrsKC<~R9n z)4+}aOrmChuokdN;Nd#*%G%&MO;YMHGxhqRi~JW9C^?jOep z{(wzxWei)Gm>n}!gMY-i+^4@NS-3PJyS>_-^&n}Yb+tK4GB6+k6hp0fpnVM z2?yh`9y2S^WZzke6VeOeG=x>vg0-f17`stYy!G43Yj4m677K*iaLnL4VlY1+=uH_Hyv`l5Qj{?4`qssX#4*ekNkcOIXszWL<9p28XuqI>`XPbYnSq0Cv!%B( z4E1Bo*VD!6v7+(OvFa0q@?IZMzCvQ}0mYqjALZze6Vq^Ojm81!aJ3gCPj99VzNcfJ?bPOb(Zq%dPU6073MVyB!JxGqDA(MVSB2AfeirY@b5 zn*gAV&_9-S&`hb+j^7P%P5WT9*Kc{-mvgpkUQezcDK7VHBDv?{UF;) zU9iLYHl`$m|5~am1M`Wu6c8kF(s7(UMA_xU^0|a#wS+vpW;`@EGf-(z)Tah}@}!=* zSsqxdtq+*X{rJYHX?g6Hqk$41BkuCVg?=O#e)iy%+rtOf~Wt8sR_>(eFk z`KyVgsUkegxUJXeS_`4OY}>CTT9mQ-D^(iywB@E9>)Vhun|)xD!$s!CCS+$M z$vVHRL*w&+`Zlqbjl_-toVS>1+OQ2sHI*PXwDI<>Xw&^kfJRIR3?2?-Q7vV!~1 z$op<3HL-mO&Oe=LeAn~Sj8G;vmGKeZ?a|uf6I|m$l52&o3ez#;&=`NLzXW>Eg?>Fu zJDXnuZnx2V7~n}>%p_SyMmkVbtC3G|7juhN79$YQ$9Gj(B^j53!4#XOB zef4I*KO4j1`&o`SEmzVep@=7}XN~JEk;ww@|Hy8qJe&?)L#Ogk4!K5KKP%{^=*I>j?o03VmW$G_n=jhgl0xSgdR_81YxI zqLi*d6;BL2J+C@A{hfB*`JqL;9pLU5id#(^7yyIW!{%{dbl`lQblCNNiM&Fj?0h5Y zN|;s*u=oBYgk;QWk}=|AMmp?tmQthD0qNbxO!z*ALJKFUn7;FJ5Fjo6yLFA26<-wF zNAVG9#xA=XX`1$qNv{v2*iFKWIh2Wy87Wq2zN(xYGhYLOJl9P70EBFrnsQS~^CV4x zAP<7|b{n8v=b4s+Vf6S}(QNm%kjzQGBeiL)tyS@OOy!a*2$(vX-{Q*F$Ai#X*5Zaa zrm+&0r+}C%E)u%*OrVqbKl*3Hf4ddVsd6EPW}$7w?*1Sx$cuzol*fX z#)q)d-`*maax@!WCwch-SmNhYYvnY1H3~!p3XoelM~PchR-!L5M=m^&1rH6h(n-3> znT1L$@ZOmDw;IGbiu=Jf*XWg8`P_BG?5n&;MKm$;0oQ)OZvz*1A3u$W;m?YK!cYY1 ziQ=Ef0@ho6NtKU;(H0ZT4lA78ApD#gwfPL|)p(pj%saiCu+9sh+qIONPT0ewC~5Bw z`uiIRMc=rdjXn^>KrQ?S5)Ga|=3beO!^V)cVue6F1E!^6kwGwGN~aA?i%(B8caOll zjqQ^PjjBu);D}pDirwG7lWa&kT93fST2wXDB6HD?myfJ{D6rHBWxYL&WiSWF(hjI$ z5+L|#n^Dn|)@m_5cd-d;8x-f9Xuu8)eT!Np68K$VwH#f!Rfq4#=aRk%0wq@shKZ5n zI#UjZkust)cNr-RX)b6dJ9Iu=qr^g{AVgWPdIVqc8NN5Ua&OrhAVy6U8E9(dNkDvC`TtI^r3vjE-iqB+Z;mKS>3 z)ULkTklfV-amu>Z)i)H=lROiyDAg#x2q(I8L>CRv?JLt6ZcYsj9UgDOLq@H{TKH0r zx{3(Z;7fe*(@YnUZtIrqc3Y;_qC-1Co7>l!a^gkyG6b+aD1+ay+@}Soa`;QxziAy#WoXBVs<5A{M^o-}(UR+akp!Yed5`2GL zf@gs-E=NFf0!DBH+>@$#!`N7s&M?g)J#yf6HI{|n8`=DL zMToK*^0pLEb{?L#uF#OA;x{d1cjt*Gb~xzHO@KX}V;_e=Qv!DIWvZu<*s0FLhgVoW zIiG^bQ;=6WMBqh7_L>b#2bT4vEfH!At``7_pn;p_4Y~%>RBaw~g9JvsM<9$}bHcbrVCjHPx zWL>#65_0=bZb_i98!D8T62g6R^U}vw;go!OmHU`=lLQl`$vl|forB9NvpVM27cu96 zh92VL?k+X2nVM+V!!}3wtfk9hO$ zwP;1XoGzV?r3*xT_`V2=LmE!fcA{lq()F|R*d|aPXn*;r#3@`MHU7wWi;!rzCI2iFBE6{DyQ3m_k>u(F7|_qQH>{1zX%be zY`vrt1lJGPL>xqf2j&}nr$RO(TI(~dcYYiy5yvDtM4n=-bmnR;*|X_zA` z{!5 z2N$6De|?sIajY_}qbK?C-F8_8A8UKoT1Ok^M%s1ne6$~p&>Vvj>DgYlkASvR%(0gQ zFG4!w*es6Au@NzvJ?cmv_S4^PeI;yfglh9Wl@yvvC#4=*QV;7{d1@U&!TLr{OGM$Y z3@AYps4ro5ySYzN5jP#i4b1Y6ew<=lS4|~rGMw;s*fBcXsk^h3G6W*|Njyok>xw>0 zi(;Ng*lWt!OWGK(8H+B6{~$ch2RXQIab(~rK*3*!;t>Hca%^Fp*>BFjYGWOEU#*N= zEGv)}aQUwhHUzQvy$#Y~;4B-95hQHr!bT8D);PpgmE`IHdgkXjZE!L3_+v)>bQrQ0 zrxVk7QjmbIAB&fj&XF4>XUhtNyonT_SFA|#CBEbl@(k0W$ILhx`22uN1#XRlOeDgR z>Chm6t2Uc7vPth_p9@~;*f^IBn z?EA}z90Nl*HExZKYVNKf4$}GEK&8kw!dzzOJx5x2$#~>@?4D96Wl~dZSY<}O3UsHh zP#2{aCe3yDu&roq{J)xW)gt_^74u67rv6gJhX(BN2NZyctM>qOsVy=^@4WuL;Bp2x zzxbJeQnDaQG`MQ}tXDaU2WdJAvW}hlm7rU*N@ndk6n2DxiL6A{7nsh8r4|G7l~}FM zDHP{ZS8oO#mGWz8Rd{DKyQgI|dQ6eaTH`1EiEA~t_F5l<2hTVrzi))2&tApR#y^e7 zj$^R{HnF92dKzKL-J)9^iW*2n$_ViqXAdoE!NJUWRYisad<>>H6vpF&JW8S>HJ^O> zas8%ZStz{jC?OMiSW8sud#Nja?C~qQkZ0H*r6g5c^w3^V*Yio7NxXdKBOiPgUD(i=K{Wrn<-9MO9j7SI$Hl6|c;!{WJ|&2~5Bc0YxL7Z}*|dlhMS z2=UoK2q>Jq=~E9SG`B_Vh(M@E*vpJMi)hNHuIej;Yf)}!Vqy~C^r5pmR72Hd)0Rui z|L|mMb^YR;%kXCVan|qzY+>piy(Wh6@lz&=IiOrHiN4IK*v`F^FMVkwhb=*Q;$BjI zv`0-1-OeMXKiRkKB>&uBk_CDJ;UcP}&*Wh-k|;{^6>~qriN8aP>zO#KXz`WaE*D*< z6tH7~{>l=M`QNNeG?yu!C`!bfR?U@a$N=Z$=`iY}na;SP3fT$+1k^&Bw53IM_t`-_X8;54VylNU38bkt5vW5!H!#hazwzDnu|Yz1${a=L>dz@(9n zlW&40pAe5`FZc6hegeb6qdfPW?b_V8uY5|);sWCHNglVwX!U|+XQI=+J2#jM7FU#jsS(7+?c7TqGje%QU zM)upf1RpIa@EQ~xy*+#xGS}aZ-Oc%_$>6B<)%nBEHk&<=^5cJ+dTnlv zxr_?&tD0ed@34aftPJ^`3$sRR8Dtgr}r*tYI${Mv+BnSW3;dt;8)+_qIcH#JNl`2BnXCoA!Kz zN}t}6_A0ydcpc-mNX|^J*MSL5$tndQU(89>DeoI-7Po5>cumne0%3`I7PgyXT6pxx z7ZQXubnsyoea1%19%mA+@Pw!|p($!8gDPmpfaDjh>roNcmk`8fmWdPt=om?b(^N_h zNg;vVsLWX9)cX>ORIf9_QK=V_f0-oZFJ$vG85}H~-L&vht>`0s2IHR-d^7;~f;?>t^vs_Q zS!!*q0N(}WiT$7idDcq#ZTZULNAZ!1##BM*$h;mj!WhfOJFeGJ0)t#I^Wj3`P`#9g z4>Wy+b1OU{LPGs-EMwBlzij59OSk@YeQ;qC|L)NrUc2nf0{^VJ@+FC6xQTZp#j`T5yN7K}l_pAIP zVyA;P>O5>W3N#+PJ(xOH&uoSRqa_)-cek1k)zi{Qn+s4cov+<2V=Dp#24W%)E_#8v zk0=uaQt1=fawcgN2MG##9k|xY;+m;|R@0BW%{tOE(WCV{W8ct@wN6L)MwHc+-y#X?8>SGSt#TgX}C_U{8zR*_YeMpi1Kdj^r zb{rRGqzs_>#v`)QVQaY^_;e1TTzLWPQ@5U(z-~gxW>8jOo=wzo34b6J!%pEn7y{2I z<@l5deuI?OW6mJ~-oNgdvb(OH;+m3fKO+gM&4PFDXt>kY#>mIU&BSA&P*cCWw~Z$r zIF|RtJHj+yS`@q&37FVvL634lV#P<#ZC9u8lt$tfTB50w>c7q81}A9Q9rvk-c55Xe zl{7Z9lQ<+b4azEgxb(D^IK{z-&M6*Z{0>&Gwd>!hqL&(n%5V}*RG`{OK`K++%j0F~ zOqZLT2cpy4vJdpiAuX#3@z?0uJMviBx5@)O*@{mvDN%-x@=@}sBWU!5FaQdG>CBK6 ztyF^tBH^dr0afDQ!<=p#`=Ybl`D{J>KJB>xc zLReCKyk`f8np|K3eiv^+T6g;ZPs0-3mTNu7I(nno~cZtq?1F8D^oP8J$v>pO!!QZ?zai zR>uv_x?H};^uvVA3}?zV$e1F#f9ITKZIXjq#SobDX>wRLR`_Zjw1Ye0!CLAKq~8k{f6Z47_Smdy! z+m$kJ!_%f2LiuShhY^+gJ{)8ECC&$7@GRZa4!$={I`jLzxEcL{+5J&nZOP*@h5^*%}@r_Kl{pMOdn2H9%A;NM{ zb^dn0Qj{8Le;*SWoG)XFGw8WnMKET)0^+gDmA{f<4h03Q+}D$i^9PVP45CX!aR~~U zm`!nHzcXeIWeF^#GTu3?47SYj-2%Sy7!zkKT|Zt$Gs(?WILKAWq8@Le(&rt@THYza z>`%9%6p+_XnWXpdA2O40i``FAb0}SLZO!I<3?+OaLmv_Z8d9c(@sSIJp*G%YrWg2w zC))|t6qZG|Vvz3$d~0T;$0c50P~S_#3}ybPNBku-kMR|Hvh7<{kIJpFd%D=fOZR!g z&*<%3ai$_{2(t1@udhTW$OxL%5{)vG8a(R#+ROq-Nh3VEW0H-L#6%#VL)l0nS9uu* zx>PlyDgY1Dw_E@Hy-YBvh>U(k%0Vzz*k@7IO=dcQqlYuyg@U4enR@6+f8;sDdw?So zi1w?PKftRCQ6-PIN``~Yj1tKYjgcA?G|2BHf|zNe8(Pj*Br4-@U%?=qaCZ*g!Ut#f zcWW3wU92NLEj~$`Lm&Albp=k6qQf45j`Voe*o)2?$VTp;+8OkCg*e;zKh|bAc8d>! z-Unx8%3?WEbJmY>o)oys=u?fH?oFSL@r~D6QRX>;sYTsngFcO~qqbt6wAcRYWalUUkN`#YVnVgSm`dNq zRd6}H>;vVK{=3bOLFf%~(jvmevXp>cql4Z^%_o=UF0EH^(Zsta<_Txo1kIn#b z*^l0TgA$gca_aK54|hOc_W?+$CWyR;ExP0ciy}FVypW!yWS7kG-UWmd(*nrbMZxg9 z>3A%vNO(u4$BQ4B=(uQvJHI`u7yth`S_K;|kWIY{j#sFSHgvH()nL_NID6%Mkdh5mgT>tKw(KNl5>RUwbG!|Lrs%-!rf!=j*dieUj9 zeH|%53wwz$+0WNfS@apJkh8V%+AWld^QHeW&0kuHTwGvkprGUMT^wx5dpm1xPJ6wY z|H~6=H?Jy26%nWm3=EX^3N{+Vid&h*;>cYVrhd@$u+|bhftt2rioyv>iMRdFw&2d$ zEb$`0=`zWMm}aAlit;T0m(uT98DB+jj+pcn_n&62n)D7ebRcoJWWRSqgs{aI%U#*Z za}1+kb>BNsP6UmOj#9S|IuAcLfB2bcp5Apeh@DPJOu}m9(q!38aTiWc-H=zLN%;DX z5P;AC06{PqMYr9%cP(e$Pd-rJ2E8e@^s~8!} zvZ@~GJbo=L^P<8xePyF>oKE^T6X^g)K)An4s4_1~6ePR^BAwr47ikB2f-BDi;x4p2 zl2v|&5Nj{nJe}E@>dq=LmWSh!VR|+;~e2AJowch7`F8E6gWBft)XGL z=&2kT@0pYvahW%39U(g2S-*@lKk2NeC^;h}l9Dx$0B%HZh0b@>%xvcz!xj8hQRQs{ zM>YbJnB+74)E|_J>WVJ*qbXVzhy)*kbG;Egq^!5v@$3|Fdighahw7WD5hRa)>uSxX zGnOd!UlohvwIaGgwJIQek;L%ahMJQVE>#@^^zabVNB0vO)nOO&@$}-%py~R=kkw3e znhB)x{J~u1hL(ASjO=9BCW)wIf}y^a*9(QC6bCbn3@qDg{DlbLq_+dBt1Q8aT?Uw5L{@E07$<%=4Ajg%0g2EzCiSI*PH-x1jDWdPU8+I&g|g7~`eprrQj;!Q!ytRbzzhiwKeUe!QUks);vPpL484qq;*YCh7dGA=vSO!kcLey?T80h?j$?z10tICCf?}- z!?9Vu=aXY}OH1&gkwH||v-~_sn2992`wpnh1I8QsBB<@J!`JGa4ik7q8}?#|1l_oB zL~4NbvCgkiP`IC-=C|0IM$)b32BVS^CVmnMHkD#$t4^W&Ba0AE3*0}FfeCG0psQJ2 z-6vrzY|lR@aaQrAsj7DeiTPXtnAb6T;U3q2*GM@t!b7QnH25vqNH!5{9dQXss*)|B zT!bE2%J3GXc1zejLadFdThnSq{P06;FB!^_=Tr8E>})-78>hF@=uJ&DfXYFmO|I>{ zb4XEEm#SyCBvxFwiW6fhZH7=dHvR-Bu%cC2v`lJsI0W2}UG&Mxwz;`Hu}rGaJ8lwl zj5JjxaZCQEKRc+vzz<9yfqR>J_qlBwliji~v>G@8R0hHO6?%}i9M@LK%~-@ypHdFk z?8cl;fhk`o>NVRDi)!1JWsHcY`EUQ^y^hCNP9-4TN+RW?Qh{FTR-dDRe+E!dl=*w* za4g=3YB^nOJ1`O{y2cU$u5bHszpj_CM(Hd~Yn7ZCG@I%_)OKCZms6h7wJ3wg-m2DFTTN#UHHm!R<_)e1 zNiWAY_7E>|I zdQ&-RGA_-gbtIRY5$eyF>|d}54J?1uzrd*pWWC<2-xe#)U|5&Coz<)M-$0|)1l|E2 zd^WJCx6lSe$LUYO7#8K1?*Y$@1bFj(*!mJDMf zo@)V8QoNo48}wXyW4GZTVM0}0(CYmk4v`r0@Y6DJG^C6qOrZySbxs6+tZeRKuNELv zXfD5tA!cTY3g406I*cZ;RpDt#7y*23qxW&RffwN!s{lE2m|Vz!_><1QlaEVCJ`J*= zWOiX`IK+A@DsZX#nux6O%_?VV!D-Ozo`kT)gKQ*LvC<;SX!*>NxtEg_-WwuPV&w!E zEbL#d4(uEvVNgmr6k9?)F=PK~0O(K~dD=6qzFSpC)Lx;YrGs5@@t- z_xh4D5E2-vyb8)yK)V$rdcpnphhZ;qwh6q0x4*?rJPf1qK^pT*@<3GZ>2`myHiN2&wa2vApg`*^ELdJMTk<@ zQ-kVXS)a2pIRqMl@&#Cta<516$-?M_il$wQu((~*%lcJoe=AOBlJGhTR#|gC4)8Pn zHys3@>bKhyJO{O{-F*xV*1Enp2q!BEwdL|sTKTgYFnqtDz_+q}-J9uuS76j&rGP5I z5W&?V2+Jl#r+%6K5fj@x!(a*YBu7z7^-MBQO~hJ8ryvxJ`S_Q$d5EJTc0+D%x-LMx zElNlng5P;dAUB5r!IHSr5^>0m5}z{FVRJEMb&TY!oVeQUtQC*>cz5{F)xN`b>5fVb zeF(Szo;mGLPF69kO+33U2Fo4cuJH7k_1$D&;V~cuLx-g%*u6Qc)rG^1zAuAG1j9o$ zw4Y}~SSizd?)P!MnX=!wm4eMDNt` zy1*$kG>k+9cJ~p8WKhAbJ0Mj*j&af#h`9c;zp zr^dHWHVIVVUAqecL&7nQ$GDN~JU zp*V|UN(nui*b5-^lWQT)b|b@0{05x(&g$`rvdY;v6yavC=&`3e?o?kqp5i(@xa+9@2a+ou4A-0MS(ExhvWmR@ zf|<1od}^#OqxbaITu=Xy`Tp2rAD}3%dqO^o(~5pOB+z*f1LZt(LNQ7OB&)|+OSJts zA8r$jXDl{#VwhGbLl()dJap=u0TtK9B>yhL`;Nq5=19oiF~Tb**wTNC`6tS5vOk`2 z7c%sCGWDmLGY~+94alu8c()OPlr(U-BDJiVwz2Kt+gF~u_FzWo7JiaJgSdDpLLu)j zLr8EVXT^VuZ-Fh)&wJ!gvP(%wxQn&Yud2@CLma?psa-&(@tE2a;pW{3X)XScR%7)&uek2yb@Dt~Im2U8acKzB&b~;O@?6uc~iTf)-lK5Hr=)r7+1v zK5^|+Q2qK9d#F7qTv0FLuN(k|%C|}1LB=Fg3ZNvmn z68(m#e#7@86TdmasPy%iZpAL(JB6au{cU{COf{^lc?AuMlojzamGSs99@CtOY8du| z+i6?Y>&wb#WjY}Mxk8W_sQ3yUzhH|~nZ`MDw)X3%hb9EpeO%VZnb^P!;>sfIg2BA& z7X?0jxS-8C($@a;=;u)tsY}&t5nm3{0q`rwv>x9zHftN7s+4&~f`y&Em?5s)ZOvZ+ zV(BCpxDLX}dBAM_5TeB>pL##*1CGMZRk_j>Qhmrm6^RUL3=;Zh_v8ASzMuE2(G7+H z{kA_%dH~f?>`zp>crp`y7A6TPKMO_=_NMY?fMtcQJdR?wy%J(y!$i!ao0mB2m*0;Ss*yZ zeqNa-VYg0i)PS`htUQxXh7!|Uc3@-I7>SD;kL2KY;lWeB!G3i}WyOe5K74kKMln!M zCv+I;RbBV0ibyB^98X7?I%CGKnp56HV`X6yY}EVIa($9+n{3p2{MzPBtZJg<#52!r z^@#1g`~(0QL>H?!=CX`dwWMfNd`Z$PW`6G~m=vt&jQtv^J=^F!6v9IgcKE>LA> zrltxt3n1!9Uh-B)Lmz5m$WjnAgQRpM{b|Dl?U|^ZQj>J8CT+B1f??Z;|NIWI_g6%+ zD!ndPFNFFQE=$tKK#0%4>RiVpQ#4R%;rL0a^6?wm%?L66YvNLn!|hbYAR82zd~}$s z;U>>hICg2@``;xi0BWK?>ZYe%A_h70!qc++t^~Nt|G))5t0c9*oIud}Zd2XN8saW@ zRx(Qa8^{Soi~vehpE@qXxqx?Ij8hWTRpZVEzNuZYH2~%Q!*gS_y=^A> ziGFv(>|p@*x^Nq-wbt5-`5n6Nr2S){qJC5d$^--;H;()m8k7-YcpqrLq&RTfGF#tP zI*lp6Rw4F9dM(UJ!FB;l`4z>cCPySuT-98Nr>*zZ_+w0q(!^EC!fKlqbq=O1<-*Dq-M<(^;=muPt=1+5AY)eGd@=bHVO(Yr}% ze4{SlxhlG{oK!cI&T$;`5uDh@g5lC@=q%!#I^b1QW^$@W3)0fdp1%U0VWM46CbZKI zJ#u~le^;S7vL!7-T996#JA2=ul$+_hF@`uxqGD{XjcL>>U|8ARs^n0TMk&*PSA?GL zLvnsZqho)jSuYsneQ2k%=U@j!+%dcFFNmD~3_?QaUrwF-Ww5qM>vi4j$BjmR8cVtL zbzNnCYdr7*818^(KrvLvTJ4}#@MdZV5zW_aC>G~a{7GO52eS#TXXBr(c(jBy4?T zOl!h}>uRJ3=AH6^queI}ow>^Has$c`zRjusq|?rFS_?*8BJ&C{)K8qM&5`Y+U9+`8 z%>7N>U#MVzD4K3m#&KeQ*!Amh$9uAv?z*^dlJ&q=i4y*8q9C>`5w&_l>0B3on1HQ) zb;abO5q0SmEnnwQU!cUg$nhZ)4r20WxUS;BsN=J_QL6VF^x%j6IdsSke95};>n*sH zXT|&VJI_MjLp249$itG*tSh&{Tc$O(@v#R{1(%C|@MuUDa>1gYy}$=r!su;w1`RP3 zEk;-!9L0FwYFjMQ50ESll!>Nv6D|y%C5ldb5@4Mz=(=&W5#9BPpw_h(pE(K6iTHx; z*zmr88v(u6g1*N}_i7X$Pva)$g!F11fp{IZ9J5P0_cD}03tL^@WB1CorRM%3o2jGu zvjoW@Gd=;TXTc7?67AB*4RMfur112Ue0RAxm&C^KPOU?Ip#41Ncd5S%vEr>$Kq+qz z*31*XEE$a>V}}v2rk%wRE>TUkQEjI1IK+^w?z4nZ9VMl)4q--)E5#YbF+^uNO4<0} z`|M&)P%-kLNIZnZqsBbV6EN0L6_yL!-4vf>Q9;+kX!6jtrg&20>L3!S6z zeQsGa8Mym6FT};Q6Z@u@ofPq!^rEqm!^~_7fDdibVE)sYgU2u(ixgV3xoI2gl^~w! zehx)Ww}J!5S~CD=zW+O6Q#JtvCZd452v`MbAoC2NFE{H*f%{YPgd`d2IsZ`fk9{H- z8CK)z%loe}J9O<9AYb~o9=RClbvXVOl(|DQP~g8LdQ@+Zp;IbVcj%I0tcqhwJVyf3 zv&MwW+S3Q!kwPZSm-HT^1tfB z{||UFGybFLLnU~7}Ek_jV;COZWj5h`~LIL4aWCK18qzYS0 zDP&rka{=Q~{<^d0FpZjT%5WKA!mKHhk2zW2;xcVIAXf@Fof&xFcz5pjpR)c&70Zxw zATG4K6ij*QHLA|l&qbGiSkEH^RNPZjT8LX_8bpC+CkOoA!T0GX<-=n{vt=R?m)R$B z7ur*gbmx~Eq6J<0ZTYR|yo7M0NcE7U5t9x$baKcDVdI|Y24ZQbfaXuoB6r>Xg!!;0 znW+?VhUVWovz#vBxMTzg_qkGN@Vt9wu1nu!km-V_1<4Q`#tPMD=j>ZcUF`SsFA=Dv zjwRDBC~%3A*X{;oTD5X2+XQ`y`L-4@Sj_9QR>Nn$U~ZKXv9J^~)!-(+tV*GO?CD(b zojQXqmV~3&e0{ycDNFI#{4I;uKs;zUePUd<{Q=p=`nqZ&rcMv~M=_B!O8f%oFk1KL%d^(I|V2F~+EH!!sH zP>|V!I_}9T>l40oyNI1#u=yp~rDi5qFN>)Xy!+okWb_d}CA5XwCxzJwc-mRX&;QQaDsFRac_7_$jrOVio6okS^NOGUL z_d&mhtt@u|`t82i18Hg9qr6OB2`=hgYaLAx@YB;uw4~#Cvb1rW%E_WXpALBL$l_lY z2Q20{r8rqkV$mS24$2E`H@&`ykd^Rd|7=p?V}viq;56D$Lo`;tHaX($w5AbSXRb=f zR8!ll9)S!Kxn14M;ASn_|4SC$HEHsM>bqoWGcEL3v;L=*g1JjmISf>v?A{y{0byVf~ zK}v9%Bp`$D5ec>FjYe2+$XjA6%qv&RQXslHJyB$V9O>RJ;0JdO=+MGMO{YeLGN)+Z*@%E1R>|QGPp`=B3LRGbinQ1%wqzZ*0B7)u`B>YNpkILK_)onUAX$*QQfprELs#&W@x`<6rX9V0y7ifH8 z@$QMAiuup*qq4pT+czjjLIX{AMaM*)@;F+=f{sEDkpe4TqnGLuFZNRHc5RKfT)L#k zQH>i?eTt`V@=Bu74iU-fFBFXIXWq>pM-y1!Bqv>PnBw}Lf^iq;&wc4p=v?IB=6ETr zUL<1qC#A_U{8a76iVl<3U4z06G}qJ9*@EZAKYUfZG#p1XJYp~!_kfES35XR|j;xk; zI$ozAr@=c@B^OBlkz4QFJ^ONBb=d%T&hedkP`4?(@p29#w%P*L>eN|aFyjZAqu|I) zPl)?PT4|B))lf{CaArcDpg{0d+$t#J^wk}WA?=CrWmpRe+{@)5KrOE$uIQK#b-pPY zUe(Mr*xB8#IajfovkI!QX!$F7?pB?&-`y|HW>)S^G+L;B$?o|4fr5Rl%!mhN!*q0IcA*ptxBO-w%P+TKR>}BCUPQ-ojOi+(tAUJB7RI2u~$q22Y&9Zx0 zWXomQfsaxn?6rJc*GGHMA1CW}O#&piiJY$ne*U6zt?BM2 z_Mu?kX(Ps%qZ`WdN8Q@GQIE$)F&q?)dv4zGC?1CiXins10o05%EY^iY_-nUB50!Yb zLC$dQ{gtEK30r!K0B?7*sSP}^#meBH#Kb?sh*LO;VG`*R|9UIa<~#6}J1XHbd;t>6 zxP`{@_{=T@W>rrx0ZV*AqQkOH5^_uj{1o-9oga@-(MOU5lu9eUqqvmitEH8BofQ0E zMJx>NJtlJJu-_5y=;v2_bb(T4CqVy`LjY<*G7si=Q(}CPS3;?<&xmrTuwf+yrrmKQ zK<1v`F@#k{K$+DEx34$MX%4QrYJu#YM|g(iUJ^tfsX_afBnvdKRk}6Y1r*=62e?yM ze7Snl6eCPY$%2lf>F0d&dlRz;$#P%-+(#LRQ1W+#rYoA7kvegnwX&vqi?(}AJ@`pq zP5&w6N2`JBaWaOtB-XarYT;VPjIxt)jSVxGmpHKkp8XwQNV#oP0z{vL(T za~`oal0%{Fyv@rZ?zYp@$7$C2W(#+M@kBtfx<4=e4pWp%rs=oa+ zq43*A*AQ}N0o7x~-HsV={whL>yMI6x75O;nE-F`CZrFG?$*IS9ZPlb_g8k2MG?%%O z_VHr0Z!odO;v`l7VQcscC{i)+I5|C_YmVX(GiW;Km7v-y6Dyebaa#LVof7e;bDYX^ zYTJhj%IG7GwPW1nDo&t{fDGIdllIoUgz+dQ=GztLfH~8n`GeZ*_q@gcVB3>(8xQYW zSx?K76eRmf%f8#kGyi0_{5+a}Zu#tl7lMM0YdvYcTs*}P*X-7kfw4Ev&}*;9>y+qK zEoYUTczNZ+fTwbbXpJd0G&E?)xz(QVK&cR2CT#aS)j(O|fMHZ!(_3Az@u#el;j$$l z4$WFNaq=E|gF}&&?sT1%C`MQqfx#HYs&P$V%90eLuK3r%x!43K-9N)Zsf*e3Cc7;l zA`?}(KUirO5o#d#?*Y9O9ID=Bt|KS3?hq%H21lNnFPljKqvXN9`XkP|veC>JH^I(A z=%Zb$fXtg{h#Rk4_-!O=cH+MRo;gliiK9j^$rv};+&j=gDLB6O?Br2R0etAwv}kTu zn<17Lw^tlsTZy^m{PcEU*d{V44qZBrq_xvfd<5CT<_H*yb$AA56bkh8(jUvzhHr)S zzJf~CNrRIlu%SO+1i%TsupYt6P2Ug$D8O%Br^4XMOxJ{lkr^PmE#AAng!3rBp2Mvr zIX6^JB;$^$3X})(h379B2;lM#+FyjLtn^x1KA-1;K5y0D_NLwUD!K~$R4kZ164F!E~tAF(@MmbHiBy*ZY=@p z9FVo<2~&gbAFKEsw|(X_(}Jj3|2fZ+ZJsc$r)$;)QU~0xpG6I|P)SRYWt>UjpN1davcT$>v z-cE-1cmIlN9R|7-T?u)a{x0qJTzVZZ_W%lxVw-i(zr4xE>L*I@!V=swXX&*VtMlHi zB0YS^OQr+D0O)|NMO;$@UqeD)r?~wmSy8tpzCjXvs&_)>D!Ot6&li_G@^jPR@OGE% zyU&e=1PDYX(lG)p^LXz;`ftJoXmEzr0Xu+G8-p^_ z+5nm9nq^wBD?0f9v(=!)3+6~8s${8#7FZjGAq)iW_piUmWM~0p>1^xS>jZ0v6NE&* z|4L?&ZR3UcSYp<=y4X4n&x@hlTJqj7c7B%K2E*~)iGsalDaxgc>~7$bi1u}v#*zE{ zrO|Z0yTRa)wKjqq3s6r zz`l6I{QurHfOj{UBXzVEGX@3#!RQEVYYP1P;K9S>7|%>M!J$>vq#} zvyO>k{8QDraFDsKv(@d4=jAoqd3u|i4HRJ9L~jUUc|jWfgp^lB@dscWsEX3b3trddg9u2;g{Wwyx~GAndNdM4k?^VJD2hmbr5zC2znZOoe?*!-SDcIT7kO3K zG`Dg0GPt1jLG3!Ez;3p4c$ENTF?%rm6uBY(A03Xv0sh(kiPk&kn*li;d8?PPO_2`~ z<)z&&`%wHHPU?{PLc*1(2v=N0aY;>Bkvm!5QzH5xD$o@34w`$(HR~2-tK~&nSiPbx zO6yZ4y)Vx_aM!U%N-Ux-zEX>fBTw5#mH2PW7~v{QYi*$aT+5v>8^!-v2F27`Em?f@ zo+DjH`;f1vFYAEh|3fp-HP%qmj@wx$+ZaWdEv5_*Ny=Yyvq@pJCK9ulp=DbzcP^qy zrCxFnGb`$sAhxc9^>n0-_?KY>%>Oh-Iq0yu4!=d9bHMI_FnlqGj#`XfCkEUzWIW|t zi+NVu`3mS3dvHdjkqX-qwNreD6AbeFyWB!vgGw!N#>b#2H3c)N`Nf=OsZKKQtu#7~ zh3B-ro0<}+sp6MGmgS%z{MzCy5h90G*W_ZrjMFngW=CPnEtAJWynE{FkY`%idGtW3 zNxPJWeRgXB-h9#Pjid zBHp4UuqM4-6t!(!d6>*^C)I5lP+wsoLkA#jzNdvOsdBLjXXkT8zpN-$79C}qPf5YNzO@R^8`X77|5W9Nk9x%z)Z{Pi) zP)u31bmvR&`9{yXNP~3RCog^YG*6LXONQ@;UScXu>aGKDAjUpm0}Ojh-iXrAlw5C%9O(nXnxgH$$%m`5{+gzXW}KV zDS9jmO8|waDgJxQDyC~K(p9|`qev9%mcT&L{qZ(=0q6^}Jv^%(kXdm?moeCdnzt@4 znWm5z&!XTDJBgsgg$fo=eB|R!1sDN!{wq<%Kd+or%QJ3`N8EW-VBrwr9gYYF$bI`1N&stWsE%{OUjJt=AC$-&2}V9n#TTKCZ9zg785 zyC*$NS7xy}*t!iN<)~NZ!hTX#pA9W2=CRjWXJ&e~X$(QgUcagPF*)n*{e?hT!KjEt zBc&I$whVQUx@7w94aL81B9o{?)|zJpDzlK7;!zc1ya<+3>VZ z5^v$m^gY-4*a;$164OS!RB3C*E2P|K$^sBVa=^E~;5NoJ1KP4Yo!fk#=rb1+?pR7e z!eueoKG7alHxm&b@4M`&q3 z%_M)Z|H3C;c#uC^6Rb)dmY;)Z9qIV&y{ElG5O~~H^^e3m@3by~TXo4bAjdG(Vx&8& z_jgPWbi+~)ucJYk<8%mgq*Mt{6pm@L#|KJJxG(dL;rQn<#X9-pz_TK-ozWM-a4ERl znGAA}$p7dC)vi;oQ3GRwTqCPL&pr5xWU^Si`N8qzxZC{V>q?iEZ*thS=bF4`u2Jxyu z(v>qCRWTxYG9$41E@*dts)YONK>rO2 zG?Uu@PbqgY;VUp440^CBXJmS(WvE78r`$DfolU*lGh9U<$ta>TP@*+7ono+_ zqk)#a!7mVA+oo|*jamDhEb#k4LOQ8aX=3*jHl_?r$e~eM_l?v`2gMItY#A)v-!`p# zkd{KtRDU930Z6)Ri&d(!8Hc7A$Kf@5er*>gkN!SDoSk9;lc9C~563HLYlH}&9N&`Z z$><{S%V3=IK9rJ)>x2Oz=zNTC04|ge)}}8%lq`4N%@dP#Vz`q1k9-}RAG2uap|?Lbc`c1BxBc%?7H3NrzsY2TVL&scJzgaL4m-#9 zNQIGy*Y4v~nrg`X0O@g7)_fr-LzE<1Kn?N-#z)}l)AlXD4l1#+oH;Ayty*38ok+rW zB{rmzTIMo1Fv6;ba>Dj}x_dfrKt(5Ar)MR^Am)i_WmN`^UqP8~Cuv$M6lxIk`olh9 ziTjUBxL5*`A{9R%|6saGckJpq3)rbxuJRB7t!mIzkqhMT&<_02%DDg>-k)^;RcvMI z(}gWI$tb9P@#5O=)Is&@X8>skX9?!H7vm!zI z%fr*fGbB)zM_&C&qOSK)+j~7(sKW<~^}VB3v*`ZWvEJB{zo}^rbW8$07nb{GmURZ5 zw|A5d#H^qcM$2qXkQ~mh#FlWo<`Iy=9Q=(=@#LR=cu6={h?QV&Ujn%yIT3r77%mc` z^D}bNQU;5|s)WFVu1U@}b=|3=gGmz!p-bs%Z*Z{2Bm}b;r_&FX!=ab>B51 zN47)l!(8Rri8RJwl`f<8M89s@_@(|Ev2*qX#)#QHES9_yl}|0IKSF33BG-}vppKIf z3!Rus-03(khtZ0hgTTQYpZHeodET-?6 zBQ?J5+jf_?sG%qb{2Myt)iy|jwhYsc>~9-N=z$>?QIK8NGIs(l8a1?PiGv&okh}K; z=UMu_N1fodoasRjljA;CUcdrrui$NJ?3)pkX>Ir_g^{lvp0+?*z`_U>o&mcHPj+Qq zb1tyzlA6WnlN$>-ghy8;_{D2KU}P95_q8XXQXSvp&RK3Hz28%`)%rn)*O9U+47|zG zLAFJc_O<4ihwna=E1=uanxg90j5s@tc+{yo0s|5Z|LoCW5tZo_4tH8$t;9hmp+5tI zk){l>3KQS9&mq&`7>FONsLw50Pt!M-)X+{m8-_XeuVh}^N}YT2K|Uy4;`gt;(H$$- zNfv?2&(*36UdKM97%acjypQN=-=+D5y@3Jmg9SY*{$Fh_HbwD}W^?d=%||`2-Y%(NiUtxw~_a_Pq2@r#7SK!AE# zj1O;A2EMuA)e?`5f-eYmMb&HE9ySw`Nv`2zx|5;y8Q7g?&k4v-&rPtxTDL@>W^Js+ zwiI>F@Y);8BTAACg{lkx$W}HJ;Tj+BZ5+y&0UvJ63*~42e$UgJu_d z1_?X^u9un`Kgt}RqSxk?ZSqKneq!0JTn&LbVDp@eMq^k3YT>(9eHvJ_3NvyO%ND+q zE!9havQaz9X=sek4IcXke8-%33ypkd3JJ|P6Yv~yJjL}j*hnyTkr4EJB>2ePY1 zXXb8!Z}dQv@rYN)=ss?Bz-E>f!EeH9KE{LJglW+wU97 z)BHWeSwcXYC5@HncJD6h_FH(7Z^R^E!?u@F6m%f)HtM)@E7Tq&CACOY-Y>J(u;=() zf8&;7^=x;{sVG#PZSJ&AO06q=*xTS#vPsRL`z44HJQR6Xuy6ii#E%g!)6rvSnydTx zLHBfCFDvFtK+$z+XM4Gf@xsyZ;i_IseG) zg<-wYVjS!BrsDtiHt+c7-d?yQCSbO`=rRrL{Pz z>_sJ|<7tw-nCc0REHCD;pn_{q+aB?zod! z;Dt|2Ql$;#>KDnC17U(xtHjcA{>>oh)ED@1#j#YC~{I9p<~ zrj}q_eFI$Lif!+3o^?>Wr+soKPw#%0GjWlvnS!Mk(<<|II_9rRTMDt=UZ?DL>^2g> zXBtU_?P)O)Oss+#s_p0NrkOzl@C#6J-Pq5;&nIxpwro^UGN5Q5E&h9V5~ux541E^I z@$_gM8bqW_YJBv`R%Q-z)?v_s@_P*n_V)*N=q-D_t#d6_R7* zyj8`>dw=(JCz;|Whp6rW16$YnhT5|g^}aI|BfrWqeA+5h(=2=|+R5obazk1MWGj() zmN$WVdd5rz_?=s;zavU+v1t1xWLT6)rlKXlJ`%}8G#Z6thK}kLfE@#fhD8Kx0NSJL zv^$5((*LX0y(3(yOtfMy*dOL7x#j5$6|QZd*Q7+T@<3-4>-^#UYsX$$g2JgO+&l41)WO>)t9W{re)mtZ?!Z62widx8}>=JH&vcxIxiabOy*S2=RUxl<2a?VFaFp~;kO=T!Mw_MUi`8tIEp9ubBvgrU zcJOYrMVO3gC2#A4Ub31H4J9LVS|V1D!AjI|Ou^}-fr{IqZ2^QfQ8z0$IubVH?}TLw z*HO@DNBjwRjI#v#8Ss*r*U~Sr{4;mXu&9uRfiLhS^a@LMu^qucbv7CA{EDWlB-GY8 z#UWBPIFsa<50B!_ASZ8<(I2Ah2?hOB0fB3Gg^@3U*8?(0Zs@=t36TnXxYD?7BhYbV zn4WlXvr0$I>MP?kHUiTLfSdh7>wV`~6?k$-^&y`!jvfUM9!!Roi{QKkMmhlT2@-gz z)B)Q#t`YSz<;7o}qHu=BrNl-cD~J_z@`h7+^!%T$F&a^`Iaql{mzGh}^z+>dJ)IM_ z^)F|Gorx$^1;Bu2LqBe!Pi7{U>ZUA)eizsbNah~gZ8uehbb)N;{^g#$el>mAGsimkasu~&(U8l zc%%`@TvZFCbn%U_c3vA>{1%R5It~mFThtxwUZswX0>$tAJ!FpXrw7+3a=VkEd$ppa zKmd%;d0nAE^|0MsDDGykFUT2jQq!gZppnfE^2$Y+qBBc~xsp_LTQ&#|SOeqy69ShG zEf4{{w^WU%RFoT4>z75%&7YtkYYM*8j`N`yn%B`s^Gtq2niYFH8#NdU+tPB{6ZX{E$VcY zDU5Lksn>%Dbr=j5oQ_tpYLV{Vb>*l}5kk1}Ba1WtoL$HKOh}9sF^<|glp?IG3opiu z-ct^XNwSQz;0gcd;^^7l5Y6RRa+T`RXftSTCyzk%;9Ay7rmRP6OZF@Cba>f79lgZK zJ?MU(TlYXI>|!-1Ytn;7^dM1%$~f{}?)N#w_SX`zN-+&_-FyGpLMi3+ugz0TXwIx> z{hrg&HAj@{>+WX!p2I8Q6!}g!^oLaWAD{Rmx`e!~?IK|^eARLx2;P(6 z$R}CXC3_Jdfp@36t+hh#;1^OjPPsC1-B^FosU!u{WzS5M+$aZ`(E(msoXRvrC<86! zq0DF1NSsWor`lY}wt=eevJyIFjGf0!1DNJaYAoz~$A3(&bk5+$_(q4#MNC-B+AYJz z^$S?c1#PnmW90R?8T)AtdYF)6O1{OcGJkwwZKK+iU8YVT=m@DVI&TS5pehd-p*U)P zW6nWyFF*_|VktW>JQP95Mk;McPN%xM<=iZ4z~pA6Z?1^}01~NHqyb!XYhAQ@qugmMzzCo@A_p zr#8WTkO6(UmXpjI^jv#vJ0VpNTl~ZL@IpH9P*g*G^?}lED|yJhrSAUTR1K zDf&_~x)>SQed%OW-_uhiytNWF{}VDeydfnL4jUqA%lqW6W5Am7z~Po~`&XL|4nvlw zJA|-9Mu_df+>;Y!*A**=+BjdP8J1g~G;!xrf8c4?WL7!{1z6xyvSwtq1z=M*vI9TD z$oU5B-*gsE^9e^cy7fd(P{My*5)-&W^Wu~(`t_?F=-)PFlgq@*qOr06+B-byV)O0P zhf{>&_Q@`o|J`&XBRO~&9x#bO%}(W`q;y=cTkF9la5JK&>*j84KxIFcPJeI) z_S#VdvC!7aL#s@Tw4H@-yN~=H_rW5P7X`<*qV@^VZLRA^1J7x<*-%NRHu+ah+#-pW3>AOailX8+%-oX<%#SS_ zLJ=BIZ^-EWXAP%Mf#LxWe3{f)xsyH@=Iu%7&7nBi$PE6Yv{~LS|xeYS4qIk|@lNBo&Jo71TE1MsNz}?p2iK z*-)b&75{|EgPnef7f0Cu1W@uMp2K^%gz8qr&z1&JVxn)~OdSe_NHuIUo5f_%NOZom zHU*3|6!VbkUD;mVr}1*d?+v@%qx9}%>s^ya{u5k$L1e!StVVVfvr8*oy`VoM{%+EM zy!EZ}Ijm8asPt!$q3q8A$K26Akd)EfGbC!wkwI z^#TK_y&VCP#a@Z5>ZketS@EQaa-lcX1y%9rXw2GB@KyU`n#4bt*2imj7hw|kQoWRt zDQ-*PjM87d0M=K2;&&PEw7e7#cEu|~(H>})>T^WKmAjDnF7> zVU@zlFKJgFbFLuWLUO%NrNW z|7g6Dlt&XW>>$#)wvx6m*qa=EmMIAP8SK;W zWrvOs*Y?)xdR0oB>d0-6wNI9@N+C`Ct*@z;CR>#m@2|(YPlpT!`HW_RSA)&^AB}Uc z$%_OiAdL3vGcUd8JqPV19RY4^nWN(O--uexp;SxDTt75aR`|;Wm405ZzNn2qX!q}h zpzGk-{7g4;vkq<7izXv} zba5HZL^8IW?_X2%*82j+@R~!Q$8fnQFol%w>);n{w< zalz2WLSPCSxma*z$vp6&nZb$s`k~vfMloPAoww5H^d`n+z}7)-lrDUnCHxSWOSd;w zM$TD^=tT~DnTo-#M7C|-mKs*q5cHQ{BFFOmR+_6ww{+81iq4hZ$S4N$x*#stE;wDcsuOq@T3OhaHn+Y|vqd{h7kNlNC+Ld4m63z?~7~D_@E!RPOSN z;5CI#fZ=ZuzG?t()gPkY@#X+LbDur>f^T?o7TAd1XUwevkt}d9VMx;Bh)gHsbSb0o z0W1GB74o{73W0Dn+4>N>#6>KdM}mA={DHe+WKF_?2B zjXwL@iOwbvD=&@2Fz!T_QKvQ?WE!ejCnrt0#=2h0Y_Ax=X9$hej~RhFX;yAx+P-Rm zun`M_hKo5wsgzbrh+Y;WWRr3q;|w%8I40W85X%%HRZ_P2E3O;1rGKa$jUI^~ZYN~= zHU}tJ)dhS}iq9Ge(E{2^qY0@*OL%s4ZQAOlJ+|p)3VBa+aazX`oXb-$Y=l>|2-U^r zo&c<78m5966tU9RFyfWc&`eq%C=vasKvYliBDe-2mFd}Fdmjal(C+%0;+4i5{H*| zs;E^ILnt#wtffwpzyZmLf^~);)au_fKJyuw)Xi|tAx0Ir915c$mfy+b^J$<|rSD>1@5~)zL%HPXBt|Rn?ZWU~ zl@5q90n%HQ#e{3adG@~HaJ=_j*sdlPm1f+Wr5k`nh!h|_M@ABF+y~?uB~6mhUYM-^ z=KP8nK5AtwiKqnrh@o-%#%2GEr-U@bNzU+?q(STRBwsmuM@a(=R0nfM#RA?|GhP5c zK)}ChagcdWyL2wjt;ZYUSngbKCvw!L+lA?9k>Fv|V>&lyWMhnH#j%W4^;hC&`e&s> zU^_-b@dA=3w`h~VrslLbDnKPfBJy_~sTD$?WzZq0_fwqB;7>0~XMi(=R!}0;n zPFR%y^noU1{wB6>zKH+zHl?sguRLxrPQSktF0dg(Aj@Mg;OsS=7e{i9RF}bu5s?KH z<`y-+Q^u=p9#99!K>j&yG(N;~kZ_XtSY)XigIv2)Pf(~^^Z2v=lj7%m|HbK;!G$#< zTgDxm!Pr3UYZ1B>>!vT5eyS5=oswJSshzQQ*2O>D-@s;`|U4~PNbb())p2a z#A&)@N)W3Kiep_W53Q_tJgw`v1`YLG#a##_QG|GN(LLNGCnWCFGQ zgs5~>8f>!(!e~Ag5pU1O;mK_3N~hyI3ZG=QdtO8@Hy2raeZ2BNJXmy+678#o9w~Eb zh5}n#dZlGSE%f@gK8kwk@%MZ#HZ=q z<*l-MDl02+^TgwiKwI)oyr@+4c))`OsLuWDR3P>l2+q>hiDNt_#QS9FaVrzIqKE*8 z+9fC^yz4q`Fknxi*zbWyFzXfTuK5Wi26>=aVQ7OANsb%lBoRjgUrUO=y7$<{wl}Rl z*0!0<>8*DC;11XmR^fmuADf?CQ#@AlLc(GA0y{4mEr5N_BJ*3rp`r4D?2r3lKM|&o zSfa8r9Y2xf5=}qCMCD2m?#zsg(Eo*7=%U*Xky$1@R4Zqr1sAR7fe2B(_#~*X#0okcxV#d zIW$BSVRO9)c)O2a{p~;h@=Rcr9h`p^*WqV8$|@48Gsj$MUh54t>U+8^3>p%*nYJ;n z#9n-BvU7Ksz0B-XT-r|F)I9vm^ki|Rps4b+^?nXm^X%cuCIM=f__TTtjgOlNb6kLB z|EuKLwx7y~oil$i?!zen*yn4$4?b?GMbM#$(%lb=fu)^To5A zSfr|k=8<5&-%P&Pa$hGk^Li~x!%#~AZVDZ?Ige-XTd+K5V#Pg?J&cZ>=Tp6m^dCg{ zk`kKL!c^jg11#fX;&bKfSSqp&GEKXB7M>U zvp!r4DbjUmNV{QI`9jfOE{Gy519;c}(%NKf?;~o@na{JOCjdLZPFWf&OE`;m-pL+? zfKxaUPOtGn@;f5aVDj;Rc3~0m5`Pjq|VMC12)(p6<>V z%GDrPGZbhE{-sdzLzY5E8-gwlb^(orq}yN**|zBH3W68LSPioJz^XrHJO(UY_C%Ui zo>1zdbRcdM5J$YkE-Zj?5mVoC+_S~p!v}zNS6LNjmLd-?t13EanUilh75>N>n2rL7 zEEpz9f>qD?i1x$+&O`vDO2ekFMw+r&t+cW~$(IYEtm@tBHUyRKH#+?6i{ArkJkK_ zs2UGv?t$Ule?+hXm4=7z;H7k@TWDk~q&Q##_cp9>1JNTWjD%9_w|$L0>2km-f%JJR z>E~dx#iJhdT$ALywmL$N7~OF)pH#h7@8N@YM8dngeES6H=JQIGQ2H04n#gws;Cgo( zWa-BqGj{tW1yA8xYl>!VT8D6gJGRX46rzNnHx^4#1LlCn(=Cice(7rfVNcl{zg;&^ z0Fl_M%h7zVs25BL93cTVyo#MD@tusq)_YhnxyV-Myf45HhfP@ugsM8zSWu1GwISp; zUGacPZwa@Fo4iAyP4DekI^q#u8PWLf7bCZEL@r*G5;qnyQkDuP(E*9vLl_IBf=IkU zspX02JO9*~3fug6EZ7Y>yp#xd|3i_n@hG$RIM6n3&-(=RM|=`pZ*FEq8Qox)A|=U5 zQ6@5pNhbiU(EO2Xc+!Gl5}=Y7XulcUztHybXVA;Ein7b8MPA3~L1FM8#E!c5aTRhP zM%7!P6#c+^13CJFi~&Hp=Sh=Uy@XAloN@kxLMZp^0RHr=cI|LvgHbtVx2NNq<(8IP zsQM?)RR{IHz8Vd!W0v*>WOoNn5eif`|KngL5=7gs)x7R@=01#Z%6`~GYnQl60H)X+eo`$EbY;`PROY z8S#aku~svV+=@HjY;B_03fB8g`Ze5wpyD&+jT>4hjYw=E`tG}t&lX*^AgESCD_YyRsN98zd}+~ z>J5qBGcMLS@(xzhw!n~1-mZScU3y#Yjtw&3EL|&D*9bv;H!ceBI3oW%m|sgx0f5s8 zJeopl@u4XHfXw5-1`|10PwBBTxXUsISLwdwnZ7P98K2pLB539t&^{)eM_D)z-jbJkiu- zJ6QT7csyZtV$PX%K{x6J4If$Ld|LwyNo)|K*JCy&#$*QYkiF!ubOoBw*6XXZj?ws3 zb;o5)SF>xG7s9<{w@~Ce=OUMcIUN0ksCVFZZQ-a^qD3|HhPnfqX^)%e5lF zlkEMvi$UsobN^&&7Ejw9CMF|9M8Y1np! z2LH#S>}bm*0e8}ol5-%>p@`ifWAi{GNe6BPsPipDf(6}}HLu_Ry6Rps&jT!K7F0w}IuJ2U03eW;;)%?NO!zhppQ? z1$hfoMBtQIL>v=AdCsMT360neq9I7P*Y5W6EzvRF9f7)&;>opWu*2vBDg~Y0pt2g|IG;5PisB+vA=C1x%7tx1`d=7h>+6znHd^u|w=nw+_gj0D>0US5YF*|6rK$#e<+OR zKbpY=A&T|kNkQJugtj{E8bS`7YedjYq3!^l z$Y6miEKZwU^eQz`1?jRhkEI`Ho{R?tewF00!4Tc1Mlta?2b{hH`pTxy!uT=I)jwV!+f9Z3~^J@Y-ghN6|m*+@=2s+DoTu!23f*%h@@m~kS=WE2FJJ z?FN=zN6943>A8Nw9CuIH8h7W}`mO}Q8=Wc`E_TcUO7N(;%h#V zhhjuxaWWIP`OOYZQ_o_g&nZu9B(disp=F_#V$8A~aWMHC7Sv;e#T~ZDVGA>AFXu3Q zjUR2Xp^#GRrCXvQej8~w$U32iSul{_LbKU}dQwHtScR0rBVEB#F|fwilbg3QE;8nw zWXYyw+H~l7BhFCf=&0Ho37T#U156TiWIr@-ZhyrkbVQXsqKMIJDv&8SsYtyO9=^(z z;Xe4Z$V=a(Mg<;E%zm7d9k&tr^a+fIZ-ElKKyEP-5T@?MlL#zv3-@DrQBv15kVKfp z*$Y(??dWJr{aNPvH~)gHkYKdbYUCa^ z#y8Kg)*`30wO{dUb)R|E`O4;)^e+&F?Pq&#Q*k;9j{*B(sj9PA)bH_uY;Pnc7dBM1 z>`r-*B7IF1+b}h-^{2341xT`>)W0r%-Wx_JXZXXWQ^pOEznQh}s{T9#m+ck)In%gW z(786Jn$OPOy@__tuZ%d_WcgoA0@K}Mm#n?jKdvhFqcHLBZg_Z~{XnoL@MI$Xi?g~6 z$-}5Gn72a%asU_+$1ygdd-2CcEW%c|v9n8`S|#|dZbLIqhW{0BF9 zyU!y`?;TgaYeNQd+u#-1BM=)e?{ydgO>-FwjY%u})+H2nfKAYmo+e)`W>s1;6=^iN zvYl(AW!0KfY|ByZUuP#liRlrzBtZqy5?LH~L#Cb9h zhPkN^&PcX;R}S0n`+ey?Nu&sEH!Y&ijG#cnYTWc-XAWf8eS@2lVq%zaTg92hT~X1& ztU_`#{{yT*)*874d=L2oehN$yC74}`l*9|_lK-N!1Dy#he91r9Po@LjaLGa^>c4UT zdmS0vn1J79cE?#Wl#mtbtTbct$A4{LGGP%)0#&_D%QN2V1!0PndkO{D1^apFUa!rt zf7gIakq23#pV}49MI={A zN+p`nF*5N&ZsKN_vs`24-51fMnSpXhn@Focd`m~ot ze~-hm`Mj1V7Wc|_yKX`g1w?HhS)fFvA(?Okt8w9lQT_k*F{jL(<#Vu?FiE<}>r5l} z`?;rHC%mklm;aN^HI~CZMZ5>xE6@~?*0JSMIqyBAwwLulFPTSRUNL;N-%tQSP((ts z#O1`LyeSLf$N)0#p)>Y66l5wRP8&KbA7(ZIJE$1kWhj|BJ{PALfP(Wiw(x&q4{s(x z4kYpJh?uYI$grzvrGw0GHNQ|FYXm8H+hpTb3^?GP1_HM0x+%A#hcc)cAN@c*smK(v z-H?**_yIHRZ_fW5~UVsS+L zq)7EgAOJBX%-wsej%g=n@jM}|d&IbHjfTxz)Z95v^iVJe{RHA1k1Jt|&zp=Obsy6O zJ24z@^X$oXSi4_DoQRWh*KIS&jFKeNn{#&SfvDnI^CkuKMsPRviMrs!=xYg!HKmDce5^3*>f!5FQc>ADFEDOF^87LK9056Jdbt0RJ zO}=If_1Ee?90;0GHbA#Vu=vAP>WPg?a^3xmiMMt0ZPx49JxdzLSXjFJ@}Av(EG5Nz zc1`pWMnH@P*zDvdeV@_*mVHm!(2rX8#QFj>ujY-3Ibo5TCWJ1JYoW(f$_juka~vtK zsXU{o>}gR&=Mn10-_s)O)(q$He!W&78p2rxK$v7qn>YP#Dc6j|*YYDMs2wvOASvuu<6*k6DfHyN8Z~ znMD$Dn>Nay1e!}bwa}9?loZpZUlVC9**)q8f!@S`-<6_rpt^RGj7Go2zI*(|iJdQ= z6)nKs2VO!*JnSLOy*%wJ&+Buf3XStzQ#Zs9U~5D;R8+VTS7=105u?sRhB z4y%EZIs6h>fq(-+27+&J!P%LDc$6XqD1`^3_M(2`lJZRfMMJaJlju#et9;g`8La{0b@GO~3iMfdxInT^a=IT25$W+j)}NnbLqa zk6&WPhvq)lFAQvANWgH~y}}QUi~)=T=)1YVY!w~(LLhx=B{xYD&{39J7PFpPoGBw8`?d-YRxNk|C>~g^cYUZ>pQ6r8)&zEUA$}AL zh#+swenPHqd`SgVdPkf_xNIUldJFV6?r%>;{_4Ra{gshG8Ds2T+D;+RNN(}I<{r&R zjRz2dtFnnBWtOyHwV151gAOXSju8yA|Ekdc5F};)EmH)3l8CelPwZV2&3Q1henMXb zH2s}RC7gg&9bO5|LIQc3&@hdBUDoN-e0jm{>PS}|1+=GN$5mOp0`(=+Pi(%RlJ?8N zlRa@7AD^LVU-TFgKNyETI^hjJ2H^ju;8FJk?;Du>LZMyP_?e2!Et?iQFXbqNRDzTG zdZ1@e46+An-Rt5OfXObQ@hLk#JKYmreqdlPqs5xHh`sFf%VjW*Ok$!QW{^E!k-8#ueUGNCL=PT8_M9J3no{wU}*7Fn27zOCGwaYx?Y&Le$6aK4M#dQB}jGGAbe#rgq)XY&xR-Bb4d3s(f(IpchFvtx9 z-!2~aL)>a?lPWcy4kH$7U3MrcHjE~7Z?JMr)ayhDSP}O-U70q3+ZkthRL6rZ0`=56 zCyO&=5$h(Lq*@N#yUgLC4SRWmkd{OV5VTxQnl5^iE`*ODhj{wu?Q?7Sp}`2WOa$$1 zXX)h-MPlVI#14gSB<4OQTgf;aktpQPczuwXd&Vz?$zg! zuDL)kHA`(1hXg+PQ}oQiE|A>p{N0bu{W#l-MP3lniCEZPbeHz!tFm_JsNd~O7|Wzj zJA5Cnr?BQMm%N-mqP$|&p!Hel63H)&|B?ooIa1J)5neM$Qo$xDMT3fdltWXiZQ{8k zOIUQa?~m~7I2Z1>T4MXY+S>^a#a}C8eq|CjSA1_Gtj)z zMUGk$AR1$Wye+haak8r)U0H~8(4qZJUEX;oy;9ps4=ff066~LegMY>J%&E?dB@y(Q z4-6VzX4=5mx1KgIrjw;Dq@{o1&|+c-<-AMlaQ=j7ooSSPS{aZ*9pJCqA0Fk}lW%J& zj*|*rsQxAyQKuGv#92=11qxqnO^id3xE2Rs*Np8Gw0n3$Z2u0CGLclz{Pn{KPi{Qi zDMbVvTfMcP9D>rbV;D?l64;*EA+)kZ+riADa&N?|Y9~}`O#>9>@95lXbf%QCuv|$>nR|GGIyN_+FGGC8sSL#gf5M;0!(snX%7!I|n7

6D)q^+~nii?E3n)O0P6;VMs|_S_t~eU9)%fWx@4(F zhpcOe?brP+V!IawE4R()#4Uj4XHeqHHuw4~#Z=Xj#+r*qUj{>{63mqSbyuPOc8hCPql!qW58clwBIFukWpJE@p!?AMynhnEAa4 z)<13YmU!O8hsrKMfC;FV>9bv}qSM-Y#~L3tYL3xFmR+Xnq!poQ=ffW)&Hf*b%ZiAF zr}sY`91qoja{mC0-~wpMz3OOwFg{w3(%3*|$&X?~wG(m~$a<*m}hV@|h zwtF@H0BP-oIF5AYg>@SBj%q6aRz$r1x8Gn!rNxZVRsy?!d}VTHPBFw@{T)S~m0MDk zvgF0dQk2c)k1Jco;|>+dGRC@ck{>5fdjoAqN0)vCGGjaR$iKL5i<;Kay>0(Svjvo{ zeS+^gsd9|w&jYvgu6Akmi0Cba zJXeCFKt6eV)M-R)9=dZdQ<>16=1Z*n=@#%ij2IJ z9j&m|OXUqv>}&gR#U7{qdT*ga3`|ix!<(liVv=cD!)x*j2TRVB#;)b#WD#T(XO@&$ zGaSfzoYjj99r>qK!Fyad_$^-DTj#}z(^LSRbfOu>%Xh9A?-8H67UA`&sxJw7EY2>F zuNQ&At{Gb_E&7y2oRoxl9YL-*U6cAHp$HHfa|ijARoJK-g?^*G#fIXcjD8FFuoVdJ z27lzTKylBUEMvB0zd4hYU>i57xf?W{WTg>M9S-$fn=y=D(pPWy3h^d+K~99>6JSp@ z6{>_7zBMQvbaWiP?U;&r-dL(Cs|7xc$egSG-20cEYB4ZM3vBUK+#jPT^fdBD5Ft@1 z<+g0%vwS*?nrRqpJxDN;$e6psrf>U0L#(*hUS%;3eIwjm<$uiH6bIy0wv3A;YUSm! z^PL!fE31m!OGv`_zhM?2c3ed&Gc8E)1<@*dg7axaTEqeSIUaD#f=DtsV@c;}TZ+$I z2fDnjmu|S?5(*Xa25;s=0xsB!+mNuehPQ1wK-V{7Sd1Z1zTaQ;FK2|R0MGMy zDgNO*u7<#ywN~5f+;7C!?i@$KLzlm7pw~>toU35p-ZDiQfkN?&x2N^Puv@q>s+HC# zGcj|)5Y)tZiF)kd%4G@7_Yp(}vI6?g+KUKV7kb9K31zS}p)3>v%C5)XCBCQy1)2!0 z4koA6;7*NN)8rvBJr1*`Ld=^|EgyE4ja%fnmGW@jc{T<>JrcThgiZb^S3yLHXO@Gi zBIQoJWW(m;0II6ii>Klk9`W=YPaj9BPqCpxtb?7nWl-$(HE3{U5Ef9XPgFN!a;Mh& zh&P|vAqiofL&yUKylJM=c(B~tLh}8l`y+R(4~?#(UpI3zBW4Q&DryuqTQmO_xRyB4 z^l?o3`A3#PL2lySCU~o~MvjJ6mG%-cR5Wku4JgxbaH3}Zdx;OSHjPHoWtzo@5B5t$9bb%C$7eq_AE>B;YV>IR=vU3TDXzNsq zhsvEm=Dzp$J(NFpH?XBA2A0%4u9m^J|FOT6a_6oNZv_1*YE6=}M_Au|FyPq;8-M_U z${4huPaKaoY*Xwc^+`XK}t zM!`IgpU+7nTam-~XW@Pz>S6D1Zo!I9?ADx+XA^j|v>dA{GQ)1*Z+r@wms8tkxR8Cp zsJNmtag&Yjz@5Kk5|dHBGAmFOjzBg5QHjomOm(to2N`{VCyM!DnwSo#S~1NU+c0i` z?hP3Qs7ZyU^Y@*0T4>{_`NKuOr7Fm_<-t5NuwRAR18@zRElyGgiQ01ePA&*aoUijo8qY)n`4YY0WZSd3d_>( zt7AQHFV@PkUjKEM#fdy4vs9jbvL)2sfg%vi7(y9+Rza^wya{8yMhckaogTAVAhY64 zhi1D5<=O@-6@1^kcF7RRm?SQX5^}|En5@iOVp3~@PLsHVTA^BTvvd;NXnq)S2wooE z+C-LyNsl9^9)&B=FyCqz1LtjL^yK*~O9A7W%>8d$(iJ=~F8O{#;YZz%fG&f%%9xjf1o8feIeH470Acqy?C227Xdr+;lI($fTzcw0? zm6Gg_oG6Y+q*lD0FCDUbndMT-*1xKyfYL>e7~K|=d~OH?&f6(UaM9Q}KnYoz$9&Ny z!&f?=Jv{5?O@MfLr)fs9m2mg_T4ZcvjzUl_`%v-bf;2fB`1c>nQ}FdLZg`Etn|D8+}q?@Q7E$ynCpqz(s$ zRl&d#5@^fpg!P^7G2b{(T9Y2IN0CcVA2Rg>)@M-#(sAl0v_=;utbs=OX@67(&T95X zpB8)p>(kZ98YtQn7-N<|QFm4z+~3$CF+l{du&VR`otHXca&Ol_{ekm4;ah3yVVUFE zyL_|m8!L3`hZ7?n+@8AjZ{SK&r8(dM3Hb(vJKux`lDWfL*cxy3YeNjze)`Dd<@tXk zw)K|yfkfOhxYrF++IRK`nP6%cM*op%%$ys|6}!C5(p}e916fKiNDUC+AFNmy`6cZ0 zhz!V@GLP`gIZM*?n*9D;341kF>uv(}2k15~fzk{P3Yo_?o zaG_lAiql0I(3`9igDmqBBZR^@h7eya^tsHY`ap)odsbZa&L_m@0z~=3WlgD1QA+*8 zI2YVT!a-ZT0FboYyd@tSi>on71o=?B^Lvf-79Fub6(p6yaDkd76Ut7n~pI^ktE(!3ryD3ae5O~r_t;shiy@8 zk$Z+TA$oGwVE1$v_D^+I40&uz7)m7Wjyga_}R~CK$l>+fwm?bTs?ho2-sm zvEFC8tvs)K44v9PojRA7*PUUe^C@l=k~rzZK7;vv-wR*x&mmgM9VIwz?m}TnvrP-rQhT(WqfxM)CXDs<=F=n!2 zRJlygSHgD55tlBsYl=jrn$Iq)Og`t{4KzXzeG3UIT#;ai$gid(?DN&4saE$0C9Z&i zD)J@*K=q(z=fRq`>zK)&M;r2x6mL|W0(hNYIhjIo4XkT;_n6LgbXPedT5CUT@z5sT z<)Nb{st8!;u`Ca?S2Sk+?v94OmQPvd3fjljI83kLz>)*mCe8Gac>3X2P8SEzM1rA!*iHp`F70-0G&k}(S1U3V*4F5ImmPG4+27^Z67v(Uyv|Hav8Yqd`Q69p zfEGH^8WYcGdhuHNoS>myYSGB}h0F$Iq#YqSi7KiDWy@InZl-{kN%OyEvyZcr z&sEEDPO15;_DxMKHx?UwLU-nxS|gmf_CvObEfjwV-yPxgC6FZ~Aj1Noxk&Wb?E7O9 z$e=*axM)E2-<0FpPtaY!qUttOSnPN8?N#? zA~^ld^Q%K;eS?;{f>?t7-^t;q6I}4RQ~lZUGEAlx-Zx@%Xt;zo-45rtK5*y%LJJ-? z1;YWe%8!bggue9tm^CZ!CjQC)dZ&rJU}uAZ0XYz3=mRo?J-B)^s~@hbr! zR?PaqqFID4_yb}CWDf{eX<2i0aqD4L0@?QLcZ>%FdrD;xIl6KT3v7atxetTQS9f6l zdL*L>xRHNb7EY`2NKCJ>tf6%+=_|DTHD_th{OOB{7M)`vwxjV^5DNJYJr z=--+4lp}@!)FaGt*~Mm6E|x^`wZuDf@yxuX<=SUx*i*!Y4oB@BTl`$)zxrbr<(;xjq;u9n=o4;E;%_=uOI>khhhXo>S7bkp zOYBhqJBl!@wLwe@>h>|c&u3e| zaKG4bZ`wDe!eYaO`QAvV%S0&EA@I79dw}->K#zvhpUfxp#qqM^d~omppLmicxuE-S zxqZ|cSbzLj@=Hu3PRolADXh9;hLkvfP#*eTB)a~4HF(BWCP^PcKj9Er#pO=Up94$o zIHz=4R(6oI>C{cOD@aUG; zSl~G&JmL->5LmZ9mp!X*+XnbS7PvR}rrwV{<0^^gec*ome%PcQ_dxLL9vQ0KD0fCW_2v~Rk0nq9@b<8J5pAQih zaWlj_jqR1H^bJ*PekO0m%n0lU?$AAaGj-=uokEH>M)3p3!RZo)@p>K*-Um6M+dp)kQsMF~tPr)f5i?_pAGA6mVRaKU&p{Le-~Ykk zuW}KEK&*JQ08DQ`c!#6kOF+)!xDtXNqZf<-fl0(k!dJokE0&;2Uro1X1qN!WU!V7m zUU|j5ceFyCncN1a<4>MoShhKfO8D}Ji{E*tj42>|>%h+h<+-d;-lS#cwGZjj)pcx& zA@1+eU2_;lBs49s#lC=O(kP4AiG_u?1@M&B44bM;{M-1w$q~VL$T-E&ex2b$PR5=2 z0&>knnmdI)SfIliQ}bDz+2D2-E*)Bt6)-;%xDHgGr{c56%-R+z5Bz%n&|$;XXx+5< zfyM}8KA^kn7@A?!gP$h88ydp8Ja*%FB3g&zvhM9akCmt^l~L*r97cxlh-oQswl2r8a;dq*Ux^UBQl9npy5t{INw>H*u(RJKB zpfX`RAdRVh<1R5{cy1pb;((ec??%R*q?G z7q-Di?>G@loWHO{=fpJGO!n>fCku11Ixr6d^+4ip>I#zk0!BOhEL1_UkacWa5@tk9 zQ<5j}>9^T3zrtv#L|>nh$xzDMtOqFe8waWWH9Xn}C?al7pT6Npa~ zFD`PNqL%+plRuIi+s%P@2_M^MH^#0JGVUvp_q}`b%eNKce)1xaU?!M&rOp;sd|+W8URh#sGaE3A zCrdF}FtuDX3>`#wk$Qz+In0B^FEiFVGO*+2&yQJM0a7HLp9H1n_GMKeyFp08nC^+2 zBei*qj%{M>$8}za4=uK28v@--d2PU9*q0|QR#uJ?(q+ZG>>nGVr{kb9BZ2D%@R8m< zr9o;8(0+47l{rz%dVOROc=5azU1^AAA^t%##VyHX#uFHMsn_c4$_?APQpB-(D%5G7 zf|EOR{*`Z3VSsQ z625|t;fQr~;=U>=3j+t4O(RKGsxlef!tbU$w;|Va`@M}|<0MOYq<)#bbFCpDimGr% zD$)_?Gn$+6LTwZJB$+qUM6!Eqm84+^#OcPAX3ayXs81R%zjF|Q;)_Sr$4LnkTQ9IF zxT$dd{pV<#IV2&-Q`c&bsFuM`<5oDr{w*w{`#0YP?QO&Evz;FWC5i7V6+`$y>o5S- zdZJJY!)~4lHbtF+aYW=b89vBtITmRRQeOJKTrlDWld?xFH%ld%wg!WH>jl)ILH8Eg zU=LGoB=DtfJR3aAFdlM;vp012tiIURw^_~^LsC=fCaAxqqc>#3Bn{UTW~WuIB@AI$ z>1?iE3pwc$k(djLy0Gz4>?(E?QCn?%8xv0|onss!^~N$|c2M7GJ{RjO(*ZsATBlE2 z8{E_g_xR*)+-WW%_%fD^Fu^!SjxacVAF&yo6JZ3XtDJBm&D7G=MW;PIcg_M8O~hmF zR}7w@xc%2m5{H@kWYTgNug8h1UIb#nBGI;`Rx2(y zPe4E#A1lXQCp$0%*6rxr0@lb*x$Z~E^y*P3Cbks#9dq|1kii3`db!amMRr|4f`x|L z(o-*qE*_Zuc)vV;7SJ?foQ(mjjLYoM)G4hMKfsFbu)m;ZUogdeh%9I?%b-pcKe))J4?}A|y`>6apyrDYD({J~! zMO=TO!NzzIl;1>y$0^YJNJ2)W5R4}^&=Eh2S(5mZs2_cTepG>3rDym76gbVR(0yN- z273(DT5c`8kzpc$Q=)81e-kjc#v`FaZm)1>NotA%)*KMR#R2#9+joy2 zyj9Dc+caIJ2@8Yyd^s_~6ej2_xkhXhQoUW~H49Z-QXC=2>Jm&_e zF8teyr?JHT9E*ArVYKdF@_*Qp&pM?T&5yYt;iG+_m$Ka@A30aI2iuVT)by^xTj&q_ ze7AmHn-LB6V%k*p5DvZ)I>!nS4&&Y+V5j$DNJ4>?atGfqLA3;%6=LjZ^3jUdC@$`s zzhw!D+>RcaSs`B?cUI#c+$KWG|HHbtQD$Y`Z62JZ%>83#!!kD-QrGQYLcHujt9BlD z?N0FM!}Z^Wu`VzP*$@A`;zyWqGl#a?L`(lri@ICrMR*Nit#I4&w=qjNC(yOcbBJwG z6t!?}BH$-Ypf!2g3cwg+`IaAS3aR+K2MbpdP_m#so%I{7r)nsbH+`1v z0Q~gn!LMZne4+MLN?(qZCYU01G>e`90Gs>fP4<}~Q}lTu$)Y03x_T00p=)L!U$)iCZid%lXis-GxO3(FbTGkD-ZsH-X{ z$7Bgt+sS4@ktCO9jdXTAA1IMGnbO!^o4v_R2grz!k)ZIwJnW(d2w#0YjKs$RG%ymG zwCZ-;Al)m97ZUuA6OJl1$$EDnF95d|{h#;#3t7o3{T~(^YNQv2Ma5wvA#mK(t=KUE zX6`nPNvonL`#N<2vqsl_YcR+nSi+4tN?Aw91H~5B5dJV|@n*e)w~_Kb+OHF|B*G^a z$f-w$pb{-^*)AgEJOM;BaL+3uB~;9;_oc{p8YB}ofxooXdE&d-uISz6@IQp7Ph z#H6IuHs`?}npTB0d<91llmwWRdZdXB^y9Bv4SV%xUnV#m55eXVqthp_9?FBGEHU+Q zQ`2yI1igUVXaau>nz_A}(`?jBxMSN`E~=`ywQ0N^rY7CSG?nu&WVkV@Di0@FL5dWr z%pl{j*Q^2?+TK&_baG23g(ck7g8yjD2!%i&D}$#%UA_Ta4x{nK+=15isu9?DSh)DN%z#v(FdO1vzkv>P8wlh! zjjTOuArNHfiYOU4n#3TEm#y@l3jxo|wKX{<=&=TGOcCMoOjg_KjRQt`JmdI6dQ6x_ zfK!g|st?}`ypQj3%?)rOr+zOT3Z%Tl8e-^+d2b zP}t&Z{eduCy^7ZiLp)@5mqV8jjCfQkAKqL*6Lw(!%MU4rVa-9KD2R9jpzzQhfm(RX zO_ELLPMlgeOKV+t&8LG0jylqa=GD#HDR}kG*^+k^F54gT)*`<2rmiBbt{9O`2@g;A zRRW3OIpTL3Moe>Y2NZ-Z&-j(Ez`@{A$(zIF-y9=n)FGG z?qPurcuI;wx=d2KcsaBJp>;5OG>sYl2JO7C9oLXzG}Y2KpKS+;yN`g_Mxv=KLSc`I ze(^|sxG-%so<0xIZ_GhlcCB36pu$XC61P_!P}{~`ZRp`w4)u=#&$dDe#XoRexD*av zR0*XS>k+CwMlA-1*mr324bou-oiH|8DXvoJDd6!@X9^{I(pM#C|I8r5GY5EF|C2~k z>|9?+6+H(BeGiB4Nl^WD=NRNyK9HI`x3&T&m`7@MfnnQwWBJ>wGHw$Lsee?z=lG?x zyG$M-_!>4eZ|(rUAPd;AB2^V{2|az>((*cAP@|z~I_rT+CDo`kekvHgSQ1-*Kkj46 zvce$+;b%RiJ<0aX!7T=?v%@|bl_7=R}De#Df&KM&(B(zQcYP;*S1C9gPD=Cx}cdm!S z>n3WP-VP?mzFN_&^m@w`-t?^6tC195>_?;DH1IStoZY>86e%0x{t}|ZnPLNTbe`Z%Gl|9N!@8z~de6KZd z27TyKbTg-%_`$L6=lnSvnBE4tyGVvs)p4Ko(g({$qUFio3aXz%y0YbI%Gl&jgkG2; zH3#wb3~qBAY44f417h5-BCnhI^66+MkFPwq= zP&CY$&XOp#9X6LqWosDNgjtI+FMA}S4-(1HJ%577Tqon$O8r$HW8E^A-ggcjw}9ii zfZWsglm$t%CN_oPC7FG$3^JW*F%8-6?Qf4Cdx4ZT^|f4P2la=mLBKWzAfiRNSRt40 z|7VE$c6SO6Mp>>!L2it9;5zdp;>gV>j0jkZrRPlM{84Imyrv_pOvbAR;bLbL-%m_a z>Z$|E81a`mOjXS`mue)QecBs^-j!yk|Ie+eTP_X8E@jiX1#iRWv*t42{>WmHZ;eIckE!y z7-Vcr{k>fG4PV`j(A>m@*X1NVt{ER@z`MG$Q zbNJ@6j%ws|yxHo$@NW74h!I9v2^7M$@sNk%gus}SY7bgU*5axd^k8?N+dT!0Z8y4B zpujsi7zKZb_#a-okYRRkjJ;}pnZdmN*_TNZeG?p3ZX)%uBHktlMpY|~pdVfEvP5f0 zolXUG*O#^kM(h&5gnj7Sd5bDS+~TyCBU$VvUf@OTD*I#R?$-WV`cYbI(ac3vMq$(; zCZqtY@Ecxe@)Sd94u?!G4~}GEoI3M{(Ol=q4o7z{J_RgOo{T@BkNNF;y`xyS9en1d z|E689I}c(TTP~!&W)mmyR@l7jbWNU5TYNiS0Hkqml;H^clp(=`*EsTzF&VOjXaFCC zt~{HP@KUmh7T!+wSLllakLvyI8$!n-&B9=NP9#9{q`dWOym51CkXjHCcwwq#ey718 zi&`}p8@vSEaxJY$Up?>423dYBAuE0X#vjoKu@}>EN)bkofqNq5^YJ_a1fc6s*dLpf zM&=lMf<{3e(MlJFB*Dg_!;J6%5sq=;*I9G=;6OfbyJ>hmsfl?2vqy6bmDW6dHaaCn z6h|18JQjn3TtGuNu?1teEm@|YOZ|H|j26})0?_UDYTGx2sRdpM9PssXyp;(AdaW+f zwl8sQO!SFrAkU`Yq;rk2l?iU(XpJ(KT}oNgb@8$vFlFm7)K*8u(A~{oU2ON=8o@0@uiioOR-}8%QR5WPuuPm@f#qw(vj~T z#8pojGZ;{&>p~w2^47lTEAIM~82A};Xd;&=Yj;KgDI!EaqO5=GOfoy7j|=9;)~GuX|YxQ&72x_SJvij z0xYao#M|mT5%-*1cs*A`1kyu2Bt5BN$AVrUdl<77q)6A1jowh@pkQ+0Gd_lHFm@6r zdQX%?i1A-Q+Io>4qZqjAqp#V8PL%2V{)2~FOTR!Gdhzk5owF>%L1Qa>8r-}PzFUKsTorrPLSO_Rnt@tUfPw> zPC=)c!@5vdNECUkvW+Rah8T9h#$2QGEj7(Mw434tLyjA9Gsh3KPZt8cqfwL*MnkvU zeE}gW>h7ouM-qx&R?*n-q&eaatMF1S8j=g6$30%F7MSq9aTl2igpsdEL3haaf9Uuz zb9yfOKS6fo)UD|;EZjtq5+-JhnLpc##v#$=b&~=nn^?2VH?U6>bxOkFewIXr7WX7x zi6|ulO*HV3qsCMo3_5e?`yd};Y?*(sHEH`^CTgA9UAMxD@D0L;sU-@6RS`NULkn|q zwkI>euV#T&cZvIH(O4YwlnSXi5dvv51v~~fj6wM$tlXR7?QB$=`4r+*H%0-S=R52y z7qVNBs%Pp_9bW=!NBX{t=ha1^v(uc zstInJ{-o(SLBDVL>NErh6?b2$n)2nfx=KOB4*-1yh|@_%?#JA1;cG#dIMq=|i04TQ zr};l}g~`okV$PKX%il^p4?nN$<|#h}qFaydty@=DSomBT4pneV=PBJOxGZ^S{55BuHB~fXOF@2L$sFS}ScnU2eneKvs}BXq6umjPFuooi%*5Lvvd~JA-4oQam|+YWR!`Leq<9c-&7jZGln4 z$AD6Ccx&LIE*0000EP`H#q*62(C0p+0#;Kwsfr^FDk#Ao{g K000001X)^QXV_5y literal 0 HcmV?d00001 diff --git a/kernel/kernel/files/patches/mageia/ata-Adding-Intel-Lewisburg-device-IDs-for-SATA.patch b/kernel/kernel/files/patches/mageia/ata-Adding-Intel-Lewisburg-device-IDs-for-SATA.patch new file mode 100644 index 00000000..96ca0e8b --- /dev/null +++ b/kernel/kernel/files/patches/mageia/ata-Adding-Intel-Lewisburg-device-IDs-for-SATA.patch @@ -0,0 +1,44 @@ +From f5bdd66c705484b4bc77eb914be15c1b7881fae7 Mon Sep 17 00:00:00 2001 +From: Alexandra Yates +Date: Wed, 17 Feb 2016 19:36:20 -0800 +Subject: [PATCH] Adding Intel Lewisburg device IDs for SATA + +This patch complements the list of device IDs previously +added for lewisburg sata. + +Signed-off-by: Alexandra Yates +Signed-off-by: Tejun Heo +Cc: stable@vger.kernel.org +--- + drivers/ata/ahci.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c +index 546a369..b6263b3 100644 +--- a/drivers/ata/ahci.c ++++ b/drivers/ata/ahci.c +@@ -367,15 +367,21 @@ static const struct pci_device_id ahci_pci_tbl[] = { + { PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */ + { PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */ + { PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* Lewisburg RAID*/ ++ { PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Lewisburg AHCI*/ + { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* Lewisburg RAID*/ ++ { PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Lewisburg RAID*/ + { PCI_VDEVICE(INTEL, 0xa182), board_ahci }, /* Lewisburg AHCI*/ + { PCI_VDEVICE(INTEL, 0xa184), board_ahci }, /* Lewisburg RAID*/ + { PCI_VDEVICE(INTEL, 0xa186), board_ahci }, /* Lewisburg RAID*/ + { PCI_VDEVICE(INTEL, 0xa18e), board_ahci }, /* Lewisburg RAID*/ ++ { PCI_VDEVICE(INTEL, 0xa1d2), board_ahci }, /* Lewisburg RAID*/ ++ { PCI_VDEVICE(INTEL, 0xa1d6), board_ahci }, /* Lewisburg RAID*/ + { PCI_VDEVICE(INTEL, 0xa202), board_ahci }, /* Lewisburg AHCI*/ + { PCI_VDEVICE(INTEL, 0xa204), board_ahci }, /* Lewisburg RAID*/ + { PCI_VDEVICE(INTEL, 0xa206), board_ahci }, /* Lewisburg RAID*/ + { PCI_VDEVICE(INTEL, 0xa20e), board_ahci }, /* Lewisburg RAID*/ ++ { PCI_VDEVICE(INTEL, 0xa252), board_ahci }, /* Lewisburg RAID*/ ++ { PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/ + + /* JMicron 360/1/3/5/6, match class to avoid IDE function */ + { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, +-- +2.7.2 + diff --git a/kernel/kernel/files/patches/mageia/ata-ahci-don-t-mark-HotPlugCapable-Ports-as-external.patch b/kernel/kernel/files/patches/mageia/ata-ahci-don-t-mark-HotPlugCapable-Ports-as-external.patch new file mode 100644 index 00000000..6b53ff17 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/ata-ahci-don-t-mark-HotPlugCapable-Ports-as-external.patch @@ -0,0 +1,45 @@ +From dc8b4afc4a04fac8ee55a19b59f2356a25e7e778 Mon Sep 17 00:00:00 2001 +From: Manuel Lauss +Date: Sat, 27 Feb 2016 16:10:05 +0100 +Subject: [PATCH] ata: ahci: don't mark HotPlugCapable Ports as + external/removable + +The HPCP bit is set by bioses for on-board sata ports either because +they think sata is hotplug capable in general or to allow Windows +to display a "device eject" icon on ports which are routed to an +external connector bracket. + +However in Redhat Bugzilla #1310682, users report that with kernel 4.4, +where this bit test first appeared, a lot of partitions on sata drives +are now mounted automatically. + +This patch should fix redhat and a lot of other distros which +unconditionally automount all devices which have the "removable" +bit set. + +Signed-off-by: Manuel Lauss +Signed-off-by: Tejun Heo +Fixes: 8a3e33cf92c7 ("ata: ahci: find eSATA ports and flag them as removable" changes userspace behavior) +Link: http://lkml.kernel.org/g/56CF35FA.1070500@redhat.com +Cc: stable@vger.kernel.org #v4.4+ +--- + drivers/ata/libahci.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c +index 513b3fa..85ea514 100644 +--- a/drivers/ata/libahci.c ++++ b/drivers/ata/libahci.c +@@ -1168,8 +1168,7 @@ static void ahci_port_init(struct device *dev, struct ata_port *ap, + + /* mark esata ports */ + tmp = readl(port_mmio + PORT_CMD); +- if ((tmp & PORT_CMD_HPCP) || +- ((tmp & PORT_CMD_ESP) && (hpriv->cap & HOST_CAP_SXS))) ++ if ((tmp & PORT_CMD_ESP) && (hpriv->cap & HOST_CAP_SXS)) + ap->pflags |= ATA_PFLAG_EXTERNAL; + } + +-- +2.7.2 + diff --git a/kernel/kernel/files/patches/mageia/fs-aufs-4.4-modular.patch b/kernel/kernel/files/patches/mageia/fs-aufs-4.4-modular.patch index 44d224bc..6d4da033 100644 --- a/kernel/kernel/files/patches/mageia/fs-aufs-4.4-modular.patch +++ b/kernel/kernel/files/patches/mageia/fs-aufs-4.4-modular.patch @@ -1,22 +1,25 @@ fs/aufs/Kconfig | 2 +- fs/dcache.c | 1 + - fs/file_table.c | 2 ++ - fs/inode.c | 1 + + fs/exec.c | 1 + + fs/fcntl.c | 1 + + fs/file_table.c | 4 ++++ fs/namespace.c | 2 ++ fs/notify/group.c | 4 ++++ fs/notify/mark.c | 4 ++++ fs/open.c | 2 ++ fs/read_write.c | 2 ++ fs/splice.c | 2 ++ + fs/xattr.c | 1 + + kernel/task_work.c | 1 + security/commoncap.c | 2 ++ security/device_cgroup.c | 2 ++ security/security.c | 10 ++++++++++ - 13 files changed, 35 insertions(+), 1 deletion(-) + 16 files changed, 40 insertions(+), 1 deletion(-) -diff -Nurp linux-4.4-rc6.aufs/fs/aufs/Kconfig linux-4.4-rc6.aufs.mod/fs/aufs/Kconfig ---- linux-4.4-rc6.aufs/fs/aufs/Kconfig 2015-12-21 19:54:42.973923445 +0200 -+++ linux-4.4-rc6.aufs.mod/fs/aufs/Kconfig 2015-12-21 19:55:29.522275768 +0200 +diff -Nurp linux-4.4.3-aufs/fs/aufs/Kconfig linux-4.4.3-aufs-mod/fs/aufs/Kconfig +--- linux-4.4.3-aufs/fs/aufs/Kconfig 2016-03-02 17:59:37.360498681 +0200 ++++ linux-4.4.3-aufs-mod/fs/aufs/Kconfig 2016-03-03 09:50:41.232631276 +0200 @@ -1,5 +1,5 @@ config AUFS_FS - bool "Aufs (Advanced multi layered unification filesystem) support" @@ -24,9 +27,9 @@ diff -Nurp linux-4.4-rc6.aufs/fs/aufs/Kconfig linux-4.4-rc6.aufs.mod/fs/aufs/Kco help Aufs is a stackable unification filesystem such as Unionfs, which unifies several directories and provides a merged single -diff -Nurp linux-4.4-rc6.aufs/fs/dcache.c linux-4.4-rc6.aufs.mod/fs/dcache.c ---- linux-4.4-rc6.aufs/fs/dcache.c 2015-12-21 19:54:42.986923543 +0200 -+++ linux-4.4-rc6.aufs.mod/fs/dcache.c 2015-12-21 19:55:29.523275775 +0200 +diff -Nurp linux-4.4.3-aufs/fs/dcache.c linux-4.4.3-aufs-mod/fs/dcache.c +--- linux-4.4.3-aufs/fs/dcache.c 2016-03-02 17:59:37.376498796 +0200 ++++ linux-4.4.3-aufs-mod/fs/dcache.c 2016-03-03 09:50:34.633586562 +0200 @@ -1272,6 +1272,7 @@ rename_retry: seq = 1; goto again; @@ -35,39 +38,66 @@ diff -Nurp linux-4.4-rc6.aufs/fs/dcache.c linux-4.4-rc6.aufs.mod/fs/dcache.c /* * Search for at least 1 mount point in the dentry's subdirs. -diff -Nurp linux-4.4-rc6.aufs/fs/file_table.c linux-4.4-rc6.aufs.mod/fs/file_table.c ---- linux-4.4-rc6.aufs/fs/file_table.c 2015-11-02 02:05:25.000000000 +0200 -+++ linux-4.4-rc6.aufs.mod/fs/file_table.c 2015-12-21 19:55:29.523275775 +0200 +diff -Nurp linux-4.4.3-aufs/fs/exec.c linux-4.4.3-aufs-mod/fs/exec.c +--- linux-4.4.3-aufs/fs/exec.c 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs-mod/fs/exec.c 2016-03-03 09:50:34.633586562 +0200 +@@ -103,6 +103,7 @@ bool path_noexec(const struct path *path + return (path->mnt->mnt_flags & MNT_NOEXEC) || + (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC); + } ++EXPORT_SYMBOL_GPL(path_noexec); + + #ifdef CONFIG_USELIB + /* +diff -Nurp linux-4.4.3-aufs/fs/fcntl.c linux-4.4.3-aufs-mod/fs/fcntl.c +--- linux-4.4.3-aufs/fs/fcntl.c 2016-03-02 17:59:37.376498796 +0200 ++++ linux-4.4.3-aufs-mod/fs/fcntl.c 2016-03-03 09:50:34.633586562 +0200 +@@ -81,6 +81,7 @@ int setfl(int fd, struct file * filp, un + out: + return error; + } ++EXPORT_SYMBOL_GPL(setfl); + + static void f_modown(struct file *filp, struct pid *pid, enum pid_type type, + int force) +diff -Nurp linux-4.4.3-aufs/fs/file_table.c linux-4.4.3-aufs-mod/fs/file_table.c +--- linux-4.4.3-aufs/fs/file_table.c 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs-mod/fs/file_table.c 2016-03-03 09:50:34.633586562 +0200 @@ -147,6 +147,7 @@ over: } return ERR_PTR(-ENFILE); } -+EXPORT_SYMBOL(get_empty_filp); ++EXPORT_SYMBOL_GPL(get_empty_filp); /** * alloc_file - allocate and initialize a 'struct file' -@@ -308,6 +309,7 @@ void put_filp(struct file *file) +@@ -258,6 +259,7 @@ void flush_delayed_fput(void) + { + delayed_fput(NULL); + } ++EXPORT_SYMBOL_GPL(flush_delayed_fput); + + static DECLARE_DELAYED_WORK(delayed_fput_work, delayed_fput); + +@@ -300,6 +302,7 @@ void __fput_sync(struct file *file) + } + + EXPORT_SYMBOL(fput); ++EXPORT_SYMBOL_GPL(__fput_sync); + + void put_filp(struct file *file) + { +@@ -308,6 +311,7 @@ void put_filp(struct file *file) file_free(file); } } -+EXPORT_SYMBOL(put_filp); ++EXPORT_SYMBOL_GPL(put_filp); void __init files_init(void) { -diff -Nurp linux-4.4-rc6.aufs/fs/inode.c linux-4.4-rc6.aufs.mod/fs/inode.c ---- linux-4.4-rc6.aufs/fs/inode.c 2015-12-21 13:06:55.265034468 +0200 -+++ linux-4.4-rc6.aufs.mod/fs/inode.c 2015-12-21 19:55:29.524275783 +0200 -@@ -1593,6 +1593,7 @@ static int update_time(struct inode *ino - - return update_time(inode, time, flags); - } -+EXPORT_SYMBOL(update_time); - - /** - * touch_atime - update the access time -diff -Nurp linux-4.4-rc6.aufs/fs/namespace.c linux-4.4-rc6.aufs.mod/fs/namespace.c ---- linux-4.4-rc6.aufs/fs/namespace.c 2015-11-02 02:05:25.000000000 +0200 -+++ linux-4.4-rc6.aufs.mod/fs/namespace.c 2015-12-21 19:55:29.525275790 +0200 +diff -Nurp linux-4.4.3-aufs/fs/namespace.c linux-4.4.3-aufs-mod/fs/namespace.c +--- linux-4.4.3-aufs/fs/namespace.c 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs-mod/fs/namespace.c 2016-03-03 09:50:34.634586569 +0200 @@ -463,6 +463,7 @@ void __mnt_drop_write(struct vfsmount *m mnt_dec_writers(real_mount(mnt)); preempt_enable(); @@ -80,13 +110,13 @@ diff -Nurp linux-4.4-rc6.aufs/fs/namespace.c linux-4.4-rc6.aufs.mod/fs/namespace } return 0; } -+EXPORT_SYMBOL(iterate_mounts); ++EXPORT_SYMBOL_GPL(iterate_mounts); static void cleanup_group_ids(struct mount *mnt, struct mount *end) { -diff -Nurp linux-4.4-rc6.aufs/fs/notify/group.c linux-4.4-rc6.aufs.mod/fs/notify/group.c ---- linux-4.4-rc6.aufs/fs/notify/group.c 2015-11-02 02:05:25.000000000 +0200 -+++ linux-4.4-rc6.aufs.mod/fs/notify/group.c 2015-12-21 19:55:29.525275790 +0200 +diff -Nurp linux-4.4.3-aufs/fs/notify/group.c linux-4.4.3-aufs-mod/fs/notify/group.c +--- linux-4.4.3-aufs/fs/notify/group.c 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs-mod/fs/notify/group.c 2016-03-03 09:50:34.634586569 +0200 @@ -22,6 +22,7 @@ #include #include @@ -99,7 +129,7 @@ diff -Nurp linux-4.4-rc6.aufs/fs/notify/group.c linux-4.4-rc6.aufs.mod/fs/notify { atomic_inc(&group->refcnt); } -+EXPORT_SYMBOL(fsnotify_get_group); ++EXPORT_SYMBOL_GPL(fsnotify_get_group); /* * Drop a reference to a group. Free it if it's through. @@ -107,7 +137,7 @@ diff -Nurp linux-4.4-rc6.aufs/fs/notify/group.c linux-4.4-rc6.aufs.mod/fs/notify if (atomic_dec_and_test(&group->refcnt)) fsnotify_final_destroy_group(group); } -+EXPORT_SYMBOL(fsnotify_put_group); ++EXPORT_SYMBOL_GPL(fsnotify_put_group); /* * Create a new fsnotify_group and hold a reference for the group returned. @@ -115,53 +145,53 @@ diff -Nurp linux-4.4-rc6.aufs/fs/notify/group.c linux-4.4-rc6.aufs.mod/fs/notify return group; } -+EXPORT_SYMBOL(fsnotify_alloc_group); ++EXPORT_SYMBOL_GPL(fsnotify_alloc_group); int fsnotify_fasync(int fd, struct file *file, int on) { -diff -Nurp linux-4.4-rc6.aufs/fs/notify/mark.c linux-4.4-rc6.aufs.mod/fs/notify/mark.c ---- linux-4.4-rc6.aufs/fs/notify/mark.c 2015-11-02 02:05:25.000000000 +0200 -+++ linux-4.4-rc6.aufs.mod/fs/notify/mark.c 2015-12-21 19:55:29.525275790 +0200 +diff -Nurp linux-4.4.3-aufs/fs/notify/mark.c linux-4.4.3-aufs-mod/fs/notify/mark.c +--- linux-4.4.3-aufs/fs/notify/mark.c 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs-mod/fs/notify/mark.c 2016-03-03 09:50:34.634586569 +0200 @@ -109,6 +109,7 @@ void fsnotify_put_mark(struct fsnotify_m mark->free_mark(mark); } } -+EXPORT_SYMBOL(fsnotify_put_mark); ++EXPORT_SYMBOL_GPL(fsnotify_put_mark); /* Calculate mask of events for a list of marks */ u32 fsnotify_recalc_mask(struct hlist_head *head) -@@ -199,6 +200,7 @@ void fsnotify_free_mark(struct fsnotify_ - if (group->ops->freeing_mark) - group->ops->freeing_mark(mark, group); - } -+EXPORT_SYMBOL(fsnotify_destroy_mark); - - void fsnotify_destroy_mark(struct fsnotify_mark *mark, - struct fsnotify_group *group) -@@ -402,6 +404,7 @@ int fsnotify_add_mark(struct fsnotify_ma +@@ -208,6 +209,7 @@ void fsnotify_destroy_mark(struct fsnoti mutex_unlock(&group->mark_mutex); + fsnotify_free_mark(mark); + } ++EXPORT_SYMBOL_GPL(fsnotify_destroy_mark); + + void fsnotify_destroy_marks(struct hlist_head *head, spinlock_t *lock) + { +@@ -392,6 +394,7 @@ err: + return ret; } -+EXPORT_SYMBOL(fsnotify_add_mark); ++EXPORT_SYMBOL_GPL(fsnotify_add_mark); - /* - * Given a list of marks, find the mark associated with given group. If found + int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group, + struct inode *inode, struct vfsmount *mnt, int allow_dups) @@ -492,6 +495,7 @@ void fsnotify_init_mark(struct fsnotify_ atomic_set(&mark->refcnt, 1); mark->free_mark = free_mark; } -+EXPORT_SYMBOL(fsnotify_init_mark); ++EXPORT_SYMBOL_GPL(fsnotify_init_mark); static int fsnotify_mark_destroy(void *ignored) { -diff -Nurp linux-4.4-rc6.aufs/fs/open.c linux-4.4-rc6.aufs.mod/fs/open.c ---- linux-4.4-rc6.aufs/fs/open.c 2015-11-02 02:05:25.000000000 +0200 -+++ linux-4.4-rc6.aufs.mod/fs/open.c 2015-12-21 19:55:29.526275798 +0200 +diff -Nurp linux-4.4.3-aufs/fs/open.c linux-4.4.3-aufs-mod/fs/open.c +--- linux-4.4.3-aufs/fs/open.c 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs-mod/fs/open.c 2016-03-03 09:50:34.634586569 +0200 @@ -64,6 +64,7 @@ int do_truncate(struct dentry *dentry, l mutex_unlock(&dentry->d_inode->i_mutex); return ret; } -+EXPORT_SYMBOL(do_truncate); ++EXPORT_SYMBOL_GPL(do_truncate); long vfs_truncate(struct path *path, loff_t length) { @@ -169,18 +199,18 @@ diff -Nurp linux-4.4-rc6.aufs/fs/open.c linux-4.4-rc6.aufs.mod/fs/open.c } return 0; } -+EXPORT_SYMBOL(open_check_o_direct); ++EXPORT_SYMBOL_GPL(open_check_o_direct); static int do_dentry_open(struct file *f, struct inode *inode, -diff -Nurp linux-4.4-rc6.aufs/fs/read_write.c linux-4.4-rc6.aufs.mod/fs/read_write.c ---- linux-4.4-rc6.aufs/fs/read_write.c 2015-12-21 19:54:42.987923551 +0200 -+++ linux-4.4-rc6.aufs.mod/fs/read_write.c 2015-12-21 19:55:29.526275798 +0200 +diff -Nurp linux-4.4.3-aufs/fs/read_write.c linux-4.4.3-aufs-mod/fs/read_write.c +--- linux-4.4.3-aufs/fs/read_write.c 2016-03-02 17:59:37.377498803 +0200 ++++ linux-4.4.3-aufs-mod/fs/read_write.c 2016-03-03 09:50:34.634586569 +0200 @@ -504,6 +504,7 @@ vfs_readf_t vfs_readf(struct file *file) return new_sync_read; return ERR_PTR(-ENOSYS); } -+EXPORT_SYMBOL(vfs_readf); ++EXPORT_SYMBOL_GPL(vfs_readf); vfs_writef_t vfs_writef(struct file *file) { @@ -188,18 +218,18 @@ diff -Nurp linux-4.4-rc6.aufs/fs/read_write.c linux-4.4-rc6.aufs.mod/fs/read_wri return new_sync_write; return ERR_PTR(-ENOSYS); } -+EXPORT_SYMBOL(vfs_writef); ++EXPORT_SYMBOL_GPL(vfs_writef); ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos) { -diff -Nurp linux-4.4-rc6.aufs/fs/splice.c linux-4.4-rc6.aufs.mod/fs/splice.c ---- linux-4.4-rc6.aufs/fs/splice.c 2015-12-21 19:54:42.987923551 +0200 -+++ linux-4.4-rc6.aufs.mod/fs/splice.c 2015-12-21 19:55:29.526275798 +0200 +diff -Nurp linux-4.4.3-aufs/fs/splice.c linux-4.4.3-aufs-mod/fs/splice.c +--- linux-4.4.3-aufs/fs/splice.c 2016-03-02 17:59:37.377498803 +0200 ++++ linux-4.4.3-aufs-mod/fs/splice.c 2016-03-03 09:50:34.635586575 +0200 @@ -1123,6 +1123,7 @@ long do_splice_from(struct pipe_inode_in return splice_write(pipe, out, ppos, len, flags); } -+EXPORT_SYMBOL(do_splice_from); ++EXPORT_SYMBOL_GPL(do_splice_from); /* * Attempt to initiate a splice from a file to a pipe. @@ -207,31 +237,50 @@ diff -Nurp linux-4.4-rc6.aufs/fs/splice.c linux-4.4-rc6.aufs.mod/fs/splice.c return splice_read(in, ppos, pipe, len, flags); } -+EXPORT_SYMBOL(do_splice_to); ++EXPORT_SYMBOL_GPL(do_splice_to); /** * splice_direct_to_actor - splices data directly between two non-pipes -diff -Nurp linux-4.4-rc6.aufs/security/commoncap.c linux-4.4-rc6.aufs.mod/security/commoncap.c ---- linux-4.4-rc6.aufs/security/commoncap.c 2015-11-02 02:05:25.000000000 +0200 -+++ linux-4.4-rc6.aufs.mod/security/commoncap.c 2015-12-21 19:55:29.527275805 +0200 -@@ -1053,12 +1053,14 @@ int cap_mmap_addr(unsigned long addr) +diff -Nurp linux-4.4.3-aufs/fs/xattr.c linux-4.4.3-aufs-mod/fs/xattr.c +--- linux-4.4.3-aufs/fs/xattr.c 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs-mod/fs/xattr.c 2016-03-03 09:50:34.635586575 +0200 +@@ -207,6 +207,7 @@ vfs_getxattr_alloc(struct dentry *dentry + *xattr_value = value; + return error; + } ++EXPORT_SYMBOL_GPL(vfs_getxattr_alloc); + + /* Compare an extended attribute value with the given value */ + int vfs_xattr_cmp(struct dentry *dentry, const char *xattr_name, +diff -Nurp linux-4.4.3-aufs/kernel/task_work.c linux-4.4.3-aufs-mod/kernel/task_work.c +--- linux-4.4.3-aufs/kernel/task_work.c 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs-mod/kernel/task_work.c 2016-03-03 09:50:34.635586575 +0200 +@@ -118,3 +118,4 @@ void task_work_run(void) + } while (work); + } + } ++EXPORT_SYMBOL_GPL(task_work_run); +diff -Nurp linux-4.4.3-aufs/security/commoncap.c linux-4.4.3-aufs-mod/security/commoncap.c +--- linux-4.4.3-aufs/security/commoncap.c 2016-03-02 17:42:59.463713410 +0200 ++++ linux-4.4.3-aufs-mod/security/commoncap.c 2016-03-03 09:50:34.635586575 +0200 +@@ -1058,12 +1058,14 @@ int cap_mmap_addr(unsigned long addr) } return ret; } -+EXPORT_SYMBOL(cap_mmap_addr); ++EXPORT_SYMBOL_GPL(cap_mmap_addr); int cap_mmap_file(struct file *file, unsigned long reqprot, unsigned long prot, unsigned long flags) { return 0; } -+EXPORT_SYMBOL(cap_mmap_file); ++EXPORT_SYMBOL_GPL(cap_mmap_file); #ifdef CONFIG_SECURITY -diff -Nurp linux-4.4-rc6.aufs/security/device_cgroup.c linux-4.4-rc6.aufs.mod/security/device_cgroup.c ---- linux-4.4-rc6.aufs/security/device_cgroup.c 2015-11-02 02:05:25.000000000 +0200 -+++ linux-4.4-rc6.aufs.mod/security/device_cgroup.c 2015-12-21 19:55:29.527275805 +0200 +diff -Nurp linux-4.4.3-aufs/security/device_cgroup.c linux-4.4.3-aufs-mod/security/device_cgroup.c +--- linux-4.4.3-aufs/security/device_cgroup.c 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs-mod/security/device_cgroup.c 2016-03-03 09:50:34.635586575 +0200 @@ -7,6 +7,7 @@ #include #include @@ -244,18 +293,18 @@ diff -Nurp linux-4.4-rc6.aufs/security/device_cgroup.c linux-4.4-rc6.aufs.mod/se return __devcgroup_check_permission(type, imajor(inode), iminor(inode), access); } -+EXPORT_SYMBOL(__devcgroup_inode_permission); ++EXPORT_SYMBOL_GPL(__devcgroup_inode_permission); int devcgroup_inode_mknod(int mode, dev_t dev) { -diff -Nurp linux-4.4-rc6.aufs/security/security.c linux-4.4-rc6.aufs.mod/security/security.c ---- linux-4.4-rc6.aufs/security/security.c 2015-11-02 02:05:25.000000000 +0200 -+++ linux-4.4-rc6.aufs.mod/security/security.c 2015-12-21 19:55:29.528275813 +0200 +diff -Nurp linux-4.4.3-aufs/security/security.c linux-4.4.3-aufs-mod/security/security.c +--- linux-4.4.3-aufs/security/security.c 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs-mod/security/security.c 2016-03-03 09:50:34.636586582 +0200 @@ -433,6 +433,7 @@ int security_path_rmdir(struct path *dir return 0; return call_int_hook(path_rmdir, 0, dir, dentry); } -+EXPORT_SYMBOL(security_path_rmdir); ++EXPORT_SYMBOL_GPL(security_path_rmdir); int security_path_unlink(struct path *dir, struct dentry *dentry) { @@ -263,7 +312,7 @@ diff -Nurp linux-4.4-rc6.aufs/security/security.c linux-4.4-rc6.aufs.mod/securit return 0; return call_int_hook(path_symlink, 0, dir, dentry, old_name); } -+EXPORT_SYMBOL(security_path_symlink); ++EXPORT_SYMBOL_GPL(security_path_symlink); int security_path_link(struct dentry *old_dentry, struct path *new_dir, struct dentry *new_dentry) @@ -271,7 +320,7 @@ diff -Nurp linux-4.4-rc6.aufs/security/security.c linux-4.4-rc6.aufs.mod/securit return 0; return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry); } -+EXPORT_SYMBOL(security_path_link); ++EXPORT_SYMBOL_GPL(security_path_link); int security_path_rename(struct path *old_dir, struct dentry *old_dentry, struct path *new_dir, struct dentry *new_dentry, @@ -279,7 +328,7 @@ diff -Nurp linux-4.4-rc6.aufs/security/security.c linux-4.4-rc6.aufs.mod/securit return 0; return call_int_hook(path_truncate, 0, path); } -+EXPORT_SYMBOL(security_path_truncate); ++EXPORT_SYMBOL_GPL(security_path_truncate); int security_path_chmod(struct path *path, umode_t mode) { @@ -287,7 +336,7 @@ diff -Nurp linux-4.4-rc6.aufs/security/security.c linux-4.4-rc6.aufs.mod/securit return 0; return call_int_hook(path_chmod, 0, path, mode); } -+EXPORT_SYMBOL(security_path_chmod); ++EXPORT_SYMBOL_GPL(security_path_chmod); int security_path_chown(struct path *path, kuid_t uid, kgid_t gid) { @@ -295,7 +344,7 @@ diff -Nurp linux-4.4-rc6.aufs/security/security.c linux-4.4-rc6.aufs.mod/securit return 0; return call_int_hook(path_chown, 0, path, uid, gid); } -+EXPORT_SYMBOL(security_path_chown); ++EXPORT_SYMBOL_GPL(security_path_chown); int security_path_chroot(struct path *path) { @@ -303,7 +352,7 @@ diff -Nurp linux-4.4-rc6.aufs/security/security.c linux-4.4-rc6.aufs.mod/securit return 0; return call_int_hook(inode_readlink, 0, dentry); } -+EXPORT_SYMBOL(security_inode_readlink); ++EXPORT_SYMBOL_GPL(security_inode_readlink); int security_inode_follow_link(struct dentry *dentry, struct inode *inode, bool rcu) @@ -311,7 +360,7 @@ diff -Nurp linux-4.4-rc6.aufs/security/security.c linux-4.4-rc6.aufs.mod/securit return 0; return call_int_hook(inode_permission, 0, inode, mask); } -+EXPORT_SYMBOL(security_inode_permission); ++EXPORT_SYMBOL_GPL(security_inode_permission); int security_inode_setattr(struct dentry *dentry, struct iattr *attr) { @@ -319,7 +368,7 @@ diff -Nurp linux-4.4-rc6.aufs/security/security.c linux-4.4-rc6.aufs.mod/securit return fsnotify_perm(file, mask); } -+EXPORT_SYMBOL(security_file_permission); ++EXPORT_SYMBOL_GPL(security_file_permission); int security_file_alloc(struct file *file) { @@ -327,7 +376,7 @@ diff -Nurp linux-4.4-rc6.aufs/security/security.c linux-4.4-rc6.aufs.mod/securit return ret; return ima_file_mmap(file, prot); } -+EXPORT_SYMBOL(security_mmap_file); ++EXPORT_SYMBOL_GPL(security_mmap_file); int security_mmap_addr(unsigned long addr) { diff --git a/kernel/kernel/files/patches/mageia/fs-aufs-4.4.patch b/kernel/kernel/files/patches/mageia/fs-aufs-4.4.patch index dde11710..fc6f4fdc 100644 --- a/kernel/kernel/files/patches/mageia/fs-aufs-4.4.patch +++ b/kernel/kernel/files/patches/mageia/fs-aufs-4.4.patch @@ -1,120 +1,120 @@ - Documentation/ABI/testing/debugfs-aufs | 50 + - Documentation/ABI/testing/sysfs-aufs | 31 + - Documentation/filesystems/aufs/README | 383 ++++ - Documentation/filesystems/aufs/design/01intro.txt | 157 ++ - Documentation/filesystems/aufs/design/02struct.txt | 245 +++ - .../filesystems/aufs/design/03atomic_open.txt | 72 + - Documentation/filesystems/aufs/design/03lookup.txt | 100 ++ - Documentation/filesystems/aufs/design/04branch.txt | 61 + - .../filesystems/aufs/design/05wbr_policy.txt | 51 + - Documentation/filesystems/aufs/design/06fhsm.txt | 105 ++ - Documentation/filesystems/aufs/design/06mmap.txt | 59 + - Documentation/filesystems/aufs/design/06xattr.txt | 81 + - Documentation/filesystems/aufs/design/07export.txt | 45 + - Documentation/filesystems/aufs/design/08shwh.txt | 39 + - Documentation/filesystems/aufs/design/10dynop.txt | 34 + - MAINTAINERS | 13 + - drivers/block/loop.c | 18 + - fs/Kconfig | 1 + - fs/Makefile | 1 + - fs/aufs/Kconfig | 185 ++ - fs/aufs/Makefile | 36 + - fs/aufs/aufs.h | 46 + - fs/aufs/branch.c | 1394 +++++++++++++++ - fs/aufs/branch.h | 266 +++ - fs/aufs/cpup.c | 1306 ++++++++++++++ - fs/aufs/cpup.h | 81 + - fs/aufs/dbgaufs.c | 419 +++++ - fs/aufs/dbgaufs.h | 35 + - fs/aufs/dcsub.c | 211 +++ - fs/aufs/dcsub.h | 123 ++ - fs/aufs/debug.c | 425 +++++ - fs/aufs/debug.h | 212 +++ - fs/aufs/dentry.c | 1123 ++++++++++++ - fs/aufs/dentry.h | 221 +++ - fs/aufs/dinfo.c | 537 ++++++ - fs/aufs/dir.c | 740 ++++++++ - fs/aufs/dir.h | 118 ++ - fs/aufs/dynop.c | 356 ++++ - fs/aufs/dynop.h | 61 + - fs/aufs/export.c | 819 +++++++++ - fs/aufs/f_op.c | 725 ++++++++ - fs/aufs/fhsm.c | 412 +++++ - fs/aufs/file.c | 831 +++++++++ - fs/aufs/file.h | 278 +++ - fs/aufs/finfo.c | 143 ++ - fs/aufs/fstype.h | 387 ++++ - fs/aufs/hfsnotify.c | 275 +++ - fs/aufs/hfsplus.c | 43 + - fs/aufs/hnotify.c | 697 ++++++++ - fs/aufs/i_op.c | 1471 ++++++++++++++++ - fs/aufs/i_op_add.c | 919 ++++++++++ - fs/aufs/i_op_del.c | 497 ++++++ - fs/aufs/i_op_ren.c | 1002 +++++++++++ - fs/aufs/iinfo.c | 264 +++ - fs/aufs/inode.c | 515 ++++++ - fs/aufs/inode.h | 672 +++++++ - fs/aufs/ioctl.c | 206 +++ - fs/aufs/loop.c | 133 ++ - fs/aufs/loop.h | 39 + - fs/aufs/magic.mk | 30 + - fs/aufs/module.c | 207 +++ - fs/aufs/module.h | 91 + - fs/aufs/mvdown.c | 690 ++++++++ - fs/aufs/opts.c | 1846 ++++++++++++++++++++ - fs/aufs/opts.h | 198 +++ - fs/aufs/plink.c | 515 ++++++ - fs/aufs/poll.c | 39 + - fs/aufs/posix_acl.c | 86 + - fs/aufs/procfs.c | 156 ++ - fs/aufs/rdu.c | 375 ++++ - fs/aufs/rwsem.h | 178 ++ - fs/aufs/sbinfo.c | 353 ++++ - fs/aufs/spl.h | 98 ++ - fs/aufs/super.c | 1026 +++++++++++ - fs/aufs/super.h | 628 +++++++ - fs/aufs/sysaufs.c | 91 + - fs/aufs/sysaufs.h | 88 + - fs/aufs/sysfs.c | 340 ++++ - fs/aufs/sysrq.c | 144 ++ - fs/aufs/vdir.c | 875 ++++++++++ - fs/aufs/vfsub.c | 835 +++++++++ - fs/aufs/vfsub.h | 274 +++ - fs/aufs/wbr_policy.c | 752 ++++++++ - fs/aufs/whout.c | 1047 +++++++++++ - fs/aufs/whout.h | 72 + - fs/aufs/wkq.c | 200 +++ - fs/aufs/wkq.h | 78 + - fs/aufs/xattr.c | 331 ++++ - fs/aufs/xino.c | 1283 ++++++++++++++ - fs/dcache.c | 2 +- - fs/proc/base.c | 2 +- - fs/proc/nommu.c | 5 +- - fs/proc/task_mmu.c | 7 +- - fs/proc/task_nommu.c | 5 +- - fs/read_write.c | 22 + - fs/splice.c | 10 +- - include/linux/file.h | 1 + - include/linux/fs.h | 6 + - include/linux/mm.h | 22 + - include/linux/mm_types.h | 2 + - include/linux/splice.h | 6 + - include/uapi/linux/Kbuild | 1 + - include/uapi/linux/aufs_type.h | 406 +++++ - kernel/fork.c | 2 +- - mm/Makefile | 2 +- - mm/filemap.c | 2 +- - mm/memory.c | 2 +- - mm/mmap.c | 17 +- - mm/nommu.c | 10 +- - mm/prfile.c | 86 + - 110 files changed, 33284 insertions(+), 29 deletions(-) -diff --git a/Documentation/ABI/testing/debugfs-aufs b/Documentation/ABI/testing/debugfs-aufs -new file mode 100644 -index 0000000..99642d1 ---- /dev/null -+++ b/Documentation/ABI/testing/debugfs-aufs + Documentation/ABI/testing/debugfs-aufs | 50 + Documentation/ABI/testing/sysfs-aufs | 31 + Documentation/filesystems/aufs/README | 391 +++ + Documentation/filesystems/aufs/design/01intro.txt | 157 + + Documentation/filesystems/aufs/design/02struct.txt | 245 ++ + Documentation/filesystems/aufs/design/03atomic_open.txt | 72 + Documentation/filesystems/aufs/design/03lookup.txt | 100 + Documentation/filesystems/aufs/design/04branch.txt | 61 + Documentation/filesystems/aufs/design/05wbr_policy.txt | 51 + Documentation/filesystems/aufs/design/06fhsm.txt | 105 + Documentation/filesystems/aufs/design/06mmap.txt | 59 + Documentation/filesystems/aufs/design/06xattr.txt | 81 + Documentation/filesystems/aufs/design/07export.txt | 45 + Documentation/filesystems/aufs/design/08shwh.txt | 39 + Documentation/filesystems/aufs/design/10dynop.txt | 34 + MAINTAINERS | 13 + drivers/block/loop.c | 18 + fs/Kconfig | 1 + fs/Makefile | 1 + fs/aufs/Kconfig | 185 + + fs/aufs/Makefile | 36 + fs/aufs/aufs.h | 46 + fs/aufs/branch.c | 1394 ++++++++++++ + fs/aufs/branch.h | 266 ++ + fs/aufs/cpup.c | 1366 +++++++++++ + fs/aufs/cpup.h | 81 + fs/aufs/dbgaufs.c | 419 +++ + fs/aufs/dbgaufs.h | 35 + fs/aufs/dcsub.c | 211 + + fs/aufs/dcsub.h | 123 + + fs/aufs/debug.c | 425 +++ + fs/aufs/debug.h | 212 + + fs/aufs/dentry.c | 1123 +++++++++ + fs/aufs/dentry.h | 221 + + fs/aufs/dinfo.c | 537 ++++ + fs/aufs/dir.c | 745 ++++++ + fs/aufs/dir.h | 118 + + fs/aufs/dynop.c | 356 +++ + fs/aufs/dynop.h | 61 + fs/aufs/export.c | 819 +++++++ + fs/aufs/f_op.c | 759 ++++++ + fs/aufs/fhsm.c | 412 +++ + fs/aufs/file.c | 831 +++++++ + fs/aufs/file.h | 278 ++ + fs/aufs/finfo.c | 143 + + fs/aufs/fstype.h | 387 +++ + fs/aufs/hfsnotify.c | 275 ++ + fs/aufs/hfsplus.c | 43 + fs/aufs/hnotify.c | 697 ++++++ + fs/aufs/i_op.c | 1477 ++++++++++++ + fs/aufs/i_op_add.c | 919 +++++++ + fs/aufs/i_op_del.c | 497 ++++ + fs/aufs/i_op_ren.c | 1002 ++++++++ + fs/aufs/iinfo.c | 264 ++ + fs/aufs/inode.c | 514 ++++ + fs/aufs/inode.h | 672 +++++ + fs/aufs/ioctl.c | 206 + + fs/aufs/loop.c | 133 + + fs/aufs/loop.h | 39 + fs/aufs/magic.mk | 30 + fs/aufs/module.c | 207 + + fs/aufs/module.h | 92 + fs/aufs/mvdown.c | 690 +++++ + fs/aufs/opts.c | 1846 ++++++++++++++++ + fs/aufs/opts.h | 198 + + fs/aufs/plink.c | 515 ++++ + fs/aufs/poll.c | 39 + fs/aufs/posix_acl.c | 85 + fs/aufs/procfs.c | 156 + + fs/aufs/rdu.c | 375 +++ + fs/aufs/rwsem.h | 178 + + fs/aufs/sbinfo.c | 353 +++ + fs/aufs/spl.h | 98 + fs/aufs/super.c | 1026 ++++++++ + fs/aufs/super.h | 628 +++++ + fs/aufs/sysaufs.c | 91 + fs/aufs/sysaufs.h | 88 + fs/aufs/sysfs.c | 340 ++ + fs/aufs/sysrq.c | 144 + + fs/aufs/vdir.c | 875 +++++++ + fs/aufs/vfsub.c | 853 +++++++ + fs/aufs/vfsub.h | 295 ++ + fs/aufs/wbr_policy.c | 752 ++++++ + fs/aufs/whout.c | 1047 +++++++++ + fs/aufs/whout.h | 72 + fs/aufs/wkq.c | 200 + + fs/aufs/wkq.h | 78 + fs/aufs/xattr.c | 331 ++ + fs/aufs/xino.c | 1305 +++++++++++ + fs/dcache.c | 2 + fs/fcntl.c | 4 + fs/proc/base.c | 2 + fs/proc/nommu.c | 5 + fs/proc/task_mmu.c | 7 + fs/proc/task_nommu.c | 5 + fs/read_write.c | 22 + fs/splice.c | 10 + include/linux/file.h | 1 + include/linux/fs.h | 8 + include/linux/mm.h | 22 + include/linux/mm_types.h | 2 + include/linux/splice.h | 6 + include/uapi/linux/Kbuild | 1 + include/uapi/linux/aufs_type.h | 406 +++ + kernel/fork.c | 2 + mm/Makefile | 2 + mm/filemap.c | 2 + mm/memory.c | 2 + mm/mmap.c | 17 + mm/nommu.c | 10 + mm/prfile.c | 86 + 111 files changed, 33462 insertions(+), 30 deletions(-) + +diff -Nurp linux-4.4.3/Documentation/ABI/testing/debugfs-aufs linux-4.4.3-aufs/Documentation/ABI/testing/debugfs-aufs +--- linux-4.4.3/Documentation/ABI/testing/debugfs-aufs 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/Documentation/ABI/testing/debugfs-aufs 2016-03-02 17:59:37.356498653 +0200 @@ -0,0 +1,50 @@ +What: /debug/aufs/si_/ +Date: March 2009 @@ -166,11 +166,9 @@ index 0000000..99642d1 + be created. + When the aufs mount option 'noxino' is specified, it + will be empty. About XINO files, see the aufs manual. -diff --git a/Documentation/ABI/testing/sysfs-aufs b/Documentation/ABI/testing/sysfs-aufs -new file mode 100644 -index 0000000..82f9518 ---- /dev/null -+++ b/Documentation/ABI/testing/sysfs-aufs +diff -Nurp linux-4.4.3/Documentation/ABI/testing/sysfs-aufs linux-4.4.3-aufs/Documentation/ABI/testing/sysfs-aufs +--- linux-4.4.3/Documentation/ABI/testing/sysfs-aufs 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/Documentation/ABI/testing/sysfs-aufs 2016-03-02 17:59:37.356498653 +0200 @@ -0,0 +1,31 @@ +What: /sys/fs/aufs/si_/ +Date: March 2009 @@ -203,403 +201,12 @@ index 0000000..82f9518 + even if it is the default path. + When the aufs mount option 'noxino' is specified, it + will be empty. About XINO files, see the aufs manual. -diff --git a/Documentation/filesystems/aufs/README b/Documentation/filesystems/aufs/README -new file mode 100644 -index 0000000..2915102 ---- /dev/null -+++ b/Documentation/filesystems/aufs/README -@@ -0,0 +1,383 @@ -+ -+Aufs4 -- advanced multi layered unification filesystem version 4.x -+http://aufs.sf.net -+Junjiro R. Okajima -+ -+ -+0. Introduction -+---------------------------------------- -+In the early days, aufs was entirely re-designed and re-implemented -+Unionfs Version 1.x series. Adding many original ideas, approaches, -+improvements and implementations, it becomes totally different from -+Unionfs while keeping the basic features. -+Recently, Unionfs Version 2.x series begin taking some of the same -+approaches to aufs1's. -+Unionfs is being developed by Professor Erez Zadok at Stony Brook -+University and his team. -+ -+Aufs4 supports linux-4.0 and later, and for linux-3.x series try aufs3. -+If you want older kernel version support, try aufs2-2.6.git or -+aufs2-standalone.git repository, aufs1 from CVS on SourceForge. -+ -+Note: it becomes clear that "Aufs was rejected. Let's give it up." -+ According to Christoph Hellwig, linux rejects all union-type -+ filesystems but UnionMount. -+ -+ -+PS. Al Viro seems have a plan to merge aufs as well as overlayfs and -+ UnionMount, and he pointed out an issue around a directory mutex -+ lock and aufs addressed it. But it is still unsure whether aufs will -+ be merged (or any other union solution). -+ -+ -+ -+1. Features -+---------------------------------------- -+- unite several directories into a single virtual filesystem. The member -+ directory is called as a branch. -+- you can specify the permission flags to the branch, which are 'readonly', -+ 'readwrite' and 'whiteout-able.' -+- by upper writable branch, internal copyup and whiteout, files/dirs on -+ readonly branch are modifiable logically. -+- dynamic branch manipulation, add, del. -+- etc... -+ -+Also there are many enhancements in aufs, such as: -+- test only the highest one for the directory permission (dirperm1) -+- copyup on open (coo=) -+- 'move' policy for copy-up between two writable branches, after -+ checking free space. -+- xattr, acl -+- readdir(3) in userspace. -+- keep inode number by external inode number table -+- keep the timestamps of file/dir in internal copyup operation -+- seekable directory, supporting NFS readdir. -+- whiteout is hardlinked in order to reduce the consumption of inodes -+ on branch -+- do not copyup, nor create a whiteout when it is unnecessary -+- revert a single systemcall when an error occurs in aufs -+- remount interface instead of ioctl -+- maintain /etc/mtab by an external command, /sbin/mount.aufs. -+- loopback mounted filesystem as a branch -+- kernel thread for removing the dir who has a plenty of whiteouts -+- support copyup sparse file (a file which has a 'hole' in it) -+- default permission flags for branches -+- selectable permission flags for ro branch, whether whiteout can -+ exist or not -+- export via NFS. -+- support /fs/aufs and /aufs. -+- support multiple writable branches, some policies to select one -+ among multiple writable branches. -+- a new semantics for link(2) and rename(2) to support multiple -+ writable branches. -+- no glibc changes are required. -+- pseudo hardlink (hardlink over branches) -+- allow a direct access manually to a file on branch, e.g. bypassing aufs. -+ including NFS or remote filesystem branch. -+- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX. -+- and more... -+ -+Currently these features are dropped temporary from aufs4. -+See design/08plan.txt in detail. -+- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs -+ (robr) -+- statistics of aufs thread (/sys/fs/aufs/stat) -+ -+Features or just an idea in the future (see also design/*.txt), -+- reorder the branch index without del/re-add. -+- permanent xino files for NFSD -+- an option for refreshing the opened files after add/del branches -+- light version, without branch manipulation. (unnecessary?) -+- copyup in userspace -+- inotify in userspace -+- readv/writev -+ -+ -+2. Download -+---------------------------------------- -+There are three GIT trees for aufs4, aufs4-linux.git, -+aufs4-standalone.git, and aufs-util.git. Note that there is no "4" in -+"aufs-util.git." -+While the aufs-util is always necessary, you need either of aufs4-linux -+or aufs4-standalone. -+ -+The aufs4-linux tree includes the whole linux mainline GIT tree, -+git://git.kernel.org/.../torvalds/linux.git. -+And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot -+build aufs4 as an external kernel module. -+Several extra patches are not included in this tree. Only -+aufs4-standalone tree contains them. They are describe in the later -+section "Configuration and Compilation." -+ -+On the other hand, the aufs4-standalone tree has only aufs source files -+and necessary patches, and you can select CONFIG_AUFS_FS=m. -+But you need to apply all aufs patches manually. -+ -+You will find GIT branches whose name is in form of "aufs4.x" where "x" -+represents the linux kernel version, "linux-4.x". For instance, -+"aufs4.0" is for linux-4.0. For latest "linux-4.x-rcN", use -+"aufs4.x-rcN" branch. -+ -+o aufs4-linux tree -+$ git clone --reference /your/linux/git/tree \ -+ git://github.com/sfjro/aufs4-linux.git aufs4-linux.git -+- if you don't have linux GIT tree, then remove "--reference ..." -+$ cd aufs4-linux.git -+$ git checkout origin/aufs4.0 -+ -+Or You may want to directly git-pull aufs into your linux GIT tree, and -+leave the patch-work to GIT. -+$ cd /your/linux/git/tree -+$ git remote add aufs4 git://github.com/sfjro/aufs4-linux.git -+$ git fetch aufs4 -+$ git checkout -b my4.0 v4.0 -+$ (add your local change...) -+$ git pull aufs4 aufs4.0 -+- now you have v4.0 + your_changes + aufs4.0 in you my4.0 branch. -+- you may need to solve some conflicts between your_changes and -+ aufs4.0. in this case, git-rerere is recommended so that you can -+ solve the similar conflicts automatically when you upgrade to 4.1 or -+ later in the future. -+ -+o aufs4-standalone tree -+$ git clone git://github.com/sfjro/aufs4-standalone.git aufs4-standalone.git -+$ cd aufs4-standalone.git -+$ git checkout origin/aufs4.0 -+ -+o aufs-util tree -+$ git clone git://git.code.sf.net/p/aufs/aufs-util aufs-util.git -+- note that the public aufs-util.git is on SourceForge instead of -+ GitHUB. -+$ cd aufs-util.git -+$ git checkout origin/aufs4.0 -+ -+Note: The 4.x-rcN branch is to be used with `rc' kernel versions ONLY. -+The minor version number, 'x' in '4.x', of aufs may not always -+follow the minor version number of the kernel. -+Because changes in the kernel that cause the use of a new -+minor version number do not always require changes to aufs-util. -+ -+Since aufs-util has its own minor version number, you may not be -+able to find a GIT branch in aufs-util for your kernel's -+exact minor version number. -+In this case, you should git-checkout the branch for the -+nearest lower number. -+ -+For (an unreleased) example: -+If you are using "linux-4.10" and the "aufs4.10" branch -+does not exist in aufs-util repository, then "aufs4.9", "aufs4.8" -+or something numerically smaller is the branch for your kernel. -+ -+Also you can view all branches by -+ $ git branch -a -+ -+ -+3. Configuration and Compilation -+---------------------------------------- -+Make sure you have git-checkout'ed the correct branch. -+ -+For aufs4-linux tree, -+- enable CONFIG_AUFS_FS. -+- set other aufs configurations if necessary. -+ -+For aufs4-standalone tree, -+There are several ways to build. -+ -+1. -+- apply ./aufs4-kbuild.patch to your kernel source files. -+- apply ./aufs4-base.patch too. -+- apply ./aufs4-mmap.patch too. -+- apply ./aufs4-standalone.patch too, if you have a plan to set -+ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs4-standalone.patch. -+- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your -+ kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild. -+- enable CONFIG_AUFS_FS, you can select either -+ =m or =y. -+- and build your kernel as usual. -+- install the built kernel. -+ Note: Since linux-3.9, every filesystem module requires an alias -+ "fs-". You should make sure that "fs-aufs" is listed in your -+ modules.aliases file if you set CONFIG_AUFS_FS=m. -+- install the header files too by "make headers_install" to the -+ directory where you specify. By default, it is $PWD/usr. -+ "make help" shows a brief note for headers_install. -+- and reboot your system. -+ -+2. -+- module only (CONFIG_AUFS_FS=m). -+- apply ./aufs4-base.patch to your kernel source files. -+- apply ./aufs4-mmap.patch too. -+- apply ./aufs4-standalone.patch too. -+- build your kernel, don't forget "make headers_install", and reboot. -+- edit ./config.mk and set other aufs configurations if necessary. -+ Note: You should read $PWD/fs/aufs/Kconfig carefully which describes -+ every aufs configurations. -+- build the module by simple "make". -+ Note: Since linux-3.9, every filesystem module requires an alias -+ "fs-". You should make sure that "fs-aufs" is listed in your -+ modules.aliases file. -+- you can specify ${KDIR} make variable which points to your kernel -+ source tree. -+- install the files -+ + run "make install" to install the aufs module, or copy the built -+ $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply). -+ + run "make install_headers" (instead of headers_install) to install -+ the modified aufs header file (you can specify DESTDIR which is -+ available in aufs standalone version's Makefile only), or copy -+ $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever -+ you like manually. By default, the target directory is $PWD/usr. -+- no need to apply aufs4-kbuild.patch, nor copying source files to your -+ kernel source tree. -+ -+Note: The header file aufs_type.h is necessary to build aufs-util -+ as well as "make headers_install" in the kernel source tree. -+ headers_install is subject to be forgotten, but it is essentially -+ necessary, not only for building aufs-util. -+ You may not meet problems without headers_install in some older -+ version though. -+ -+And then, -+- read README in aufs-util, build and install it -+- note that your distribution may contain an obsoleted version of -+ aufs_type.h in /usr/include/linux or something. When you build aufs -+ utilities, make sure that your compiler refers the correct aufs header -+ file which is built by "make headers_install." -+- if you want to use readdir(3) in userspace or pathconf(3) wrapper, -+ then run "make install_ulib" too. And refer to the aufs manual in -+ detail. -+ -+There several other patches in aufs4-standalone.git. They are all -+optional. When you meet some problems, they will help you. -+- aufs4-loopback.patch -+ Supports a nested loopback mount in a branch-fs. This patch is -+ unnecessary until aufs produces a message like "you may want to try -+ another patch for loopback file". -+- vfs-ino.patch -+ Modifies a system global kernel internal function get_next_ino() in -+ order to stop assigning 0 for an inode-number. Not directly related to -+ aufs, but recommended generally. -+- tmpfs-idr.patch -+ Keeps the tmpfs inode number as the lowest value. Effective to reduce -+ the size of aufs XINO files for tmpfs branch. Also it prevents the -+ duplication of inode number, which is important for backup tools and -+ other utilities. When you find aufs XINO files for tmpfs branch -+ growing too much, try this patch. -+ -+ -+4. Usage -+---------------------------------------- -+At first, make sure aufs-util are installed, and please read the aufs -+manual, aufs.5 in aufs-util.git tree. -+$ man -l aufs.5 -+ -+And then, -+$ mkdir /tmp/rw /tmp/aufs -+# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs -+ -+Here is another example. The result is equivalent. -+# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs -+ Or -+# mount -t aufs -o br:/tmp/rw none /tmp/aufs -+# mount -o remount,append:${HOME} /tmp/aufs -+ -+Then, you can see whole tree of your home dir through /tmp/aufs. If -+you modify a file under /tmp/aufs, the one on your home directory is -+not affected, instead the same named file will be newly created under -+/tmp/rw. And all of your modification to a file will be applied to -+the one under /tmp/rw. This is called the file based Copy on Write -+(COW) method. -+Aufs mount options are described in aufs.5. -+If you run chroot or something and make your aufs as a root directory, -+then you need to customize the shutdown script. See the aufs manual in -+detail. -+ -+Additionally, there are some sample usages of aufs which are a -+diskless system with network booting, and LiveCD over NFS. -+See sample dir in CVS tree on SourceForge. -+ -+ -+5. Contact -+---------------------------------------- -+When you have any problems or strange behaviour in aufs, please let me -+know with: -+- /proc/mounts (instead of the output of mount(8)) -+- /sys/module/aufs/* -+- /sys/fs/aufs/* (if you have them) -+- /debug/aufs/* (if you have them) -+- linux kernel version -+ if your kernel is not plain, for example modified by distributor, -+ the url where i can download its source is necessary too. -+- aufs version which was printed at loading the module or booting the -+ system, instead of the date you downloaded. -+- configuration (define/undefine CONFIG_AUFS_xxx) -+- kernel configuration or /proc/config.gz (if you have it) -+- behaviour which you think to be incorrect -+- actual operation, reproducible one is better -+- mailto: aufs-users at lists.sourceforge.net -+ -+Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches, -+and Feature Requests) on SourceForge. Please join and write to -+aufs-users ML. -+ -+ -+6. Acknowledgements -+---------------------------------------- -+Thanks to everyone who have tried and are using aufs, whoever -+have reported a bug or any feedback. -+ -+Especially donators: -+Tomas Matejicek(slax.org) made a donation (much more than once). -+ Since Apr 2010, Tomas M (the author of Slax and Linux Live -+ scripts) is making "doubling" donations. -+ Unfortunately I cannot list all of the donators, but I really -+ appreciate. -+ It ends Aug 2010, but the ordinary donation URL is still available. -+ -+Dai Itasaka made a donation (2007/8). -+Chuck Smith made a donation (2008/4, 10 and 12). -+Henk Schoneveld made a donation (2008/9). -+Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10). -+Francois Dupoux made a donation (2008/11). -+Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public -+ aufs2 GIT tree (2009/2). -+William Grant made a donation (2009/3). -+Patrick Lane made a donation (2009/4). -+The Mail Archive (mail-archive.com) made donations (2009/5). -+Nippy Networks (Ed Wildgoose) made a donation (2009/7). -+New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11). -+Pavel Pronskiy made a donation (2011/2). -+Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy -+ Networks (Ed Wildgoose) made a donation for hardware (2011/3). -+Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and -+11). -+Sam Liddicott made a donation (2011/9). -+Era Scarecrow made a donation (2013/4). -+Bor Ratajc made a donation (2013/4). -+Alessandro Gorreta made a donation (2013/4). -+POIRETTE Marc made a donation (2013/4). -+Alessandro Gorreta made a donation (2013/4). -+lauri kasvandik made a donation (2013/5). -+"pemasu from Finland" made a donation (2013/7). -+The Parted Magic Project made a donation (2013/9 and 11). -+Pavel Barta made a donation (2013/10). -+Nikolay Pertsev made a donation (2014/5). -+James B made a donation (2014/7 and 2015/7). -+Stefano Di Biase made a donation (2014/8). -+Daniel Epellei made a donation (2015/1). -+ -+Thank you very much. -+Donations are always, including future donations, very important and -+helpful for me to keep on developing aufs. -+ -+ -+7. -+---------------------------------------- -+If you are an experienced user, no explanation is needed. Aufs is -+just a linux filesystem. -+ -+ -+Enjoy! -+ -+# Local variables: ; -+# mode: text; -+# End: ; -diff --git a/Documentation/filesystems/aufs/design/01intro.txt b/Documentation/filesystems/aufs/design/01intro.txt -new file mode 100644 -index 0000000..02a8c7b ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/01intro.txt +diff -Nurp linux-4.4.3/Documentation/filesystems/aufs/design/01intro.txt linux-4.4.3-aufs/Documentation/filesystems/aufs/design/01intro.txt +--- linux-4.4.3/Documentation/filesystems/aufs/design/01intro.txt 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/Documentation/filesystems/aufs/design/01intro.txt 2016-03-02 17:59:37.357498660 +0200 @@ -0,0 +1,157 @@ + -+# Copyright (C) 2005-2015 Junjiro R. Okajima ++# Copyright (C) 2005-2016 Junjiro R. Okajima + +Introduction +---------------------------------------- @@ -755,14 +362,12 @@ index 0000000..02a8c7b +Some people may think it is better to pass such work to user space +helper, instead of doing in kernel space. Actually I am still thinking +about it. But currently I have implemented it in kernel space. -diff --git a/Documentation/filesystems/aufs/design/02struct.txt b/Documentation/filesystems/aufs/design/02struct.txt -new file mode 100644 -index 0000000..1a5e5d0 ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/02struct.txt +diff -Nurp linux-4.4.3/Documentation/filesystems/aufs/design/02struct.txt linux-4.4.3-aufs/Documentation/filesystems/aufs/design/02struct.txt +--- linux-4.4.3/Documentation/filesystems/aufs/design/02struct.txt 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/Documentation/filesystems/aufs/design/02struct.txt 2016-03-02 17:59:37.357498660 +0200 @@ -0,0 +1,245 @@ + -+# Copyright (C) 2005-2015 Junjiro R. Okajima ++# Copyright (C) 2005-2016 Junjiro R. Okajima + +Basic Aufs Internal Structure + @@ -1006,14 +611,12 @@ index 0000000..1a5e5d0 +- etc. + +For this purpose, use "aumvdown" command in aufs-util.git. -diff --git a/Documentation/filesystems/aufs/design/03atomic_open.txt b/Documentation/filesystems/aufs/design/03atomic_open.txt -new file mode 100644 -index 0000000..d2c9834 ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/03atomic_open.txt +diff -Nurp linux-4.4.3/Documentation/filesystems/aufs/design/03atomic_open.txt linux-4.4.3-aufs/Documentation/filesystems/aufs/design/03atomic_open.txt +--- linux-4.4.3/Documentation/filesystems/aufs/design/03atomic_open.txt 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/Documentation/filesystems/aufs/design/03atomic_open.txt 2016-03-02 17:59:37.357498660 +0200 @@ -0,0 +1,72 @@ + -+# Copyright (C) 2015 Junjiro R. Okajima ++# Copyright (C) 2015-2016 Junjiro R. Okajima + +Support for a branch who has its ->atomic_open() +---------------------------------------------------------------------- @@ -1084,14 +687,12 @@ index 0000000..d2c9834 + ->atomic_open() are lost. in the ordinary case, the checks are + done by VFS:do_last(), lookup_open() and atomic_open(). some can + be implemented in aufs, but not all I am afraid. -diff --git a/Documentation/filesystems/aufs/design/03lookup.txt b/Documentation/filesystems/aufs/design/03lookup.txt -new file mode 100644 -index 0000000..7adf4cc ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/03lookup.txt +diff -Nurp linux-4.4.3/Documentation/filesystems/aufs/design/03lookup.txt linux-4.4.3-aufs/Documentation/filesystems/aufs/design/03lookup.txt +--- linux-4.4.3/Documentation/filesystems/aufs/design/03lookup.txt 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/Documentation/filesystems/aufs/design/03lookup.txt 2016-03-02 17:59:37.358498667 +0200 @@ -0,0 +1,100 @@ + -+# Copyright (C) 2005-2015 Junjiro R. Okajima ++# Copyright (C) 2005-2016 Junjiro R. Okajima + +Lookup in a Branch +---------------------------------------------------------------------- @@ -1190,14 +791,12 @@ index 0000000..7adf4cc + test, and skip the revalidation in step 4. It is useful and improves + aufs performance when system surely hide the aufs branches from user, + by over-mounting something (or another method). -diff --git a/Documentation/filesystems/aufs/design/04branch.txt b/Documentation/filesystems/aufs/design/04branch.txt -new file mode 100644 -index 0000000..1d11dbe ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/04branch.txt +diff -Nurp linux-4.4.3/Documentation/filesystems/aufs/design/04branch.txt linux-4.4.3-aufs/Documentation/filesystems/aufs/design/04branch.txt +--- linux-4.4.3/Documentation/filesystems/aufs/design/04branch.txt 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/Documentation/filesystems/aufs/design/04branch.txt 2016-03-02 17:59:37.358498667 +0200 @@ -0,0 +1,61 @@ + -+# Copyright (C) 2005-2015 Junjiro R. Okajima ++# Copyright (C) 2005-2016 Junjiro R. Okajima + +Branch Manipulation + @@ -1257,14 +856,12 @@ index 0000000..1d11dbe + - a file on the branch is mmap-ed. + - a regular file on the branch is opened for write and there is no + same named entry on the upper branch. -diff --git a/Documentation/filesystems/aufs/design/05wbr_policy.txt b/Documentation/filesystems/aufs/design/05wbr_policy.txt -new file mode 100644 -index 0000000..0419a90 ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/05wbr_policy.txt +diff -Nurp linux-4.4.3/Documentation/filesystems/aufs/design/05wbr_policy.txt linux-4.4.3-aufs/Documentation/filesystems/aufs/design/05wbr_policy.txt +--- linux-4.4.3/Documentation/filesystems/aufs/design/05wbr_policy.txt 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/Documentation/filesystems/aufs/design/05wbr_policy.txt 2016-03-02 17:59:37.358498667 +0200 @@ -0,0 +1,51 @@ + -+# Copyright (C) 2005-2015 Junjiro R. Okajima ++# Copyright (C) 2005-2016 Junjiro R. Okajima + +Policies to Select One among Multiple Writable Branches +---------------------------------------------------------------------- @@ -1314,14 +911,12 @@ index 0000000..0419a90 + where the source and the target exists and selects the higher + one. If the selected branch is readonly, then aufs follows the + copyup policy. -diff --git a/Documentation/filesystems/aufs/design/06fhsm.txt b/Documentation/filesystems/aufs/design/06fhsm.txt -new file mode 100644 -index 0000000..0eb7a82 ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/06fhsm.txt +diff -Nurp linux-4.4.3/Documentation/filesystems/aufs/design/06fhsm.txt linux-4.4.3-aufs/Documentation/filesystems/aufs/design/06fhsm.txt +--- linux-4.4.3/Documentation/filesystems/aufs/design/06fhsm.txt 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/Documentation/filesystems/aufs/design/06fhsm.txt 2016-03-02 17:59:37.358498667 +0200 @@ -0,0 +1,105 @@ + -+# Copyright (C) 2011-2015 Junjiro R. Okajima ++# Copyright (C) 2011-2016 Junjiro R. Okajima + +File-based Hierarchical Storage Management (FHSM) +---------------------------------------------------------------------- @@ -1425,14 +1020,12 @@ index 0000000..0eb7a82 + +And of course, in every step, an error may happen. So the operation +should restore the original file state after an error happens. -diff --git a/Documentation/filesystems/aufs/design/06mmap.txt b/Documentation/filesystems/aufs/design/06mmap.txt -new file mode 100644 -index 0000000..f22d2a1 ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/06mmap.txt +diff -Nurp linux-4.4.3/Documentation/filesystems/aufs/design/06mmap.txt linux-4.4.3-aufs/Documentation/filesystems/aufs/design/06mmap.txt +--- linux-4.4.3/Documentation/filesystems/aufs/design/06mmap.txt 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/Documentation/filesystems/aufs/design/06mmap.txt 2016-03-02 17:59:37.358498667 +0200 @@ -0,0 +1,59 @@ + -+# Copyright (C) 2005-2015 Junjiro R. Okajima ++# Copyright (C) 2005-2016 Junjiro R. Okajima + +mmap(2) -- File Memory Mapping +---------------------------------------------------------------------- @@ -1490,14 +1083,12 @@ index 0000000..f22d2a1 + equivalent to vm_prfile described above. + +I have to give up this "looks-smater" approach. -diff --git a/Documentation/filesystems/aufs/design/06xattr.txt b/Documentation/filesystems/aufs/design/06xattr.txt -new file mode 100644 -index 0000000..ec1e68c ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/06xattr.txt +diff -Nurp linux-4.4.3/Documentation/filesystems/aufs/design/06xattr.txt linux-4.4.3-aufs/Documentation/filesystems/aufs/design/06xattr.txt +--- linux-4.4.3/Documentation/filesystems/aufs/design/06xattr.txt 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/Documentation/filesystems/aufs/design/06xattr.txt 2016-03-02 17:59:37.358498667 +0200 @@ -0,0 +1,81 @@ + -+# Copyright (C) 2014-2015 Junjiro R. Okajima ++# Copyright (C) 2014-2016 Junjiro R. Okajima + +Listing XATTR/EA and getting the value +---------------------------------------------------------------------- @@ -1577,14 +1168,12 @@ index 0000000..ec1e68c +Some contradiction may happen I am afraid. +Do we need another attribute to stop copying XATTR? I am unsure. For +now, aufs implements the branch attributes to ignore the error. -diff --git a/Documentation/filesystems/aufs/design/07export.txt b/Documentation/filesystems/aufs/design/07export.txt -new file mode 100644 -index 0000000..221d70c ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/07export.txt +diff -Nurp linux-4.4.3/Documentation/filesystems/aufs/design/07export.txt linux-4.4.3-aufs/Documentation/filesystems/aufs/design/07export.txt +--- linux-4.4.3/Documentation/filesystems/aufs/design/07export.txt 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/Documentation/filesystems/aufs/design/07export.txt 2016-03-02 17:59:37.358498667 +0200 @@ -0,0 +1,45 @@ + -+# Copyright (C) 2005-2015 Junjiro R. Okajima ++# Copyright (C) 2005-2016 Junjiro R. Okajima + +Export Aufs via NFS +---------------------------------------------------------------------- @@ -1628,14 +1217,12 @@ index 0000000..221d70c + convert it into ESTALE for NFSD. +- readdir(): call lockdep_on/off() because filldir in NFSD calls + lookup_one_len(), vfs_getattr(), encode_fh() and others. -diff --git a/Documentation/filesystems/aufs/design/08shwh.txt b/Documentation/filesystems/aufs/design/08shwh.txt -new file mode 100644 -index 0000000..181dc02 ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/08shwh.txt +diff -Nurp linux-4.4.3/Documentation/filesystems/aufs/design/08shwh.txt linux-4.4.3-aufs/Documentation/filesystems/aufs/design/08shwh.txt +--- linux-4.4.3/Documentation/filesystems/aufs/design/08shwh.txt 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/Documentation/filesystems/aufs/design/08shwh.txt 2016-03-02 17:59:37.358498667 +0200 @@ -0,0 +1,39 @@ + -+# Copyright (C) 2005-2015 Junjiro R. Okajima ++# Copyright (C) 2005-2016 Junjiro R. Okajima + +Show Whiteout Mode (shwh) +---------------------------------------------------------------------- @@ -1673,14 +1260,12 @@ index 0000000..181dc02 + +This new squashfs archive can be stored on the boot device and the +initramfs will use it to replace the old one at the next boot. -diff --git a/Documentation/filesystems/aufs/design/10dynop.txt b/Documentation/filesystems/aufs/design/10dynop.txt -new file mode 100644 -index 0000000..9d502b5 ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/10dynop.txt +diff -Nurp linux-4.4.3/Documentation/filesystems/aufs/design/10dynop.txt linux-4.4.3-aufs/Documentation/filesystems/aufs/design/10dynop.txt +--- linux-4.4.3/Documentation/filesystems/aufs/design/10dynop.txt 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/Documentation/filesystems/aufs/design/10dynop.txt 2016-03-02 17:59:37.359498674 +0200 @@ -0,0 +1,34 @@ + -+# Copyright (C) 2010-2015 Junjiro R. Okajima ++# Copyright (C) 2010-2016 Junjiro R. Okajima + +Dynamically customizable FS operations +---------------------------------------------------------------------- @@ -1713,35 +1298,405 @@ index 0000000..9d502b5 +XIP (DAX) mainly. +Currently this approach is applied to address_space_operations for +regular files only. -diff --git a/MAINTAINERS b/MAINTAINERS -index 9bff63c..093dd5b 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -2029,6 +2029,19 @@ F: include/linux/audit.h - F: include/uapi/linux/audit.h - F: kernel/audit* - -+AUFS (advanced multi layered unification filesystem) FILESYSTEM -+M: "J. R. Okajima" -+L: linux-unionfs@vger.kernel.org -+L: aufs-users@lists.sourceforge.net (members only) -+W: http://aufs.sourceforge.net -+T: git://github.com/sfjro/aufs4-linux.git -+S: Supported -+F: Documentation/filesystems/aufs/ -+F: Documentation/ABI/testing/debugfs-aufs -+F: Documentation/ABI/testing/sysfs-aufs -+F: fs/aufs/ -+F: include/uapi/linux/aufs_type.h +diff -Nurp linux-4.4.3/Documentation/filesystems/aufs/README linux-4.4.3-aufs/Documentation/filesystems/aufs/README +--- linux-4.4.3/Documentation/filesystems/aufs/README 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/Documentation/filesystems/aufs/README 2016-03-02 17:59:37.357498660 +0200 +@@ -0,0 +1,391 @@ + - AUXILIARY DISPLAY DRIVERS - M: Miguel Ojeda Sandonis - W: http://miguelojeda.es/auxdisplay.htm -diff --git a/drivers/block/loop.c b/drivers/block/loop.c -index 423f4ca..abfdd2b 100644 ---- a/drivers/block/loop.c -+++ b/drivers/block/loop.c -@@ -706,6 +706,24 @@ static inline int is_loop_device(struct file *file) ++Aufs4 -- advanced multi layered unification filesystem version 4.x ++http://aufs.sf.net ++Junjiro R. Okajima ++ ++ ++0. Introduction ++---------------------------------------- ++In the early days, aufs was entirely re-designed and re-implemented ++Unionfs Version 1.x series. Adding many original ideas, approaches, ++improvements and implementations, it becomes totally different from ++Unionfs while keeping the basic features. ++Recently, Unionfs Version 2.x series begin taking some of the same ++approaches to aufs1's. ++Unionfs is being developed by Professor Erez Zadok at Stony Brook ++University and his team. ++ ++Aufs4 supports linux-4.0 and later, and for linux-3.x series try aufs3. ++If you want older kernel version support, try aufs2-2.6.git or ++aufs2-standalone.git repository, aufs1 from CVS on SourceForge. ++ ++Note: it becomes clear that "Aufs was rejected. Let's give it up." ++ According to Christoph Hellwig, linux rejects all union-type ++ filesystems but UnionMount. ++ ++ ++PS. Al Viro seems have a plan to merge aufs as well as overlayfs and ++ UnionMount, and he pointed out an issue around a directory mutex ++ lock and aufs addressed it. But it is still unsure whether aufs will ++ be merged (or any other union solution). ++ ++ ++ ++1. Features ++---------------------------------------- ++- unite several directories into a single virtual filesystem. The member ++ directory is called as a branch. ++- you can specify the permission flags to the branch, which are 'readonly', ++ 'readwrite' and 'whiteout-able.' ++- by upper writable branch, internal copyup and whiteout, files/dirs on ++ readonly branch are modifiable logically. ++- dynamic branch manipulation, add, del. ++- etc... ++ ++Also there are many enhancements in aufs, such as: ++- test only the highest one for the directory permission (dirperm1) ++- copyup on open (coo=) ++- 'move' policy for copy-up between two writable branches, after ++ checking free space. ++- xattr, acl ++- readdir(3) in userspace. ++- keep inode number by external inode number table ++- keep the timestamps of file/dir in internal copyup operation ++- seekable directory, supporting NFS readdir. ++- whiteout is hardlinked in order to reduce the consumption of inodes ++ on branch ++- do not copyup, nor create a whiteout when it is unnecessary ++- revert a single systemcall when an error occurs in aufs ++- remount interface instead of ioctl ++- maintain /etc/mtab by an external command, /sbin/mount.aufs. ++- loopback mounted filesystem as a branch ++- kernel thread for removing the dir who has a plenty of whiteouts ++- support copyup sparse file (a file which has a 'hole' in it) ++- default permission flags for branches ++- selectable permission flags for ro branch, whether whiteout can ++ exist or not ++- export via NFS. ++- support /fs/aufs and /aufs. ++- support multiple writable branches, some policies to select one ++ among multiple writable branches. ++- a new semantics for link(2) and rename(2) to support multiple ++ writable branches. ++- no glibc changes are required. ++- pseudo hardlink (hardlink over branches) ++- allow a direct access manually to a file on branch, e.g. bypassing aufs. ++ including NFS or remote filesystem branch. ++- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX. ++- and more... ++ ++Currently these features are dropped temporary from aufs4. ++See design/08plan.txt in detail. ++- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs ++ (robr) ++- statistics of aufs thread (/sys/fs/aufs/stat) ++ ++Features or just an idea in the future (see also design/*.txt), ++- reorder the branch index without del/re-add. ++- permanent xino files for NFSD ++- an option for refreshing the opened files after add/del branches ++- light version, without branch manipulation. (unnecessary?) ++- copyup in userspace ++- inotify in userspace ++- readv/writev ++ ++ ++2. Download ++---------------------------------------- ++There are three GIT trees for aufs4, aufs4-linux.git, ++aufs4-standalone.git, and aufs-util.git. Note that there is no "4" in ++"aufs-util.git." ++While the aufs-util is always necessary, you need either of aufs4-linux ++or aufs4-standalone. ++ ++The aufs4-linux tree includes the whole linux mainline GIT tree, ++git://git.kernel.org/.../torvalds/linux.git. ++And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot ++build aufs4 as an external kernel module. ++Several extra patches are not included in this tree. Only ++aufs4-standalone tree contains them. They are described in the later ++section "Configuration and Compilation." ++ ++On the other hand, the aufs4-standalone tree has only aufs source files ++and necessary patches, and you can select CONFIG_AUFS_FS=m. ++But you need to apply all aufs patches manually. ++ ++You will find GIT branches whose name is in form of "aufs4.x" where "x" ++represents the linux kernel version, "linux-4.x". For instance, ++"aufs4.0" is for linux-4.0. For latest "linux-4.x-rcN", use ++"aufs4.x-rcN" branch. ++ ++o aufs4-linux tree ++$ git clone --reference /your/linux/git/tree \ ++ git://github.com/sfjro/aufs4-linux.git aufs4-linux.git ++- if you don't have linux GIT tree, then remove "--reference ..." ++$ cd aufs4-linux.git ++$ git checkout origin/aufs4.0 ++ ++Or You may want to directly git-pull aufs into your linux GIT tree, and ++leave the patch-work to GIT. ++$ cd /your/linux/git/tree ++$ git remote add aufs4 git://github.com/sfjro/aufs4-linux.git ++$ git fetch aufs4 ++$ git checkout -b my4.0 v4.0 ++$ (add your local change...) ++$ git pull aufs4 aufs4.0 ++- now you have v4.0 + your_changes + aufs4.0 in you my4.0 branch. ++- you may need to solve some conflicts between your_changes and ++ aufs4.0. in this case, git-rerere is recommended so that you can ++ solve the similar conflicts automatically when you upgrade to 4.1 or ++ later in the future. ++ ++o aufs4-standalone tree ++$ git clone git://github.com/sfjro/aufs4-standalone.git aufs4-standalone.git ++$ cd aufs4-standalone.git ++$ git checkout origin/aufs4.0 ++ ++o aufs-util tree ++$ git clone git://git.code.sf.net/p/aufs/aufs-util aufs-util.git ++- note that the public aufs-util.git is on SourceForge instead of ++ GitHUB. ++$ cd aufs-util.git ++$ git checkout origin/aufs4.0 ++ ++Note: The 4.x-rcN branch is to be used with `rc' kernel versions ONLY. ++The minor version number, 'x' in '4.x', of aufs may not always ++follow the minor version number of the kernel. ++Because changes in the kernel that cause the use of a new ++minor version number do not always require changes to aufs-util. ++ ++Since aufs-util has its own minor version number, you may not be ++able to find a GIT branch in aufs-util for your kernel's ++exact minor version number. ++In this case, you should git-checkout the branch for the ++nearest lower number. ++ ++For (an unreleased) example: ++If you are using "linux-4.10" and the "aufs4.10" branch ++does not exist in aufs-util repository, then "aufs4.9", "aufs4.8" ++or something numerically smaller is the branch for your kernel. ++ ++Also you can view all branches by ++ $ git branch -a ++ ++ ++3. Configuration and Compilation ++---------------------------------------- ++Make sure you have git-checkout'ed the correct branch. ++ ++For aufs4-linux tree, ++- enable CONFIG_AUFS_FS. ++- set other aufs configurations if necessary. ++ ++For aufs4-standalone tree, ++There are several ways to build. ++ ++1. ++- apply ./aufs4-kbuild.patch to your kernel source files. ++- apply ./aufs4-base.patch too. ++- apply ./aufs4-mmap.patch too. ++- apply ./aufs4-standalone.patch too, if you have a plan to set ++ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs4-standalone.patch. ++- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your ++ kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild. ++- enable CONFIG_AUFS_FS, you can select either ++ =m or =y. ++- and build your kernel as usual. ++- install the built kernel. ++ Note: Since linux-3.9, every filesystem module requires an alias ++ "fs-". You should make sure that "fs-aufs" is listed in your ++ modules.aliases file if you set CONFIG_AUFS_FS=m. ++- install the header files too by "make headers_install" to the ++ directory where you specify. By default, it is $PWD/usr. ++ "make help" shows a brief note for headers_install. ++- and reboot your system. ++ ++2. ++- module only (CONFIG_AUFS_FS=m). ++- apply ./aufs4-base.patch to your kernel source files. ++- apply ./aufs4-mmap.patch too. ++- apply ./aufs4-standalone.patch too. ++- build your kernel, don't forget "make headers_install", and reboot. ++- edit ./config.mk and set other aufs configurations if necessary. ++ Note: You should read $PWD/fs/aufs/Kconfig carefully which describes ++ every aufs configurations. ++- build the module by simple "make". ++ Note: Since linux-3.9, every filesystem module requires an alias ++ "fs-". You should make sure that "fs-aufs" is listed in your ++ modules.aliases file. ++- you can specify ${KDIR} make variable which points to your kernel ++ source tree. ++- install the files ++ + run "make install" to install the aufs module, or copy the built ++ $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply). ++ + run "make install_headers" (instead of headers_install) to install ++ the modified aufs header file (you can specify DESTDIR which is ++ available in aufs standalone version's Makefile only), or copy ++ $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever ++ you like manually. By default, the target directory is $PWD/usr. ++- no need to apply aufs4-kbuild.patch, nor copying source files to your ++ kernel source tree. ++ ++Note: The header file aufs_type.h is necessary to build aufs-util ++ as well as "make headers_install" in the kernel source tree. ++ headers_install is subject to be forgotten, but it is essentially ++ necessary, not only for building aufs-util. ++ You may not meet problems without headers_install in some older ++ version though. ++ ++And then, ++- read README in aufs-util, build and install it ++- note that your distribution may contain an obsoleted version of ++ aufs_type.h in /usr/include/linux or something. When you build aufs ++ utilities, make sure that your compiler refers the correct aufs header ++ file which is built by "make headers_install." ++- if you want to use readdir(3) in userspace or pathconf(3) wrapper, ++ then run "make install_ulib" too. And refer to the aufs manual in ++ detail. ++ ++There several other patches in aufs4-standalone.git. They are all ++optional. When you meet some problems, they will help you. ++- aufs4-loopback.patch ++ Supports a nested loopback mount in a branch-fs. This patch is ++ unnecessary until aufs produces a message like "you may want to try ++ another patch for loopback file". ++- vfs-ino.patch ++ Modifies a system global kernel internal function get_next_ino() in ++ order to stop assigning 0 for an inode-number. Not directly related to ++ aufs, but recommended generally. ++- tmpfs-idr.patch ++ Keeps the tmpfs inode number as the lowest value. Effective to reduce ++ the size of aufs XINO files for tmpfs branch. Also it prevents the ++ duplication of inode number, which is important for backup tools and ++ other utilities. When you find aufs XINO files for tmpfs branch ++ growing too much, try this patch. ++- lockdep-debug.patch ++ Because aufs is not only an ordinary filesystem (callee of VFS), but ++ also a caller of VFS functions for branch filesystems, subclassing of ++ the internal locks for LOCKDEP is necessary. LOCKDEP is a debugging ++ feature of linux kernel. If you enable CONFIG_LOCKDEP, then you will ++ need to apply this debug patch to expand several constant values. ++ If don't know what LOCKDEP, then you don't have apply this patch. ++ ++ ++4. Usage ++---------------------------------------- ++At first, make sure aufs-util are installed, and please read the aufs ++manual, aufs.5 in aufs-util.git tree. ++$ man -l aufs.5 ++ ++And then, ++$ mkdir /tmp/rw /tmp/aufs ++# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs ++ ++Here is another example. The result is equivalent. ++# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs ++ Or ++# mount -t aufs -o br:/tmp/rw none /tmp/aufs ++# mount -o remount,append:${HOME} /tmp/aufs ++ ++Then, you can see whole tree of your home dir through /tmp/aufs. If ++you modify a file under /tmp/aufs, the one on your home directory is ++not affected, instead the same named file will be newly created under ++/tmp/rw. And all of your modification to a file will be applied to ++the one under /tmp/rw. This is called the file based Copy on Write ++(COW) method. ++Aufs mount options are described in aufs.5. ++If you run chroot or something and make your aufs as a root directory, ++then you need to customize the shutdown script. See the aufs manual in ++detail. ++ ++Additionally, there are some sample usages of aufs which are a ++diskless system with network booting, and LiveCD over NFS. ++See sample dir in CVS tree on SourceForge. ++ ++ ++5. Contact ++---------------------------------------- ++When you have any problems or strange behaviour in aufs, please let me ++know with: ++- /proc/mounts (instead of the output of mount(8)) ++- /sys/module/aufs/* ++- /sys/fs/aufs/* (if you have them) ++- /debug/aufs/* (if you have them) ++- linux kernel version ++ if your kernel is not plain, for example modified by distributor, ++ the url where i can download its source is necessary too. ++- aufs version which was printed at loading the module or booting the ++ system, instead of the date you downloaded. ++- configuration (define/undefine CONFIG_AUFS_xxx) ++- kernel configuration or /proc/config.gz (if you have it) ++- behaviour which you think to be incorrect ++- actual operation, reproducible one is better ++- mailto: aufs-users at lists.sourceforge.net ++ ++Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches, ++and Feature Requests) on SourceForge. Please join and write to ++aufs-users ML. ++ ++ ++6. Acknowledgements ++---------------------------------------- ++Thanks to everyone who have tried and are using aufs, whoever ++have reported a bug or any feedback. ++ ++Especially donators: ++Tomas Matejicek(slax.org) made a donation (much more than once). ++ Since Apr 2010, Tomas M (the author of Slax and Linux Live ++ scripts) is making "doubling" donations. ++ Unfortunately I cannot list all of the donators, but I really ++ appreciate. ++ It ends Aug 2010, but the ordinary donation URL is still available. ++ ++Dai Itasaka made a donation (2007/8). ++Chuck Smith made a donation (2008/4, 10 and 12). ++Henk Schoneveld made a donation (2008/9). ++Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10). ++Francois Dupoux made a donation (2008/11). ++Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public ++ aufs2 GIT tree (2009/2). ++William Grant made a donation (2009/3). ++Patrick Lane made a donation (2009/4). ++The Mail Archive (mail-archive.com) made donations (2009/5). ++Nippy Networks (Ed Wildgoose) made a donation (2009/7). ++New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11). ++Pavel Pronskiy made a donation (2011/2). ++Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy ++ Networks (Ed Wildgoose) made a donation for hardware (2011/3). ++Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and ++11). ++Sam Liddicott made a donation (2011/9). ++Era Scarecrow made a donation (2013/4). ++Bor Ratajc made a donation (2013/4). ++Alessandro Gorreta made a donation (2013/4). ++POIRETTE Marc made a donation (2013/4). ++Alessandro Gorreta made a donation (2013/4). ++lauri kasvandik made a donation (2013/5). ++"pemasu from Finland" made a donation (2013/7). ++The Parted Magic Project made a donation (2013/9 and 11). ++Pavel Barta made a donation (2013/10). ++Nikolay Pertsev made a donation (2014/5). ++James B made a donation (2014/7 and 2015/7). ++Stefano Di Biase made a donation (2014/8). ++Daniel Epellei made a donation (2015/1). ++OmegaPhil made a donation (2016/1). ++ ++Thank you very much. ++Donations are always, including future donations, very important and ++helpful for me to keep on developing aufs. ++ ++ ++7. ++---------------------------------------- ++If you are an experienced user, no explanation is needed. Aufs is ++just a linux filesystem. ++ ++ ++Enjoy! ++ ++# Local variables: ; ++# mode: text; ++# End: ; +diff -Nurp linux-4.4.3/drivers/block/loop.c linux-4.4.3-aufs/drivers/block/loop.c +--- linux-4.4.3/drivers/block/loop.c 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs/drivers/block/loop.c 2016-03-02 17:59:37.360498681 +0200 +@@ -706,6 +706,24 @@ static inline int is_loop_device(struct return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR; } @@ -1761,273 +1716,17 @@ index 423f4ca..abfdd2b 100644 + } + return ret; +} -+EXPORT_SYMBOL(loop_backing_file); ++EXPORT_SYMBOL_GPL(loop_backing_file); + /* loop sysfs attributes */ static ssize_t loop_attr_show(struct device *dev, char *page, -diff --git a/fs/Kconfig b/fs/Kconfig -index 6ce72d8..4aa31ea 100644 ---- a/fs/Kconfig -+++ b/fs/Kconfig -@@ -221,6 +221,7 @@ source "fs/pstore/Kconfig" - source "fs/sysv/Kconfig" - source "fs/ufs/Kconfig" - source "fs/exofs/Kconfig" -+source "fs/aufs/Kconfig" - - endif # MISC_FILESYSTEMS - -diff --git a/fs/Makefile b/fs/Makefile -index 79f5225..a7c7f16 100644 ---- a/fs/Makefile -+++ b/fs/Makefile -@@ -126,3 +126,4 @@ obj-y += exofs/ # Multiple modules - obj-$(CONFIG_CEPH_FS) += ceph/ - obj-$(CONFIG_PSTORE) += pstore/ - obj-$(CONFIG_EFIVAR_FS) += efivarfs/ -+obj-$(CONFIG_AUFS_FS) += aufs/ -diff --git a/fs/aufs/Kconfig b/fs/aufs/Kconfig -new file mode 100644 -index 0000000..a4efb8b ---- /dev/null -+++ b/fs/aufs/Kconfig -@@ -0,0 +1,185 @@ -+config AUFS_FS -+ bool "Aufs (Advanced multi layered unification filesystem) support" -+ help -+ Aufs is a stackable unification filesystem such as Unionfs, -+ which unifies several directories and provides a merged single -+ directory. -+ In the early days, aufs was entirely re-designed and -+ re-implemented Unionfs Version 1.x series. Introducing many -+ original ideas, approaches and improvements, it becomes totally -+ different from Unionfs while keeping the basic features. -+ -+if AUFS_FS -+choice -+ prompt "Maximum number of branches" -+ default AUFS_BRANCH_MAX_127 -+ help -+ Specifies the maximum number of branches (or member directories) -+ in a single aufs. The larger value consumes more system -+ resources and has a minor impact to performance. -+config AUFS_BRANCH_MAX_127 -+ bool "127" -+ help -+ Specifies the maximum number of branches (or member directories) -+ in a single aufs. The larger value consumes more system -+ resources and has a minor impact to performance. -+config AUFS_BRANCH_MAX_511 -+ bool "511" -+ help -+ Specifies the maximum number of branches (or member directories) -+ in a single aufs. The larger value consumes more system -+ resources and has a minor impact to performance. -+config AUFS_BRANCH_MAX_1023 -+ bool "1023" -+ help -+ Specifies the maximum number of branches (or member directories) -+ in a single aufs. The larger value consumes more system -+ resources and has a minor impact to performance. -+config AUFS_BRANCH_MAX_32767 -+ bool "32767" -+ help -+ Specifies the maximum number of branches (or member directories) -+ in a single aufs. The larger value consumes more system -+ resources and has a minor impact to performance. -+endchoice -+ -+config AUFS_SBILIST -+ bool -+ depends on AUFS_MAGIC_SYSRQ || PROC_FS -+ default y -+ help -+ Automatic configuration for internal use. -+ When aufs supports Magic SysRq or /proc, enabled automatically. -+ -+config AUFS_HNOTIFY -+ bool "Detect direct branch access (bypassing aufs)" -+ help -+ If you want to modify files on branches directly, eg. bypassing aufs, -+ and want aufs to detect the changes of them fully, then enable this -+ option and use 'udba=notify' mount option. -+ Currently there is only one available configuration, "fsnotify". -+ It will have a negative impact to the performance. -+ See detail in aufs.5. -+ -+choice -+ prompt "method" if AUFS_HNOTIFY -+ default AUFS_HFSNOTIFY -+config AUFS_HFSNOTIFY -+ bool "fsnotify" -+ select FSNOTIFY -+endchoice -+ -+config AUFS_EXPORT -+ bool "NFS-exportable aufs" -+ depends on EXPORTFS = y -+ help -+ If you want to export your mounted aufs via NFS, then enable this -+ option. There are several requirements for this configuration. -+ See detail in aufs.5. -+ -+config AUFS_INO_T_64 -+ bool -+ depends on AUFS_EXPORT -+ depends on 64BIT && !(ALPHA || S390) -+ default y -+ help -+ Automatic configuration for internal use. -+ /* typedef unsigned long/int __kernel_ino_t */ -+ /* alpha and s390x are int */ -+ -+config AUFS_XATTR -+ bool "support for XATTR/EA (including Security Labels)" -+ help -+ If your branch fs supports XATTR/EA and you want to make them -+ available in aufs too, then enable this opsion and specify the -+ branch attributes for EA. -+ See detail in aufs.5. -+ -+config AUFS_FHSM -+ bool "File-based Hierarchical Storage Management" -+ help -+ Hierarchical Storage Management (or HSM) is a well-known feature -+ in the storage world. Aufs provides this feature as file-based. -+ with multiple branches. -+ These multiple branches are prioritized, ie. the topmost one -+ should be the fastest drive and be used heavily. -+ -+config AUFS_RDU -+ bool "Readdir in userspace" -+ help -+ Aufs has two methods to provide a merged view for a directory, -+ by a user-space library and by kernel-space natively. The latter -+ is always enabled but sometimes large and slow. -+ If you enable this option, install the library in aufs2-util -+ package, and set some environment variables for your readdir(3), -+ then the work will be handled in user-space which generally -+ shows better performance in most cases. -+ See detail in aufs.5. -+ -+config AUFS_SHWH -+ bool "Show whiteouts" -+ help -+ If you want to make the whiteouts in aufs visible, then enable -+ this option and specify 'shwh' mount option. Although it may -+ sounds like philosophy or something, but in technically it -+ simply shows the name of whiteout with keeping its behaviour. -+ -+config AUFS_BR_RAMFS -+ bool "Ramfs (initramfs/rootfs) as an aufs branch" -+ help -+ If you want to use ramfs as an aufs branch fs, then enable this -+ option. Generally tmpfs is recommended. -+ Aufs prohibited them to be a branch fs by default, because -+ initramfs becomes unusable after switch_root or something -+ generally. If you sets initramfs as an aufs branch and boot your -+ system by switch_root, you will meet a problem easily since the -+ files in initramfs may be inaccessible. -+ Unless you are going to use ramfs as an aufs branch fs without -+ switch_root or something, leave it N. -+ -+config AUFS_BR_FUSE -+ bool "Fuse fs as an aufs branch" -+ depends on FUSE_FS -+ select AUFS_POLL -+ help -+ If you want to use fuse-based userspace filesystem as an aufs -+ branch fs, then enable this option. -+ It implements the internal poll(2) operation which is -+ implemented by fuse only (curretnly). -+ -+config AUFS_POLL -+ bool -+ help -+ Automatic configuration for internal use. -+ -+config AUFS_BR_HFSPLUS -+ bool "Hfsplus as an aufs branch" -+ depends on HFSPLUS_FS -+ default y -+ help -+ If you want to use hfsplus fs as an aufs branch fs, then enable -+ this option. This option introduces a small overhead at -+ copying-up a file on hfsplus. -+ -+config AUFS_BDEV_LOOP -+ bool -+ depends on BLK_DEV_LOOP -+ default y -+ help -+ Automatic configuration for internal use. -+ Convert =[ym] into =y. -+ -+config AUFS_DEBUG -+ bool "Debug aufs" -+ help -+ Enable this to compile aufs internal debug code. -+ It will have a negative impact to the performance. -+ -+config AUFS_MAGIC_SYSRQ -+ bool -+ depends on AUFS_DEBUG && MAGIC_SYSRQ -+ default y -+ help -+ Automatic configuration for internal use. -+ When aufs supports Magic SysRq, enabled automatically. -+endif -diff --git a/fs/aufs/Makefile b/fs/aufs/Makefile -new file mode 100644 -index 0000000..c7efb62 ---- /dev/null -+++ b/fs/aufs/Makefile -@@ -0,0 +1,36 @@ -+ -+include ${srctree}/${src}/magic.mk -+ -+# cf. include/linux/kernel.h -+# enable pr_debug -+ccflags-y += -DDEBUG -+# sparse requires the full pathname -+ccflags-y += -include ${srctree}/include/uapi/linux/aufs_type.h -+ -+obj-$(CONFIG_AUFS_FS) += aufs.o -+aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \ -+ wkq.o vfsub.o dcsub.o \ -+ cpup.o whout.o wbr_policy.o \ -+ dinfo.o dentry.o \ -+ dynop.o \ -+ finfo.o file.o f_op.o \ -+ dir.o vdir.o \ -+ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \ -+ mvdown.o ioctl.o -+ -+# all are boolean -+aufs-$(CONFIG_PROC_FS) += procfs.o plink.o -+aufs-$(CONFIG_SYSFS) += sysfs.o -+aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o -+aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o -+aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o -+aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o -+aufs-$(CONFIG_AUFS_EXPORT) += export.o -+aufs-$(CONFIG_AUFS_XATTR) += xattr.o -+aufs-$(CONFIG_FS_POSIX_ACL) += posix_acl.o -+aufs-$(CONFIG_AUFS_FHSM) += fhsm.o -+aufs-$(CONFIG_AUFS_POLL) += poll.o -+aufs-$(CONFIG_AUFS_RDU) += rdu.o -+aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o -+aufs-$(CONFIG_AUFS_DEBUG) += debug.o -+aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o -diff --git a/fs/aufs/aufs.h b/fs/aufs/aufs.h -new file mode 100644 -index 0000000..75290bd ---- /dev/null -+++ b/fs/aufs/aufs.h +diff -Nurp linux-4.4.3/fs/aufs/aufs.h linux-4.4.3-aufs/fs/aufs/aufs.h +--- linux-4.4.3/fs/aufs/aufs.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/aufs.h 2016-03-02 17:59:37.361498688 +0200 @@ -0,0 +1,46 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -2072,14 +1771,12 @@ index 0000000..75290bd + +#endif /* __KERNEL__ */ +#endif /* __AUFS_H__ */ -diff --git a/fs/aufs/branch.c b/fs/aufs/branch.c -new file mode 100644 -index 0000000..f491422 ---- /dev/null -+++ b/fs/aufs/branch.c +diff -Nurp linux-4.4.3/fs/aufs/branch.c linux-4.4.3-aufs/fs/aufs/branch.c +--- linux-4.4.3/fs/aufs/branch.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/branch.c 2016-03-02 17:59:37.361498688 +0200 @@ -0,0 +1,1394 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -3472,14 +3169,12 @@ index 0000000..f491422 + + return err; +} -diff --git a/fs/aufs/branch.h b/fs/aufs/branch.h -new file mode 100644 -index 0000000..7b9e7c9 ---- /dev/null -+++ b/fs/aufs/branch.h +diff -Nurp linux-4.4.3/fs/aufs/branch.h linux-4.4.3-aufs/fs/aufs/branch.h +--- linux-4.4.3/fs/aufs/branch.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/branch.h 2016-03-02 17:59:37.361498688 +0200 @@ -0,0 +1,266 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -3744,14 +3439,12 @@ index 0000000..7b9e7c9 + +#endif /* __KERNEL__ */ +#endif /* __AUFS_BRANCH_H__ */ -diff --git a/fs/aufs/cpup.c b/fs/aufs/cpup.c -new file mode 100644 -index 0000000..cd32274 ---- /dev/null -+++ b/fs/aufs/cpup.c -@@ -0,0 +1,1306 @@ +diff -Nurp linux-4.4.3/fs/aufs/cpup.c linux-4.4.3-aufs/fs/aufs/cpup.c +--- linux-4.4.3/fs/aufs/cpup.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/cpup.c 2016-03-02 17:59:37.362498696 +0200 +@@ -0,0 +1,1366 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -3760,6 +3453,7 @@ index 0000000..cd32274 + +#include +#include ++#include +#include "aufs.h" + +void au_cpup_attr_flags(struct inode *dst, unsigned int iflags) @@ -4132,6 +3826,7 @@ index 0000000..cd32274 + } + }; + struct super_block *sb; ++ struct task_struct *tsk = current; + + /* bsrc branch can be ro/rw. */ + sb = cpg->dentry->d_sb; @@ -4149,7 +3844,21 @@ index 0000000..cd32274 + IMustLock(d_inode(file[SRC].dentry)); + err = au_copy_file(file[DST].file, file[SRC].file, cpg->len); + -+ fput(file[DST].file); ++ /* i wonder if we had O_NO_DELAY_FPUT flag */ ++ if (tsk->flags & PF_KTHREAD) ++ __fput_sync(file[DST].file); ++ else { ++ WARN(1, "%pD\nPlease report this warning to aufs-users ML", ++ file[DST].file); ++ fput(file[DST].file); ++ /* ++ * too bad. ++ * we have to call both since we don't know which place the file ++ * was added to. ++ */ ++ task_work_run(); ++ flush_delayed_fput(); ++ } + au_sbr_put(sb, file[DST].bindex); + +out_src: @@ -4248,6 +3957,57 @@ index 0000000..cd32274 + return err; +} + ++/* ++ * regardless 'acl' option, reset all ACL. ++ * All ACL will be copied up later from the original entry on the lower branch. ++ */ ++static int au_reset_acl(struct inode *h_dir, struct path *h_path, umode_t mode) ++{ ++ int err; ++ struct dentry *h_dentry; ++ struct inode *h_inode; ++ ++ h_dentry = h_path->dentry; ++ h_inode = d_inode(h_dentry); ++ /* forget_all_cached_acls(h_inode)); */ ++ err = vfsub_removexattr(h_dentry, XATTR_NAME_POSIX_ACL_ACCESS); ++ AuTraceErr(err); ++ if (err == -EOPNOTSUPP) ++ err = 0; ++ if (!err) ++ err = vfsub_acl_chmod(h_inode, mode); ++ ++ AuTraceErr(err); ++ return err; ++} ++ ++static int au_do_cpup_dir(struct au_cp_generic *cpg, struct dentry *dst_parent, ++ struct inode *h_dir, struct path *h_path) ++{ ++ int err; ++ struct inode *dir, *inode; ++ ++ err = vfsub_removexattr(h_path->dentry, XATTR_NAME_POSIX_ACL_DEFAULT); ++ AuTraceErr(err); ++ if (err == -EOPNOTSUPP) ++ err = 0; ++ if (unlikely(err)) ++ goto out; ++ ++ /* ++ * strange behaviour from the users view, ++ * particularry setattr case ++ */ ++ dir = d_inode(dst_parent); ++ if (au_ibstart(dir) == cpg->bdst) ++ au_cpup_attr_nlink(dir, /*force*/1); ++ inode = d_inode(cpg->dentry); ++ au_cpup_attr_nlink(inode, /*force*/1); ++ ++out: ++ return err; ++} ++ +static noinline_for_stack +int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent, + struct au_cpup_reg_attr *h_src_attr) @@ -4260,7 +4020,7 @@ index 0000000..cd32274 + struct au_dtime dt; + struct path h_path; + struct dentry *h_src, *h_dst, *h_parent; -+ struct inode *h_inode, *h_dir, *dir, *inode; ++ struct inode *h_inode, *h_dir; + struct super_block *sb; + + /* bsrc branch can be ro/rw. */ @@ -4292,7 +4052,7 @@ index 0000000..cd32274 + switch (mode & S_IFMT) { + case S_IFREG: + isreg = 1; -+ err = vfsub_create(h_dir, &h_path, mode | S_IWUSR, ++ err = vfsub_create(h_dir, &h_path, S_IRUSR | S_IWUSR, + /*want_excl*/true); + if (!err) + err = au_do_cpup_regular(cpg, h_src_attr); @@ -4300,17 +4060,8 @@ index 0000000..cd32274 + case S_IFDIR: + isdir = 1; + err = vfsub_mkdir(h_dir, &h_path, mode); -+ if (!err) { -+ /* -+ * strange behaviour from the users view, -+ * particularry setattr case -+ */ -+ dir = d_inode(dst_parent); -+ if (au_ibstart(dir) == cpg->bdst) -+ au_cpup_attr_nlink(dir, /*force*/1); -+ inode = d_inode(cpg->dentry); -+ au_cpup_attr_nlink(inode, /*force*/1); -+ } ++ if (!err) ++ err = au_do_cpup_dir(cpg, dst_parent, h_dir, &h_path); + break; + case S_IFLNK: + err = au_do_cpup_symlink(&h_path, h_src, h_dir); @@ -4327,6 +4078,8 @@ index 0000000..cd32274 + AuIOErr("Unknown inode type 0%o\n", mode); + err = -EIO; + } ++ if (!err) ++ err = au_reset_acl(h_dir, &h_path, mode); + + mnt_flags = au_mntflags(sb); + if (!au_opt_test(mnt_flags, UDBA_NONE) @@ -5056,14 +4809,12 @@ index 0000000..cd32274 + dput(parent); + return err; +} -diff --git a/fs/aufs/cpup.h b/fs/aufs/cpup.h -new file mode 100644 -index 0000000..3355f08 ---- /dev/null -+++ b/fs/aufs/cpup.h +diff -Nurp linux-4.4.3/fs/aufs/cpup.h linux-4.4.3-aufs/fs/aufs/cpup.h +--- linux-4.4.3/fs/aufs/cpup.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/cpup.h 2016-03-02 17:59:37.362498696 +0200 @@ -0,0 +1,81 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -5143,14 +4894,12 @@ index 0000000..3355f08 + +#endif /* __KERNEL__ */ +#endif /* __AUFS_CPUP_H__ */ -diff --git a/fs/aufs/dbgaufs.c b/fs/aufs/dbgaufs.c -new file mode 100644 -index 0000000..c7c612c ---- /dev/null -+++ b/fs/aufs/dbgaufs.c +diff -Nurp linux-4.4.3/fs/aufs/dbgaufs.c linux-4.4.3-aufs/fs/aufs/dbgaufs.c +--- linux-4.4.3/fs/aufs/dbgaufs.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/dbgaufs.c 2016-03-02 17:59:37.362498696 +0200 @@ -0,0 +1,419 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -5568,14 +5317,12 @@ index 0000000..c7c612c + err = 0; + return err; +} -diff --git a/fs/aufs/dbgaufs.h b/fs/aufs/dbgaufs.h -new file mode 100644 -index 0000000..efa9a4d ---- /dev/null -+++ b/fs/aufs/dbgaufs.h +diff -Nurp linux-4.4.3/fs/aufs/dbgaufs.h linux-4.4.3-aufs/fs/aufs/dbgaufs.h +--- linux-4.4.3/fs/aufs/dbgaufs.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/dbgaufs.h 2016-03-02 17:59:37.362498696 +0200 @@ -0,0 +1,35 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -5609,14 +5356,12 @@ index 0000000..efa9a4d + +#endif /* __KERNEL__ */ +#endif /* __DBGAUFS_H__ */ -diff --git a/fs/aufs/dcsub.c b/fs/aufs/dcsub.c -new file mode 100644 -index 0000000..f9d9d52 ---- /dev/null -+++ b/fs/aufs/dcsub.c +diff -Nurp linux-4.4.3/fs/aufs/dcsub.c linux-4.4.3-aufs/fs/aufs/dcsub.c +--- linux-4.4.3/fs/aufs/dcsub.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/dcsub.c 2016-03-02 17:59:37.362498696 +0200 @@ -0,0 +1,211 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -5826,14 +5571,12 @@ index 0000000..f9d9d52 + + return path_is_under(path + 0, path + 1); +} -diff --git a/fs/aufs/dcsub.h b/fs/aufs/dcsub.h -new file mode 100644 -index 0000000..2aa87ac ---- /dev/null -+++ b/fs/aufs/dcsub.h +diff -Nurp linux-4.4.3/fs/aufs/dcsub.h linux-4.4.3-aufs/fs/aufs/dcsub.h +--- linux-4.4.3/fs/aufs/dcsub.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/dcsub.h 2016-03-02 17:59:37.362498696 +0200 @@ -0,0 +1,123 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -5955,14 +5698,12 @@ index 0000000..2aa87ac + +#endif /* __KERNEL__ */ +#endif /* __AUFS_DCSUB_H__ */ -diff --git a/fs/aufs/debug.c b/fs/aufs/debug.c -new file mode 100644 -index 0000000..42053aa ---- /dev/null -+++ b/fs/aufs/debug.c +diff -Nurp linux-4.4.3/fs/aufs/debug.c linux-4.4.3-aufs/fs/aufs/debug.c +--- linux-4.4.3/fs/aufs/debug.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/debug.c 2016-03-02 17:59:37.363498703 +0200 @@ -0,0 +1,425 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -6386,14 +6127,12 @@ index 0000000..42053aa + + return 0; +} -diff --git a/fs/aufs/debug.h b/fs/aufs/debug.h -new file mode 100644 -index 0000000..0a2e7e7 ---- /dev/null -+++ b/fs/aufs/debug.h +diff -Nurp linux-4.4.3/fs/aufs/debug.h linux-4.4.3-aufs/fs/aufs/debug.h +--- linux-4.4.3/fs/aufs/debug.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/debug.h 2016-03-02 17:59:37.363498703 +0200 @@ -0,0 +1,212 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -6604,14 +6343,12 @@ index 0000000..0a2e7e7 + +#endif /* __KERNEL__ */ +#endif /* __AUFS_DEBUG_H__ */ -diff --git a/fs/aufs/dentry.c b/fs/aufs/dentry.c -new file mode 100644 -index 0000000..aad25be ---- /dev/null -+++ b/fs/aufs/dentry.c +diff -Nurp linux-4.4.3/fs/aufs/dentry.c linux-4.4.3-aufs/fs/aufs/dentry.c +--- linux-4.4.3/fs/aufs/dentry.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/dentry.c 2016-03-02 17:59:37.363498703 +0200 @@ -0,0 +1,1123 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -7733,14 +7470,12 @@ index 0000000..aad25be +const struct dentry_operations aufs_dop_noreval = { + .d_release = aufs_d_release +}; -diff --git a/fs/aufs/dentry.h b/fs/aufs/dentry.h -new file mode 100644 -index 0000000..5225221 ---- /dev/null -+++ b/fs/aufs/dentry.h +diff -Nurp linux-4.4.3/fs/aufs/dentry.h linux-4.4.3-aufs/fs/aufs/dentry.h +--- linux-4.4.3/fs/aufs/dentry.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/dentry.h 2016-03-02 17:59:37.363498703 +0200 @@ -0,0 +1,221 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -7960,14 +7695,12 @@ index 0000000..5225221 + +#endif /* __KERNEL__ */ +#endif /* __AUFS_DENTRY_H__ */ -diff --git a/fs/aufs/dinfo.c b/fs/aufs/dinfo.c -new file mode 100644 -index 0000000..25b971b ---- /dev/null -+++ b/fs/aufs/dinfo.c +diff -Nurp linux-4.4.3/fs/aufs/dinfo.c linux-4.4.3-aufs/fs/aufs/dinfo.c +--- linux-4.4.3/fs/aufs/dinfo.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/dinfo.c 2016-03-02 17:59:37.364498710 +0200 @@ -0,0 +1,537 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -8503,14 +8236,12 @@ index 0000000..25b971b + return bindex; + return -1; +} -diff --git a/fs/aufs/dir.c b/fs/aufs/dir.c -new file mode 100644 -index 0000000..ccdcebe ---- /dev/null -+++ b/fs/aufs/dir.c -@@ -0,0 +1,740 @@ +diff -Nurp linux-4.4.3/fs/aufs/dir.c linux-4.4.3-aufs/fs/aufs/dir.c +--- linux-4.4.3/fs/aufs/dir.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/dir.c 2016-03-02 17:59:37.364498710 +0200 +@@ -0,0 +1,745 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -8748,11 +8479,13 @@ index 0000000..ccdcebe + int err; + aufs_bindex_t bindex, btail; + struct dentry *dentry, *h_dentry; ++ struct vfsmount *mnt; + + FiMustWriteLock(file); + AuDebugOn(h_file); + + err = 0; ++ mnt = file->f_path.mnt; + dentry = file->f_path.dentry; + file->f_version = d_inode(dentry)->i_version; + bindex = au_dbstart(dentry); @@ -8764,6 +8497,9 @@ index 0000000..ccdcebe + if (!h_dentry) + continue; + ++ err = vfsub_test_mntns(mnt, h_dentry->d_sb); ++ if (unlikely(err)) ++ break; + h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0); + if (IS_ERR(h_file)) { + err = PTR_ERR(h_file); @@ -9249,14 +8985,12 @@ index 0000000..ccdcebe + .flush = aufs_flush_dir, + .fsync = aufs_fsync_dir +}; -diff --git a/fs/aufs/dir.h b/fs/aufs/dir.h -new file mode 100644 -index 0000000..803a0f1 ---- /dev/null -+++ b/fs/aufs/dir.h +diff -Nurp linux-4.4.3/fs/aufs/dir.h linux-4.4.3-aufs/fs/aufs/dir.h +--- linux-4.4.3/fs/aufs/dir.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/dir.h 2016-03-02 17:59:37.364498710 +0200 @@ -0,0 +1,118 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -9373,14 +9107,12 @@ index 0000000..803a0f1 + +#endif /* __KERNEL__ */ +#endif /* __AUFS_DIR_H__ */ -diff --git a/fs/aufs/dynop.c b/fs/aufs/dynop.c -new file mode 100644 -index 0000000..1f12838 ---- /dev/null -+++ b/fs/aufs/dynop.c +diff -Nurp linux-4.4.3/fs/aufs/dynop.c linux-4.4.3-aufs/fs/aufs/dynop.c +--- linux-4.4.3/fs/aufs/dynop.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/dynop.c 2016-03-02 17:59:37.364498710 +0200 @@ -0,0 +1,356 @@ +/* -+ * Copyright (C) 2010-2015 Junjiro R. Okajima ++ * Copyright (C) 2010-2016 Junjiro R. Okajima + */ + +/* @@ -9735,14 +9467,12 @@ index 0000000..1f12838 + for (i = 0; i < AuDyLast; i++) + WARN_ON(!list_empty(&dynop[i].head)); +} -diff --git a/fs/aufs/dynop.h b/fs/aufs/dynop.h -new file mode 100644 -index 0000000..6d739c1 ---- /dev/null -+++ b/fs/aufs/dynop.h +diff -Nurp linux-4.4.3/fs/aufs/dynop.h linux-4.4.3-aufs/fs/aufs/dynop.h +--- linux-4.4.3/fs/aufs/dynop.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/dynop.h 2016-03-02 17:59:37.364498710 +0200 @@ -0,0 +1,61 @@ +/* -+ * Copyright (C) 2010-2015 Junjiro R. Okajima ++ * Copyright (C) 2010-2016 Junjiro R. Okajima + */ + +/* @@ -9802,14 +9532,12 @@ index 0000000..6d739c1 + +#endif /* __KERNEL__ */ +#endif /* __AUFS_DYNOP_H__ */ -diff --git a/fs/aufs/export.c b/fs/aufs/export.c -new file mode 100644 -index 0000000..3026f39 ---- /dev/null -+++ b/fs/aufs/export.c +diff -Nurp linux-4.4.3/fs/aufs/export.c linux-4.4.3-aufs/fs/aufs/export.c +--- linux-4.4.3/fs/aufs/export.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/export.c 2016-03-02 17:59:37.365498717 +0200 @@ -0,0 +1,819 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -10407,7 +10135,7 @@ index 0000000..3026f39 + ino = decode_ino(fh + Fh_ino); + /* it should never happen */ + if (unlikely(ino == AUFS_ROOT_INO)) -+ goto out; ++ goto out_unlock; + + dir_ino = decode_ino(fh + Fh_dir_ino); + dentry = decode_by_ino(sb, ino, dir_ino); @@ -10627,745 +10355,12 @@ index 0000000..3026f39 + BUILD_BUG_ON(sizeof(u) != sizeof(int)); + atomic_set(&sbinfo->si_xigen_next, u); +} -diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c -new file mode 100644 -index 0000000..91c2ce7 ---- /dev/null -+++ b/fs/aufs/f_op.c -@@ -0,0 +1,725 @@ -+/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima -+ */ -+ -+/* -+ * file and vm operations -+ */ -+ -+#include -+#include -+#include -+#include -+#include "aufs.h" -+ -+int au_do_open_nondir(struct file *file, int flags, struct file *h_file) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ struct dentry *dentry; -+ struct au_finfo *finfo; -+ struct inode *h_inode; -+ -+ FiMustWriteLock(file); -+ -+ err = 0; -+ dentry = file->f_path.dentry; -+ AuDebugOn(IS_ERR_OR_NULL(dentry)); -+ finfo = au_fi(file); -+ memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop)); -+ atomic_set(&finfo->fi_mmapped, 0); -+ bindex = au_dbstart(dentry); -+ if (!h_file) -+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0); -+ else -+ get_file(h_file); -+ if (IS_ERR(h_file)) -+ err = PTR_ERR(h_file); -+ else { -+ if ((flags & __O_TMPFILE) -+ && !(flags & O_EXCL)) { -+ h_inode = file_inode(h_file); -+ spin_lock(&h_inode->i_lock); -+ h_inode->i_state |= I_LINKABLE; -+ spin_unlock(&h_inode->i_lock); -+ } -+ au_set_fbstart(file, bindex); -+ au_set_h_fptr(file, bindex, h_file); -+ au_update_figen(file); -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ } -+ -+ return err; -+} -+ -+static int aufs_open_nondir(struct inode *inode __maybe_unused, -+ struct file *file) -+{ -+ int err; -+ struct super_block *sb; -+ struct au_do_open_args args = { -+ .open = au_do_open_nondir -+ }; -+ -+ AuDbg("%pD, f_flags 0x%x, f_mode 0x%x\n", -+ file, vfsub_file_flags(file), file->f_mode); -+ -+ sb = file->f_path.dentry->d_sb; -+ si_read_lock(sb, AuLock_FLUSH); -+ err = au_do_open(file, &args); -+ si_read_unlock(sb); -+ return err; -+} -+ -+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file) -+{ -+ struct au_finfo *finfo; -+ aufs_bindex_t bindex; -+ -+ finfo = au_fi(file); -+ au_sphl_del(&finfo->fi_hlist, -+ &au_sbi(file->f_path.dentry->d_sb)->si_files); -+ bindex = finfo->fi_btop; -+ if (bindex >= 0) -+ au_set_h_fptr(file, bindex, NULL); -+ -+ au_finfo_fin(file); -+ return 0; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_do_flush_nondir(struct file *file, fl_owner_t id) -+{ -+ int err; -+ struct file *h_file; -+ -+ err = 0; -+ h_file = au_hf_top(file); -+ if (h_file) -+ err = vfsub_flush(h_file, id); -+ return err; -+} -+ -+static int aufs_flush_nondir(struct file *file, fl_owner_t id) -+{ -+ return au_do_flush(file, id, au_do_flush_nondir); -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * read and write functions acquire [fdi]_rwsem once, but release before -+ * mmap_sem. This is because to stop a race condition between mmap(2). -+ * Releasing these aufs-rwsem should be safe, no branch-mamagement (by keeping -+ * si_rwsem), no harmful copy-up should happen. Actually copy-up may happen in -+ * read functions after [fdi]_rwsem are released, but it should be harmless. -+ */ -+ -+/* Callers should call au_read_post() or fput() in the end */ -+struct file *au_read_pre(struct file *file, int keep_fi) -+{ -+ struct file *h_file; -+ int err; -+ -+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0); -+ if (!err) { -+ di_read_unlock(file->f_path.dentry, AuLock_IR); -+ h_file = au_hf_top(file); -+ get_file(h_file); -+ if (!keep_fi) -+ fi_read_unlock(file); -+ } else -+ h_file = ERR_PTR(err); -+ -+ return h_file; -+} -+ -+static void au_read_post(struct inode *inode, struct file *h_file) -+{ -+ /* update without lock, I don't think it a problem */ -+ fsstack_copy_attr_atime(inode, file_inode(h_file)); -+ fput(h_file); -+} -+ -+struct au_write_pre { -+ blkcnt_t blks; -+ aufs_bindex_t bstart; -+}; -+ -+/* -+ * return with iinfo is write-locked -+ * callers should call au_write_post() or iinfo_write_unlock() + fput() in the -+ * end -+ */ -+static struct file *au_write_pre(struct file *file, int do_ready, -+ struct au_write_pre *wpre) -+{ -+ struct file *h_file; -+ struct dentry *dentry; -+ int err; -+ struct au_pin pin; -+ -+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1); -+ h_file = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out; -+ -+ dentry = file->f_path.dentry; -+ if (do_ready) { -+ err = au_ready_to_write(file, -1, &pin); -+ if (unlikely(err)) { -+ h_file = ERR_PTR(err); -+ di_write_unlock(dentry); -+ goto out_fi; -+ } -+ } -+ -+ di_downgrade_lock(dentry, /*flags*/0); -+ if (wpre) -+ wpre->bstart = au_fbstart(file); -+ h_file = au_hf_top(file); -+ get_file(h_file); -+ if (wpre) -+ wpre->blks = file_inode(h_file)->i_blocks; -+ if (do_ready) -+ au_unpin(&pin); -+ di_read_unlock(dentry, /*flags*/0); -+ -+out_fi: -+ fi_write_unlock(file); -+out: -+ return h_file; -+} -+ -+static void au_write_post(struct inode *inode, struct file *h_file, -+ struct au_write_pre *wpre, ssize_t written) -+{ -+ struct inode *h_inode; -+ -+ au_cpup_attr_timesizes(inode); -+ AuDebugOn(au_ibstart(inode) != wpre->bstart); -+ h_inode = file_inode(h_file); -+ inode->i_mode = h_inode->i_mode; -+ ii_write_unlock(inode); -+ fput(h_file); -+ -+ /* AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks); */ -+ if (written > 0) -+ au_fhsm_wrote(inode->i_sb, wpre->bstart, -+ /*force*/h_inode->i_blocks > wpre->blks); -+} -+ -+static ssize_t aufs_read(struct file *file, char __user *buf, size_t count, -+ loff_t *ppos) -+{ -+ ssize_t err; -+ struct inode *inode; -+ struct file *h_file; -+ struct super_block *sb; -+ -+ inode = file_inode(file); -+ sb = inode->i_sb; -+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); -+ -+ h_file = au_read_pre(file, /*keep_fi*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ /* filedata may be obsoleted by concurrent copyup, but no problem */ -+ err = vfsub_read_u(h_file, buf, count, ppos); -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ au_read_post(inode, h_file); -+ -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+/* -+ * todo: very ugly -+ * it locks both of i_mutex and si_rwsem for read in safe. -+ * if the plink maintenance mode continues forever (that is the problem), -+ * may loop forever. -+ */ -+static void au_mtx_and_read_lock(struct inode *inode) -+{ -+ int err; -+ struct super_block *sb = inode->i_sb; -+ -+ while (1) { -+ mutex_lock(&inode->i_mutex); -+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (!err) -+ break; -+ mutex_unlock(&inode->i_mutex); -+ si_read_lock(sb, AuLock_NOPLMW); -+ si_read_unlock(sb); -+ } -+} -+ -+static ssize_t aufs_write(struct file *file, const char __user *ubuf, -+ size_t count, loff_t *ppos) -+{ -+ ssize_t err; -+ struct au_write_pre wpre; -+ struct inode *inode; -+ struct file *h_file; -+ char __user *buf = (char __user *)ubuf; -+ -+ inode = file_inode(file); -+ au_mtx_and_read_lock(inode); -+ -+ h_file = au_write_pre(file, /*do_ready*/1, &wpre); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ err = vfsub_write_u(h_file, buf, count, ppos); -+ au_write_post(inode, h_file, &wpre, err); -+ -+out: -+ si_read_unlock(inode->i_sb); -+ mutex_unlock(&inode->i_mutex); -+ return err; -+} -+ -+static ssize_t au_do_iter(struct file *h_file, int rw, struct kiocb *kio, -+ struct iov_iter *iov_iter) -+{ -+ ssize_t err; -+ struct file *file; -+ ssize_t (*iter)(struct kiocb *, struct iov_iter *); -+ -+ err = security_file_permission(h_file, rw); -+ if (unlikely(err)) -+ goto out; -+ -+ err = -ENOSYS; -+ iter = NULL; -+ if (rw == MAY_READ) -+ iter = h_file->f_op->read_iter; -+ else if (rw == MAY_WRITE) -+ iter = h_file->f_op->write_iter; -+ -+ file = kio->ki_filp; -+ kio->ki_filp = h_file; -+ if (iter) { -+ lockdep_off(); -+ err = iter(kio, iov_iter); -+ lockdep_on(); -+ } else -+ /* currently there is no such fs */ -+ WARN_ON_ONCE(1); -+ kio->ki_filp = file; -+ -+out: -+ return err; -+} -+ -+static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter) -+{ -+ ssize_t err; -+ struct file *file, *h_file; -+ struct inode *inode; -+ struct super_block *sb; -+ -+ file = kio->ki_filp; -+ inode = file_inode(file); -+ sb = inode->i_sb; -+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); -+ -+ h_file = au_read_pre(file, /*keep_fi*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ err = au_do_iter(h_file, MAY_READ, kio, iov_iter); -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ au_read_post(inode, h_file); -+ -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+static ssize_t aufs_write_iter(struct kiocb *kio, struct iov_iter *iov_iter) -+{ -+ ssize_t err; -+ struct au_write_pre wpre; -+ struct inode *inode; -+ struct file *file, *h_file; -+ -+ file = kio->ki_filp; -+ inode = file_inode(file); -+ au_mtx_and_read_lock(inode); -+ -+ h_file = au_write_pre(file, /*do_ready*/1, &wpre); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ err = au_do_iter(h_file, MAY_WRITE, kio, iov_iter); -+ au_write_post(inode, h_file, &wpre, err); -+ -+out: -+ si_read_unlock(inode->i_sb); -+ mutex_unlock(&inode->i_mutex); -+ return err; -+} -+ -+static ssize_t aufs_splice_read(struct file *file, loff_t *ppos, -+ struct pipe_inode_info *pipe, size_t len, -+ unsigned int flags) -+{ -+ ssize_t err; -+ struct file *h_file; -+ struct inode *inode; -+ struct super_block *sb; -+ -+ inode = file_inode(file); -+ sb = inode->i_sb; -+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); -+ -+ h_file = au_read_pre(file, /*keep_fi*/1); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ if (au_test_loopback_kthread()) { -+ au_warn_loopback(h_file->f_path.dentry->d_sb); -+ if (file->f_mapping != h_file->f_mapping) { -+ file->f_mapping = h_file->f_mapping; -+ smp_mb(); /* unnecessary? */ -+ } -+ } -+ fi_read_unlock(file); -+ -+ err = vfsub_splice_to(h_file, ppos, pipe, len, flags); -+ /* todo: necessasry? */ -+ /* file->f_ra = h_file->f_ra; */ -+ au_read_post(inode, h_file); -+ -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+static ssize_t -+aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos, -+ size_t len, unsigned int flags) -+{ -+ ssize_t err; -+ struct au_write_pre wpre; -+ struct inode *inode; -+ struct file *h_file; -+ -+ inode = file_inode(file); -+ au_mtx_and_read_lock(inode); -+ -+ h_file = au_write_pre(file, /*do_ready*/1, &wpre); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ err = vfsub_splice_from(pipe, h_file, ppos, len, flags); -+ au_write_post(inode, h_file, &wpre, err); -+ -+out: -+ si_read_unlock(inode->i_sb); -+ mutex_unlock(&inode->i_mutex); -+ return err; -+} -+ -+static long aufs_fallocate(struct file *file, int mode, loff_t offset, -+ loff_t len) -+{ -+ long err; -+ struct au_write_pre wpre; -+ struct inode *inode; -+ struct file *h_file; -+ -+ inode = file_inode(file); -+ au_mtx_and_read_lock(inode); -+ -+ h_file = au_write_pre(file, /*do_ready*/1, &wpre); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ lockdep_off(); -+ err = vfs_fallocate(h_file, mode, offset, len); -+ lockdep_on(); -+ au_write_post(inode, h_file, &wpre, /*written*/1); -+ -+out: -+ si_read_unlock(inode->i_sb); -+ mutex_unlock(&inode->i_mutex); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * The locking order around current->mmap_sem. -+ * - in most and regular cases -+ * file I/O syscall -- aufs_read() or something -+ * -- si_rwsem for read -- mmap_sem -+ * (Note that [fdi]i_rwsem are released before mmap_sem). -+ * - in mmap case -+ * mmap(2) -- mmap_sem -- aufs_mmap() -- si_rwsem for read -- [fdi]i_rwsem -+ * This AB-BA order is definitly bad, but is not a problem since "si_rwsem for -+ * read" allows muliple processes to acquire it and [fdi]i_rwsem are not held in -+ * file I/O. Aufs needs to stop lockdep in aufs_mmap() though. -+ * It means that when aufs acquires si_rwsem for write, the process should never -+ * acquire mmap_sem. -+ * -+ * Actually aufs_iterate() holds [fdi]i_rwsem before mmap_sem, but this is not a -+ * problem either since any directory is not able to be mmap-ed. -+ * The similar scenario is applied to aufs_readlink() too. -+ */ -+ -+#if 0 /* stop calling security_file_mmap() */ -+/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */ -+#define AuConv_VM_PROT(f, b) _calc_vm_trans(f, VM_##b, PROT_##b) -+ -+static unsigned long au_arch_prot_conv(unsigned long flags) -+{ -+ /* currently ppc64 only */ -+#ifdef CONFIG_PPC64 -+ /* cf. linux/arch/powerpc/include/asm/mman.h */ -+ AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO); -+ return AuConv_VM_PROT(flags, SAO); -+#else -+ AuDebugOn(arch_calc_vm_prot_bits(-1)); -+ return 0; -+#endif -+} -+ -+static unsigned long au_prot_conv(unsigned long flags) -+{ -+ return AuConv_VM_PROT(flags, READ) -+ | AuConv_VM_PROT(flags, WRITE) -+ | AuConv_VM_PROT(flags, EXEC) -+ | au_arch_prot_conv(flags); -+} -+ -+/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */ -+#define AuConv_VM_MAP(f, b) _calc_vm_trans(f, VM_##b, MAP_##b) -+ -+static unsigned long au_flag_conv(unsigned long flags) -+{ -+ return AuConv_VM_MAP(flags, GROWSDOWN) -+ | AuConv_VM_MAP(flags, DENYWRITE) -+ | AuConv_VM_MAP(flags, LOCKED); -+} -+#endif -+ -+static int aufs_mmap(struct file *file, struct vm_area_struct *vma) -+{ -+ int err; -+ const unsigned char wlock -+ = (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED); -+ struct super_block *sb; -+ struct file *h_file; -+ struct inode *inode; -+ -+ AuDbgVmRegion(file, vma); -+ -+ inode = file_inode(file); -+ sb = inode->i_sb; -+ lockdep_off(); -+ si_read_lock(sb, AuLock_NOPLMW); -+ -+ h_file = au_write_pre(file, wlock, /*wpre*/NULL); -+ lockdep_on(); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ err = 0; -+ au_set_mmapped(file); -+ au_vm_file_reset(vma, h_file); -+ /* -+ * we cannot call security_mmap_file() here since it may acquire -+ * mmap_sem or i_mutex. -+ * -+ * err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags), -+ * au_flag_conv(vma->vm_flags)); -+ */ -+ if (!err) -+ err = h_file->f_op->mmap(h_file, vma); -+ if (!err) { -+ au_vm_prfile_set(vma, file); -+ fsstack_copy_attr_atime(inode, file_inode(h_file)); -+ goto out_fput; /* success */ -+ } -+ au_unset_mmapped(file); -+ au_vm_file_reset(vma, file); -+ -+out_fput: -+ lockdep_off(); -+ ii_write_unlock(inode); -+ lockdep_on(); -+ fput(h_file); -+out: -+ lockdep_off(); -+ si_read_unlock(sb); -+ lockdep_on(); -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int aufs_fsync_nondir(struct file *file, loff_t start, loff_t end, -+ int datasync) -+{ -+ int err; -+ struct au_write_pre wpre; -+ struct inode *inode; -+ struct file *h_file; -+ -+ err = 0; /* -EBADF; */ /* posix? */ -+ if (unlikely(!(file->f_mode & FMODE_WRITE))) -+ goto out; -+ -+ inode = file_inode(file); -+ au_mtx_and_read_lock(inode); -+ -+ h_file = au_write_pre(file, /*do_ready*/1, &wpre); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out_unlock; -+ -+ err = vfsub_fsync(h_file, &h_file->f_path, datasync); -+ au_write_post(inode, h_file, &wpre, /*written*/0); -+ -+out_unlock: -+ si_read_unlock(inode->i_sb); -+ mutex_unlock(&inode->i_mutex); -+out: -+ return err; -+} -+ -+/* no one supports this operation, currently */ -+#if 0 -+static int aufs_aio_fsync_nondir(struct kiocb *kio, int datasync) -+{ -+ int err; -+ struct au_write_pre wpre; -+ struct inode *inode; -+ struct file *file, *h_file; -+ -+ err = 0; /* -EBADF; */ /* posix? */ -+ if (unlikely(!(file->f_mode & FMODE_WRITE))) -+ goto out; -+ -+ file = kio->ki_filp; -+ inode = file_inode(file); -+ au_mtx_and_read_lock(inode); -+ -+ h_file = au_write_pre(file, /*do_ready*/1, &wpre); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out_unlock; -+ -+ err = -ENOSYS; -+ h_file = au_hf_top(file); -+ if (h_file->f_op->aio_fsync) { -+ struct mutex *h_mtx; -+ -+ h_mtx = &file_inode(h_file)->i_mutex; -+ if (!is_sync_kiocb(kio)) { -+ get_file(h_file); -+ fput(file); -+ } -+ kio->ki_filp = h_file; -+ err = h_file->f_op->aio_fsync(kio, datasync); -+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); -+ if (!err) -+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); -+ /*ignore*/ -+ mutex_unlock(h_mtx); -+ } -+ au_write_post(inode, h_file, &wpre, /*written*/0); -+ -+out_unlock: -+ si_read_unlock(inode->sb); -+ mutex_unlock(&inode->i_mutex); -+out: -+ return err; -+} -+#endif -+ -+static int aufs_fasync(int fd, struct file *file, int flag) -+{ -+ int err; -+ struct file *h_file; -+ struct super_block *sb; -+ -+ sb = file->f_path.dentry->d_sb; -+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); -+ -+ h_file = au_read_pre(file, /*keep_fi*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ if (h_file->f_op->fasync) -+ err = h_file->f_op->fasync(fd, h_file, flag); -+ fput(h_file); /* instead of au_read_post() */ -+ -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* no one supports this operation, currently */ -+#if 0 -+static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset, -+ size_t len, loff_t *pos, int more) -+{ -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+const struct file_operations aufs_file_fop = { -+ .owner = THIS_MODULE, -+ -+ .llseek = default_llseek, -+ -+ .read = aufs_read, -+ .write = aufs_write, -+ .read_iter = aufs_read_iter, -+ .write_iter = aufs_write_iter, -+ -+#ifdef CONFIG_AUFS_POLL -+ .poll = aufs_poll, -+#endif -+ .unlocked_ioctl = aufs_ioctl_nondir, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = aufs_compat_ioctl_nondir, -+#endif -+ .mmap = aufs_mmap, -+ .open = aufs_open_nondir, -+ .flush = aufs_flush_nondir, -+ .release = aufs_release_nondir, -+ .fsync = aufs_fsync_nondir, -+ /* .aio_fsync = aufs_aio_fsync_nondir, */ -+ .fasync = aufs_fasync, -+ /* .sendpage = aufs_sendpage, */ -+ .splice_write = aufs_splice_write, -+ .splice_read = aufs_splice_read, -+#if 0 -+ .aio_splice_write = aufs_aio_splice_write, -+ .aio_splice_read = aufs_aio_splice_read, -+#endif -+ .fallocate = aufs_fallocate -+}; -diff --git a/fs/aufs/fhsm.c b/fs/aufs/fhsm.c -new file mode 100644 -index 0000000..47106cb ---- /dev/null -+++ b/fs/aufs/fhsm.c +diff -Nurp linux-4.4.3/fs/aufs/fhsm.c linux-4.4.3-aufs/fs/aufs/fhsm.c +--- linux-4.4.3/fs/aufs/fhsm.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/fhsm.c 2016-03-02 17:59:37.365498717 +0200 @@ -0,0 +1,412 @@ +/* -+ * Copyright (C) 2011-2015 Junjiro R. Okajima ++ * Copyright (C) 2011-2016 Junjiro R. Okajima + */ + +/* @@ -11776,14 +10771,12 @@ index 0000000..47106cb + if (u != AUFS_FHSM_CACHE_DEF_SEC) + seq_printf(seq, ",fhsm_sec=%u", u); +} -diff --git a/fs/aufs/file.c b/fs/aufs/file.c -new file mode 100644 -index 0000000..72316b1 ---- /dev/null -+++ b/fs/aufs/file.c +diff -Nurp linux-4.4.3/fs/aufs/file.c linux-4.4.3-aufs/fs/aufs/file.c +--- linux-4.4.3/fs/aufs/file.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/file.c 2016-03-02 17:59:37.366498724 +0200 @@ -0,0 +1,831 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -12613,14 +11606,12 @@ index 0000000..72316b1 + .swap_deactivate = aufs_swap_deactivate +#endif /* CONFIG_AUFS_DEBUG */ +}; -diff --git a/fs/aufs/file.h b/fs/aufs/file.h -new file mode 100644 -index 0000000..488473e ---- /dev/null -+++ b/fs/aufs/file.h +diff -Nurp linux-4.4.3/fs/aufs/file.h linux-4.4.3-aufs/fs/aufs/file.h +--- linux-4.4.3/fs/aufs/file.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/file.h 2016-03-02 17:59:37.366498724 +0200 @@ -0,0 +1,278 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -12897,14 +11888,12 @@ index 0000000..488473e + +#endif /* __KERNEL__ */ +#endif /* __AUFS_FILE_H__ */ -diff --git a/fs/aufs/finfo.c b/fs/aufs/finfo.c -new file mode 100644 -index 0000000..e709205 ---- /dev/null -+++ b/fs/aufs/finfo.c +diff -Nurp linux-4.4.3/fs/aufs/finfo.c linux-4.4.3-aufs/fs/aufs/finfo.c +--- linux-4.4.3/fs/aufs/finfo.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/finfo.c 2016-03-02 17:59:37.366498724 +0200 @@ -0,0 +1,143 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -13046,14 +12035,775 @@ index 0000000..e709205 +out: + return err; +} -diff --git a/fs/aufs/fstype.h b/fs/aufs/fstype.h -new file mode 100644 -index 0000000..6196c60 ---- /dev/null -+++ b/fs/aufs/fstype.h +diff -Nurp linux-4.4.3/fs/aufs/f_op.c linux-4.4.3-aufs/fs/aufs/f_op.c +--- linux-4.4.3/fs/aufs/f_op.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/f_op.c 2016-03-02 17:59:37.365498717 +0200 +@@ -0,0 +1,759 @@ ++/* ++ * Copyright (C) 2005-2016 Junjiro R. Okajima ++ */ ++ ++/* ++ * file and vm operations ++ */ ++ ++#include ++#include ++#include ++#include ++#include "aufs.h" ++ ++int au_do_open_nondir(struct file *file, int flags, struct file *h_file) ++{ ++ int err; ++ aufs_bindex_t bindex; ++ struct dentry *dentry, *h_dentry; ++ struct au_finfo *finfo; ++ struct inode *h_inode; ++ ++ FiMustWriteLock(file); ++ ++ err = 0; ++ dentry = file->f_path.dentry; ++ AuDebugOn(IS_ERR_OR_NULL(dentry)); ++ finfo = au_fi(file); ++ memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop)); ++ atomic_set(&finfo->fi_mmapped, 0); ++ bindex = au_dbstart(dentry); ++ if (!h_file) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ err = vfsub_test_mntns(file->f_path.mnt, h_dentry->d_sb); ++ if (unlikely(err)) ++ goto out; ++ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0); ++ } else { ++ h_dentry = h_file->f_path.dentry; ++ err = vfsub_test_mntns(file->f_path.mnt, h_dentry->d_sb); ++ if (unlikely(err)) ++ goto out; ++ get_file(h_file); ++ } ++ if (IS_ERR(h_file)) ++ err = PTR_ERR(h_file); ++ else { ++ if ((flags & __O_TMPFILE) ++ && !(flags & O_EXCL)) { ++ h_inode = file_inode(h_file); ++ spin_lock(&h_inode->i_lock); ++ h_inode->i_state |= I_LINKABLE; ++ spin_unlock(&h_inode->i_lock); ++ } ++ au_set_fbstart(file, bindex); ++ au_set_h_fptr(file, bindex, h_file); ++ au_update_figen(file); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ } ++ ++out: ++ return err; ++} ++ ++static int aufs_open_nondir(struct inode *inode __maybe_unused, ++ struct file *file) ++{ ++ int err; ++ struct super_block *sb; ++ struct au_do_open_args args = { ++ .open = au_do_open_nondir ++ }; ++ ++ AuDbg("%pD, f_flags 0x%x, f_mode 0x%x\n", ++ file, vfsub_file_flags(file), file->f_mode); ++ ++ sb = file->f_path.dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_do_open(file, &args); ++ si_read_unlock(sb); ++ return err; ++} ++ ++int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file) ++{ ++ struct au_finfo *finfo; ++ aufs_bindex_t bindex; ++ ++ finfo = au_fi(file); ++ au_sphl_del(&finfo->fi_hlist, ++ &au_sbi(file->f_path.dentry->d_sb)->si_files); ++ bindex = finfo->fi_btop; ++ if (bindex >= 0) ++ au_set_h_fptr(file, bindex, NULL); ++ ++ au_finfo_fin(file); ++ return 0; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_do_flush_nondir(struct file *file, fl_owner_t id) ++{ ++ int err; ++ struct file *h_file; ++ ++ err = 0; ++ h_file = au_hf_top(file); ++ if (h_file) ++ err = vfsub_flush(h_file, id); ++ return err; ++} ++ ++static int aufs_flush_nondir(struct file *file, fl_owner_t id) ++{ ++ return au_do_flush(file, id, au_do_flush_nondir); ++} ++ ++/* ---------------------------------------------------------------------- */ ++/* ++ * read and write functions acquire [fdi]_rwsem once, but release before ++ * mmap_sem. This is because to stop a race condition between mmap(2). ++ * Releasing these aufs-rwsem should be safe, no branch-mamagement (by keeping ++ * si_rwsem), no harmful copy-up should happen. Actually copy-up may happen in ++ * read functions after [fdi]_rwsem are released, but it should be harmless. ++ */ ++ ++/* Callers should call au_read_post() or fput() in the end */ ++struct file *au_read_pre(struct file *file, int keep_fi) ++{ ++ struct file *h_file; ++ int err; ++ ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0); ++ if (!err) { ++ di_read_unlock(file->f_path.dentry, AuLock_IR); ++ h_file = au_hf_top(file); ++ get_file(h_file); ++ if (!keep_fi) ++ fi_read_unlock(file); ++ } else ++ h_file = ERR_PTR(err); ++ ++ return h_file; ++} ++ ++static void au_read_post(struct inode *inode, struct file *h_file) ++{ ++ /* update without lock, I don't think it a problem */ ++ fsstack_copy_attr_atime(inode, file_inode(h_file)); ++ fput(h_file); ++} ++ ++struct au_write_pre { ++ blkcnt_t blks; ++ aufs_bindex_t bstart; ++}; ++ ++/* ++ * return with iinfo is write-locked ++ * callers should call au_write_post() or iinfo_write_unlock() + fput() in the ++ * end ++ */ ++static struct file *au_write_pre(struct file *file, int do_ready, ++ struct au_write_pre *wpre) ++{ ++ struct file *h_file; ++ struct dentry *dentry; ++ int err; ++ struct au_pin pin; ++ ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1); ++ h_file = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out; ++ ++ dentry = file->f_path.dentry; ++ if (do_ready) { ++ err = au_ready_to_write(file, -1, &pin); ++ if (unlikely(err)) { ++ h_file = ERR_PTR(err); ++ di_write_unlock(dentry); ++ goto out_fi; ++ } ++ } ++ ++ di_downgrade_lock(dentry, /*flags*/0); ++ if (wpre) ++ wpre->bstart = au_fbstart(file); ++ h_file = au_hf_top(file); ++ get_file(h_file); ++ if (wpre) ++ wpre->blks = file_inode(h_file)->i_blocks; ++ if (do_ready) ++ au_unpin(&pin); ++ di_read_unlock(dentry, /*flags*/0); ++ ++out_fi: ++ fi_write_unlock(file); ++out: ++ return h_file; ++} ++ ++static void au_write_post(struct inode *inode, struct file *h_file, ++ struct au_write_pre *wpre, ssize_t written) ++{ ++ struct inode *h_inode; ++ ++ au_cpup_attr_timesizes(inode); ++ AuDebugOn(au_ibstart(inode) != wpre->bstart); ++ h_inode = file_inode(h_file); ++ inode->i_mode = h_inode->i_mode; ++ ii_write_unlock(inode); ++ fput(h_file); ++ ++ /* AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks); */ ++ if (written > 0) ++ au_fhsm_wrote(inode->i_sb, wpre->bstart, ++ /*force*/h_inode->i_blocks > wpre->blks); ++} ++ ++static ssize_t aufs_read(struct file *file, char __user *buf, size_t count, ++ loff_t *ppos) ++{ ++ ssize_t err; ++ struct inode *inode; ++ struct file *h_file; ++ struct super_block *sb; ++ ++ inode = file_inode(file); ++ sb = inode->i_sb; ++ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); ++ ++ h_file = au_read_pre(file, /*keep_fi*/0); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out; ++ ++ /* filedata may be obsoleted by concurrent copyup, but no problem */ ++ err = vfsub_read_u(h_file, buf, count, ppos); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ au_read_post(inode, h_file); ++ ++out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ++ * todo: very ugly ++ * it locks both of i_mutex and si_rwsem for read in safe. ++ * if the plink maintenance mode continues forever (that is the problem), ++ * may loop forever. ++ */ ++static void au_mtx_and_read_lock(struct inode *inode) ++{ ++ int err; ++ struct super_block *sb = inode->i_sb; ++ ++ while (1) { ++ mutex_lock(&inode->i_mutex); ++ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); ++ if (!err) ++ break; ++ mutex_unlock(&inode->i_mutex); ++ si_read_lock(sb, AuLock_NOPLMW); ++ si_read_unlock(sb); ++ } ++} ++ ++static ssize_t aufs_write(struct file *file, const char __user *ubuf, ++ size_t count, loff_t *ppos) ++{ ++ ssize_t err; ++ struct au_write_pre wpre; ++ struct inode *inode; ++ struct file *h_file; ++ char __user *buf = (char __user *)ubuf; ++ ++ inode = file_inode(file); ++ au_mtx_and_read_lock(inode); ++ ++ h_file = au_write_pre(file, /*do_ready*/1, &wpre); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out; ++ ++ err = vfsub_write_u(h_file, buf, count, ppos); ++ au_write_post(inode, h_file, &wpre, err); ++ ++out: ++ si_read_unlock(inode->i_sb); ++ mutex_unlock(&inode->i_mutex); ++ return err; ++} ++ ++static ssize_t au_do_iter(struct file *h_file, int rw, struct kiocb *kio, ++ struct iov_iter *iov_iter) ++{ ++ ssize_t err; ++ struct file *file; ++ ssize_t (*iter)(struct kiocb *, struct iov_iter *); ++ ++ err = security_file_permission(h_file, rw); ++ if (unlikely(err)) ++ goto out; ++ ++ err = -ENOSYS; ++ iter = NULL; ++ if (rw == MAY_READ) ++ iter = h_file->f_op->read_iter; ++ else if (rw == MAY_WRITE) ++ iter = h_file->f_op->write_iter; ++ ++ file = kio->ki_filp; ++ kio->ki_filp = h_file; ++ if (iter) { ++ lockdep_off(); ++ err = iter(kio, iov_iter); ++ lockdep_on(); ++ } else ++ /* currently there is no such fs */ ++ WARN_ON_ONCE(1); ++ kio->ki_filp = file; ++ ++out: ++ return err; ++} ++ ++static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter) ++{ ++ ssize_t err; ++ struct file *file, *h_file; ++ struct inode *inode; ++ struct super_block *sb; ++ ++ file = kio->ki_filp; ++ inode = file_inode(file); ++ sb = inode->i_sb; ++ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); ++ ++ h_file = au_read_pre(file, /*keep_fi*/0); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out; ++ ++ err = au_do_iter(h_file, MAY_READ, kio, iov_iter); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ au_read_post(inode, h_file); ++ ++out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++static ssize_t aufs_write_iter(struct kiocb *kio, struct iov_iter *iov_iter) ++{ ++ ssize_t err; ++ struct au_write_pre wpre; ++ struct inode *inode; ++ struct file *file, *h_file; ++ ++ file = kio->ki_filp; ++ inode = file_inode(file); ++ au_mtx_and_read_lock(inode); ++ ++ h_file = au_write_pre(file, /*do_ready*/1, &wpre); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out; ++ ++ err = au_do_iter(h_file, MAY_WRITE, kio, iov_iter); ++ au_write_post(inode, h_file, &wpre, err); ++ ++out: ++ si_read_unlock(inode->i_sb); ++ mutex_unlock(&inode->i_mutex); ++ return err; ++} ++ ++static ssize_t aufs_splice_read(struct file *file, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags) ++{ ++ ssize_t err; ++ struct file *h_file; ++ struct inode *inode; ++ struct super_block *sb; ++ ++ inode = file_inode(file); ++ sb = inode->i_sb; ++ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); ++ ++ h_file = au_read_pre(file, /*keep_fi*/1); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out; ++ ++ if (au_test_loopback_kthread()) { ++ au_warn_loopback(h_file->f_path.dentry->d_sb); ++ if (file->f_mapping != h_file->f_mapping) { ++ file->f_mapping = h_file->f_mapping; ++ smp_mb(); /* unnecessary? */ ++ } ++ } ++ fi_read_unlock(file); ++ ++ err = vfsub_splice_to(h_file, ppos, pipe, len, flags); ++ /* todo: necessasry? */ ++ /* file->f_ra = h_file->f_ra; */ ++ au_read_post(inode, h_file); ++ ++out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++static ssize_t ++aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos, ++ size_t len, unsigned int flags) ++{ ++ ssize_t err; ++ struct au_write_pre wpre; ++ struct inode *inode; ++ struct file *h_file; ++ ++ inode = file_inode(file); ++ au_mtx_and_read_lock(inode); ++ ++ h_file = au_write_pre(file, /*do_ready*/1, &wpre); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out; ++ ++ err = vfsub_splice_from(pipe, h_file, ppos, len, flags); ++ au_write_post(inode, h_file, &wpre, err); ++ ++out: ++ si_read_unlock(inode->i_sb); ++ mutex_unlock(&inode->i_mutex); ++ return err; ++} ++ ++static long aufs_fallocate(struct file *file, int mode, loff_t offset, ++ loff_t len) ++{ ++ long err; ++ struct au_write_pre wpre; ++ struct inode *inode; ++ struct file *h_file; ++ ++ inode = file_inode(file); ++ au_mtx_and_read_lock(inode); ++ ++ h_file = au_write_pre(file, /*do_ready*/1, &wpre); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out; ++ ++ lockdep_off(); ++ err = vfs_fallocate(h_file, mode, offset, len); ++ lockdep_on(); ++ au_write_post(inode, h_file, &wpre, /*written*/1); ++ ++out: ++ si_read_unlock(inode->i_sb); ++ mutex_unlock(&inode->i_mutex); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * The locking order around current->mmap_sem. ++ * - in most and regular cases ++ * file I/O syscall -- aufs_read() or something ++ * -- si_rwsem for read -- mmap_sem ++ * (Note that [fdi]i_rwsem are released before mmap_sem). ++ * - in mmap case ++ * mmap(2) -- mmap_sem -- aufs_mmap() -- si_rwsem for read -- [fdi]i_rwsem ++ * This AB-BA order is definitly bad, but is not a problem since "si_rwsem for ++ * read" allows muliple processes to acquire it and [fdi]i_rwsem are not held in ++ * file I/O. Aufs needs to stop lockdep in aufs_mmap() though. ++ * It means that when aufs acquires si_rwsem for write, the process should never ++ * acquire mmap_sem. ++ * ++ * Actually aufs_iterate() holds [fdi]i_rwsem before mmap_sem, but this is not a ++ * problem either since any directory is not able to be mmap-ed. ++ * The similar scenario is applied to aufs_readlink() too. ++ */ ++ ++#if 0 /* stop calling security_file_mmap() */ ++/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */ ++#define AuConv_VM_PROT(f, b) _calc_vm_trans(f, VM_##b, PROT_##b) ++ ++static unsigned long au_arch_prot_conv(unsigned long flags) ++{ ++ /* currently ppc64 only */ ++#ifdef CONFIG_PPC64 ++ /* cf. linux/arch/powerpc/include/asm/mman.h */ ++ AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO); ++ return AuConv_VM_PROT(flags, SAO); ++#else ++ AuDebugOn(arch_calc_vm_prot_bits(-1)); ++ return 0; ++#endif ++} ++ ++static unsigned long au_prot_conv(unsigned long flags) ++{ ++ return AuConv_VM_PROT(flags, READ) ++ | AuConv_VM_PROT(flags, WRITE) ++ | AuConv_VM_PROT(flags, EXEC) ++ | au_arch_prot_conv(flags); ++} ++ ++/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */ ++#define AuConv_VM_MAP(f, b) _calc_vm_trans(f, VM_##b, MAP_##b) ++ ++static unsigned long au_flag_conv(unsigned long flags) ++{ ++ return AuConv_VM_MAP(flags, GROWSDOWN) ++ | AuConv_VM_MAP(flags, DENYWRITE) ++ | AuConv_VM_MAP(flags, LOCKED); ++} ++#endif ++ ++static int aufs_mmap(struct file *file, struct vm_area_struct *vma) ++{ ++ int err; ++ const unsigned char wlock ++ = (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED); ++ struct super_block *sb; ++ struct file *h_file; ++ struct inode *inode; ++ ++ AuDbgVmRegion(file, vma); ++ ++ inode = file_inode(file); ++ sb = inode->i_sb; ++ lockdep_off(); ++ si_read_lock(sb, AuLock_NOPLMW); ++ ++ h_file = au_write_pre(file, wlock, /*wpre*/NULL); ++ lockdep_on(); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out; ++ ++ err = 0; ++ au_set_mmapped(file); ++ au_vm_file_reset(vma, h_file); ++ /* ++ * we cannot call security_mmap_file() here since it may acquire ++ * mmap_sem or i_mutex. ++ * ++ * err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags), ++ * au_flag_conv(vma->vm_flags)); ++ */ ++ if (!err) ++ err = h_file->f_op->mmap(h_file, vma); ++ if (!err) { ++ au_vm_prfile_set(vma, file); ++ fsstack_copy_attr_atime(inode, file_inode(h_file)); ++ goto out_fput; /* success */ ++ } ++ au_unset_mmapped(file); ++ au_vm_file_reset(vma, file); ++ ++out_fput: ++ lockdep_off(); ++ ii_write_unlock(inode); ++ lockdep_on(); ++ fput(h_file); ++out: ++ lockdep_off(); ++ si_read_unlock(sb); ++ lockdep_on(); ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int aufs_fsync_nondir(struct file *file, loff_t start, loff_t end, ++ int datasync) ++{ ++ int err; ++ struct au_write_pre wpre; ++ struct inode *inode; ++ struct file *h_file; ++ ++ err = 0; /* -EBADF; */ /* posix? */ ++ if (unlikely(!(file->f_mode & FMODE_WRITE))) ++ goto out; ++ ++ inode = file_inode(file); ++ au_mtx_and_read_lock(inode); ++ ++ h_file = au_write_pre(file, /*do_ready*/1, &wpre); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out_unlock; ++ ++ err = vfsub_fsync(h_file, &h_file->f_path, datasync); ++ au_write_post(inode, h_file, &wpre, /*written*/0); ++ ++out_unlock: ++ si_read_unlock(inode->i_sb); ++ mutex_unlock(&inode->i_mutex); ++out: ++ return err; ++} ++ ++/* no one supports this operation, currently */ ++#if 0 ++static int aufs_aio_fsync_nondir(struct kiocb *kio, int datasync) ++{ ++ int err; ++ struct au_write_pre wpre; ++ struct inode *inode; ++ struct file *file, *h_file; ++ ++ err = 0; /* -EBADF; */ /* posix? */ ++ if (unlikely(!(file->f_mode & FMODE_WRITE))) ++ goto out; ++ ++ file = kio->ki_filp; ++ inode = file_inode(file); ++ au_mtx_and_read_lock(inode); ++ ++ h_file = au_write_pre(file, /*do_ready*/1, &wpre); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out_unlock; ++ ++ err = -ENOSYS; ++ h_file = au_hf_top(file); ++ if (h_file->f_op->aio_fsync) { ++ struct mutex *h_mtx; ++ ++ h_mtx = &file_inode(h_file)->i_mutex; ++ if (!is_sync_kiocb(kio)) { ++ get_file(h_file); ++ fput(file); ++ } ++ kio->ki_filp = h_file; ++ err = h_file->f_op->aio_fsync(kio, datasync); ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ if (!err) ++ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); ++ /*ignore*/ ++ mutex_unlock(h_mtx); ++ } ++ au_write_post(inode, h_file, &wpre, /*written*/0); ++ ++out_unlock: ++ si_read_unlock(inode->sb); ++ mutex_unlock(&inode->i_mutex); ++out: ++ return err; ++} ++#endif ++ ++static int aufs_fasync(int fd, struct file *file, int flag) ++{ ++ int err; ++ struct file *h_file; ++ struct super_block *sb; ++ ++ sb = file->f_path.dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); ++ ++ h_file = au_read_pre(file, /*keep_fi*/0); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out; ++ ++ if (h_file->f_op->fasync) ++ err = h_file->f_op->fasync(fd, h_file, flag); ++ fput(h_file); /* instead of au_read_post() */ ++ ++out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++static int aufs_setfl(struct file *file, unsigned long arg) ++{ ++ int err; ++ struct file *h_file; ++ struct super_block *sb; ++ ++ sb = file->f_path.dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); ++ ++ h_file = au_read_pre(file, /*keep_fi*/0); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out; ++ ++ arg |= vfsub_file_flags(file) & FASYNC; /* stop calling h_file->fasync */ ++ err = setfl(/*unused fd*/-1, h_file, arg); ++ fput(h_file); /* instead of au_read_post() */ ++ ++out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* no one supports this operation, currently */ ++#if 0 ++static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset, ++ size_t len, loff_t *pos, int more) ++{ ++} ++#endif ++ ++/* ---------------------------------------------------------------------- */ ++ ++const struct file_operations aufs_file_fop = { ++ .owner = THIS_MODULE, ++ ++ .llseek = default_llseek, ++ ++ .read = aufs_read, ++ .write = aufs_write, ++ .read_iter = aufs_read_iter, ++ .write_iter = aufs_write_iter, ++ ++#ifdef CONFIG_AUFS_POLL ++ .poll = aufs_poll, ++#endif ++ .unlocked_ioctl = aufs_ioctl_nondir, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = aufs_compat_ioctl_nondir, ++#endif ++ .mmap = aufs_mmap, ++ .open = aufs_open_nondir, ++ .flush = aufs_flush_nondir, ++ .release = aufs_release_nondir, ++ .fsync = aufs_fsync_nondir, ++ /* .aio_fsync = aufs_aio_fsync_nondir, */ ++ .fasync = aufs_fasync, ++ /* .sendpage = aufs_sendpage, */ ++ .setfl = aufs_setfl, ++ .splice_write = aufs_splice_write, ++ .splice_read = aufs_splice_read, ++#if 0 ++ .aio_splice_write = aufs_aio_splice_write, ++ .aio_splice_read = aufs_aio_splice_read, ++#endif ++ .fallocate = aufs_fallocate ++}; +diff -Nurp linux-4.4.3/fs/aufs/fstype.h linux-4.4.3-aufs/fs/aufs/fstype.h +--- linux-4.4.3/fs/aufs/fstype.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/fstype.h 2016-03-02 17:59:37.366498724 +0200 @@ -0,0 +1,387 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -13439,14 +13189,12 @@ index 0000000..6196c60 + +#endif /* __KERNEL__ */ +#endif /* __AUFS_FSTYPE_H__ */ -diff --git a/fs/aufs/hfsnotify.c b/fs/aufs/hfsnotify.c -new file mode 100644 -index 0000000..5c370196 ---- /dev/null -+++ b/fs/aufs/hfsnotify.c +diff -Nurp linux-4.4.3/fs/aufs/hfsnotify.c linux-4.4.3-aufs/fs/aufs/hfsnotify.c +--- linux-4.4.3/fs/aufs/hfsnotify.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/hfsnotify.c 2016-03-02 17:59:37.366498724 +0200 @@ -0,0 +1,275 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -13720,14 +13468,12 @@ index 0000000..5c370196 + .fin_br = au_hfsn_fin_br, + .init_br = au_hfsn_init_br +}; -diff --git a/fs/aufs/hfsplus.c b/fs/aufs/hfsplus.c -new file mode 100644 -index 0000000..34c1f1a ---- /dev/null -+++ b/fs/aufs/hfsplus.c +diff -Nurp linux-4.4.3/fs/aufs/hfsplus.c linux-4.4.3-aufs/fs/aufs/hfsplus.c +--- linux-4.4.3/fs/aufs/hfsplus.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/hfsplus.c 2016-03-02 17:59:37.366498724 +0200 @@ -0,0 +1,43 @@ +/* -+ * Copyright (C) 2010-2015 Junjiro R. Okajima ++ * Copyright (C) 2010-2016 Junjiro R. Okajima + */ + +/* @@ -13769,14 +13515,12 @@ index 0000000..34c1f1a + au_sbr_put(dentry->d_sb, bindex); + } +} -diff --git a/fs/aufs/hnotify.c b/fs/aufs/hnotify.c -new file mode 100644 -index 0000000..3943dc4 ---- /dev/null -+++ b/fs/aufs/hnotify.c +diff -Nurp linux-4.4.3/fs/aufs/hnotify.c linux-4.4.3-aufs/fs/aufs/hnotify.c +--- linux-4.4.3/fs/aufs/hnotify.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/hnotify.c 2016-03-02 17:59:37.367498731 +0200 @@ -0,0 +1,697 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -14472,14 +14216,2607 @@ index 0000000..3943dc4 + if (au_cachep[AuCache_HNOTIFY]) + au_hn_destroy_cache(); +} -diff --git a/fs/aufs/i_op.c b/fs/aufs/i_op.c -new file mode 100644 -index 0000000..daad67a ---- /dev/null -+++ b/fs/aufs/i_op.c -@@ -0,0 +1,1471 @@ +diff -Nurp linux-4.4.3/fs/aufs/iinfo.c linux-4.4.3-aufs/fs/aufs/iinfo.c +--- linux-4.4.3/fs/aufs/iinfo.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/iinfo.c 2016-03-02 17:59:37.368498738 +0200 +@@ -0,0 +1,264 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima ++ */ ++ ++/* ++ * inode private data ++ */ ++ ++#include "aufs.h" ++ ++struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex) ++{ ++ struct inode *h_inode; ++ ++ IiMustAnyLock(inode); ++ ++ h_inode = au_ii(inode)->ii_hinode[0 + bindex].hi_inode; ++ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0); ++ return h_inode; ++} ++ ++/* todo: hard/soft set? */ ++void au_hiput(struct au_hinode *hinode) ++{ ++ au_hn_free(hinode); ++ dput(hinode->hi_whdentry); ++ iput(hinode->hi_inode); ++} ++ ++unsigned int au_hi_flags(struct inode *inode, int isdir) ++{ ++ unsigned int flags; ++ const unsigned int mnt_flags = au_mntflags(inode->i_sb); ++ ++ flags = 0; ++ if (au_opt_test(mnt_flags, XINO)) ++ au_fset_hi(flags, XINO); ++ if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY)) ++ au_fset_hi(flags, HNOTIFY); ++ return flags; ++} ++ ++void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex, ++ struct inode *h_inode, unsigned int flags) ++{ ++ struct au_hinode *hinode; ++ struct inode *hi; ++ struct au_iinfo *iinfo = au_ii(inode); ++ ++ IiMustWriteLock(inode); ++ ++ hinode = iinfo->ii_hinode + bindex; ++ hi = hinode->hi_inode; ++ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0); ++ ++ if (hi) ++ au_hiput(hinode); ++ hinode->hi_inode = h_inode; ++ if (h_inode) { ++ int err; ++ struct super_block *sb = inode->i_sb; ++ struct au_branch *br; ++ ++ AuDebugOn(inode->i_mode ++ && (h_inode->i_mode & S_IFMT) ++ != (inode->i_mode & S_IFMT)); ++ if (bindex == iinfo->ii_bstart) ++ au_cpup_igen(inode, h_inode); ++ br = au_sbr(sb, bindex); ++ hinode->hi_id = br->br_id; ++ if (au_ftest_hi(flags, XINO)) { ++ err = au_xino_write(sb, bindex, h_inode->i_ino, ++ inode->i_ino); ++ if (unlikely(err)) ++ AuIOErr1("failed au_xino_write() %d\n", err); ++ } ++ ++ if (au_ftest_hi(flags, HNOTIFY) ++ && au_br_hnotifyable(br->br_perm)) { ++ err = au_hn_alloc(hinode, inode); ++ if (unlikely(err)) ++ AuIOErr1("au_hn_alloc() %d\n", err); ++ } ++ } ++} ++ ++void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex, ++ struct dentry *h_wh) ++{ ++ struct au_hinode *hinode; ++ ++ IiMustWriteLock(inode); ++ ++ hinode = au_ii(inode)->ii_hinode + bindex; ++ AuDebugOn(hinode->hi_whdentry); ++ hinode->hi_whdentry = h_wh; ++} ++ ++void au_update_iigen(struct inode *inode, int half) ++{ ++ struct au_iinfo *iinfo; ++ struct au_iigen *iigen; ++ unsigned int sigen; ++ ++ sigen = au_sigen(inode->i_sb); ++ iinfo = au_ii(inode); ++ iigen = &iinfo->ii_generation; ++ spin_lock(&iigen->ig_spin); ++ iigen->ig_generation = sigen; ++ if (half) ++ au_ig_fset(iigen->ig_flags, HALF_REFRESHED); ++ else ++ au_ig_fclr(iigen->ig_flags, HALF_REFRESHED); ++ spin_unlock(&iigen->ig_spin); ++} ++ ++/* it may be called at remount time, too */ ++void au_update_ibrange(struct inode *inode, int do_put_zero) ++{ ++ struct au_iinfo *iinfo; ++ aufs_bindex_t bindex, bend; ++ ++ iinfo = au_ii(inode); ++ if (!iinfo) ++ return; ++ ++ IiMustWriteLock(inode); ++ ++ if (do_put_zero && iinfo->ii_bstart >= 0) { ++ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; ++ bindex++) { ++ struct inode *h_i; ++ ++ h_i = iinfo->ii_hinode[0 + bindex].hi_inode; ++ if (h_i ++ && !h_i->i_nlink ++ && !(h_i->i_state & I_LINKABLE)) ++ au_set_h_iptr(inode, bindex, NULL, 0); ++ } ++ } ++ ++ iinfo->ii_bstart = -1; ++ iinfo->ii_bend = -1; ++ bend = au_sbend(inode->i_sb); ++ for (bindex = 0; bindex <= bend; bindex++) ++ if (iinfo->ii_hinode[0 + bindex].hi_inode) { ++ iinfo->ii_bstart = bindex; ++ break; ++ } ++ if (iinfo->ii_bstart >= 0) ++ for (bindex = bend; bindex >= iinfo->ii_bstart; bindex--) ++ if (iinfo->ii_hinode[0 + bindex].hi_inode) { ++ iinfo->ii_bend = bindex; ++ break; ++ } ++ AuDebugOn(iinfo->ii_bstart > iinfo->ii_bend); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_icntnr_init_once(void *_c) ++{ ++ struct au_icntnr *c = _c; ++ struct au_iinfo *iinfo = &c->iinfo; ++ static struct lock_class_key aufs_ii; ++ ++ spin_lock_init(&iinfo->ii_generation.ig_spin); ++ au_rw_init(&iinfo->ii_rwsem); ++ au_rw_class(&iinfo->ii_rwsem, &aufs_ii); ++ inode_init_once(&c->vfs_inode); ++} ++ ++int au_iinfo_init(struct inode *inode) ++{ ++ struct au_iinfo *iinfo; ++ struct super_block *sb; ++ int nbr, i; ++ ++ sb = inode->i_sb; ++ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo); ++ nbr = au_sbend(sb) + 1; ++ if (unlikely(nbr <= 0)) ++ nbr = 1; ++ iinfo->ii_hinode = kcalloc(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS); ++ if (iinfo->ii_hinode) { ++ au_ninodes_inc(sb); ++ for (i = 0; i < nbr; i++) ++ iinfo->ii_hinode[i].hi_id = -1; ++ ++ iinfo->ii_generation.ig_generation = au_sigen(sb); ++ iinfo->ii_bstart = -1; ++ iinfo->ii_bend = -1; ++ iinfo->ii_vdir = NULL; ++ return 0; ++ } ++ return -ENOMEM; ++} ++ ++int au_ii_realloc(struct au_iinfo *iinfo, int nbr) ++{ ++ int err, sz; ++ struct au_hinode *hip; ++ ++ AuRwMustWriteLock(&iinfo->ii_rwsem); ++ ++ err = -ENOMEM; ++ sz = sizeof(*hip) * (iinfo->ii_bend + 1); ++ if (!sz) ++ sz = sizeof(*hip); ++ hip = au_kzrealloc(iinfo->ii_hinode, sz, sizeof(*hip) * nbr, GFP_NOFS); ++ if (hip) { ++ iinfo->ii_hinode = hip; ++ err = 0; ++ } ++ ++ return err; ++} ++ ++void au_iinfo_fin(struct inode *inode) ++{ ++ struct au_iinfo *iinfo; ++ struct au_hinode *hi; ++ struct super_block *sb; ++ aufs_bindex_t bindex, bend; ++ const unsigned char unlinked = !inode->i_nlink; ++ ++ iinfo = au_ii(inode); ++ /* bad_inode case */ ++ if (!iinfo) ++ return; ++ ++ sb = inode->i_sb; ++ au_ninodes_dec(sb); ++ if (si_pid_test(sb)) ++ au_xino_delete_inode(inode, unlinked); ++ else { ++ /* ++ * it is safe to hide the dependency between sbinfo and ++ * sb->s_umount. ++ */ ++ lockdep_off(); ++ si_noflush_read_lock(sb); ++ au_xino_delete_inode(inode, unlinked); ++ si_read_unlock(sb); ++ lockdep_on(); ++ } ++ ++ if (iinfo->ii_vdir) ++ au_vdir_free(iinfo->ii_vdir); ++ ++ bindex = iinfo->ii_bstart; ++ if (bindex >= 0) { ++ hi = iinfo->ii_hinode + bindex; ++ bend = iinfo->ii_bend; ++ while (bindex++ <= bend) { ++ if (hi->hi_inode) ++ au_hiput(hi); ++ hi++; ++ } ++ } ++ kfree(iinfo->ii_hinode); ++ iinfo->ii_hinode = NULL; ++ AuRwDestroy(&iinfo->ii_rwsem); ++} +diff -Nurp linux-4.4.3/fs/aufs/inode.c linux-4.4.3-aufs/fs/aufs/inode.c +--- linux-4.4.3/fs/aufs/inode.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/inode.c 2016-03-02 17:59:37.368498738 +0200 +@@ -0,0 +1,514 @@ ++/* ++ * Copyright (C) 2005-2016 Junjiro R. Okajima ++ */ ++ ++/* ++ * inode functions ++ */ ++ ++#include "aufs.h" ++ ++struct inode *au_igrab(struct inode *inode) ++{ ++ if (inode) { ++ AuDebugOn(!atomic_read(&inode->i_count)); ++ ihold(inode); ++ } ++ return inode; ++} ++ ++static void au_refresh_hinode_attr(struct inode *inode, int do_version) ++{ ++ au_cpup_attr_all(inode, /*force*/0); ++ au_update_iigen(inode, /*half*/1); ++ if (do_version) ++ inode->i_version++; ++} ++ ++static int au_ii_refresh(struct inode *inode, int *update) ++{ ++ int err, e; ++ umode_t type; ++ aufs_bindex_t bindex, new_bindex; ++ struct super_block *sb; ++ struct au_iinfo *iinfo; ++ struct au_hinode *p, *q, tmp; ++ ++ IiMustWriteLock(inode); ++ ++ *update = 0; ++ sb = inode->i_sb; ++ type = inode->i_mode & S_IFMT; ++ iinfo = au_ii(inode); ++ err = au_ii_realloc(iinfo, au_sbend(sb) + 1); ++ if (unlikely(err)) ++ goto out; ++ ++ AuDebugOn(iinfo->ii_bstart < 0); ++ p = iinfo->ii_hinode + iinfo->ii_bstart; ++ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; ++ bindex++, p++) { ++ if (!p->hi_inode) ++ continue; ++ ++ AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT)); ++ new_bindex = au_br_index(sb, p->hi_id); ++ if (new_bindex == bindex) ++ continue; ++ ++ if (new_bindex < 0) { ++ *update = 1; ++ au_hiput(p); ++ p->hi_inode = NULL; ++ continue; ++ } ++ ++ if (new_bindex < iinfo->ii_bstart) ++ iinfo->ii_bstart = new_bindex; ++ if (iinfo->ii_bend < new_bindex) ++ iinfo->ii_bend = new_bindex; ++ /* swap two lower inode, and loop again */ ++ q = iinfo->ii_hinode + new_bindex; ++ tmp = *q; ++ *q = *p; ++ *p = tmp; ++ if (tmp.hi_inode) { ++ bindex--; ++ p--; ++ } ++ } ++ au_update_ibrange(inode, /*do_put_zero*/0); ++ e = au_dy_irefresh(inode); ++ if (unlikely(e && !err)) ++ err = e; ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++void au_refresh_iop(struct inode *inode, int force_getattr) ++{ ++ int type; ++ struct au_sbinfo *sbi = au_sbi(inode->i_sb); ++ const struct inode_operations *iop ++ = force_getattr ? aufs_iop : sbi->si_iop_array; ++ ++ if (inode->i_op == iop) ++ return; ++ ++ switch (inode->i_mode & S_IFMT) { ++ case S_IFDIR: ++ type = AuIop_DIR; ++ break; ++ case S_IFLNK: ++ type = AuIop_SYMLINK; ++ break; ++ default: ++ type = AuIop_OTHER; ++ break; ++ } ++ ++ inode->i_op = iop + type; ++ /* unnecessary smp_wmb() */ ++} ++ ++int au_refresh_hinode_self(struct inode *inode) ++{ ++ int err, update; ++ ++ err = au_ii_refresh(inode, &update); ++ if (!err) ++ au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode)); ++ ++ AuTraceErr(err); ++ return err; ++} ++ ++int au_refresh_hinode(struct inode *inode, struct dentry *dentry) ++{ ++ int err, e, update; ++ unsigned int flags; ++ umode_t mode; ++ aufs_bindex_t bindex, bend; ++ unsigned char isdir; ++ struct au_hinode *p; ++ struct au_iinfo *iinfo; ++ ++ err = au_ii_refresh(inode, &update); ++ if (unlikely(err)) ++ goto out; ++ ++ update = 0; ++ iinfo = au_ii(inode); ++ p = iinfo->ii_hinode + iinfo->ii_bstart; ++ mode = (inode->i_mode & S_IFMT); ++ isdir = S_ISDIR(mode); ++ flags = au_hi_flags(inode, isdir); ++ bend = au_dbend(dentry); ++ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) { ++ struct inode *h_i, *h_inode; ++ struct dentry *h_d; ++ ++ h_d = au_h_dptr(dentry, bindex); ++ if (!h_d || d_is_negative(h_d)) ++ continue; ++ ++ h_inode = d_inode(h_d); ++ AuDebugOn(mode != (h_inode->i_mode & S_IFMT)); ++ if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) { ++ h_i = au_h_iptr(inode, bindex); ++ if (h_i) { ++ if (h_i == h_inode) ++ continue; ++ err = -EIO; ++ break; ++ } ++ } ++ if (bindex < iinfo->ii_bstart) ++ iinfo->ii_bstart = bindex; ++ if (iinfo->ii_bend < bindex) ++ iinfo->ii_bend = bindex; ++ au_set_h_iptr(inode, bindex, au_igrab(h_inode), flags); ++ update = 1; ++ } ++ au_update_ibrange(inode, /*do_put_zero*/0); ++ e = au_dy_irefresh(inode); ++ if (unlikely(e && !err)) ++ err = e; ++ if (!err) ++ au_refresh_hinode_attr(inode, update && isdir); ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++static int set_inode(struct inode *inode, struct dentry *dentry) ++{ ++ int err; ++ unsigned int flags; ++ umode_t mode; ++ aufs_bindex_t bindex, bstart, btail; ++ unsigned char isdir; ++ struct dentry *h_dentry; ++ struct inode *h_inode; ++ struct au_iinfo *iinfo; ++ struct inode_operations *iop; ++ ++ IiMustWriteLock(inode); ++ ++ err = 0; ++ isdir = 0; ++ iop = au_sbi(inode->i_sb)->si_iop_array; ++ bstart = au_dbstart(dentry); ++ h_dentry = au_h_dptr(dentry, bstart); ++ h_inode = d_inode(h_dentry); ++ mode = h_inode->i_mode; ++ switch (mode & S_IFMT) { ++ case S_IFREG: ++ btail = au_dbtail(dentry); ++ inode->i_op = iop + AuIop_OTHER; ++ inode->i_fop = &aufs_file_fop; ++ err = au_dy_iaop(inode, bstart, h_inode); ++ if (unlikely(err)) ++ goto out; ++ break; ++ case S_IFDIR: ++ isdir = 1; ++ btail = au_dbtaildir(dentry); ++ inode->i_op = iop + AuIop_DIR; ++ inode->i_fop = &aufs_dir_fop; ++ break; ++ case S_IFLNK: ++ btail = au_dbtail(dentry); ++ inode->i_op = iop + AuIop_SYMLINK; ++ break; ++ case S_IFBLK: ++ case S_IFCHR: ++ case S_IFIFO: ++ case S_IFSOCK: ++ btail = au_dbtail(dentry); ++ inode->i_op = iop + AuIop_OTHER; ++ init_special_inode(inode, mode, h_inode->i_rdev); ++ break; ++ default: ++ AuIOErr("Unknown file type 0%o\n", mode); ++ err = -EIO; ++ goto out; ++ } ++ ++ /* do not set hnotify for whiteouted dirs (SHWH mode) */ ++ flags = au_hi_flags(inode, isdir); ++ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH) ++ && au_ftest_hi(flags, HNOTIFY) ++ && dentry->d_name.len > AUFS_WH_PFX_LEN ++ && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) ++ au_fclr_hi(flags, HNOTIFY); ++ iinfo = au_ii(inode); ++ iinfo->ii_bstart = bstart; ++ iinfo->ii_bend = btail; ++ for (bindex = bstart; bindex <= btail; bindex++) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (h_dentry) ++ au_set_h_iptr(inode, bindex, ++ au_igrab(d_inode(h_dentry)), flags); ++ } ++ au_cpup_attr_all(inode, /*force*/1); ++ /* ++ * to force calling aufs_get_acl() every time, ++ * do not call cache_no_acl() for aufs inode. ++ */ ++ ++out: ++ return err; ++} ++ ++/* ++ * successful returns with iinfo write_locked ++ * minus: errno ++ * zero: success, matched ++ * plus: no error, but unmatched ++ */ ++static int reval_inode(struct inode *inode, struct dentry *dentry) ++{ ++ int err; ++ unsigned int gen, igflags; ++ aufs_bindex_t bindex, bend; ++ struct inode *h_inode, *h_dinode; ++ struct dentry *h_dentry; ++ ++ /* ++ * before this function, if aufs got any iinfo lock, it must be only ++ * one, the parent dir. ++ * it can happen by UDBA and the obsoleted inode number. ++ */ ++ err = -EIO; ++ if (unlikely(inode->i_ino == parent_ino(dentry))) ++ goto out; ++ ++ err = 1; ++ ii_write_lock_new_child(inode); ++ h_dentry = au_h_dptr(dentry, au_dbstart(dentry)); ++ h_dinode = d_inode(h_dentry); ++ bend = au_ibend(inode); ++ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) { ++ h_inode = au_h_iptr(inode, bindex); ++ if (!h_inode || h_inode != h_dinode) ++ continue; ++ ++ err = 0; ++ gen = au_iigen(inode, &igflags); ++ if (gen == au_digen(dentry) ++ && !au_ig_ftest(igflags, HALF_REFRESHED)) ++ break; ++ ++ /* fully refresh inode using dentry */ ++ err = au_refresh_hinode(inode, dentry); ++ if (!err) ++ au_update_iigen(inode, /*half*/0); ++ break; ++ } ++ ++ if (unlikely(err)) ++ ii_write_unlock(inode); ++out: ++ return err; ++} ++ ++int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ unsigned int d_type, ino_t *ino) ++{ ++ int err; ++ struct mutex *mtx; ++ ++ /* prevent hardlinked inode number from race condition */ ++ mtx = NULL; ++ if (d_type != DT_DIR) { ++ mtx = &au_sbr(sb, bindex)->br_xino.xi_nondir_mtx; ++ mutex_lock(mtx); ++ } ++ err = au_xino_read(sb, bindex, h_ino, ino); ++ if (unlikely(err)) ++ goto out; ++ ++ if (!*ino) { ++ err = -EIO; ++ *ino = au_xino_new_ino(sb); ++ if (unlikely(!*ino)) ++ goto out; ++ err = au_xino_write(sb, bindex, h_ino, *ino); ++ if (unlikely(err)) ++ goto out; ++ } ++ ++out: ++ if (mtx) ++ mutex_unlock(mtx); ++ return err; ++} ++ ++/* successful returns with iinfo write_locked */ ++/* todo: return with unlocked? */ ++struct inode *au_new_inode(struct dentry *dentry, int must_new) ++{ ++ struct inode *inode, *h_inode; ++ struct dentry *h_dentry; ++ struct super_block *sb; ++ struct mutex *mtx; ++ ino_t h_ino, ino; ++ int err; ++ aufs_bindex_t bstart; ++ ++ sb = dentry->d_sb; ++ bstart = au_dbstart(dentry); ++ h_dentry = au_h_dptr(dentry, bstart); ++ h_inode = d_inode(h_dentry); ++ h_ino = h_inode->i_ino; ++ ++ /* ++ * stop 'race'-ing between hardlinks under different ++ * parents. ++ */ ++ mtx = NULL; ++ if (!d_is_dir(h_dentry)) ++ mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx; ++ ++new_ino: ++ if (mtx) ++ mutex_lock(mtx); ++ err = au_xino_read(sb, bstart, h_ino, &ino); ++ inode = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out; ++ ++ if (!ino) { ++ ino = au_xino_new_ino(sb); ++ if (unlikely(!ino)) { ++ inode = ERR_PTR(-EIO); ++ goto out; ++ } ++ } ++ ++ AuDbg("i%lu\n", (unsigned long)ino); ++ inode = au_iget_locked(sb, ino); ++ err = PTR_ERR(inode); ++ if (IS_ERR(inode)) ++ goto out; ++ ++ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW)); ++ if (inode->i_state & I_NEW) { ++ /* verbose coding for lock class name */ ++ if (unlikely(d_is_symlink(h_dentry))) ++ au_rw_class(&au_ii(inode)->ii_rwsem, ++ au_lc_key + AuLcSymlink_IIINFO); ++ else if (unlikely(d_is_dir(h_dentry))) ++ au_rw_class(&au_ii(inode)->ii_rwsem, ++ au_lc_key + AuLcDir_IIINFO); ++ else /* likely */ ++ au_rw_class(&au_ii(inode)->ii_rwsem, ++ au_lc_key + AuLcNonDir_IIINFO); ++ ++ ii_write_lock_new_child(inode); ++ err = set_inode(inode, dentry); ++ if (!err) { ++ unlock_new_inode(inode); ++ goto out; /* success */ ++ } ++ ++ /* ++ * iget_failed() calls iput(), but we need to call ++ * ii_write_unlock() after iget_failed(). so dirty hack for ++ * i_count. ++ */ ++ atomic_inc(&inode->i_count); ++ iget_failed(inode); ++ ii_write_unlock(inode); ++ au_xino_write(sb, bstart, h_ino, /*ino*/0); ++ /* ignore this error */ ++ goto out_iput; ++ } else if (!must_new && !IS_DEADDIR(inode) && inode->i_nlink) { ++ /* ++ * horrible race condition between lookup, readdir and copyup ++ * (or something). ++ */ ++ if (mtx) ++ mutex_unlock(mtx); ++ err = reval_inode(inode, dentry); ++ if (unlikely(err < 0)) { ++ mtx = NULL; ++ goto out_iput; ++ } ++ ++ if (!err) { ++ mtx = NULL; ++ goto out; /* success */ ++ } else if (mtx) ++ mutex_lock(mtx); ++ } ++ ++ if (unlikely(au_test_fs_unique_ino(h_inode))) ++ AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir," ++ " b%d, %s, %pd, hi%lu, i%lu.\n", ++ bstart, au_sbtype(h_dentry->d_sb), dentry, ++ (unsigned long)h_ino, (unsigned long)ino); ++ ino = 0; ++ err = au_xino_write(sb, bstart, h_ino, /*ino*/0); ++ if (!err) { ++ iput(inode); ++ if (mtx) ++ mutex_unlock(mtx); ++ goto new_ino; ++ } ++ ++out_iput: ++ iput(inode); ++ inode = ERR_PTR(err); ++out: ++ if (mtx) ++ mutex_unlock(mtx); ++ return inode; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_test_ro(struct super_block *sb, aufs_bindex_t bindex, ++ struct inode *inode) ++{ ++ int err; ++ struct inode *hi; ++ ++ err = au_br_rdonly(au_sbr(sb, bindex)); ++ ++ /* pseudo-link after flushed may happen out of bounds */ ++ if (!err ++ && inode ++ && au_ibstart(inode) <= bindex ++ && bindex <= au_ibend(inode)) { ++ /* ++ * permission check is unnecessary since vfsub routine ++ * will be called later ++ */ ++ hi = au_h_iptr(inode, bindex); ++ if (hi) ++ err = IS_IMMUTABLE(hi) ? -EROFS : 0; ++ } ++ ++ return err; ++} ++ ++int au_test_h_perm(struct inode *h_inode, int mask) ++{ ++ if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) ++ return 0; ++ return inode_permission(h_inode, mask); ++} ++ ++int au_test_h_perm_sio(struct inode *h_inode, int mask) ++{ ++ if (au_test_nfs(h_inode->i_sb) ++ && (mask & MAY_WRITE) ++ && S_ISDIR(h_inode->i_mode)) ++ mask |= MAY_READ; /* force permission check */ ++ return au_test_h_perm(h_inode, mask); ++} +diff -Nurp linux-4.4.3/fs/aufs/inode.h linux-4.4.3-aufs/fs/aufs/inode.h +--- linux-4.4.3/fs/aufs/inode.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/inode.h 2016-03-02 17:59:37.369498746 +0200 +@@ -0,0 +1,672 @@ ++/* ++ * Copyright (C) 2005-2016 Junjiro R. Okajima ++ */ ++ ++/* ++ * inode operations ++ */ ++ ++#ifndef __AUFS_INODE_H__ ++#define __AUFS_INODE_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include "rwsem.h" ++ ++struct vfsmount; ++ ++struct au_hnotify { ++#ifdef CONFIG_AUFS_HNOTIFY ++#ifdef CONFIG_AUFS_HFSNOTIFY ++ /* never use fsnotify_add_vfsmount_mark() */ ++ struct fsnotify_mark hn_mark; ++#endif ++ struct inode *hn_aufs_inode; /* no get/put */ ++#endif ++} ____cacheline_aligned_in_smp; ++ ++struct au_hinode { ++ struct inode *hi_inode; ++ aufs_bindex_t hi_id; ++#ifdef CONFIG_AUFS_HNOTIFY ++ struct au_hnotify *hi_notify; ++#endif ++ ++ /* reference to the copied-up whiteout with get/put */ ++ struct dentry *hi_whdentry; ++}; ++ ++/* ig_flags */ ++#define AuIG_HALF_REFRESHED 1 ++#define au_ig_ftest(flags, name) ((flags) & AuIG_##name) ++#define au_ig_fset(flags, name) \ ++ do { (flags) |= AuIG_##name; } while (0) ++#define au_ig_fclr(flags, name) \ ++ do { (flags) &= ~AuIG_##name; } while (0) ++ ++struct au_iigen { ++ spinlock_t ig_spin; ++ __u32 ig_generation, ig_flags; ++}; ++ ++struct au_vdir; ++struct au_iinfo { ++ struct au_iigen ii_generation; ++ struct super_block *ii_hsb1; /* no get/put */ ++ ++ struct au_rwsem ii_rwsem; ++ aufs_bindex_t ii_bstart, ii_bend; ++ __u32 ii_higen; ++ struct au_hinode *ii_hinode; ++ struct au_vdir *ii_vdir; ++}; ++ ++struct au_icntnr { ++ struct au_iinfo iinfo; ++ struct inode vfs_inode; ++} ____cacheline_aligned_in_smp; ++ ++/* au_pin flags */ ++#define AuPin_DI_LOCKED 1 ++#define AuPin_MNT_WRITE (1 << 1) ++#define au_ftest_pin(flags, name) ((flags) & AuPin_##name) ++#define au_fset_pin(flags, name) \ ++ do { (flags) |= AuPin_##name; } while (0) ++#define au_fclr_pin(flags, name) \ ++ do { (flags) &= ~AuPin_##name; } while (0) ++ ++struct au_pin { ++ /* input */ ++ struct dentry *dentry; ++ unsigned int udba; ++ unsigned char lsc_di, lsc_hi, flags; ++ aufs_bindex_t bindex; ++ ++ /* output */ ++ struct dentry *parent; ++ struct au_hinode *hdir; ++ struct vfsmount *h_mnt; ++ ++ /* temporary unlock/relock for copyup */ ++ struct dentry *h_dentry, *h_parent; ++ struct au_branch *br; ++ struct task_struct *task; ++}; ++ ++void au_pin_hdir_unlock(struct au_pin *p); ++int au_pin_hdir_lock(struct au_pin *p); ++int au_pin_hdir_relock(struct au_pin *p); ++void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task); ++void au_pin_hdir_acquire_nest(struct au_pin *p); ++void au_pin_hdir_release(struct au_pin *p); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct au_iinfo *au_ii(struct inode *inode) ++{ ++ struct au_iinfo *iinfo; ++ ++ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo); ++ if (iinfo->ii_hinode) ++ return iinfo; ++ return NULL; /* debugging bad_inode case */ ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* inode.c */ ++struct inode *au_igrab(struct inode *inode); ++void au_refresh_iop(struct inode *inode, int force_getattr); ++int au_refresh_hinode_self(struct inode *inode); ++int au_refresh_hinode(struct inode *inode, struct dentry *dentry); ++int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ unsigned int d_type, ino_t *ino); ++struct inode *au_new_inode(struct dentry *dentry, int must_new); ++int au_test_ro(struct super_block *sb, aufs_bindex_t bindex, ++ struct inode *inode); ++int au_test_h_perm(struct inode *h_inode, int mask); ++int au_test_h_perm_sio(struct inode *h_inode, int mask); ++ ++static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex, ++ ino_t h_ino, unsigned int d_type, ino_t *ino) ++{ ++#ifdef CONFIG_AUFS_SHWH ++ return au_ino(sb, bindex, h_ino, d_type, ino); ++#else ++ return 0; ++#endif ++} ++ ++/* i_op.c */ ++enum { ++ AuIop_SYMLINK, ++ AuIop_DIR, ++ AuIop_OTHER, ++ AuIop_Last ++}; ++extern struct inode_operations aufs_iop[AuIop_Last], ++ aufs_iop_nogetattr[AuIop_Last]; ++ ++/* au_wr_dir flags */ ++#define AuWrDir_ADD_ENTRY 1 ++#define AuWrDir_ISDIR (1 << 1) ++#define AuWrDir_TMPFILE (1 << 2) ++#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name) ++#define au_fset_wrdir(flags, name) \ ++ do { (flags) |= AuWrDir_##name; } while (0) ++#define au_fclr_wrdir(flags, name) \ ++ do { (flags) &= ~AuWrDir_##name; } while (0) ++ ++struct au_wr_dir_args { ++ aufs_bindex_t force_btgt; ++ unsigned char flags; ++}; ++int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry, ++ struct au_wr_dir_args *args); ++ ++struct dentry *au_pinned_h_parent(struct au_pin *pin); ++void au_pin_init(struct au_pin *pin, struct dentry *dentry, ++ aufs_bindex_t bindex, int lsc_di, int lsc_hi, ++ unsigned int udba, unsigned char flags); ++int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex, ++ unsigned int udba, unsigned char flags) __must_check; ++int au_do_pin(struct au_pin *pin) __must_check; ++void au_unpin(struct au_pin *pin); ++int au_reval_for_attr(struct dentry *dentry, unsigned int sigen); ++ ++#define AuIcpup_DID_CPUP 1 ++#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name) ++#define au_fset_icpup(flags, name) \ ++ do { (flags) |= AuIcpup_##name; } while (0) ++#define au_fclr_icpup(flags, name) \ ++ do { (flags) &= ~AuIcpup_##name; } while (0) ++ ++struct au_icpup_args { ++ unsigned char flags; ++ unsigned char pin_flags; ++ aufs_bindex_t btgt; ++ unsigned int udba; ++ struct au_pin pin; ++ struct path h_path; ++ struct inode *h_inode; ++}; ++ ++int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia, ++ struct au_icpup_args *a); ++ ++int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path); ++ ++/* i_op_add.c */ ++int au_may_add(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent, int isdir); ++int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, ++ dev_t dev); ++int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname); ++int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode, ++ bool want_excl); ++struct vfsub_aopen_args; ++int au_aopen_or_create(struct inode *dir, struct dentry *dentry, ++ struct vfsub_aopen_args *args); ++int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode); ++int aufs_link(struct dentry *src_dentry, struct inode *dir, ++ struct dentry *dentry); ++int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode); ++ ++/* i_op_del.c */ ++int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup); ++int au_may_del(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent, int isdir); ++int aufs_unlink(struct inode *dir, struct dentry *dentry); ++int aufs_rmdir(struct inode *dir, struct dentry *dentry); ++ ++/* i_op_ren.c */ ++int au_wbr(struct dentry *dentry, aufs_bindex_t btgt); ++int aufs_rename(struct inode *src_dir, struct dentry *src_dentry, ++ struct inode *dir, struct dentry *dentry); ++ ++/* iinfo.c */ ++struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex); ++void au_hiput(struct au_hinode *hinode); ++void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex, ++ struct dentry *h_wh); ++unsigned int au_hi_flags(struct inode *inode, int isdir); ++ ++/* hinode flags */ ++#define AuHi_XINO 1 ++#define AuHi_HNOTIFY (1 << 1) ++#define au_ftest_hi(flags, name) ((flags) & AuHi_##name) ++#define au_fset_hi(flags, name) \ ++ do { (flags) |= AuHi_##name; } while (0) ++#define au_fclr_hi(flags, name) \ ++ do { (flags) &= ~AuHi_##name; } while (0) ++ ++#ifndef CONFIG_AUFS_HNOTIFY ++#undef AuHi_HNOTIFY ++#define AuHi_HNOTIFY 0 ++#endif ++ ++void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex, ++ struct inode *h_inode, unsigned int flags); ++ ++void au_update_iigen(struct inode *inode, int half); ++void au_update_ibrange(struct inode *inode, int do_put_zero); ++ ++void au_icntnr_init_once(void *_c); ++int au_iinfo_init(struct inode *inode); ++void au_iinfo_fin(struct inode *inode); ++int au_ii_realloc(struct au_iinfo *iinfo, int nbr); ++ ++#ifdef CONFIG_PROC_FS ++/* plink.c */ ++int au_plink_maint(struct super_block *sb, int flags); ++struct au_sbinfo; ++void au_plink_maint_leave(struct au_sbinfo *sbinfo); ++int au_plink_maint_enter(struct super_block *sb); ++#ifdef CONFIG_AUFS_DEBUG ++void au_plink_list(struct super_block *sb); ++#else ++AuStubVoid(au_plink_list, struct super_block *sb) ++#endif ++int au_plink_test(struct inode *inode); ++struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex); ++void au_plink_append(struct inode *inode, aufs_bindex_t bindex, ++ struct dentry *h_dentry); ++void au_plink_put(struct super_block *sb, int verbose); ++void au_plink_clean(struct super_block *sb, int verbose); ++void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id); ++#else ++AuStubInt0(au_plink_maint, struct super_block *sb, int flags); ++AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo); ++AuStubInt0(au_plink_maint_enter, struct super_block *sb); ++AuStubVoid(au_plink_list, struct super_block *sb); ++AuStubInt0(au_plink_test, struct inode *inode); ++AuStub(struct dentry *, au_plink_lkup, return NULL, ++ struct inode *inode, aufs_bindex_t bindex); ++AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex, ++ struct dentry *h_dentry); ++AuStubVoid(au_plink_put, struct super_block *sb, int verbose); ++AuStubVoid(au_plink_clean, struct super_block *sb, int verbose); ++AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id); ++#endif /* CONFIG_PROC_FS */ ++ ++#ifdef CONFIG_AUFS_XATTR ++/* xattr.c */ ++int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags, ++ unsigned int verbose); ++ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size); ++ssize_t aufs_getxattr(struct dentry *dentry, const char *name, void *value, ++ size_t size); ++int aufs_setxattr(struct dentry *dentry, const char *name, const void *value, ++ size_t size, int flags); ++int aufs_removexattr(struct dentry *dentry, const char *name); ++ ++/* void au_xattr_init(struct super_block *sb); */ ++#else ++AuStubInt0(au_cpup_xattr, struct dentry *h_dst, struct dentry *h_src, ++ int ignore_flags, unsigned int verbose); ++/* AuStubVoid(au_xattr_init, struct super_block *sb); */ ++#endif ++ ++#ifdef CONFIG_FS_POSIX_ACL ++struct posix_acl *aufs_get_acl(struct inode *inode, int type); ++int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type); ++#endif ++ ++#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL) ++enum { ++ AU_XATTR_SET, ++ AU_XATTR_REMOVE, ++ AU_ACL_SET ++}; ++ ++struct au_srxattr { ++ int type; ++ union { ++ struct { ++ const char *name; ++ const void *value; ++ size_t size; ++ int flags; ++ } set; ++ struct { ++ const char *name; ++ } remove; ++ struct { ++ struct posix_acl *acl; ++ int type; ++ } acl_set; ++ } u; ++}; ++ssize_t au_srxattr(struct dentry *dentry, struct au_srxattr *arg); ++#endif ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* lock subclass for iinfo */ ++enum { ++ AuLsc_II_CHILD, /* child first */ ++ AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hnotify */ ++ AuLsc_II_CHILD3, /* copyup dirs */ ++ AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */ ++ AuLsc_II_PARENT2, ++ AuLsc_II_PARENT3, /* copyup dirs */ ++ AuLsc_II_NEW_CHILD ++}; ++ ++/* ++ * ii_read_lock_child, ii_write_lock_child, ++ * ii_read_lock_child2, ii_write_lock_child2, ++ * ii_read_lock_child3, ii_write_lock_child3, ++ * ii_read_lock_parent, ii_write_lock_parent, ++ * ii_read_lock_parent2, ii_write_lock_parent2, ++ * ii_read_lock_parent3, ii_write_lock_parent3, ++ * ii_read_lock_new_child, ii_write_lock_new_child, ++ */ ++#define AuReadLockFunc(name, lsc) \ ++static inline void ii_read_lock_##name(struct inode *i) \ ++{ \ ++ au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \ ++} ++ ++#define AuWriteLockFunc(name, lsc) \ ++static inline void ii_write_lock_##name(struct inode *i) \ ++{ \ ++ au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \ ++} ++ ++#define AuRWLockFuncs(name, lsc) \ ++ AuReadLockFunc(name, lsc) \ ++ AuWriteLockFunc(name, lsc) ++ ++AuRWLockFuncs(child, CHILD); ++AuRWLockFuncs(child2, CHILD2); ++AuRWLockFuncs(child3, CHILD3); ++AuRWLockFuncs(parent, PARENT); ++AuRWLockFuncs(parent2, PARENT2); ++AuRWLockFuncs(parent3, PARENT3); ++AuRWLockFuncs(new_child, NEW_CHILD); ++ ++#undef AuReadLockFunc ++#undef AuWriteLockFunc ++#undef AuRWLockFuncs ++ ++/* ++ * ii_read_unlock, ii_write_unlock, ii_downgrade_lock ++ */ ++AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem); ++ ++#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem) ++#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem) ++#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem) ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline void au_icntnr_init(struct au_icntnr *c) ++{ ++#ifdef CONFIG_AUFS_DEBUG ++ c->vfs_inode.i_mode = 0; ++#endif ++} ++ ++static inline unsigned int au_iigen(struct inode *inode, unsigned int *igflags) ++{ ++ unsigned int gen; ++ struct au_iinfo *iinfo; ++ struct au_iigen *iigen; ++ ++ iinfo = au_ii(inode); ++ iigen = &iinfo->ii_generation; ++ spin_lock(&iigen->ig_spin); ++ if (igflags) ++ *igflags = iigen->ig_flags; ++ gen = iigen->ig_generation; ++ spin_unlock(&iigen->ig_spin); ++ ++ return gen; ++} ++ ++/* tiny test for inode number */ ++/* tmpfs generation is too rough */ ++static inline int au_test_higen(struct inode *inode, struct inode *h_inode) ++{ ++ struct au_iinfo *iinfo; ++ ++ iinfo = au_ii(inode); ++ AuRwMustAnyLock(&iinfo->ii_rwsem); ++ return !(iinfo->ii_hsb1 == h_inode->i_sb ++ && iinfo->ii_higen == h_inode->i_generation); ++} ++ ++static inline void au_iigen_dec(struct inode *inode) ++{ ++ struct au_iinfo *iinfo; ++ struct au_iigen *iigen; ++ ++ iinfo = au_ii(inode); ++ iigen = &iinfo->ii_generation; ++ spin_lock(&iigen->ig_spin); ++ iigen->ig_generation--; ++ spin_unlock(&iigen->ig_spin); ++} ++ ++static inline int au_iigen_test(struct inode *inode, unsigned int sigen) ++{ ++ int err; ++ ++ err = 0; ++ if (unlikely(inode && au_iigen(inode, NULL) != sigen)) ++ err = -EIO; ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline aufs_bindex_t au_ii_br_id(struct inode *inode, ++ aufs_bindex_t bindex) ++{ ++ IiMustAnyLock(inode); ++ return au_ii(inode)->ii_hinode[0 + bindex].hi_id; ++} ++ ++static inline aufs_bindex_t au_ibstart(struct inode *inode) ++{ ++ IiMustAnyLock(inode); ++ return au_ii(inode)->ii_bstart; ++} ++ ++static inline aufs_bindex_t au_ibend(struct inode *inode) ++{ ++ IiMustAnyLock(inode); ++ return au_ii(inode)->ii_bend; ++} ++ ++static inline struct au_vdir *au_ivdir(struct inode *inode) ++{ ++ IiMustAnyLock(inode); ++ return au_ii(inode)->ii_vdir; ++} ++ ++static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex) ++{ ++ IiMustAnyLock(inode); ++ return au_ii(inode)->ii_hinode[0 + bindex].hi_whdentry; ++} ++ ++static inline void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex) ++{ ++ IiMustWriteLock(inode); ++ au_ii(inode)->ii_bstart = bindex; ++} ++ ++static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex) ++{ ++ IiMustWriteLock(inode); ++ au_ii(inode)->ii_bend = bindex; ++} ++ ++static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir) ++{ ++ IiMustWriteLock(inode); ++ au_ii(inode)->ii_vdir = vdir; ++} ++ ++static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex) ++{ ++ IiMustAnyLock(inode); ++ return au_ii(inode)->ii_hinode + bindex; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct dentry *au_pinned_parent(struct au_pin *pin) ++{ ++ if (pin) ++ return pin->parent; ++ return NULL; ++} ++ ++static inline struct inode *au_pinned_h_dir(struct au_pin *pin) ++{ ++ if (pin && pin->hdir) ++ return pin->hdir->hi_inode; ++ return NULL; ++} ++ ++static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin) ++{ ++ if (pin) ++ return pin->hdir; ++ return NULL; ++} ++ ++static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry) ++{ ++ if (pin) ++ pin->dentry = dentry; ++} ++ ++static inline void au_pin_set_parent_lflag(struct au_pin *pin, ++ unsigned char lflag) ++{ ++ if (pin) { ++ if (lflag) ++ au_fset_pin(pin->flags, DI_LOCKED); ++ else ++ au_fclr_pin(pin->flags, DI_LOCKED); ++ } ++} ++ ++#if 0 /* reserved */ ++static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent) ++{ ++ if (pin) { ++ dput(pin->parent); ++ pin->parent = dget(parent); ++ } ++} ++#endif ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_branch; ++#ifdef CONFIG_AUFS_HNOTIFY ++struct au_hnotify_op { ++ void (*ctl)(struct au_hinode *hinode, int do_set); ++ int (*alloc)(struct au_hinode *hinode); ++ ++ /* ++ * if it returns true, the the caller should free hinode->hi_notify, ++ * otherwise ->free() frees it. ++ */ ++ int (*free)(struct au_hinode *hinode, ++ struct au_hnotify *hn) __must_check; ++ ++ void (*fin)(void); ++ int (*init)(void); ++ ++ int (*reset_br)(unsigned int udba, struct au_branch *br, int perm); ++ void (*fin_br)(struct au_branch *br); ++ int (*init_br)(struct au_branch *br, int perm); ++}; ++ ++/* hnotify.c */ ++int au_hn_alloc(struct au_hinode *hinode, struct inode *inode); ++void au_hn_free(struct au_hinode *hinode); ++void au_hn_ctl(struct au_hinode *hinode, int do_set); ++void au_hn_reset(struct inode *inode, unsigned int flags); ++int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask, ++ struct qstr *h_child_qstr, struct inode *h_child_inode); ++int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm); ++int au_hnotify_init_br(struct au_branch *br, int perm); ++void au_hnotify_fin_br(struct au_branch *br); ++int __init au_hnotify_init(void); ++void au_hnotify_fin(void); ++ ++/* hfsnotify.c */ ++extern const struct au_hnotify_op au_hnotify_op; ++ ++static inline ++void au_hn_init(struct au_hinode *hinode) ++{ ++ hinode->hi_notify = NULL; ++} ++ ++static inline struct au_hnotify *au_hn(struct au_hinode *hinode) ++{ ++ return hinode->hi_notify; ++} ++ ++#else ++AuStub(int, au_hn_alloc, return -EOPNOTSUPP, ++ struct au_hinode *hinode __maybe_unused, ++ struct inode *inode __maybe_unused) ++AuStub(struct au_hnotify *, au_hn, return NULL, struct au_hinode *hinode) ++AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused) ++AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused, ++ int do_set __maybe_unused) ++AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused, ++ unsigned int flags __maybe_unused) ++AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused, ++ struct au_branch *br __maybe_unused, ++ int perm __maybe_unused) ++AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused, ++ int perm __maybe_unused) ++AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused) ++AuStubInt0(__init au_hnotify_init, void) ++AuStubVoid(au_hnotify_fin, void) ++AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused) ++#endif /* CONFIG_AUFS_HNOTIFY */ ++ ++static inline void au_hn_suspend(struct au_hinode *hdir) ++{ ++ au_hn_ctl(hdir, /*do_set*/0); ++} ++ ++static inline void au_hn_resume(struct au_hinode *hdir) ++{ ++ au_hn_ctl(hdir, /*do_set*/1); ++} ++ ++static inline void au_hn_imtx_lock(struct au_hinode *hdir) ++{ ++ mutex_lock(&hdir->hi_inode->i_mutex); ++ au_hn_suspend(hdir); ++} ++ ++static inline void au_hn_imtx_lock_nested(struct au_hinode *hdir, ++ unsigned int sc __maybe_unused) ++{ ++ mutex_lock_nested(&hdir->hi_inode->i_mutex, sc); ++ au_hn_suspend(hdir); ++} ++ ++static inline void au_hn_imtx_unlock(struct au_hinode *hdir) ++{ ++ au_hn_resume(hdir); ++ mutex_unlock(&hdir->hi_inode->i_mutex); ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_INODE_H__ */ +diff -Nurp linux-4.4.3/fs/aufs/ioctl.c linux-4.4.3-aufs/fs/aufs/ioctl.c +--- linux-4.4.3/fs/aufs/ioctl.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/ioctl.c 2016-03-02 17:59:37.369498746 +0200 +@@ -0,0 +1,206 @@ ++/* ++ * Copyright (C) 2005-2016 Junjiro R. Okajima ++ */ ++ ++/* ++ * ioctl ++ * plink-management and readdir in userspace. ++ * assist the pathconf(3) wrapper library. ++ * move-down ++ * File-based Hierarchical Storage Management. ++ */ ++ ++#include ++#include ++#include "aufs.h" ++ ++static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg) ++{ ++ int err, fd; ++ aufs_bindex_t wbi, bindex, bend; ++ struct file *h_file; ++ struct super_block *sb; ++ struct dentry *root; ++ struct au_branch *br; ++ struct aufs_wbr_fd wbrfd = { ++ .oflags = au_dir_roflags, ++ .brid = -1 ++ }; ++ const int valid = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY ++ | O_NOATIME | O_CLOEXEC; ++ ++ AuDebugOn(wbrfd.oflags & ~valid); ++ ++ if (arg) { ++ err = copy_from_user(&wbrfd, arg, sizeof(wbrfd)); ++ if (unlikely(err)) { ++ err = -EFAULT; ++ goto out; ++ } ++ ++ err = -EINVAL; ++ AuDbg("wbrfd{0%o, %d}\n", wbrfd.oflags, wbrfd.brid); ++ wbrfd.oflags |= au_dir_roflags; ++ AuDbg("0%o\n", wbrfd.oflags); ++ if (unlikely(wbrfd.oflags & ~valid)) ++ goto out; ++ } ++ ++ fd = get_unused_fd_flags(0); ++ err = fd; ++ if (unlikely(fd < 0)) ++ goto out; ++ ++ h_file = ERR_PTR(-EINVAL); ++ wbi = 0; ++ br = NULL; ++ sb = path->dentry->d_sb; ++ root = sb->s_root; ++ aufs_read_lock(root, AuLock_IR); ++ bend = au_sbend(sb); ++ if (wbrfd.brid >= 0) { ++ wbi = au_br_index(sb, wbrfd.brid); ++ if (unlikely(wbi < 0 || wbi > bend)) ++ goto out_unlock; ++ } ++ ++ h_file = ERR_PTR(-ENOENT); ++ br = au_sbr(sb, wbi); ++ if (!au_br_writable(br->br_perm)) { ++ if (arg) ++ goto out_unlock; ++ ++ bindex = wbi + 1; ++ wbi = -1; ++ for (; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ if (au_br_writable(br->br_perm)) { ++ wbi = bindex; ++ br = au_sbr(sb, wbi); ++ break; ++ } ++ } ++ } ++ AuDbg("wbi %d\n", wbi); ++ if (wbi >= 0) ++ h_file = au_h_open(root, wbi, wbrfd.oflags, NULL, ++ /*force_wr*/0); ++ ++out_unlock: ++ aufs_read_unlock(root, AuLock_IR); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out_fd; ++ ++ atomic_dec(&br->br_count); /* cf. au_h_open() */ ++ fd_install(fd, h_file); ++ err = fd; ++ goto out; /* success */ ++ ++out_fd: ++ put_unused_fd(fd); ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ long err; ++ struct dentry *dentry; ++ ++ switch (cmd) { ++ case AUFS_CTL_RDU: ++ case AUFS_CTL_RDU_INO: ++ err = au_rdu_ioctl(file, cmd, arg); ++ break; ++ ++ case AUFS_CTL_WBR_FD: ++ err = au_wbr_fd(&file->f_path, (void __user *)arg); ++ break; ++ ++ case AUFS_CTL_IBUSY: ++ err = au_ibusy_ioctl(file, arg); ++ break; ++ ++ case AUFS_CTL_BRINFO: ++ err = au_brinfo_ioctl(file, arg); ++ break; ++ ++ case AUFS_CTL_FHSM_FD: ++ dentry = file->f_path.dentry; ++ if (IS_ROOT(dentry)) ++ err = au_fhsm_fd(dentry->d_sb, arg); ++ else ++ err = -ENOTTY; ++ break; ++ ++ default: ++ /* do not call the lower */ ++ AuDbg("0x%x\n", cmd); ++ err = -ENOTTY; ++ } ++ ++ AuTraceErr(err); ++ return err; ++} ++ ++long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ long err; ++ ++ switch (cmd) { ++ case AUFS_CTL_MVDOWN: ++ err = au_mvdown(file->f_path.dentry, (void __user *)arg); ++ break; ++ ++ case AUFS_CTL_WBR_FD: ++ err = au_wbr_fd(&file->f_path, (void __user *)arg); ++ break; ++ ++ default: ++ /* do not call the lower */ ++ AuDbg("0x%x\n", cmd); ++ err = -ENOTTY; ++ } ++ ++ AuTraceErr(err); ++ return err; ++} ++ ++#ifdef CONFIG_COMPAT ++long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ long err; ++ ++ switch (cmd) { ++ case AUFS_CTL_RDU: ++ case AUFS_CTL_RDU_INO: ++ err = au_rdu_compat_ioctl(file, cmd, arg); ++ break; ++ ++ case AUFS_CTL_IBUSY: ++ err = au_ibusy_compat_ioctl(file, arg); ++ break; ++ ++ case AUFS_CTL_BRINFO: ++ err = au_brinfo_compat_ioctl(file, arg); ++ break; ++ ++ default: ++ err = aufs_ioctl_dir(file, cmd, arg); ++ } ++ ++ AuTraceErr(err); ++ return err; ++} ++ ++long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg)); ++} ++#endif +diff -Nurp linux-4.4.3/fs/aufs/i_op_add.c linux-4.4.3-aufs/fs/aufs/i_op_add.c +--- linux-4.4.3/fs/aufs/i_op_add.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/i_op_add.c 2016-03-02 17:59:37.367498731 +0200 +@@ -0,0 +1,919 @@ ++/* ++ * Copyright (C) 2005-2016 Junjiro R. Okajima ++ */ ++ ++/* ++ * inode operations (add entry) ++ */ ++ ++#include "aufs.h" ++ ++/* ++ * final procedure of adding a new entry, except link(2). ++ * remove whiteout, instantiate, copyup the parent dir's times and size ++ * and update version. ++ * if it failed, re-create the removed whiteout. ++ */ ++static int epilog(struct inode *dir, aufs_bindex_t bindex, ++ struct dentry *wh_dentry, struct dentry *dentry) ++{ ++ int err, rerr; ++ aufs_bindex_t bwh; ++ struct path h_path; ++ struct super_block *sb; ++ struct inode *inode, *h_dir; ++ struct dentry *wh; ++ ++ bwh = -1; ++ sb = dir->i_sb; ++ if (wh_dentry) { ++ h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */ ++ IMustLock(h_dir); ++ AuDebugOn(au_h_iptr(dir, bindex) != h_dir); ++ bwh = au_dbwh(dentry); ++ h_path.dentry = wh_dentry; ++ h_path.mnt = au_sbr_mnt(sb, bindex); ++ err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, ++ dentry); ++ if (unlikely(err)) ++ goto out; ++ } ++ ++ inode = au_new_inode(dentry, /*must_new*/1); ++ if (!IS_ERR(inode)) { ++ d_instantiate(dentry, inode); ++ dir = d_inode(dentry->d_parent); /* dir inode is locked */ ++ IMustLock(dir); ++ au_dir_ts(dir, bindex); ++ dir->i_version++; ++ au_fhsm_wrote(sb, bindex, /*force*/0); ++ return 0; /* success */ ++ } ++ ++ err = PTR_ERR(inode); ++ if (!wh_dentry) ++ goto out; ++ ++ /* revert */ ++ /* dir inode is locked */ ++ wh = au_wh_create(dentry, bwh, wh_dentry->d_parent); ++ rerr = PTR_ERR(wh); ++ if (IS_ERR(wh)) { ++ AuIOErr("%pd reverting whiteout failed(%d, %d)\n", ++ dentry, err, rerr); ++ err = -EIO; ++ } else ++ dput(wh); ++ ++out: ++ return err; ++} ++ ++static int au_d_may_add(struct dentry *dentry) ++{ ++ int err; ++ ++ err = 0; ++ if (unlikely(d_unhashed(dentry))) ++ err = -ENOENT; ++ if (unlikely(d_really_is_positive(dentry))) ++ err = -EEXIST; ++ return err; ++} ++ ++/* ++ * simple tests for the adding inode operations. ++ * following the checks in vfs, plus the parent-child relationship. ++ */ ++int au_may_add(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent, int isdir) ++{ ++ int err; ++ umode_t h_mode; ++ struct dentry *h_dentry; ++ struct inode *h_inode; ++ ++ err = -ENAMETOOLONG; ++ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN)) ++ goto out; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (d_really_is_negative(dentry)) { ++ err = -EEXIST; ++ if (unlikely(d_is_positive(h_dentry))) ++ goto out; ++ } else { ++ /* rename(2) case */ ++ err = -EIO; ++ if (unlikely(d_is_negative(h_dentry))) ++ goto out; ++ h_inode = d_inode(h_dentry); ++ if (unlikely(!h_inode->i_nlink)) ++ goto out; ++ ++ h_mode = h_inode->i_mode; ++ if (!isdir) { ++ err = -EISDIR; ++ if (unlikely(S_ISDIR(h_mode))) ++ goto out; ++ } else if (unlikely(!S_ISDIR(h_mode))) { ++ err = -ENOTDIR; ++ goto out; ++ } ++ } ++ ++ err = 0; ++ /* expected parent dir is locked */ ++ if (unlikely(h_parent != h_dentry->d_parent)) ++ err = -EIO; ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ++ * initial procedure of adding a new entry. ++ * prepare writable branch and the parent dir, lock it, ++ * and lookup whiteout for the new entry. ++ */ ++static struct dentry* ++lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt, ++ struct dentry *src_dentry, struct au_pin *pin, ++ struct au_wr_dir_args *wr_dir_args) ++{ ++ struct dentry *wh_dentry, *h_parent; ++ struct super_block *sb; ++ struct au_branch *br; ++ int err; ++ unsigned int udba; ++ aufs_bindex_t bcpup; ++ ++ AuDbg("%pd\n", dentry); ++ ++ err = au_wr_dir(dentry, src_dentry, wr_dir_args); ++ bcpup = err; ++ wh_dentry = ERR_PTR(err); ++ if (unlikely(err < 0)) ++ goto out; ++ ++ sb = dentry->d_sb; ++ udba = au_opt_udba(sb); ++ err = au_pin(pin, dentry, bcpup, udba, ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ wh_dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out; ++ ++ h_parent = au_pinned_h_parent(pin); ++ if (udba != AuOpt_UDBA_NONE ++ && au_dbstart(dentry) == bcpup) ++ err = au_may_add(dentry, bcpup, h_parent, ++ au_ftest_wrdir(wr_dir_args->flags, ISDIR)); ++ else if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN)) ++ err = -ENAMETOOLONG; ++ wh_dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out_unpin; ++ ++ br = au_sbr(sb, bcpup); ++ if (dt) { ++ struct path tmp = { ++ .dentry = h_parent, ++ .mnt = au_br_mnt(br) ++ }; ++ au_dtime_store(dt, au_pinned_parent(pin), &tmp); ++ } ++ ++ wh_dentry = NULL; ++ if (bcpup != au_dbwh(dentry)) ++ goto out; /* success */ ++ ++ /* ++ * ENAMETOOLONG here means that if we allowed create such name, then it ++ * would not be able to removed in the future. So we don't allow such ++ * name here and we don't handle ENAMETOOLONG differently here. ++ */ ++ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br); ++ ++out_unpin: ++ if (IS_ERR(wh_dentry)) ++ au_unpin(pin); ++out: ++ return wh_dentry; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++enum { Mknod, Symlink, Creat }; ++struct simple_arg { ++ int type; ++ union { ++ struct { ++ umode_t mode; ++ bool want_excl; ++ bool try_aopen; ++ struct vfsub_aopen_args *aopen; ++ } c; ++ struct { ++ const char *symname; ++ } s; ++ struct { ++ umode_t mode; ++ dev_t dev; ++ } m; ++ } u; ++}; ++ ++static int add_simple(struct inode *dir, struct dentry *dentry, ++ struct simple_arg *arg) ++{ ++ int err, rerr; ++ aufs_bindex_t bstart; ++ unsigned char created; ++ const unsigned char try_aopen ++ = (arg->type == Creat && arg->u.c.try_aopen); ++ struct dentry *wh_dentry, *parent; ++ struct inode *h_dir; ++ struct super_block *sb; ++ struct au_branch *br; ++ /* to reuduce stack size */ ++ struct { ++ struct au_dtime dt; ++ struct au_pin pin; ++ struct path h_path; ++ struct au_wr_dir_args wr_dir_args; ++ } *a; ++ ++ AuDbg("%pd\n", dentry); ++ IMustLock(dir); ++ ++ err = -ENOMEM; ++ a = kmalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ a->wr_dir_args.force_btgt = -1; ++ a->wr_dir_args.flags = AuWrDir_ADD_ENTRY; ++ ++ parent = dentry->d_parent; /* dir inode is locked */ ++ if (!try_aopen) { ++ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN); ++ if (unlikely(err)) ++ goto out_free; ++ } ++ err = au_d_may_add(dentry); ++ if (unlikely(err)) ++ goto out_unlock; ++ if (!try_aopen) ++ di_write_lock_parent(parent); ++ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL, ++ &a->pin, &a->wr_dir_args); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out_parent; ++ ++ bstart = au_dbstart(dentry); ++ sb = dentry->d_sb; ++ br = au_sbr(sb, bstart); ++ a->h_path.dentry = au_h_dptr(dentry, bstart); ++ a->h_path.mnt = au_br_mnt(br); ++ h_dir = au_pinned_h_dir(&a->pin); ++ switch (arg->type) { ++ case Creat: ++ err = 0; ++ if (!try_aopen || !h_dir->i_op->atomic_open) ++ err = vfsub_create(h_dir, &a->h_path, arg->u.c.mode, ++ arg->u.c.want_excl); ++ else ++ err = vfsub_atomic_open(h_dir, a->h_path.dentry, ++ arg->u.c.aopen, br); ++ break; ++ case Symlink: ++ err = vfsub_symlink(h_dir, &a->h_path, arg->u.s.symname); ++ break; ++ case Mknod: ++ err = vfsub_mknod(h_dir, &a->h_path, arg->u.m.mode, ++ arg->u.m.dev); ++ break; ++ default: ++ BUG(); ++ } ++ created = !err; ++ if (!err) ++ err = epilog(dir, bstart, wh_dentry, dentry); ++ ++ /* revert */ ++ if (unlikely(created && err && d_is_positive(a->h_path.dentry))) { ++ /* no delegation since it is just created */ ++ rerr = vfsub_unlink(h_dir, &a->h_path, /*delegated*/NULL, ++ /*force*/0); ++ if (rerr) { ++ AuIOErr("%pd revert failure(%d, %d)\n", ++ dentry, err, rerr); ++ err = -EIO; ++ } ++ au_dtime_revert(&a->dt); ++ } ++ ++ if (!err && try_aopen && !h_dir->i_op->atomic_open) ++ *arg->u.c.aopen->opened |= FILE_CREATED; ++ ++ au_unpin(&a->pin); ++ dput(wh_dentry); ++ ++out_parent: ++ if (!try_aopen) ++ di_write_unlock(parent); ++out_unlock: ++ if (unlikely(err)) { ++ au_update_dbstart(dentry); ++ d_drop(dentry); ++ } ++ if (!try_aopen) ++ aufs_read_unlock(dentry, AuLock_DW); ++out_free: ++ kfree(a); ++out: ++ return err; ++} ++ ++int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, ++ dev_t dev) ++{ ++ struct simple_arg arg = { ++ .type = Mknod, ++ .u.m = { ++ .mode = mode, ++ .dev = dev ++ } ++ }; ++ return add_simple(dir, dentry, &arg); ++} ++ ++int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) ++{ ++ struct simple_arg arg = { ++ .type = Symlink, ++ .u.s.symname = symname ++ }; ++ return add_simple(dir, dentry, &arg); ++} ++ ++int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode, ++ bool want_excl) ++{ ++ struct simple_arg arg = { ++ .type = Creat, ++ .u.c = { ++ .mode = mode, ++ .want_excl = want_excl ++ } ++ }; ++ return add_simple(dir, dentry, &arg); ++} ++ ++int au_aopen_or_create(struct inode *dir, struct dentry *dentry, ++ struct vfsub_aopen_args *aopen_args) ++{ ++ struct simple_arg arg = { ++ .type = Creat, ++ .u.c = { ++ .mode = aopen_args->create_mode, ++ .want_excl = aopen_args->open_flag & O_EXCL, ++ .try_aopen = true, ++ .aopen = aopen_args ++ } ++ }; ++ return add_simple(dir, dentry, &arg); ++} ++ ++int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) ++{ ++ int err; ++ aufs_bindex_t bindex; ++ struct super_block *sb; ++ struct dentry *parent, *h_parent, *h_dentry; ++ struct inode *h_dir, *inode; ++ struct vfsmount *h_mnt; ++ struct au_wr_dir_args wr_dir_args = { ++ .force_btgt = -1, ++ .flags = AuWrDir_TMPFILE ++ }; ++ ++ /* copy-up may happen */ ++ mutex_lock(&dir->i_mutex); ++ ++ sb = dir->i_sb; ++ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_di_init(dentry); ++ if (unlikely(err)) ++ goto out_si; ++ ++ err = -EBUSY; ++ parent = d_find_any_alias(dir); ++ AuDebugOn(!parent); ++ di_write_lock_parent(parent); ++ if (unlikely(d_inode(parent) != dir)) ++ goto out_parent; ++ ++ err = au_digen_test(parent, au_sigen(sb)); ++ if (unlikely(err)) ++ goto out_parent; ++ ++ bindex = au_dbstart(parent); ++ au_set_dbstart(dentry, bindex); ++ au_set_dbend(dentry, bindex); ++ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args); ++ bindex = err; ++ if (unlikely(err < 0)) ++ goto out_parent; ++ ++ err = -EOPNOTSUPP; ++ h_dir = au_h_iptr(dir, bindex); ++ if (unlikely(!h_dir->i_op->tmpfile)) ++ goto out_parent; ++ ++ h_mnt = au_sbr_mnt(sb, bindex); ++ err = vfsub_mnt_want_write(h_mnt); ++ if (unlikely(err)) ++ goto out_parent; ++ ++ h_parent = au_h_dptr(parent, bindex); ++ err = inode_permission(d_inode(h_parent), MAY_WRITE | MAY_EXEC); ++ if (unlikely(err)) ++ goto out_mnt; ++ ++ err = -ENOMEM; ++ h_dentry = d_alloc(h_parent, &dentry->d_name); ++ if (unlikely(!h_dentry)) ++ goto out_mnt; ++ ++ err = h_dir->i_op->tmpfile(h_dir, h_dentry, mode); ++ if (unlikely(err)) ++ goto out_dentry; ++ ++ au_set_dbstart(dentry, bindex); ++ au_set_dbend(dentry, bindex); ++ au_set_h_dptr(dentry, bindex, dget(h_dentry)); ++ inode = au_new_inode(dentry, /*must_new*/1); ++ if (IS_ERR(inode)) { ++ err = PTR_ERR(inode); ++ au_set_h_dptr(dentry, bindex, NULL); ++ au_set_dbstart(dentry, -1); ++ au_set_dbend(dentry, -1); ++ } else { ++ if (!inode->i_nlink) ++ set_nlink(inode, 1); ++ d_tmpfile(dentry, inode); ++ au_di(dentry)->di_tmpfile = 1; ++ ++ /* update without i_mutex */ ++ if (au_ibstart(dir) == au_dbstart(dentry)) ++ au_cpup_attr_timesizes(dir); ++ } ++ ++out_dentry: ++ dput(h_dentry); ++out_mnt: ++ vfsub_mnt_drop_write(h_mnt); ++out_parent: ++ di_write_unlock(parent); ++ dput(parent); ++ di_write_unlock(dentry); ++ if (!err) ++#if 0 ++ /* verbose coding for lock class name */ ++ au_rw_class(&au_di(dentry)->di_rwsem, ++ au_lc_key + AuLcNonDir_DIINFO); ++#else ++ ; ++#endif ++ else { ++ au_di_fin(dentry); ++ dentry->d_fsdata = NULL; ++ } ++out_si: ++ si_read_unlock(sb); ++out: ++ mutex_unlock(&dir->i_mutex); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_link_args { ++ aufs_bindex_t bdst, bsrc; ++ struct au_pin pin; ++ struct path h_path; ++ struct dentry *src_parent, *parent; ++}; ++ ++static int au_cpup_before_link(struct dentry *src_dentry, ++ struct au_link_args *a) ++{ ++ int err; ++ struct dentry *h_src_dentry; ++ struct au_cp_generic cpg = { ++ .dentry = src_dentry, ++ .bdst = a->bdst, ++ .bsrc = a->bsrc, ++ .len = -1, ++ .pin = &a->pin, ++ .flags = AuCpup_DTIME | AuCpup_HOPEN /* | AuCpup_KEEPLINO */ ++ }; ++ ++ di_read_lock_parent(a->src_parent, AuLock_IR); ++ err = au_test_and_cpup_dirs(src_dentry, a->bdst); ++ if (unlikely(err)) ++ goto out; ++ ++ h_src_dentry = au_h_dptr(src_dentry, a->bsrc); ++ err = au_pin(&a->pin, src_dentry, a->bdst, ++ au_opt_udba(src_dentry->d_sb), ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_sio_cpup_simple(&cpg); ++ au_unpin(&a->pin); ++ ++out: ++ di_read_unlock(a->src_parent, AuLock_IR); ++ return err; ++} ++ ++static int au_cpup_or_link(struct dentry *src_dentry, struct dentry *dentry, ++ struct au_link_args *a) ++{ ++ int err; ++ unsigned char plink; ++ aufs_bindex_t bend; ++ struct dentry *h_src_dentry; ++ struct inode *h_inode, *inode, *delegated; ++ struct super_block *sb; ++ struct file *h_file; ++ ++ plink = 0; ++ h_inode = NULL; ++ sb = src_dentry->d_sb; ++ inode = d_inode(src_dentry); ++ if (au_ibstart(inode) <= a->bdst) ++ h_inode = au_h_iptr(inode, a->bdst); ++ if (!h_inode || !h_inode->i_nlink) { ++ /* copyup src_dentry as the name of dentry. */ ++ bend = au_dbend(dentry); ++ if (bend < a->bsrc) ++ au_set_dbend(dentry, a->bsrc); ++ au_set_h_dptr(dentry, a->bsrc, ++ dget(au_h_dptr(src_dentry, a->bsrc))); ++ dget(a->h_path.dentry); ++ au_set_h_dptr(dentry, a->bdst, NULL); ++ AuDbg("temporary d_inode...\n"); ++ spin_lock(&dentry->d_lock); ++ dentry->d_inode = d_inode(src_dentry); /* tmp */ ++ spin_unlock(&dentry->d_lock); ++ h_file = au_h_open_pre(dentry, a->bsrc, /*force_wr*/0); ++ if (IS_ERR(h_file)) ++ err = PTR_ERR(h_file); ++ else { ++ struct au_cp_generic cpg = { ++ .dentry = dentry, ++ .bdst = a->bdst, ++ .bsrc = -1, ++ .len = -1, ++ .pin = &a->pin, ++ .flags = AuCpup_KEEPLINO ++ }; ++ err = au_sio_cpup_simple(&cpg); ++ au_h_open_post(dentry, a->bsrc, h_file); ++ if (!err) { ++ dput(a->h_path.dentry); ++ a->h_path.dentry = au_h_dptr(dentry, a->bdst); ++ } else ++ au_set_h_dptr(dentry, a->bdst, ++ a->h_path.dentry); ++ } ++ spin_lock(&dentry->d_lock); ++ dentry->d_inode = NULL; /* restore */ ++ spin_unlock(&dentry->d_lock); ++ AuDbg("temporary d_inode...done\n"); ++ au_set_h_dptr(dentry, a->bsrc, NULL); ++ au_set_dbend(dentry, bend); ++ } else { ++ /* the inode of src_dentry already exists on a.bdst branch */ ++ h_src_dentry = d_find_alias(h_inode); ++ if (!h_src_dentry && au_plink_test(inode)) { ++ plink = 1; ++ h_src_dentry = au_plink_lkup(inode, a->bdst); ++ err = PTR_ERR(h_src_dentry); ++ if (IS_ERR(h_src_dentry)) ++ goto out; ++ ++ if (unlikely(d_is_negative(h_src_dentry))) { ++ dput(h_src_dentry); ++ h_src_dentry = NULL; ++ } ++ ++ } ++ if (h_src_dentry) { ++ delegated = NULL; ++ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin), ++ &a->h_path, &delegated); ++ if (unlikely(err == -EWOULDBLOCK)) { ++ pr_warn("cannot retry for NFSv4 delegation" ++ " for an internal link\n"); ++ iput(delegated); ++ } ++ dput(h_src_dentry); ++ } else { ++ AuIOErr("no dentry found for hi%lu on b%d\n", ++ h_inode->i_ino, a->bdst); ++ err = -EIO; ++ } ++ } ++ ++ if (!err && !plink) ++ au_plink_append(inode, a->bdst, a->h_path.dentry); ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++int aufs_link(struct dentry *src_dentry, struct inode *dir, ++ struct dentry *dentry) ++{ ++ int err, rerr; ++ struct au_dtime dt; ++ struct au_link_args *a; ++ struct dentry *wh_dentry, *h_src_dentry; ++ struct inode *inode, *delegated; ++ struct super_block *sb; ++ struct au_wr_dir_args wr_dir_args = { ++ /* .force_btgt = -1, */ ++ .flags = AuWrDir_ADD_ENTRY ++ }; ++ ++ IMustLock(dir); ++ inode = d_inode(src_dentry); ++ IMustLock(inode); ++ ++ err = -ENOMEM; ++ a = kzalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ a->parent = dentry->d_parent; /* dir inode is locked */ ++ err = aufs_read_and_write_lock2(dentry, src_dentry, ++ AuLock_NOPLM | AuLock_GEN); ++ if (unlikely(err)) ++ goto out_kfree; ++ err = au_d_linkable(src_dentry); ++ if (unlikely(err)) ++ goto out_unlock; ++ err = au_d_may_add(dentry); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ a->src_parent = dget_parent(src_dentry); ++ wr_dir_args.force_btgt = au_ibstart(inode); ++ ++ di_write_lock_parent(a->parent); ++ wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt); ++ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin, ++ &wr_dir_args); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out_parent; ++ ++ err = 0; ++ sb = dentry->d_sb; ++ a->bdst = au_dbstart(dentry); ++ a->h_path.dentry = au_h_dptr(dentry, a->bdst); ++ a->h_path.mnt = au_sbr_mnt(sb, a->bdst); ++ a->bsrc = au_ibstart(inode); ++ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc); ++ if (!h_src_dentry && au_di(src_dentry)->di_tmpfile) ++ h_src_dentry = dget(au_hi_wh(inode, a->bsrc)); ++ if (!h_src_dentry) { ++ a->bsrc = au_dbstart(src_dentry); ++ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc); ++ AuDebugOn(!h_src_dentry); ++ } else if (IS_ERR(h_src_dentry)) { ++ err = PTR_ERR(h_src_dentry); ++ goto out_parent; ++ } ++ ++ if (au_opt_test(au_mntflags(sb), PLINK)) { ++ if (a->bdst < a->bsrc ++ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) ++ err = au_cpup_or_link(src_dentry, dentry, a); ++ else { ++ delegated = NULL; ++ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin), ++ &a->h_path, &delegated); ++ if (unlikely(err == -EWOULDBLOCK)) { ++ pr_warn("cannot retry for NFSv4 delegation" ++ " for an internal link\n"); ++ iput(delegated); ++ } ++ } ++ dput(h_src_dentry); ++ } else { ++ /* ++ * copyup src_dentry to the branch we process, ++ * and then link(2) to it. ++ */ ++ dput(h_src_dentry); ++ if (a->bdst < a->bsrc ++ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) { ++ au_unpin(&a->pin); ++ di_write_unlock(a->parent); ++ err = au_cpup_before_link(src_dentry, a); ++ di_write_lock_parent(a->parent); ++ if (!err) ++ err = au_pin(&a->pin, dentry, a->bdst, ++ au_opt_udba(sb), ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ if (unlikely(err)) ++ goto out_wh; ++ } ++ if (!err) { ++ h_src_dentry = au_h_dptr(src_dentry, a->bdst); ++ err = -ENOENT; ++ if (h_src_dentry && d_is_positive(h_src_dentry)) { ++ delegated = NULL; ++ err = vfsub_link(h_src_dentry, ++ au_pinned_h_dir(&a->pin), ++ &a->h_path, &delegated); ++ if (unlikely(err == -EWOULDBLOCK)) { ++ pr_warn("cannot retry" ++ " for NFSv4 delegation" ++ " for an internal link\n"); ++ iput(delegated); ++ } ++ } ++ } ++ } ++ if (unlikely(err)) ++ goto out_unpin; ++ ++ if (wh_dentry) { ++ a->h_path.dentry = wh_dentry; ++ err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path, ++ dentry); ++ if (unlikely(err)) ++ goto out_revert; ++ } ++ ++ au_dir_ts(dir, a->bdst); ++ dir->i_version++; ++ inc_nlink(inode); ++ inode->i_ctime = dir->i_ctime; ++ d_instantiate(dentry, au_igrab(inode)); ++ if (d_unhashed(a->h_path.dentry)) ++ /* some filesystem calls d_drop() */ ++ d_drop(dentry); ++ /* some filesystems consume an inode even hardlink */ ++ au_fhsm_wrote(sb, a->bdst, /*force*/0); ++ goto out_unpin; /* success */ ++ ++out_revert: ++ /* no delegation since it is just created */ ++ rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path, ++ /*delegated*/NULL, /*force*/0); ++ if (unlikely(rerr)) { ++ AuIOErr("%pd reverting failed(%d, %d)\n", dentry, err, rerr); ++ err = -EIO; ++ } ++ au_dtime_revert(&dt); ++out_unpin: ++ au_unpin(&a->pin); ++out_wh: ++ dput(wh_dentry); ++out_parent: ++ di_write_unlock(a->parent); ++ dput(a->src_parent); ++out_unlock: ++ if (unlikely(err)) { ++ au_update_dbstart(dentry); ++ d_drop(dentry); ++ } ++ aufs_read_and_write_unlock2(dentry, src_dentry); ++out_kfree: ++ kfree(a); ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) ++{ ++ int err, rerr; ++ aufs_bindex_t bindex; ++ unsigned char diropq; ++ struct path h_path; ++ struct dentry *wh_dentry, *parent, *opq_dentry; ++ struct mutex *h_mtx; ++ struct super_block *sb; ++ struct { ++ struct au_pin pin; ++ struct au_dtime dt; ++ } *a; /* reduce the stack usage */ ++ struct au_wr_dir_args wr_dir_args = { ++ .force_btgt = -1, ++ .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR ++ }; ++ ++ IMustLock(dir); ++ ++ err = -ENOMEM; ++ a = kmalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN); ++ if (unlikely(err)) ++ goto out_free; ++ err = au_d_may_add(dentry); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ parent = dentry->d_parent; /* dir inode is locked */ ++ di_write_lock_parent(parent); ++ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL, ++ &a->pin, &wr_dir_args); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out_parent; ++ ++ sb = dentry->d_sb; ++ bindex = au_dbstart(dentry); ++ h_path.dentry = au_h_dptr(dentry, bindex); ++ h_path.mnt = au_sbr_mnt(sb, bindex); ++ err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode); ++ if (unlikely(err)) ++ goto out_unpin; ++ ++ /* make the dir opaque */ ++ diropq = 0; ++ h_mtx = &d_inode(h_path.dentry)->i_mutex; ++ if (wh_dentry ++ || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) { ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ opq_dentry = au_diropq_create(dentry, bindex); ++ mutex_unlock(h_mtx); ++ err = PTR_ERR(opq_dentry); ++ if (IS_ERR(opq_dentry)) ++ goto out_dir; ++ dput(opq_dentry); ++ diropq = 1; ++ } ++ ++ err = epilog(dir, bindex, wh_dentry, dentry); ++ if (!err) { ++ inc_nlink(dir); ++ goto out_unpin; /* success */ ++ } ++ ++ /* revert */ ++ if (diropq) { ++ AuLabel(revert opq); ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ rerr = au_diropq_remove(dentry, bindex); ++ mutex_unlock(h_mtx); ++ if (rerr) { ++ AuIOErr("%pd reverting diropq failed(%d, %d)\n", ++ dentry, err, rerr); ++ err = -EIO; ++ } ++ } ++ ++out_dir: ++ AuLabel(revert dir); ++ rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path); ++ if (rerr) { ++ AuIOErr("%pd reverting dir failed(%d, %d)\n", ++ dentry, err, rerr); ++ err = -EIO; ++ } ++ au_dtime_revert(&a->dt); ++out_unpin: ++ au_unpin(&a->pin); ++ dput(wh_dentry); ++out_parent: ++ di_write_unlock(parent); ++out_unlock: ++ if (unlikely(err)) { ++ au_update_dbstart(dentry); ++ d_drop(dentry); ++ } ++ aufs_read_unlock(dentry, AuLock_DW); ++out_free: ++ kfree(a); ++out: ++ return err; ++} +diff -Nurp linux-4.4.3/fs/aufs/i_op.c linux-4.4.3-aufs/fs/aufs/i_op.c +--- linux-4.4.3/fs/aufs/i_op.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/i_op.c 2016-03-02 17:59:37.367498731 +0200 +@@ -0,0 +1,1477 @@ ++/* ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -15443,6 +17780,12 @@ index 0000000..daad67a + break; + } + } ++ /* ++ * regardless aufs 'acl' option setting. ++ * why don't all acl-aware fs call this func from their ->setattr()? ++ */ ++ if (!err && (ia->ia_valid & ATTR_MODE)) ++ err = vfsub_acl_chmod(a->h_inode, ia->ia_mode); + if (!err) + au_cpup_attr_changeable(inode); + @@ -15949,939 +18292,12 @@ index 0000000..daad67a + .update_time = aufs_update_time + } +}; -diff --git a/fs/aufs/i_op_add.c b/fs/aufs/i_op_add.c -new file mode 100644 -index 0000000..0c3530e ---- /dev/null -+++ b/fs/aufs/i_op_add.c -@@ -0,0 +1,919 @@ -+/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima -+ */ -+ -+/* -+ * inode operations (add entry) -+ */ -+ -+#include "aufs.h" -+ -+/* -+ * final procedure of adding a new entry, except link(2). -+ * remove whiteout, instantiate, copyup the parent dir's times and size -+ * and update version. -+ * if it failed, re-create the removed whiteout. -+ */ -+static int epilog(struct inode *dir, aufs_bindex_t bindex, -+ struct dentry *wh_dentry, struct dentry *dentry) -+{ -+ int err, rerr; -+ aufs_bindex_t bwh; -+ struct path h_path; -+ struct super_block *sb; -+ struct inode *inode, *h_dir; -+ struct dentry *wh; -+ -+ bwh = -1; -+ sb = dir->i_sb; -+ if (wh_dentry) { -+ h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */ -+ IMustLock(h_dir); -+ AuDebugOn(au_h_iptr(dir, bindex) != h_dir); -+ bwh = au_dbwh(dentry); -+ h_path.dentry = wh_dentry; -+ h_path.mnt = au_sbr_mnt(sb, bindex); -+ err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, -+ dentry); -+ if (unlikely(err)) -+ goto out; -+ } -+ -+ inode = au_new_inode(dentry, /*must_new*/1); -+ if (!IS_ERR(inode)) { -+ d_instantiate(dentry, inode); -+ dir = d_inode(dentry->d_parent); /* dir inode is locked */ -+ IMustLock(dir); -+ au_dir_ts(dir, bindex); -+ dir->i_version++; -+ au_fhsm_wrote(sb, bindex, /*force*/0); -+ return 0; /* success */ -+ } -+ -+ err = PTR_ERR(inode); -+ if (!wh_dentry) -+ goto out; -+ -+ /* revert */ -+ /* dir inode is locked */ -+ wh = au_wh_create(dentry, bwh, wh_dentry->d_parent); -+ rerr = PTR_ERR(wh); -+ if (IS_ERR(wh)) { -+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n", -+ dentry, err, rerr); -+ err = -EIO; -+ } else -+ dput(wh); -+ -+out: -+ return err; -+} -+ -+static int au_d_may_add(struct dentry *dentry) -+{ -+ int err; -+ -+ err = 0; -+ if (unlikely(d_unhashed(dentry))) -+ err = -ENOENT; -+ if (unlikely(d_really_is_positive(dentry))) -+ err = -EEXIST; -+ return err; -+} -+ -+/* -+ * simple tests for the adding inode operations. -+ * following the checks in vfs, plus the parent-child relationship. -+ */ -+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_parent, int isdir) -+{ -+ int err; -+ umode_t h_mode; -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ -+ err = -ENAMETOOLONG; -+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN)) -+ goto out; -+ -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (d_really_is_negative(dentry)) { -+ err = -EEXIST; -+ if (unlikely(d_is_positive(h_dentry))) -+ goto out; -+ } else { -+ /* rename(2) case */ -+ err = -EIO; -+ if (unlikely(d_is_negative(h_dentry))) -+ goto out; -+ h_inode = d_inode(h_dentry); -+ if (unlikely(!h_inode->i_nlink)) -+ goto out; -+ -+ h_mode = h_inode->i_mode; -+ if (!isdir) { -+ err = -EISDIR; -+ if (unlikely(S_ISDIR(h_mode))) -+ goto out; -+ } else if (unlikely(!S_ISDIR(h_mode))) { -+ err = -ENOTDIR; -+ goto out; -+ } -+ } -+ -+ err = 0; -+ /* expected parent dir is locked */ -+ if (unlikely(h_parent != h_dentry->d_parent)) -+ err = -EIO; -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* -+ * initial procedure of adding a new entry. -+ * prepare writable branch and the parent dir, lock it, -+ * and lookup whiteout for the new entry. -+ */ -+static struct dentry* -+lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt, -+ struct dentry *src_dentry, struct au_pin *pin, -+ struct au_wr_dir_args *wr_dir_args) -+{ -+ struct dentry *wh_dentry, *h_parent; -+ struct super_block *sb; -+ struct au_branch *br; -+ int err; -+ unsigned int udba; -+ aufs_bindex_t bcpup; -+ -+ AuDbg("%pd\n", dentry); -+ -+ err = au_wr_dir(dentry, src_dentry, wr_dir_args); -+ bcpup = err; -+ wh_dentry = ERR_PTR(err); -+ if (unlikely(err < 0)) -+ goto out; -+ -+ sb = dentry->d_sb; -+ udba = au_opt_udba(sb); -+ err = au_pin(pin, dentry, bcpup, udba, -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ wh_dentry = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out; -+ -+ h_parent = au_pinned_h_parent(pin); -+ if (udba != AuOpt_UDBA_NONE -+ && au_dbstart(dentry) == bcpup) -+ err = au_may_add(dentry, bcpup, h_parent, -+ au_ftest_wrdir(wr_dir_args->flags, ISDIR)); -+ else if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN)) -+ err = -ENAMETOOLONG; -+ wh_dentry = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out_unpin; -+ -+ br = au_sbr(sb, bcpup); -+ if (dt) { -+ struct path tmp = { -+ .dentry = h_parent, -+ .mnt = au_br_mnt(br) -+ }; -+ au_dtime_store(dt, au_pinned_parent(pin), &tmp); -+ } -+ -+ wh_dentry = NULL; -+ if (bcpup != au_dbwh(dentry)) -+ goto out; /* success */ -+ -+ /* -+ * ENAMETOOLONG here means that if we allowed create such name, then it -+ * would not be able to removed in the future. So we don't allow such -+ * name here and we don't handle ENAMETOOLONG differently here. -+ */ -+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br); -+ -+out_unpin: -+ if (IS_ERR(wh_dentry)) -+ au_unpin(pin); -+out: -+ return wh_dentry; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+enum { Mknod, Symlink, Creat }; -+struct simple_arg { -+ int type; -+ union { -+ struct { -+ umode_t mode; -+ bool want_excl; -+ bool try_aopen; -+ struct vfsub_aopen_args *aopen; -+ } c; -+ struct { -+ const char *symname; -+ } s; -+ struct { -+ umode_t mode; -+ dev_t dev; -+ } m; -+ } u; -+}; -+ -+static int add_simple(struct inode *dir, struct dentry *dentry, -+ struct simple_arg *arg) -+{ -+ int err, rerr; -+ aufs_bindex_t bstart; -+ unsigned char created; -+ const unsigned char try_aopen -+ = (arg->type == Creat && arg->u.c.try_aopen); -+ struct dentry *wh_dentry, *parent; -+ struct inode *h_dir; -+ struct super_block *sb; -+ struct au_branch *br; -+ /* to reuduce stack size */ -+ struct { -+ struct au_dtime dt; -+ struct au_pin pin; -+ struct path h_path; -+ struct au_wr_dir_args wr_dir_args; -+ } *a; -+ -+ AuDbg("%pd\n", dentry); -+ IMustLock(dir); -+ -+ err = -ENOMEM; -+ a = kmalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ a->wr_dir_args.force_btgt = -1; -+ a->wr_dir_args.flags = AuWrDir_ADD_ENTRY; -+ -+ parent = dentry->d_parent; /* dir inode is locked */ -+ if (!try_aopen) { -+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN); -+ if (unlikely(err)) -+ goto out_free; -+ } -+ err = au_d_may_add(dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ if (!try_aopen) -+ di_write_lock_parent(parent); -+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL, -+ &a->pin, &a->wr_dir_args); -+ err = PTR_ERR(wh_dentry); -+ if (IS_ERR(wh_dentry)) -+ goto out_parent; -+ -+ bstart = au_dbstart(dentry); -+ sb = dentry->d_sb; -+ br = au_sbr(sb, bstart); -+ a->h_path.dentry = au_h_dptr(dentry, bstart); -+ a->h_path.mnt = au_br_mnt(br); -+ h_dir = au_pinned_h_dir(&a->pin); -+ switch (arg->type) { -+ case Creat: -+ err = 0; -+ if (!try_aopen || !h_dir->i_op->atomic_open) -+ err = vfsub_create(h_dir, &a->h_path, arg->u.c.mode, -+ arg->u.c.want_excl); -+ else -+ err = vfsub_atomic_open(h_dir, a->h_path.dentry, -+ arg->u.c.aopen, br); -+ break; -+ case Symlink: -+ err = vfsub_symlink(h_dir, &a->h_path, arg->u.s.symname); -+ break; -+ case Mknod: -+ err = vfsub_mknod(h_dir, &a->h_path, arg->u.m.mode, -+ arg->u.m.dev); -+ break; -+ default: -+ BUG(); -+ } -+ created = !err; -+ if (!err) -+ err = epilog(dir, bstart, wh_dentry, dentry); -+ -+ /* revert */ -+ if (unlikely(created && err && d_is_positive(a->h_path.dentry))) { -+ /* no delegation since it is just created */ -+ rerr = vfsub_unlink(h_dir, &a->h_path, /*delegated*/NULL, -+ /*force*/0); -+ if (rerr) { -+ AuIOErr("%pd revert failure(%d, %d)\n", -+ dentry, err, rerr); -+ err = -EIO; -+ } -+ au_dtime_revert(&a->dt); -+ } -+ -+ if (!err && try_aopen && !h_dir->i_op->atomic_open) -+ *arg->u.c.aopen->opened |= FILE_CREATED; -+ -+ au_unpin(&a->pin); -+ dput(wh_dentry); -+ -+out_parent: -+ if (!try_aopen) -+ di_write_unlock(parent); -+out_unlock: -+ if (unlikely(err)) { -+ au_update_dbstart(dentry); -+ d_drop(dentry); -+ } -+ if (!try_aopen) -+ aufs_read_unlock(dentry, AuLock_DW); -+out_free: -+ kfree(a); -+out: -+ return err; -+} -+ -+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, -+ dev_t dev) -+{ -+ struct simple_arg arg = { -+ .type = Mknod, -+ .u.m = { -+ .mode = mode, -+ .dev = dev -+ } -+ }; -+ return add_simple(dir, dentry, &arg); -+} -+ -+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) -+{ -+ struct simple_arg arg = { -+ .type = Symlink, -+ .u.s.symname = symname -+ }; -+ return add_simple(dir, dentry, &arg); -+} -+ -+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode, -+ bool want_excl) -+{ -+ struct simple_arg arg = { -+ .type = Creat, -+ .u.c = { -+ .mode = mode, -+ .want_excl = want_excl -+ } -+ }; -+ return add_simple(dir, dentry, &arg); -+} -+ -+int au_aopen_or_create(struct inode *dir, struct dentry *dentry, -+ struct vfsub_aopen_args *aopen_args) -+{ -+ struct simple_arg arg = { -+ .type = Creat, -+ .u.c = { -+ .mode = aopen_args->create_mode, -+ .want_excl = aopen_args->open_flag & O_EXCL, -+ .try_aopen = true, -+ .aopen = aopen_args -+ } -+ }; -+ return add_simple(dir, dentry, &arg); -+} -+ -+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ struct super_block *sb; -+ struct dentry *parent, *h_parent, *h_dentry; -+ struct inode *h_dir, *inode; -+ struct vfsmount *h_mnt; -+ struct au_wr_dir_args wr_dir_args = { -+ .force_btgt = -1, -+ .flags = AuWrDir_TMPFILE -+ }; -+ -+ /* copy-up may happen */ -+ mutex_lock(&dir->i_mutex); -+ -+ sb = dir->i_sb; -+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out; -+ -+ err = au_di_init(dentry); -+ if (unlikely(err)) -+ goto out_si; -+ -+ err = -EBUSY; -+ parent = d_find_any_alias(dir); -+ AuDebugOn(!parent); -+ di_write_lock_parent(parent); -+ if (unlikely(d_inode(parent) != dir)) -+ goto out_parent; -+ -+ err = au_digen_test(parent, au_sigen(sb)); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ bindex = au_dbstart(parent); -+ au_set_dbstart(dentry, bindex); -+ au_set_dbend(dentry, bindex); -+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args); -+ bindex = err; -+ if (unlikely(err < 0)) -+ goto out_parent; -+ -+ err = -EOPNOTSUPP; -+ h_dir = au_h_iptr(dir, bindex); -+ if (unlikely(!h_dir->i_op->tmpfile)) -+ goto out_parent; -+ -+ h_mnt = au_sbr_mnt(sb, bindex); -+ err = vfsub_mnt_want_write(h_mnt); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ h_parent = au_h_dptr(parent, bindex); -+ err = inode_permission(d_inode(h_parent), MAY_WRITE | MAY_EXEC); -+ if (unlikely(err)) -+ goto out_mnt; -+ -+ err = -ENOMEM; -+ h_dentry = d_alloc(h_parent, &dentry->d_name); -+ if (unlikely(!h_dentry)) -+ goto out_mnt; -+ -+ err = h_dir->i_op->tmpfile(h_dir, h_dentry, mode); -+ if (unlikely(err)) -+ goto out_dentry; -+ -+ au_set_dbstart(dentry, bindex); -+ au_set_dbend(dentry, bindex); -+ au_set_h_dptr(dentry, bindex, dget(h_dentry)); -+ inode = au_new_inode(dentry, /*must_new*/1); -+ if (IS_ERR(inode)) { -+ err = PTR_ERR(inode); -+ au_set_h_dptr(dentry, bindex, NULL); -+ au_set_dbstart(dentry, -1); -+ au_set_dbend(dentry, -1); -+ } else { -+ if (!inode->i_nlink) -+ set_nlink(inode, 1); -+ d_tmpfile(dentry, inode); -+ au_di(dentry)->di_tmpfile = 1; -+ -+ /* update without i_mutex */ -+ if (au_ibstart(dir) == au_dbstart(dentry)) -+ au_cpup_attr_timesizes(dir); -+ } -+ -+out_dentry: -+ dput(h_dentry); -+out_mnt: -+ vfsub_mnt_drop_write(h_mnt); -+out_parent: -+ di_write_unlock(parent); -+ dput(parent); -+ di_write_unlock(dentry); -+ if (!err) -+#if 0 -+ /* verbose coding for lock class name */ -+ au_rw_class(&au_di(dentry)->di_rwsem, -+ au_lc_key + AuLcNonDir_DIINFO); -+#else -+ ; -+#endif -+ else { -+ au_di_fin(dentry); -+ dentry->d_fsdata = NULL; -+ } -+out_si: -+ si_read_unlock(sb); -+out: -+ mutex_unlock(&dir->i_mutex); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_link_args { -+ aufs_bindex_t bdst, bsrc; -+ struct au_pin pin; -+ struct path h_path; -+ struct dentry *src_parent, *parent; -+}; -+ -+static int au_cpup_before_link(struct dentry *src_dentry, -+ struct au_link_args *a) -+{ -+ int err; -+ struct dentry *h_src_dentry; -+ struct au_cp_generic cpg = { -+ .dentry = src_dentry, -+ .bdst = a->bdst, -+ .bsrc = a->bsrc, -+ .len = -1, -+ .pin = &a->pin, -+ .flags = AuCpup_DTIME | AuCpup_HOPEN /* | AuCpup_KEEPLINO */ -+ }; -+ -+ di_read_lock_parent(a->src_parent, AuLock_IR); -+ err = au_test_and_cpup_dirs(src_dentry, a->bdst); -+ if (unlikely(err)) -+ goto out; -+ -+ h_src_dentry = au_h_dptr(src_dentry, a->bsrc); -+ err = au_pin(&a->pin, src_dentry, a->bdst, -+ au_opt_udba(src_dentry->d_sb), -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (unlikely(err)) -+ goto out; -+ -+ err = au_sio_cpup_simple(&cpg); -+ au_unpin(&a->pin); -+ -+out: -+ di_read_unlock(a->src_parent, AuLock_IR); -+ return err; -+} -+ -+static int au_cpup_or_link(struct dentry *src_dentry, struct dentry *dentry, -+ struct au_link_args *a) -+{ -+ int err; -+ unsigned char plink; -+ aufs_bindex_t bend; -+ struct dentry *h_src_dentry; -+ struct inode *h_inode, *inode, *delegated; -+ struct super_block *sb; -+ struct file *h_file; -+ -+ plink = 0; -+ h_inode = NULL; -+ sb = src_dentry->d_sb; -+ inode = d_inode(src_dentry); -+ if (au_ibstart(inode) <= a->bdst) -+ h_inode = au_h_iptr(inode, a->bdst); -+ if (!h_inode || !h_inode->i_nlink) { -+ /* copyup src_dentry as the name of dentry. */ -+ bend = au_dbend(dentry); -+ if (bend < a->bsrc) -+ au_set_dbend(dentry, a->bsrc); -+ au_set_h_dptr(dentry, a->bsrc, -+ dget(au_h_dptr(src_dentry, a->bsrc))); -+ dget(a->h_path.dentry); -+ au_set_h_dptr(dentry, a->bdst, NULL); -+ AuDbg("temporary d_inode...\n"); -+ spin_lock(&dentry->d_lock); -+ dentry->d_inode = d_inode(src_dentry); /* tmp */ -+ spin_unlock(&dentry->d_lock); -+ h_file = au_h_open_pre(dentry, a->bsrc, /*force_wr*/0); -+ if (IS_ERR(h_file)) -+ err = PTR_ERR(h_file); -+ else { -+ struct au_cp_generic cpg = { -+ .dentry = dentry, -+ .bdst = a->bdst, -+ .bsrc = -1, -+ .len = -1, -+ .pin = &a->pin, -+ .flags = AuCpup_KEEPLINO -+ }; -+ err = au_sio_cpup_simple(&cpg); -+ au_h_open_post(dentry, a->bsrc, h_file); -+ if (!err) { -+ dput(a->h_path.dentry); -+ a->h_path.dentry = au_h_dptr(dentry, a->bdst); -+ } else -+ au_set_h_dptr(dentry, a->bdst, -+ a->h_path.dentry); -+ } -+ spin_lock(&dentry->d_lock); -+ dentry->d_inode = NULL; /* restore */ -+ spin_unlock(&dentry->d_lock); -+ AuDbg("temporary d_inode...done\n"); -+ au_set_h_dptr(dentry, a->bsrc, NULL); -+ au_set_dbend(dentry, bend); -+ } else { -+ /* the inode of src_dentry already exists on a.bdst branch */ -+ h_src_dentry = d_find_alias(h_inode); -+ if (!h_src_dentry && au_plink_test(inode)) { -+ plink = 1; -+ h_src_dentry = au_plink_lkup(inode, a->bdst); -+ err = PTR_ERR(h_src_dentry); -+ if (IS_ERR(h_src_dentry)) -+ goto out; -+ -+ if (unlikely(d_is_negative(h_src_dentry))) { -+ dput(h_src_dentry); -+ h_src_dentry = NULL; -+ } -+ -+ } -+ if (h_src_dentry) { -+ delegated = NULL; -+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin), -+ &a->h_path, &delegated); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal link\n"); -+ iput(delegated); -+ } -+ dput(h_src_dentry); -+ } else { -+ AuIOErr("no dentry found for hi%lu on b%d\n", -+ h_inode->i_ino, a->bdst); -+ err = -EIO; -+ } -+ } -+ -+ if (!err && !plink) -+ au_plink_append(inode, a->bdst, a->h_path.dentry); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int aufs_link(struct dentry *src_dentry, struct inode *dir, -+ struct dentry *dentry) -+{ -+ int err, rerr; -+ struct au_dtime dt; -+ struct au_link_args *a; -+ struct dentry *wh_dentry, *h_src_dentry; -+ struct inode *inode, *delegated; -+ struct super_block *sb; -+ struct au_wr_dir_args wr_dir_args = { -+ /* .force_btgt = -1, */ -+ .flags = AuWrDir_ADD_ENTRY -+ }; -+ -+ IMustLock(dir); -+ inode = d_inode(src_dentry); -+ IMustLock(inode); -+ -+ err = -ENOMEM; -+ a = kzalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ a->parent = dentry->d_parent; /* dir inode is locked */ -+ err = aufs_read_and_write_lock2(dentry, src_dentry, -+ AuLock_NOPLM | AuLock_GEN); -+ if (unlikely(err)) -+ goto out_kfree; -+ err = au_d_linkable(src_dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ err = au_d_may_add(dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ -+ a->src_parent = dget_parent(src_dentry); -+ wr_dir_args.force_btgt = au_ibstart(inode); -+ -+ di_write_lock_parent(a->parent); -+ wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt); -+ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin, -+ &wr_dir_args); -+ err = PTR_ERR(wh_dentry); -+ if (IS_ERR(wh_dentry)) -+ goto out_parent; -+ -+ err = 0; -+ sb = dentry->d_sb; -+ a->bdst = au_dbstart(dentry); -+ a->h_path.dentry = au_h_dptr(dentry, a->bdst); -+ a->h_path.mnt = au_sbr_mnt(sb, a->bdst); -+ a->bsrc = au_ibstart(inode); -+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc); -+ if (!h_src_dentry && au_di(src_dentry)->di_tmpfile) -+ h_src_dentry = dget(au_hi_wh(inode, a->bsrc)); -+ if (!h_src_dentry) { -+ a->bsrc = au_dbstart(src_dentry); -+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc); -+ AuDebugOn(!h_src_dentry); -+ } else if (IS_ERR(h_src_dentry)) { -+ err = PTR_ERR(h_src_dentry); -+ goto out_parent; -+ } -+ -+ if (au_opt_test(au_mntflags(sb), PLINK)) { -+ if (a->bdst < a->bsrc -+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) -+ err = au_cpup_or_link(src_dentry, dentry, a); -+ else { -+ delegated = NULL; -+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin), -+ &a->h_path, &delegated); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal link\n"); -+ iput(delegated); -+ } -+ } -+ dput(h_src_dentry); -+ } else { -+ /* -+ * copyup src_dentry to the branch we process, -+ * and then link(2) to it. -+ */ -+ dput(h_src_dentry); -+ if (a->bdst < a->bsrc -+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) { -+ au_unpin(&a->pin); -+ di_write_unlock(a->parent); -+ err = au_cpup_before_link(src_dentry, a); -+ di_write_lock_parent(a->parent); -+ if (!err) -+ err = au_pin(&a->pin, dentry, a->bdst, -+ au_opt_udba(sb), -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (unlikely(err)) -+ goto out_wh; -+ } -+ if (!err) { -+ h_src_dentry = au_h_dptr(src_dentry, a->bdst); -+ err = -ENOENT; -+ if (h_src_dentry && d_is_positive(h_src_dentry)) { -+ delegated = NULL; -+ err = vfsub_link(h_src_dentry, -+ au_pinned_h_dir(&a->pin), -+ &a->h_path, &delegated); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry" -+ " for NFSv4 delegation" -+ " for an internal link\n"); -+ iput(delegated); -+ } -+ } -+ } -+ } -+ if (unlikely(err)) -+ goto out_unpin; -+ -+ if (wh_dentry) { -+ a->h_path.dentry = wh_dentry; -+ err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path, -+ dentry); -+ if (unlikely(err)) -+ goto out_revert; -+ } -+ -+ au_dir_ts(dir, a->bdst); -+ dir->i_version++; -+ inc_nlink(inode); -+ inode->i_ctime = dir->i_ctime; -+ d_instantiate(dentry, au_igrab(inode)); -+ if (d_unhashed(a->h_path.dentry)) -+ /* some filesystem calls d_drop() */ -+ d_drop(dentry); -+ /* some filesystems consume an inode even hardlink */ -+ au_fhsm_wrote(sb, a->bdst, /*force*/0); -+ goto out_unpin; /* success */ -+ -+out_revert: -+ /* no delegation since it is just created */ -+ rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path, -+ /*delegated*/NULL, /*force*/0); -+ if (unlikely(rerr)) { -+ AuIOErr("%pd reverting failed(%d, %d)\n", dentry, err, rerr); -+ err = -EIO; -+ } -+ au_dtime_revert(&dt); -+out_unpin: -+ au_unpin(&a->pin); -+out_wh: -+ dput(wh_dentry); -+out_parent: -+ di_write_unlock(a->parent); -+ dput(a->src_parent); -+out_unlock: -+ if (unlikely(err)) { -+ au_update_dbstart(dentry); -+ d_drop(dentry); -+ } -+ aufs_read_and_write_unlock2(dentry, src_dentry); -+out_kfree: -+ kfree(a); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) -+{ -+ int err, rerr; -+ aufs_bindex_t bindex; -+ unsigned char diropq; -+ struct path h_path; -+ struct dentry *wh_dentry, *parent, *opq_dentry; -+ struct mutex *h_mtx; -+ struct super_block *sb; -+ struct { -+ struct au_pin pin; -+ struct au_dtime dt; -+ } *a; /* reduce the stack usage */ -+ struct au_wr_dir_args wr_dir_args = { -+ .force_btgt = -1, -+ .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR -+ }; -+ -+ IMustLock(dir); -+ -+ err = -ENOMEM; -+ a = kmalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN); -+ if (unlikely(err)) -+ goto out_free; -+ err = au_d_may_add(dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ -+ parent = dentry->d_parent; /* dir inode is locked */ -+ di_write_lock_parent(parent); -+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL, -+ &a->pin, &wr_dir_args); -+ err = PTR_ERR(wh_dentry); -+ if (IS_ERR(wh_dentry)) -+ goto out_parent; -+ -+ sb = dentry->d_sb; -+ bindex = au_dbstart(dentry); -+ h_path.dentry = au_h_dptr(dentry, bindex); -+ h_path.mnt = au_sbr_mnt(sb, bindex); -+ err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode); -+ if (unlikely(err)) -+ goto out_unpin; -+ -+ /* make the dir opaque */ -+ diropq = 0; -+ h_mtx = &d_inode(h_path.dentry)->i_mutex; -+ if (wh_dentry -+ || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) { -+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); -+ opq_dentry = au_diropq_create(dentry, bindex); -+ mutex_unlock(h_mtx); -+ err = PTR_ERR(opq_dentry); -+ if (IS_ERR(opq_dentry)) -+ goto out_dir; -+ dput(opq_dentry); -+ diropq = 1; -+ } -+ -+ err = epilog(dir, bindex, wh_dentry, dentry); -+ if (!err) { -+ inc_nlink(dir); -+ goto out_unpin; /* success */ -+ } -+ -+ /* revert */ -+ if (diropq) { -+ AuLabel(revert opq); -+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); -+ rerr = au_diropq_remove(dentry, bindex); -+ mutex_unlock(h_mtx); -+ if (rerr) { -+ AuIOErr("%pd reverting diropq failed(%d, %d)\n", -+ dentry, err, rerr); -+ err = -EIO; -+ } -+ } -+ -+out_dir: -+ AuLabel(revert dir); -+ rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path); -+ if (rerr) { -+ AuIOErr("%pd reverting dir failed(%d, %d)\n", -+ dentry, err, rerr); -+ err = -EIO; -+ } -+ au_dtime_revert(&a->dt); -+out_unpin: -+ au_unpin(&a->pin); -+ dput(wh_dentry); -+out_parent: -+ di_write_unlock(parent); -+out_unlock: -+ if (unlikely(err)) { -+ au_update_dbstart(dentry); -+ d_drop(dentry); -+ } -+ aufs_read_unlock(dentry, AuLock_DW); -+out_free: -+ kfree(a); -+out: -+ return err; -+} -diff --git a/fs/aufs/i_op_del.c b/fs/aufs/i_op_del.c -new file mode 100644 -index 0000000..3cd4c7b ---- /dev/null -+++ b/fs/aufs/i_op_del.c +diff -Nurp linux-4.4.3/fs/aufs/i_op_del.c linux-4.4.3-aufs/fs/aufs/i_op_del.c +--- linux-4.4.3/fs/aufs/i_op_del.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/i_op_del.c 2016-03-02 17:59:37.368498738 +0200 @@ -0,0 +1,497 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -17377,14 +18793,12 @@ index 0000000..3cd4c7b + AuTraceErr(err); + return err; +} -diff --git a/fs/aufs/i_op_ren.c b/fs/aufs/i_op_ren.c -new file mode 100644 -index 0000000..fd815fd ---- /dev/null -+++ b/fs/aufs/i_op_ren.c +diff -Nurp linux-4.4.3/fs/aufs/i_op_ren.c linux-4.4.3-aufs/fs/aufs/i_op_ren.c +--- linux-4.4.3/fs/aufs/i_op_ren.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/i_op_ren.c 2016-03-02 17:59:37.368498738 +0200 @@ -0,0 +1,1002 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -18385,1695 +19799,201 @@ index 0000000..fd815fd + AuTraceErr(err); + return err; +} -diff --git a/fs/aufs/iinfo.c b/fs/aufs/iinfo.c -new file mode 100644 -index 0000000..c604f69 ---- /dev/null -+++ b/fs/aufs/iinfo.c -@@ -0,0 +1,264 @@ -+/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima -+ */ -+ -+/* -+ * inode private data -+ */ -+ -+#include "aufs.h" -+ -+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex) -+{ -+ struct inode *h_inode; -+ -+ IiMustAnyLock(inode); -+ -+ h_inode = au_ii(inode)->ii_hinode[0 + bindex].hi_inode; -+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0); -+ return h_inode; -+} -+ -+/* todo: hard/soft set? */ -+void au_hiput(struct au_hinode *hinode) -+{ -+ au_hn_free(hinode); -+ dput(hinode->hi_whdentry); -+ iput(hinode->hi_inode); -+} -+ -+unsigned int au_hi_flags(struct inode *inode, int isdir) -+{ -+ unsigned int flags; -+ const unsigned int mnt_flags = au_mntflags(inode->i_sb); -+ -+ flags = 0; -+ if (au_opt_test(mnt_flags, XINO)) -+ au_fset_hi(flags, XINO); -+ if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY)) -+ au_fset_hi(flags, HNOTIFY); -+ return flags; -+} -+ -+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex, -+ struct inode *h_inode, unsigned int flags) -+{ -+ struct au_hinode *hinode; -+ struct inode *hi; -+ struct au_iinfo *iinfo = au_ii(inode); -+ -+ IiMustWriteLock(inode); -+ -+ hinode = iinfo->ii_hinode + bindex; -+ hi = hinode->hi_inode; -+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0); -+ -+ if (hi) -+ au_hiput(hinode); -+ hinode->hi_inode = h_inode; -+ if (h_inode) { -+ int err; -+ struct super_block *sb = inode->i_sb; -+ struct au_branch *br; -+ -+ AuDebugOn(inode->i_mode -+ && (h_inode->i_mode & S_IFMT) -+ != (inode->i_mode & S_IFMT)); -+ if (bindex == iinfo->ii_bstart) -+ au_cpup_igen(inode, h_inode); -+ br = au_sbr(sb, bindex); -+ hinode->hi_id = br->br_id; -+ if (au_ftest_hi(flags, XINO)) { -+ err = au_xino_write(sb, bindex, h_inode->i_ino, -+ inode->i_ino); -+ if (unlikely(err)) -+ AuIOErr1("failed au_xino_write() %d\n", err); -+ } -+ -+ if (au_ftest_hi(flags, HNOTIFY) -+ && au_br_hnotifyable(br->br_perm)) { -+ err = au_hn_alloc(hinode, inode); -+ if (unlikely(err)) -+ AuIOErr1("au_hn_alloc() %d\n", err); -+ } -+ } -+} -+ -+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex, -+ struct dentry *h_wh) -+{ -+ struct au_hinode *hinode; -+ -+ IiMustWriteLock(inode); -+ -+ hinode = au_ii(inode)->ii_hinode + bindex; -+ AuDebugOn(hinode->hi_whdentry); -+ hinode->hi_whdentry = h_wh; -+} -+ -+void au_update_iigen(struct inode *inode, int half) -+{ -+ struct au_iinfo *iinfo; -+ struct au_iigen *iigen; -+ unsigned int sigen; -+ -+ sigen = au_sigen(inode->i_sb); -+ iinfo = au_ii(inode); -+ iigen = &iinfo->ii_generation; -+ spin_lock(&iigen->ig_spin); -+ iigen->ig_generation = sigen; -+ if (half) -+ au_ig_fset(iigen->ig_flags, HALF_REFRESHED); -+ else -+ au_ig_fclr(iigen->ig_flags, HALF_REFRESHED); -+ spin_unlock(&iigen->ig_spin); -+} -+ -+/* it may be called at remount time, too */ -+void au_update_ibrange(struct inode *inode, int do_put_zero) -+{ -+ struct au_iinfo *iinfo; -+ aufs_bindex_t bindex, bend; -+ -+ iinfo = au_ii(inode); -+ if (!iinfo) -+ return; -+ -+ IiMustWriteLock(inode); -+ -+ if (do_put_zero && iinfo->ii_bstart >= 0) { -+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; -+ bindex++) { -+ struct inode *h_i; -+ -+ h_i = iinfo->ii_hinode[0 + bindex].hi_inode; -+ if (h_i -+ && !h_i->i_nlink -+ && !(h_i->i_state & I_LINKABLE)) -+ au_set_h_iptr(inode, bindex, NULL, 0); -+ } -+ } -+ -+ iinfo->ii_bstart = -1; -+ iinfo->ii_bend = -1; -+ bend = au_sbend(inode->i_sb); -+ for (bindex = 0; bindex <= bend; bindex++) -+ if (iinfo->ii_hinode[0 + bindex].hi_inode) { -+ iinfo->ii_bstart = bindex; -+ break; -+ } -+ if (iinfo->ii_bstart >= 0) -+ for (bindex = bend; bindex >= iinfo->ii_bstart; bindex--) -+ if (iinfo->ii_hinode[0 + bindex].hi_inode) { -+ iinfo->ii_bend = bindex; -+ break; -+ } -+ AuDebugOn(iinfo->ii_bstart > iinfo->ii_bend); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_icntnr_init_once(void *_c) -+{ -+ struct au_icntnr *c = _c; -+ struct au_iinfo *iinfo = &c->iinfo; -+ static struct lock_class_key aufs_ii; -+ -+ spin_lock_init(&iinfo->ii_generation.ig_spin); -+ au_rw_init(&iinfo->ii_rwsem); -+ au_rw_class(&iinfo->ii_rwsem, &aufs_ii); -+ inode_init_once(&c->vfs_inode); -+} -+ -+int au_iinfo_init(struct inode *inode) -+{ -+ struct au_iinfo *iinfo; -+ struct super_block *sb; -+ int nbr, i; -+ -+ sb = inode->i_sb; -+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo); -+ nbr = au_sbend(sb) + 1; -+ if (unlikely(nbr <= 0)) -+ nbr = 1; -+ iinfo->ii_hinode = kcalloc(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS); -+ if (iinfo->ii_hinode) { -+ au_ninodes_inc(sb); -+ for (i = 0; i < nbr; i++) -+ iinfo->ii_hinode[i].hi_id = -1; -+ -+ iinfo->ii_generation.ig_generation = au_sigen(sb); -+ iinfo->ii_bstart = -1; -+ iinfo->ii_bend = -1; -+ iinfo->ii_vdir = NULL; -+ return 0; -+ } -+ return -ENOMEM; -+} -+ -+int au_ii_realloc(struct au_iinfo *iinfo, int nbr) -+{ -+ int err, sz; -+ struct au_hinode *hip; -+ -+ AuRwMustWriteLock(&iinfo->ii_rwsem); -+ -+ err = -ENOMEM; -+ sz = sizeof(*hip) * (iinfo->ii_bend + 1); -+ if (!sz) -+ sz = sizeof(*hip); -+ hip = au_kzrealloc(iinfo->ii_hinode, sz, sizeof(*hip) * nbr, GFP_NOFS); -+ if (hip) { -+ iinfo->ii_hinode = hip; -+ err = 0; -+ } -+ -+ return err; -+} -+ -+void au_iinfo_fin(struct inode *inode) -+{ -+ struct au_iinfo *iinfo; -+ struct au_hinode *hi; -+ struct super_block *sb; -+ aufs_bindex_t bindex, bend; -+ const unsigned char unlinked = !inode->i_nlink; -+ -+ iinfo = au_ii(inode); -+ /* bad_inode case */ -+ if (!iinfo) -+ return; -+ -+ sb = inode->i_sb; -+ au_ninodes_dec(sb); -+ if (si_pid_test(sb)) -+ au_xino_delete_inode(inode, unlinked); -+ else { -+ /* -+ * it is safe to hide the dependency between sbinfo and -+ * sb->s_umount. -+ */ -+ lockdep_off(); -+ si_noflush_read_lock(sb); -+ au_xino_delete_inode(inode, unlinked); -+ si_read_unlock(sb); -+ lockdep_on(); -+ } -+ -+ if (iinfo->ii_vdir) -+ au_vdir_free(iinfo->ii_vdir); -+ -+ bindex = iinfo->ii_bstart; -+ if (bindex >= 0) { -+ hi = iinfo->ii_hinode + bindex; -+ bend = iinfo->ii_bend; -+ while (bindex++ <= bend) { -+ if (hi->hi_inode) -+ au_hiput(hi); -+ hi++; -+ } -+ } -+ kfree(iinfo->ii_hinode); -+ iinfo->ii_hinode = NULL; -+ AuRwDestroy(&iinfo->ii_rwsem); -+} -diff --git a/fs/aufs/inode.c b/fs/aufs/inode.c -new file mode 100644 -index 0000000..6db3d6f ---- /dev/null -+++ b/fs/aufs/inode.c -@@ -0,0 +1,515 @@ -+/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima -+ */ -+ -+/* -+ * inode functions -+ */ -+ -+#include "aufs.h" -+ -+struct inode *au_igrab(struct inode *inode) -+{ -+ if (inode) { -+ AuDebugOn(!atomic_read(&inode->i_count)); -+ ihold(inode); -+ } -+ return inode; -+} -+ -+static void au_refresh_hinode_attr(struct inode *inode, int do_version) -+{ -+ au_cpup_attr_all(inode, /*force*/0); -+ au_update_iigen(inode, /*half*/1); -+ if (do_version) -+ inode->i_version++; -+} -+ -+static int au_ii_refresh(struct inode *inode, int *update) -+{ -+ int err, e; -+ umode_t type; -+ aufs_bindex_t bindex, new_bindex; -+ struct super_block *sb; -+ struct au_iinfo *iinfo; -+ struct au_hinode *p, *q, tmp; -+ -+ IiMustWriteLock(inode); -+ -+ *update = 0; -+ sb = inode->i_sb; -+ type = inode->i_mode & S_IFMT; -+ iinfo = au_ii(inode); -+ err = au_ii_realloc(iinfo, au_sbend(sb) + 1); -+ if (unlikely(err)) -+ goto out; -+ -+ AuDebugOn(iinfo->ii_bstart < 0); -+ p = iinfo->ii_hinode + iinfo->ii_bstart; -+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; -+ bindex++, p++) { -+ if (!p->hi_inode) -+ continue; -+ -+ AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT)); -+ new_bindex = au_br_index(sb, p->hi_id); -+ if (new_bindex == bindex) -+ continue; -+ -+ if (new_bindex < 0) { -+ *update = 1; -+ au_hiput(p); -+ p->hi_inode = NULL; -+ continue; -+ } -+ -+ if (new_bindex < iinfo->ii_bstart) -+ iinfo->ii_bstart = new_bindex; -+ if (iinfo->ii_bend < new_bindex) -+ iinfo->ii_bend = new_bindex; -+ /* swap two lower inode, and loop again */ -+ q = iinfo->ii_hinode + new_bindex; -+ tmp = *q; -+ *q = *p; -+ *p = tmp; -+ if (tmp.hi_inode) { -+ bindex--; -+ p--; -+ } -+ } -+ au_update_ibrange(inode, /*do_put_zero*/0); -+ e = au_dy_irefresh(inode); -+ if (unlikely(e && !err)) -+ err = e; -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+void au_refresh_iop(struct inode *inode, int force_getattr) -+{ -+ int type; -+ struct au_sbinfo *sbi = au_sbi(inode->i_sb); -+ const struct inode_operations *iop -+ = force_getattr ? aufs_iop : sbi->si_iop_array; -+ -+ if (inode->i_op == iop) -+ return; -+ -+ switch (inode->i_mode & S_IFMT) { -+ case S_IFDIR: -+ type = AuIop_DIR; -+ break; -+ case S_IFLNK: -+ type = AuIop_SYMLINK; -+ break; -+ default: -+ type = AuIop_OTHER; -+ break; -+ } -+ -+ inode->i_op = iop + type; -+ /* unnecessary smp_wmb() */ -+} -+ -+int au_refresh_hinode_self(struct inode *inode) -+{ -+ int err, update; -+ -+ err = au_ii_refresh(inode, &update); -+ if (!err) -+ au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode)); -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_refresh_hinode(struct inode *inode, struct dentry *dentry) -+{ -+ int err, e, update; -+ unsigned int flags; -+ umode_t mode; -+ aufs_bindex_t bindex, bend; -+ unsigned char isdir; -+ struct au_hinode *p; -+ struct au_iinfo *iinfo; -+ -+ err = au_ii_refresh(inode, &update); -+ if (unlikely(err)) -+ goto out; -+ -+ update = 0; -+ iinfo = au_ii(inode); -+ p = iinfo->ii_hinode + iinfo->ii_bstart; -+ mode = (inode->i_mode & S_IFMT); -+ isdir = S_ISDIR(mode); -+ flags = au_hi_flags(inode, isdir); -+ bend = au_dbend(dentry); -+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) { -+ struct inode *h_i, *h_inode; -+ struct dentry *h_d; -+ -+ h_d = au_h_dptr(dentry, bindex); -+ if (!h_d || d_is_negative(h_d)) -+ continue; -+ -+ h_inode = d_inode(h_d); -+ AuDebugOn(mode != (h_inode->i_mode & S_IFMT)); -+ if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) { -+ h_i = au_h_iptr(inode, bindex); -+ if (h_i) { -+ if (h_i == h_inode) -+ continue; -+ err = -EIO; -+ break; -+ } -+ } -+ if (bindex < iinfo->ii_bstart) -+ iinfo->ii_bstart = bindex; -+ if (iinfo->ii_bend < bindex) -+ iinfo->ii_bend = bindex; -+ au_set_h_iptr(inode, bindex, au_igrab(h_inode), flags); -+ update = 1; -+ } -+ au_update_ibrange(inode, /*do_put_zero*/0); -+ e = au_dy_irefresh(inode); -+ if (unlikely(e && !err)) -+ err = e; -+ if (!err) -+ au_refresh_hinode_attr(inode, update && isdir); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int set_inode(struct inode *inode, struct dentry *dentry) -+{ -+ int err; -+ unsigned int flags; -+ umode_t mode; -+ aufs_bindex_t bindex, bstart, btail; -+ unsigned char isdir; -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ struct au_iinfo *iinfo; -+ struct inode_operations *iop; -+ -+ IiMustWriteLock(inode); -+ -+ err = 0; -+ isdir = 0; -+ iop = au_sbi(inode->i_sb)->si_iop_array; -+ bstart = au_dbstart(dentry); -+ h_dentry = au_h_dptr(dentry, bstart); -+ h_inode = d_inode(h_dentry); -+ mode = h_inode->i_mode; -+ switch (mode & S_IFMT) { -+ case S_IFREG: -+ btail = au_dbtail(dentry); -+ inode->i_op = iop + AuIop_OTHER; -+ inode->i_fop = &aufs_file_fop; -+ err = au_dy_iaop(inode, bstart, h_inode); -+ if (unlikely(err)) -+ goto out; -+ break; -+ case S_IFDIR: -+ isdir = 1; -+ btail = au_dbtaildir(dentry); -+ inode->i_op = iop + AuIop_DIR; -+ inode->i_fop = &aufs_dir_fop; -+ break; -+ case S_IFLNK: -+ btail = au_dbtail(dentry); -+ inode->i_op = iop + AuIop_SYMLINK; -+ break; -+ case S_IFBLK: -+ case S_IFCHR: -+ case S_IFIFO: -+ case S_IFSOCK: -+ btail = au_dbtail(dentry); -+ inode->i_op = iop + AuIop_OTHER; -+ init_special_inode(inode, mode, h_inode->i_rdev); -+ break; -+ default: -+ AuIOErr("Unknown file type 0%o\n", mode); -+ err = -EIO; -+ goto out; -+ } -+ -+ /* do not set hnotify for whiteouted dirs (SHWH mode) */ -+ flags = au_hi_flags(inode, isdir); -+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH) -+ && au_ftest_hi(flags, HNOTIFY) -+ && dentry->d_name.len > AUFS_WH_PFX_LEN -+ && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) -+ au_fclr_hi(flags, HNOTIFY); -+ iinfo = au_ii(inode); -+ iinfo->ii_bstart = bstart; -+ iinfo->ii_bend = btail; -+ for (bindex = bstart; bindex <= btail; bindex++) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (h_dentry) -+ au_set_h_iptr(inode, bindex, -+ au_igrab(d_inode(h_dentry)), flags); -+ } -+ au_cpup_attr_all(inode, /*force*/1); -+ /* -+ * to force calling aufs_get_acl() every time, -+ * do not call cache_no_acl() for aufs inode. -+ */ -+ -+out: -+ return err; -+} -+ -+/* -+ * successful returns with iinfo write_locked -+ * minus: errno -+ * zero: success, matched -+ * plus: no error, but unmatched -+ */ -+static int reval_inode(struct inode *inode, struct dentry *dentry) -+{ -+ int err; -+ unsigned int gen; -+ struct au_iigen iigen; -+ aufs_bindex_t bindex, bend; -+ struct inode *h_inode, *h_dinode; -+ struct dentry *h_dentry; -+ -+ /* -+ * before this function, if aufs got any iinfo lock, it must be only -+ * one, the parent dir. -+ * it can happen by UDBA and the obsoleted inode number. -+ */ -+ err = -EIO; -+ if (unlikely(inode->i_ino == parent_ino(dentry))) -+ goto out; -+ -+ err = 1; -+ ii_write_lock_new_child(inode); -+ h_dentry = au_h_dptr(dentry, au_dbstart(dentry)); -+ h_dinode = d_inode(h_dentry); -+ bend = au_ibend(inode); -+ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) { -+ h_inode = au_h_iptr(inode, bindex); -+ if (!h_inode || h_inode != h_dinode) -+ continue; -+ -+ err = 0; -+ gen = au_iigen(inode, &iigen); -+ if (gen == au_digen(dentry) -+ && !au_ig_ftest(iigen.ig_flags, HALF_REFRESHED)) -+ break; -+ -+ /* fully refresh inode using dentry */ -+ err = au_refresh_hinode(inode, dentry); -+ if (!err) -+ au_update_iigen(inode, /*half*/0); -+ break; -+ } -+ -+ if (unlikely(err)) -+ ii_write_unlock(inode); -+out: -+ return err; -+} -+ -+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ unsigned int d_type, ino_t *ino) -+{ -+ int err; -+ struct mutex *mtx; -+ -+ /* prevent hardlinked inode number from race condition */ -+ mtx = NULL; -+ if (d_type != DT_DIR) { -+ mtx = &au_sbr(sb, bindex)->br_xino.xi_nondir_mtx; -+ mutex_lock(mtx); -+ } -+ err = au_xino_read(sb, bindex, h_ino, ino); -+ if (unlikely(err)) -+ goto out; -+ -+ if (!*ino) { -+ err = -EIO; -+ *ino = au_xino_new_ino(sb); -+ if (unlikely(!*ino)) -+ goto out; -+ err = au_xino_write(sb, bindex, h_ino, *ino); -+ if (unlikely(err)) -+ goto out; -+ } -+ -+out: -+ if (mtx) -+ mutex_unlock(mtx); -+ return err; -+} -+ -+/* successful returns with iinfo write_locked */ -+/* todo: return with unlocked? */ -+struct inode *au_new_inode(struct dentry *dentry, int must_new) -+{ -+ struct inode *inode, *h_inode; -+ struct dentry *h_dentry; -+ struct super_block *sb; -+ struct mutex *mtx; -+ ino_t h_ino, ino; -+ int err; -+ aufs_bindex_t bstart; -+ -+ sb = dentry->d_sb; -+ bstart = au_dbstart(dentry); -+ h_dentry = au_h_dptr(dentry, bstart); -+ h_inode = d_inode(h_dentry); -+ h_ino = h_inode->i_ino; -+ -+ /* -+ * stop 'race'-ing between hardlinks under different -+ * parents. -+ */ -+ mtx = NULL; -+ if (!d_is_dir(h_dentry)) -+ mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx; -+ -+new_ino: -+ if (mtx) -+ mutex_lock(mtx); -+ err = au_xino_read(sb, bstart, h_ino, &ino); -+ inode = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out; -+ -+ if (!ino) { -+ ino = au_xino_new_ino(sb); -+ if (unlikely(!ino)) { -+ inode = ERR_PTR(-EIO); -+ goto out; -+ } -+ } -+ -+ AuDbg("i%lu\n", (unsigned long)ino); -+ inode = au_iget_locked(sb, ino); -+ err = PTR_ERR(inode); -+ if (IS_ERR(inode)) -+ goto out; -+ -+ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW)); -+ if (inode->i_state & I_NEW) { -+ /* verbose coding for lock class name */ -+ if (unlikely(d_is_symlink(h_dentry))) -+ au_rw_class(&au_ii(inode)->ii_rwsem, -+ au_lc_key + AuLcSymlink_IIINFO); -+ else if (unlikely(d_is_dir(h_dentry))) -+ au_rw_class(&au_ii(inode)->ii_rwsem, -+ au_lc_key + AuLcDir_IIINFO); -+ else /* likely */ -+ au_rw_class(&au_ii(inode)->ii_rwsem, -+ au_lc_key + AuLcNonDir_IIINFO); -+ -+ ii_write_lock_new_child(inode); -+ err = set_inode(inode, dentry); -+ if (!err) { -+ unlock_new_inode(inode); -+ goto out; /* success */ -+ } -+ -+ /* -+ * iget_failed() calls iput(), but we need to call -+ * ii_write_unlock() after iget_failed(). so dirty hack for -+ * i_count. -+ */ -+ atomic_inc(&inode->i_count); -+ iget_failed(inode); -+ ii_write_unlock(inode); -+ au_xino_write(sb, bstart, h_ino, /*ino*/0); -+ /* ignore this error */ -+ goto out_iput; -+ } else if (!must_new && !IS_DEADDIR(inode) && inode->i_nlink) { -+ /* -+ * horrible race condition between lookup, readdir and copyup -+ * (or something). -+ */ -+ if (mtx) -+ mutex_unlock(mtx); -+ err = reval_inode(inode, dentry); -+ if (unlikely(err < 0)) { -+ mtx = NULL; -+ goto out_iput; -+ } -+ -+ if (!err) { -+ mtx = NULL; -+ goto out; /* success */ -+ } else if (mtx) -+ mutex_lock(mtx); -+ } -+ -+ if (unlikely(au_test_fs_unique_ino(h_inode))) -+ AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir," -+ " b%d, %s, %pd, hi%lu, i%lu.\n", -+ bstart, au_sbtype(h_dentry->d_sb), dentry, -+ (unsigned long)h_ino, (unsigned long)ino); -+ ino = 0; -+ err = au_xino_write(sb, bstart, h_ino, /*ino*/0); -+ if (!err) { -+ iput(inode); -+ if (mtx) -+ mutex_unlock(mtx); -+ goto new_ino; -+ } -+ -+out_iput: -+ iput(inode); -+ inode = ERR_PTR(err); -+out: -+ if (mtx) -+ mutex_unlock(mtx); -+ return inode; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex, -+ struct inode *inode) -+{ -+ int err; -+ struct inode *hi; -+ -+ err = au_br_rdonly(au_sbr(sb, bindex)); -+ -+ /* pseudo-link after flushed may happen out of bounds */ -+ if (!err -+ && inode -+ && au_ibstart(inode) <= bindex -+ && bindex <= au_ibend(inode)) { -+ /* -+ * permission check is unnecessary since vfsub routine -+ * will be called later -+ */ -+ hi = au_h_iptr(inode, bindex); -+ if (hi) -+ err = IS_IMMUTABLE(hi) ? -EROFS : 0; -+ } -+ -+ return err; -+} -+ -+int au_test_h_perm(struct inode *h_inode, int mask) -+{ -+ if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) -+ return 0; -+ return inode_permission(h_inode, mask); -+} -+ -+int au_test_h_perm_sio(struct inode *h_inode, int mask) -+{ -+ if (au_test_nfs(h_inode->i_sb) -+ && (mask & MAY_WRITE) -+ && S_ISDIR(h_inode->i_mode)) -+ mask |= MAY_READ; /* force permission check */ -+ return au_test_h_perm(h_inode, mask); -+} -diff --git a/fs/aufs/inode.h b/fs/aufs/inode.h -new file mode 100644 -index 0000000..31e31f4 ---- /dev/null -+++ b/fs/aufs/inode.h -@@ -0,0 +1,672 @@ -+/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima -+ */ -+ -+/* -+ * inode operations -+ */ -+ -+#ifndef __AUFS_INODE_H__ -+#define __AUFS_INODE_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include "rwsem.h" -+ -+struct vfsmount; -+ -+struct au_hnotify { -+#ifdef CONFIG_AUFS_HNOTIFY -+#ifdef CONFIG_AUFS_HFSNOTIFY -+ /* never use fsnotify_add_vfsmount_mark() */ -+ struct fsnotify_mark hn_mark; -+#endif -+ struct inode *hn_aufs_inode; /* no get/put */ -+#endif -+} ____cacheline_aligned_in_smp; -+ -+struct au_hinode { -+ struct inode *hi_inode; -+ aufs_bindex_t hi_id; -+#ifdef CONFIG_AUFS_HNOTIFY -+ struct au_hnotify *hi_notify; -+#endif -+ -+ /* reference to the copied-up whiteout with get/put */ -+ struct dentry *hi_whdentry; -+}; -+ -+/* ig_flags */ -+#define AuIG_HALF_REFRESHED 1 -+#define au_ig_ftest(flags, name) ((flags) & AuIG_##name) -+#define au_ig_fset(flags, name) \ -+ do { (flags) |= AuIG_##name; } while (0) -+#define au_ig_fclr(flags, name) \ -+ do { (flags) &= ~AuIG_##name; } while (0) -+ -+struct au_iigen { -+ spinlock_t ig_spin; -+ __u32 ig_generation, ig_flags; -+}; -+ -+struct au_vdir; -+struct au_iinfo { -+ struct au_iigen ii_generation; -+ struct super_block *ii_hsb1; /* no get/put */ -+ -+ struct au_rwsem ii_rwsem; -+ aufs_bindex_t ii_bstart, ii_bend; -+ __u32 ii_higen; -+ struct au_hinode *ii_hinode; -+ struct au_vdir *ii_vdir; -+}; -+ -+struct au_icntnr { -+ struct au_iinfo iinfo; -+ struct inode vfs_inode; -+} ____cacheline_aligned_in_smp; -+ -+/* au_pin flags */ -+#define AuPin_DI_LOCKED 1 -+#define AuPin_MNT_WRITE (1 << 1) -+#define au_ftest_pin(flags, name) ((flags) & AuPin_##name) -+#define au_fset_pin(flags, name) \ -+ do { (flags) |= AuPin_##name; } while (0) -+#define au_fclr_pin(flags, name) \ -+ do { (flags) &= ~AuPin_##name; } while (0) -+ -+struct au_pin { -+ /* input */ -+ struct dentry *dentry; -+ unsigned int udba; -+ unsigned char lsc_di, lsc_hi, flags; -+ aufs_bindex_t bindex; -+ -+ /* output */ -+ struct dentry *parent; -+ struct au_hinode *hdir; -+ struct vfsmount *h_mnt; -+ -+ /* temporary unlock/relock for copyup */ -+ struct dentry *h_dentry, *h_parent; -+ struct au_branch *br; -+ struct task_struct *task; -+}; -+ -+void au_pin_hdir_unlock(struct au_pin *p); -+int au_pin_hdir_lock(struct au_pin *p); -+int au_pin_hdir_relock(struct au_pin *p); -+void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task); -+void au_pin_hdir_acquire_nest(struct au_pin *p); -+void au_pin_hdir_release(struct au_pin *p); -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct au_iinfo *au_ii(struct inode *inode) -+{ -+ struct au_iinfo *iinfo; -+ -+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo); -+ if (iinfo->ii_hinode) -+ return iinfo; -+ return NULL; /* debugging bad_inode case */ -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* inode.c */ -+struct inode *au_igrab(struct inode *inode); -+void au_refresh_iop(struct inode *inode, int force_getattr); -+int au_refresh_hinode_self(struct inode *inode); -+int au_refresh_hinode(struct inode *inode, struct dentry *dentry); -+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ unsigned int d_type, ino_t *ino); -+struct inode *au_new_inode(struct dentry *dentry, int must_new); -+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex, -+ struct inode *inode); -+int au_test_h_perm(struct inode *h_inode, int mask); -+int au_test_h_perm_sio(struct inode *h_inode, int mask); -+ -+static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex, -+ ino_t h_ino, unsigned int d_type, ino_t *ino) -+{ -+#ifdef CONFIG_AUFS_SHWH -+ return au_ino(sb, bindex, h_ino, d_type, ino); -+#else -+ return 0; -+#endif -+} -+ -+/* i_op.c */ -+enum { -+ AuIop_SYMLINK, -+ AuIop_DIR, -+ AuIop_OTHER, -+ AuIop_Last -+}; -+extern struct inode_operations aufs_iop[AuIop_Last], -+ aufs_iop_nogetattr[AuIop_Last]; -+ -+/* au_wr_dir flags */ -+#define AuWrDir_ADD_ENTRY 1 -+#define AuWrDir_ISDIR (1 << 1) -+#define AuWrDir_TMPFILE (1 << 2) -+#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name) -+#define au_fset_wrdir(flags, name) \ -+ do { (flags) |= AuWrDir_##name; } while (0) -+#define au_fclr_wrdir(flags, name) \ -+ do { (flags) &= ~AuWrDir_##name; } while (0) -+ -+struct au_wr_dir_args { -+ aufs_bindex_t force_btgt; -+ unsigned char flags; -+}; -+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry, -+ struct au_wr_dir_args *args); -+ -+struct dentry *au_pinned_h_parent(struct au_pin *pin); -+void au_pin_init(struct au_pin *pin, struct dentry *dentry, -+ aufs_bindex_t bindex, int lsc_di, int lsc_hi, -+ unsigned int udba, unsigned char flags); -+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex, -+ unsigned int udba, unsigned char flags) __must_check; -+int au_do_pin(struct au_pin *pin) __must_check; -+void au_unpin(struct au_pin *pin); -+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen); -+ -+#define AuIcpup_DID_CPUP 1 -+#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name) -+#define au_fset_icpup(flags, name) \ -+ do { (flags) |= AuIcpup_##name; } while (0) -+#define au_fclr_icpup(flags, name) \ -+ do { (flags) &= ~AuIcpup_##name; } while (0) -+ -+struct au_icpup_args { -+ unsigned char flags; -+ unsigned char pin_flags; -+ aufs_bindex_t btgt; -+ unsigned int udba; -+ struct au_pin pin; -+ struct path h_path; -+ struct inode *h_inode; -+}; -+ -+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia, -+ struct au_icpup_args *a); -+ -+int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path); -+ -+/* i_op_add.c */ -+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_parent, int isdir); -+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, -+ dev_t dev); -+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname); -+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode, -+ bool want_excl); -+struct vfsub_aopen_args; -+int au_aopen_or_create(struct inode *dir, struct dentry *dentry, -+ struct vfsub_aopen_args *args); -+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode); -+int aufs_link(struct dentry *src_dentry, struct inode *dir, -+ struct dentry *dentry); -+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode); -+ -+/* i_op_del.c */ -+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup); -+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_parent, int isdir); -+int aufs_unlink(struct inode *dir, struct dentry *dentry); -+int aufs_rmdir(struct inode *dir, struct dentry *dentry); -+ -+/* i_op_ren.c */ -+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt); -+int aufs_rename(struct inode *src_dir, struct dentry *src_dentry, -+ struct inode *dir, struct dentry *dentry); -+ -+/* iinfo.c */ -+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex); -+void au_hiput(struct au_hinode *hinode); -+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex, -+ struct dentry *h_wh); -+unsigned int au_hi_flags(struct inode *inode, int isdir); -+ -+/* hinode flags */ -+#define AuHi_XINO 1 -+#define AuHi_HNOTIFY (1 << 1) -+#define au_ftest_hi(flags, name) ((flags) & AuHi_##name) -+#define au_fset_hi(flags, name) \ -+ do { (flags) |= AuHi_##name; } while (0) -+#define au_fclr_hi(flags, name) \ -+ do { (flags) &= ~AuHi_##name; } while (0) -+ -+#ifndef CONFIG_AUFS_HNOTIFY -+#undef AuHi_HNOTIFY -+#define AuHi_HNOTIFY 0 -+#endif -+ -+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex, -+ struct inode *h_inode, unsigned int flags); -+ -+void au_update_iigen(struct inode *inode, int half); -+void au_update_ibrange(struct inode *inode, int do_put_zero); -+ -+void au_icntnr_init_once(void *_c); -+int au_iinfo_init(struct inode *inode); -+void au_iinfo_fin(struct inode *inode); -+int au_ii_realloc(struct au_iinfo *iinfo, int nbr); -+ -+#ifdef CONFIG_PROC_FS -+/* plink.c */ -+int au_plink_maint(struct super_block *sb, int flags); -+struct au_sbinfo; -+void au_plink_maint_leave(struct au_sbinfo *sbinfo); -+int au_plink_maint_enter(struct super_block *sb); -+#ifdef CONFIG_AUFS_DEBUG -+void au_plink_list(struct super_block *sb); -+#else -+AuStubVoid(au_plink_list, struct super_block *sb) -+#endif -+int au_plink_test(struct inode *inode); -+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex); -+void au_plink_append(struct inode *inode, aufs_bindex_t bindex, -+ struct dentry *h_dentry); -+void au_plink_put(struct super_block *sb, int verbose); -+void au_plink_clean(struct super_block *sb, int verbose); -+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id); -+#else -+AuStubInt0(au_plink_maint, struct super_block *sb, int flags); -+AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo); -+AuStubInt0(au_plink_maint_enter, struct super_block *sb); -+AuStubVoid(au_plink_list, struct super_block *sb); -+AuStubInt0(au_plink_test, struct inode *inode); -+AuStub(struct dentry *, au_plink_lkup, return NULL, -+ struct inode *inode, aufs_bindex_t bindex); -+AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex, -+ struct dentry *h_dentry); -+AuStubVoid(au_plink_put, struct super_block *sb, int verbose); -+AuStubVoid(au_plink_clean, struct super_block *sb, int verbose); -+AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id); -+#endif /* CONFIG_PROC_FS */ -+ -+#ifdef CONFIG_AUFS_XATTR -+/* xattr.c */ -+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags, -+ unsigned int verbose); -+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size); -+ssize_t aufs_getxattr(struct dentry *dentry, const char *name, void *value, -+ size_t size); -+int aufs_setxattr(struct dentry *dentry, const char *name, const void *value, -+ size_t size, int flags); -+int aufs_removexattr(struct dentry *dentry, const char *name); -+ -+/* void au_xattr_init(struct super_block *sb); */ -+#else -+AuStubInt0(au_cpup_xattr, struct dentry *h_dst, struct dentry *h_src, -+ int ignore_flags, unsigned int verbose); -+/* AuStubVoid(au_xattr_init, struct super_block *sb); */ -+#endif -+ -+#ifdef CONFIG_FS_POSIX_ACL -+struct posix_acl *aufs_get_acl(struct inode *inode, int type); -+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type); -+#endif -+ -+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL) -+enum { -+ AU_XATTR_SET, -+ AU_XATTR_REMOVE, -+ AU_ACL_SET -+}; -+ -+struct au_srxattr { -+ int type; -+ union { -+ struct { -+ const char *name; -+ const void *value; -+ size_t size; -+ int flags; -+ } set; -+ struct { -+ const char *name; -+ } remove; -+ struct { -+ struct posix_acl *acl; -+ int type; -+ } acl_set; -+ } u; -+}; -+ssize_t au_srxattr(struct dentry *dentry, struct au_srxattr *arg); -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* lock subclass for iinfo */ -+enum { -+ AuLsc_II_CHILD, /* child first */ -+ AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hnotify */ -+ AuLsc_II_CHILD3, /* copyup dirs */ -+ AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */ -+ AuLsc_II_PARENT2, -+ AuLsc_II_PARENT3, /* copyup dirs */ -+ AuLsc_II_NEW_CHILD -+}; -+ -+/* -+ * ii_read_lock_child, ii_write_lock_child, -+ * ii_read_lock_child2, ii_write_lock_child2, -+ * ii_read_lock_child3, ii_write_lock_child3, -+ * ii_read_lock_parent, ii_write_lock_parent, -+ * ii_read_lock_parent2, ii_write_lock_parent2, -+ * ii_read_lock_parent3, ii_write_lock_parent3, -+ * ii_read_lock_new_child, ii_write_lock_new_child, -+ */ -+#define AuReadLockFunc(name, lsc) \ -+static inline void ii_read_lock_##name(struct inode *i) \ -+{ \ -+ au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \ -+} -+ -+#define AuWriteLockFunc(name, lsc) \ -+static inline void ii_write_lock_##name(struct inode *i) \ -+{ \ -+ au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \ -+} -+ -+#define AuRWLockFuncs(name, lsc) \ -+ AuReadLockFunc(name, lsc) \ -+ AuWriteLockFunc(name, lsc) -+ -+AuRWLockFuncs(child, CHILD); -+AuRWLockFuncs(child2, CHILD2); -+AuRWLockFuncs(child3, CHILD3); -+AuRWLockFuncs(parent, PARENT); -+AuRWLockFuncs(parent2, PARENT2); -+AuRWLockFuncs(parent3, PARENT3); -+AuRWLockFuncs(new_child, NEW_CHILD); -+ -+#undef AuReadLockFunc -+#undef AuWriteLockFunc -+#undef AuRWLockFuncs -+ -+/* -+ * ii_read_unlock, ii_write_unlock, ii_downgrade_lock -+ */ -+AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem); -+ -+#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem) -+#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem) -+#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem) -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline void au_icntnr_init(struct au_icntnr *c) -+{ -+#ifdef CONFIG_AUFS_DEBUG -+ c->vfs_inode.i_mode = 0; -+#endif -+} -+ -+static inline unsigned int au_iigen(struct inode *inode, struct au_iigen *iigen_arg) -+{ -+ unsigned int gen; -+ struct au_iinfo *iinfo; -+ struct au_iigen *iigen; -+ -+ iinfo = au_ii(inode); -+ iigen = &iinfo->ii_generation; -+ spin_lock(&iigen->ig_spin); -+ if (iigen_arg) -+ *iigen_arg = *iigen; -+ gen = iigen->ig_generation; -+ spin_unlock(&iigen->ig_spin); -+ -+ return gen; -+} -+ -+/* tiny test for inode number */ -+/* tmpfs generation is too rough */ -+static inline int au_test_higen(struct inode *inode, struct inode *h_inode) -+{ -+ struct au_iinfo *iinfo; -+ -+ iinfo = au_ii(inode); -+ AuRwMustAnyLock(&iinfo->ii_rwsem); -+ return !(iinfo->ii_hsb1 == h_inode->i_sb -+ && iinfo->ii_higen == h_inode->i_generation); -+} -+ -+static inline void au_iigen_dec(struct inode *inode) -+{ -+ struct au_iinfo *iinfo; -+ struct au_iigen *iigen; -+ -+ iinfo = au_ii(inode); -+ iigen = &iinfo->ii_generation; -+ spin_lock(&iigen->ig_spin); -+ iigen->ig_generation--; -+ spin_unlock(&iigen->ig_spin); -+} -+ -+static inline int au_iigen_test(struct inode *inode, unsigned int sigen) -+{ -+ int err; -+ -+ err = 0; -+ if (unlikely(inode && au_iigen(inode, NULL) != sigen)) -+ err = -EIO; -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline aufs_bindex_t au_ii_br_id(struct inode *inode, -+ aufs_bindex_t bindex) -+{ -+ IiMustAnyLock(inode); -+ return au_ii(inode)->ii_hinode[0 + bindex].hi_id; -+} -+ -+static inline aufs_bindex_t au_ibstart(struct inode *inode) -+{ -+ IiMustAnyLock(inode); -+ return au_ii(inode)->ii_bstart; -+} -+ -+static inline aufs_bindex_t au_ibend(struct inode *inode) -+{ -+ IiMustAnyLock(inode); -+ return au_ii(inode)->ii_bend; -+} -+ -+static inline struct au_vdir *au_ivdir(struct inode *inode) -+{ -+ IiMustAnyLock(inode); -+ return au_ii(inode)->ii_vdir; -+} -+ -+static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex) -+{ -+ IiMustAnyLock(inode); -+ return au_ii(inode)->ii_hinode[0 + bindex].hi_whdentry; -+} -+ -+static inline void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex) -+{ -+ IiMustWriteLock(inode); -+ au_ii(inode)->ii_bstart = bindex; -+} -+ -+static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex) -+{ -+ IiMustWriteLock(inode); -+ au_ii(inode)->ii_bend = bindex; -+} -+ -+static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir) -+{ -+ IiMustWriteLock(inode); -+ au_ii(inode)->ii_vdir = vdir; -+} -+ -+static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex) -+{ -+ IiMustAnyLock(inode); -+ return au_ii(inode)->ii_hinode + bindex; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct dentry *au_pinned_parent(struct au_pin *pin) -+{ -+ if (pin) -+ return pin->parent; -+ return NULL; -+} -+ -+static inline struct inode *au_pinned_h_dir(struct au_pin *pin) -+{ -+ if (pin && pin->hdir) -+ return pin->hdir->hi_inode; -+ return NULL; -+} -+ -+static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin) -+{ -+ if (pin) -+ return pin->hdir; -+ return NULL; -+} -+ -+static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry) -+{ -+ if (pin) -+ pin->dentry = dentry; -+} -+ -+static inline void au_pin_set_parent_lflag(struct au_pin *pin, -+ unsigned char lflag) -+{ -+ if (pin) { -+ if (lflag) -+ au_fset_pin(pin->flags, DI_LOCKED); -+ else -+ au_fclr_pin(pin->flags, DI_LOCKED); -+ } -+} -+ -+#if 0 /* reserved */ -+static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent) -+{ -+ if (pin) { -+ dput(pin->parent); -+ pin->parent = dget(parent); -+ } -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_branch; -+#ifdef CONFIG_AUFS_HNOTIFY -+struct au_hnotify_op { -+ void (*ctl)(struct au_hinode *hinode, int do_set); -+ int (*alloc)(struct au_hinode *hinode); -+ -+ /* -+ * if it returns true, the the caller should free hinode->hi_notify, -+ * otherwise ->free() frees it. -+ */ -+ int (*free)(struct au_hinode *hinode, -+ struct au_hnotify *hn) __must_check; -+ -+ void (*fin)(void); -+ int (*init)(void); -+ -+ int (*reset_br)(unsigned int udba, struct au_branch *br, int perm); -+ void (*fin_br)(struct au_branch *br); -+ int (*init_br)(struct au_branch *br, int perm); -+}; -+ -+/* hnotify.c */ -+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode); -+void au_hn_free(struct au_hinode *hinode); -+void au_hn_ctl(struct au_hinode *hinode, int do_set); -+void au_hn_reset(struct inode *inode, unsigned int flags); -+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask, -+ struct qstr *h_child_qstr, struct inode *h_child_inode); -+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm); -+int au_hnotify_init_br(struct au_branch *br, int perm); -+void au_hnotify_fin_br(struct au_branch *br); -+int __init au_hnotify_init(void); -+void au_hnotify_fin(void); -+ -+/* hfsnotify.c */ -+extern const struct au_hnotify_op au_hnotify_op; -+ -+static inline -+void au_hn_init(struct au_hinode *hinode) -+{ -+ hinode->hi_notify = NULL; -+} -+ -+static inline struct au_hnotify *au_hn(struct au_hinode *hinode) -+{ -+ return hinode->hi_notify; -+} -+ -+#else -+AuStub(int, au_hn_alloc, return -EOPNOTSUPP, -+ struct au_hinode *hinode __maybe_unused, -+ struct inode *inode __maybe_unused) -+AuStub(struct au_hnotify *, au_hn, return NULL, struct au_hinode *hinode) -+AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused) -+AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused, -+ int do_set __maybe_unused) -+AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused, -+ unsigned int flags __maybe_unused) -+AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused, -+ struct au_branch *br __maybe_unused, -+ int perm __maybe_unused) -+AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused, -+ int perm __maybe_unused) -+AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused) -+AuStubInt0(__init au_hnotify_init, void) -+AuStubVoid(au_hnotify_fin, void) -+AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused) -+#endif /* CONFIG_AUFS_HNOTIFY */ -+ -+static inline void au_hn_suspend(struct au_hinode *hdir) -+{ -+ au_hn_ctl(hdir, /*do_set*/0); -+} -+ -+static inline void au_hn_resume(struct au_hinode *hdir) -+{ -+ au_hn_ctl(hdir, /*do_set*/1); -+} -+ -+static inline void au_hn_imtx_lock(struct au_hinode *hdir) -+{ -+ mutex_lock(&hdir->hi_inode->i_mutex); -+ au_hn_suspend(hdir); -+} -+ -+static inline void au_hn_imtx_lock_nested(struct au_hinode *hdir, -+ unsigned int sc __maybe_unused) -+{ -+ mutex_lock_nested(&hdir->hi_inode->i_mutex, sc); -+ au_hn_suspend(hdir); -+} -+ -+static inline void au_hn_imtx_unlock(struct au_hinode *hdir) -+{ -+ au_hn_resume(hdir); -+ mutex_unlock(&hdir->hi_inode->i_mutex); -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_INODE_H__ */ -diff --git a/fs/aufs/ioctl.c b/fs/aufs/ioctl.c -new file mode 100644 -index 0000000..87e3ddc ---- /dev/null -+++ b/fs/aufs/ioctl.c -@@ -0,0 +1,206 @@ -+/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima -+ */ -+ -+/* -+ * ioctl -+ * plink-management and readdir in userspace. -+ * assist the pathconf(3) wrapper library. -+ * move-down -+ * File-based Hierarchical Storage Management. -+ */ -+ -+#include -+#include -+#include "aufs.h" -+ -+static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg) -+{ -+ int err, fd; -+ aufs_bindex_t wbi, bindex, bend; -+ struct file *h_file; -+ struct super_block *sb; -+ struct dentry *root; -+ struct au_branch *br; -+ struct aufs_wbr_fd wbrfd = { -+ .oflags = au_dir_roflags, -+ .brid = -1 -+ }; -+ const int valid = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY -+ | O_NOATIME | O_CLOEXEC; -+ -+ AuDebugOn(wbrfd.oflags & ~valid); -+ -+ if (arg) { -+ err = copy_from_user(&wbrfd, arg, sizeof(wbrfd)); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ goto out; -+ } -+ -+ err = -EINVAL; -+ AuDbg("wbrfd{0%o, %d}\n", wbrfd.oflags, wbrfd.brid); -+ wbrfd.oflags |= au_dir_roflags; -+ AuDbg("0%o\n", wbrfd.oflags); -+ if (unlikely(wbrfd.oflags & ~valid)) -+ goto out; -+ } -+ -+ fd = get_unused_fd_flags(0); -+ err = fd; -+ if (unlikely(fd < 0)) -+ goto out; -+ -+ h_file = ERR_PTR(-EINVAL); -+ wbi = 0; -+ br = NULL; -+ sb = path->dentry->d_sb; -+ root = sb->s_root; -+ aufs_read_lock(root, AuLock_IR); -+ bend = au_sbend(sb); -+ if (wbrfd.brid >= 0) { -+ wbi = au_br_index(sb, wbrfd.brid); -+ if (unlikely(wbi < 0 || wbi > bend)) -+ goto out_unlock; -+ } -+ -+ h_file = ERR_PTR(-ENOENT); -+ br = au_sbr(sb, wbi); -+ if (!au_br_writable(br->br_perm)) { -+ if (arg) -+ goto out_unlock; -+ -+ bindex = wbi + 1; -+ wbi = -1; -+ for (; bindex <= bend; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (au_br_writable(br->br_perm)) { -+ wbi = bindex; -+ br = au_sbr(sb, wbi); -+ break; -+ } -+ } -+ } -+ AuDbg("wbi %d\n", wbi); -+ if (wbi >= 0) -+ h_file = au_h_open(root, wbi, wbrfd.oflags, NULL, -+ /*force_wr*/0); -+ -+out_unlock: -+ aufs_read_unlock(root, AuLock_IR); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out_fd; -+ -+ atomic_dec(&br->br_count); /* cf. au_h_open() */ -+ fd_install(fd, h_file); -+ err = fd; -+ goto out; /* success */ -+ -+out_fd: -+ put_unused_fd(fd); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ long err; -+ struct dentry *dentry; -+ -+ switch (cmd) { -+ case AUFS_CTL_RDU: -+ case AUFS_CTL_RDU_INO: -+ err = au_rdu_ioctl(file, cmd, arg); -+ break; -+ -+ case AUFS_CTL_WBR_FD: -+ err = au_wbr_fd(&file->f_path, (void __user *)arg); -+ break; -+ -+ case AUFS_CTL_IBUSY: -+ err = au_ibusy_ioctl(file, arg); -+ break; -+ -+ case AUFS_CTL_BRINFO: -+ err = au_brinfo_ioctl(file, arg); -+ break; -+ -+ case AUFS_CTL_FHSM_FD: -+ dentry = file->f_path.dentry; -+ if (IS_ROOT(dentry)) -+ err = au_fhsm_fd(dentry->d_sb, arg); -+ else -+ err = -ENOTTY; -+ break; -+ -+ default: -+ /* do not call the lower */ -+ AuDbg("0x%x\n", cmd); -+ err = -ENOTTY; -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ long err; -+ -+ switch (cmd) { -+ case AUFS_CTL_MVDOWN: -+ err = au_mvdown(file->f_path.dentry, (void __user *)arg); -+ break; -+ -+ case AUFS_CTL_WBR_FD: -+ err = au_wbr_fd(&file->f_path, (void __user *)arg); -+ break; -+ -+ default: -+ /* do not call the lower */ -+ AuDbg("0x%x\n", cmd); -+ err = -ENOTTY; -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+#ifdef CONFIG_COMPAT -+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd, -+ unsigned long arg) -+{ -+ long err; -+ -+ switch (cmd) { -+ case AUFS_CTL_RDU: -+ case AUFS_CTL_RDU_INO: -+ err = au_rdu_compat_ioctl(file, cmd, arg); -+ break; -+ -+ case AUFS_CTL_IBUSY: -+ err = au_ibusy_compat_ioctl(file, arg); -+ break; -+ -+ case AUFS_CTL_BRINFO: -+ err = au_brinfo_compat_ioctl(file, arg); -+ break; -+ -+ default: -+ err = aufs_ioctl_dir(file, cmd, arg); -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd, -+ unsigned long arg) -+{ -+ return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg)); -+} -+#endif -diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c -new file mode 100644 -index 0000000..f324758 ---- /dev/null -+++ b/fs/aufs/loop.c +diff -Nurp linux-4.4.3/fs/aufs/Kconfig linux-4.4.3-aufs/fs/aufs/Kconfig +--- linux-4.4.3/fs/aufs/Kconfig 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/Kconfig 2016-03-02 17:59:37.360498681 +0200 +@@ -0,0 +1,185 @@ ++config AUFS_FS ++ bool "Aufs (Advanced multi layered unification filesystem) support" ++ help ++ Aufs is a stackable unification filesystem such as Unionfs, ++ which unifies several directories and provides a merged single ++ directory. ++ In the early days, aufs was entirely re-designed and ++ re-implemented Unionfs Version 1.x series. Introducing many ++ original ideas, approaches and improvements, it becomes totally ++ different from Unionfs while keeping the basic features. ++ ++if AUFS_FS ++choice ++ prompt "Maximum number of branches" ++ default AUFS_BRANCH_MAX_127 ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++config AUFS_BRANCH_MAX_127 ++ bool "127" ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++config AUFS_BRANCH_MAX_511 ++ bool "511" ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++config AUFS_BRANCH_MAX_1023 ++ bool "1023" ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++config AUFS_BRANCH_MAX_32767 ++ bool "32767" ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++endchoice ++ ++config AUFS_SBILIST ++ bool ++ depends on AUFS_MAGIC_SYSRQ || PROC_FS ++ default y ++ help ++ Automatic configuration for internal use. ++ When aufs supports Magic SysRq or /proc, enabled automatically. ++ ++config AUFS_HNOTIFY ++ bool "Detect direct branch access (bypassing aufs)" ++ help ++ If you want to modify files on branches directly, eg. bypassing aufs, ++ and want aufs to detect the changes of them fully, then enable this ++ option and use 'udba=notify' mount option. ++ Currently there is only one available configuration, "fsnotify". ++ It will have a negative impact to the performance. ++ See detail in aufs.5. ++ ++choice ++ prompt "method" if AUFS_HNOTIFY ++ default AUFS_HFSNOTIFY ++config AUFS_HFSNOTIFY ++ bool "fsnotify" ++ select FSNOTIFY ++endchoice ++ ++config AUFS_EXPORT ++ bool "NFS-exportable aufs" ++ depends on EXPORTFS = y ++ help ++ If you want to export your mounted aufs via NFS, then enable this ++ option. There are several requirements for this configuration. ++ See detail in aufs.5. ++ ++config AUFS_INO_T_64 ++ bool ++ depends on AUFS_EXPORT ++ depends on 64BIT && !(ALPHA || S390) ++ default y ++ help ++ Automatic configuration for internal use. ++ /* typedef unsigned long/int __kernel_ino_t */ ++ /* alpha and s390x are int */ ++ ++config AUFS_XATTR ++ bool "support for XATTR/EA (including Security Labels)" ++ help ++ If your branch fs supports XATTR/EA and you want to make them ++ available in aufs too, then enable this opsion and specify the ++ branch attributes for EA. ++ See detail in aufs.5. ++ ++config AUFS_FHSM ++ bool "File-based Hierarchical Storage Management" ++ help ++ Hierarchical Storage Management (or HSM) is a well-known feature ++ in the storage world. Aufs provides this feature as file-based. ++ with multiple branches. ++ These multiple branches are prioritized, ie. the topmost one ++ should be the fastest drive and be used heavily. ++ ++config AUFS_RDU ++ bool "Readdir in userspace" ++ help ++ Aufs has two methods to provide a merged view for a directory, ++ by a user-space library and by kernel-space natively. The latter ++ is always enabled but sometimes large and slow. ++ If you enable this option, install the library in aufs2-util ++ package, and set some environment variables for your readdir(3), ++ then the work will be handled in user-space which generally ++ shows better performance in most cases. ++ See detail in aufs.5. ++ ++config AUFS_SHWH ++ bool "Show whiteouts" ++ help ++ If you want to make the whiteouts in aufs visible, then enable ++ this option and specify 'shwh' mount option. Although it may ++ sounds like philosophy or something, but in technically it ++ simply shows the name of whiteout with keeping its behaviour. ++ ++config AUFS_BR_RAMFS ++ bool "Ramfs (initramfs/rootfs) as an aufs branch" ++ help ++ If you want to use ramfs as an aufs branch fs, then enable this ++ option. Generally tmpfs is recommended. ++ Aufs prohibited them to be a branch fs by default, because ++ initramfs becomes unusable after switch_root or something ++ generally. If you sets initramfs as an aufs branch and boot your ++ system by switch_root, you will meet a problem easily since the ++ files in initramfs may be inaccessible. ++ Unless you are going to use ramfs as an aufs branch fs without ++ switch_root or something, leave it N. ++ ++config AUFS_BR_FUSE ++ bool "Fuse fs as an aufs branch" ++ depends on FUSE_FS ++ select AUFS_POLL ++ help ++ If you want to use fuse-based userspace filesystem as an aufs ++ branch fs, then enable this option. ++ It implements the internal poll(2) operation which is ++ implemented by fuse only (curretnly). ++ ++config AUFS_POLL ++ bool ++ help ++ Automatic configuration for internal use. ++ ++config AUFS_BR_HFSPLUS ++ bool "Hfsplus as an aufs branch" ++ depends on HFSPLUS_FS ++ default y ++ help ++ If you want to use hfsplus fs as an aufs branch fs, then enable ++ this option. This option introduces a small overhead at ++ copying-up a file on hfsplus. ++ ++config AUFS_BDEV_LOOP ++ bool ++ depends on BLK_DEV_LOOP ++ default y ++ help ++ Automatic configuration for internal use. ++ Convert =[ym] into =y. ++ ++config AUFS_DEBUG ++ bool "Debug aufs" ++ help ++ Enable this to compile aufs internal debug code. ++ It will have a negative impact to the performance. ++ ++config AUFS_MAGIC_SYSRQ ++ bool ++ depends on AUFS_DEBUG && MAGIC_SYSRQ ++ default y ++ help ++ Automatic configuration for internal use. ++ When aufs supports Magic SysRq, enabled automatically. ++endif +diff -Nurp linux-4.4.3/fs/aufs/loop.c linux-4.4.3-aufs/fs/aufs/loop.c +--- linux-4.4.3/fs/aufs/loop.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/loop.c 2016-03-02 17:59:37.369498746 +0200 @@ -0,0 +1,133 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -20205,14 +20125,12 @@ index 0000000..f324758 + symbol_put(loop_backing_file); + kfree(au_warn_loopback_array); +} -diff --git a/fs/aufs/loop.h b/fs/aufs/loop.h -new file mode 100644 -index 0000000..6d9864d ---- /dev/null -+++ b/fs/aufs/loop.h +diff -Nurp linux-4.4.3/fs/aufs/loop.h linux-4.4.3-aufs/fs/aufs/loop.h +--- linux-4.4.3/fs/aufs/loop.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/loop.h 2016-03-02 17:59:37.369498746 +0200 @@ -0,0 +1,39 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -20250,11 +20168,9 @@ index 0000000..6d9864d + +#endif /* __KERNEL__ */ +#endif /* __AUFS_LOOP_H__ */ -diff --git a/fs/aufs/magic.mk b/fs/aufs/magic.mk -new file mode 100644 -index 0000000..4f83bdf ---- /dev/null -+++ b/fs/aufs/magic.mk +diff -Nurp linux-4.4.3/fs/aufs/magic.mk linux-4.4.3-aufs/fs/aufs/magic.mk +--- linux-4.4.3/fs/aufs/magic.mk 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/magic.mk 2016-03-02 17:59:37.369498746 +0200 @@ -0,0 +1,30 @@ + +# defined in ${srctree}/fs/fuse/inode.c @@ -20286,14 +20202,52 @@ index 0000000..4f83bdf +ifdef CONFIG_HFSPLUS_FS +ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b +endif -diff --git a/fs/aufs/module.c b/fs/aufs/module.c -new file mode 100644 -index 0000000..3268e62 ---- /dev/null -+++ b/fs/aufs/module.c +diff -Nurp linux-4.4.3/fs/aufs/Makefile linux-4.4.3-aufs/fs/aufs/Makefile +--- linux-4.4.3/fs/aufs/Makefile 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/Makefile 2016-03-02 17:59:37.361498688 +0200 +@@ -0,0 +1,36 @@ ++ ++include ${srctree}/${src}/magic.mk ++ ++# cf. include/linux/kernel.h ++# enable pr_debug ++ccflags-y += -DDEBUG ++# sparse requires the full pathname ++ccflags-y += -include ${srctree}/include/uapi/linux/aufs_type.h ++ ++obj-$(CONFIG_AUFS_FS) += aufs.o ++aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \ ++ wkq.o vfsub.o dcsub.o \ ++ cpup.o whout.o wbr_policy.o \ ++ dinfo.o dentry.o \ ++ dynop.o \ ++ finfo.o file.o f_op.o \ ++ dir.o vdir.o \ ++ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \ ++ mvdown.o ioctl.o ++ ++# all are boolean ++aufs-$(CONFIG_PROC_FS) += procfs.o plink.o ++aufs-$(CONFIG_SYSFS) += sysfs.o ++aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o ++aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o ++aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o ++aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o ++aufs-$(CONFIG_AUFS_EXPORT) += export.o ++aufs-$(CONFIG_AUFS_XATTR) += xattr.o ++aufs-$(CONFIG_FS_POSIX_ACL) += posix_acl.o ++aufs-$(CONFIG_AUFS_FHSM) += fhsm.o ++aufs-$(CONFIG_AUFS_POLL) += poll.o ++aufs-$(CONFIG_AUFS_RDU) += rdu.o ++aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o ++aufs-$(CONFIG_AUFS_DEBUG) += debug.o ++aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o +diff -Nurp linux-4.4.3/fs/aufs/module.c linux-4.4.3-aufs/fs/aufs/module.c +--- linux-4.4.3/fs/aufs/module.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/module.c 2016-03-02 17:59:37.369498746 +0200 @@ -0,0 +1,207 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -20389,7 +20343,7 @@ index 0000000..3268e62 +module_param_named(brs, sysaufs_brs, int, S_IRUGO); + +/* this module parameter has no meaning when USER_NS is disabled */ -+static bool au_userns; ++bool au_userns; +MODULE_PARM_DESC(allow_userns, "allow unprivileged to mount under userns"); +module_param_named(allow_userns, au_userns, bool, S_IRUGO); + @@ -20499,14 +20453,12 @@ index 0000000..3268e62 + +module_init(aufs_init); +module_exit(aufs_exit); -diff --git a/fs/aufs/module.h b/fs/aufs/module.h -new file mode 100644 -index 0000000..adee827 ---- /dev/null -+++ b/fs/aufs/module.h -@@ -0,0 +1,91 @@ +diff -Nurp linux-4.4.3/fs/aufs/module.h linux-4.4.3-aufs/fs/aufs/module.h +--- linux-4.4.3/fs/aufs/module.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/module.h 2016-03-02 17:59:37.369498746 +0200 +@@ -0,0 +1,92 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -20525,6 +20477,7 @@ index 0000000..adee827 + +/* module parameters */ +extern int sysaufs_brs; ++extern bool au_userns; + +/* ---------------------------------------------------------------------- */ + @@ -20596,14 +20549,12 @@ index 0000000..adee827 + +#endif /* __KERNEL__ */ +#endif /* __AUFS_MODULE_H__ */ -diff --git a/fs/aufs/mvdown.c b/fs/aufs/mvdown.c -new file mode 100644 -index 0000000..53e0f6a ---- /dev/null -+++ b/fs/aufs/mvdown.c +diff -Nurp linux-4.4.3/fs/aufs/mvdown.c linux-4.4.3-aufs/fs/aufs/mvdown.c +--- linux-4.4.3/fs/aufs/mvdown.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/mvdown.c 2016-03-02 17:59:37.370498753 +0200 @@ -0,0 +1,690 @@ +/* -+ * Copyright (C) 2011-2015 Junjiro R. Okajima ++ * Copyright (C) 2011-2016 Junjiro R. Okajima + */ + +/* @@ -21292,14 +21243,12 @@ index 0000000..53e0f6a + AuTraceErr(err); + return err; +} -diff --git a/fs/aufs/opts.c b/fs/aufs/opts.c -new file mode 100644 -index 0000000..f79d15e ---- /dev/null -+++ b/fs/aufs/opts.c +diff -Nurp linux-4.4.3/fs/aufs/opts.c linux-4.4.3-aufs/fs/aufs/opts.c +--- linux-4.4.3/fs/aufs/opts.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/opts.c 2016-03-02 17:59:37.370498753 +0200 @@ -0,0 +1,1846 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -23144,14 +23093,12 @@ index 0000000..f79d15e +{ + return au_mntflags(sb) & AuOptMask_UDBA; +} -diff --git a/fs/aufs/opts.h b/fs/aufs/opts.h -new file mode 100644 -index 0000000..3899e92 ---- /dev/null -+++ b/fs/aufs/opts.h +diff -Nurp linux-4.4.3/fs/aufs/opts.h linux-4.4.3-aufs/fs/aufs/opts.h +--- linux-4.4.3/fs/aufs/opts.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/opts.h 2016-03-02 17:59:37.370498753 +0200 @@ -0,0 +1,198 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -23348,14 +23295,12 @@ index 0000000..3899e92 + +#endif /* __KERNEL__ */ +#endif /* __AUFS_OPTS_H__ */ -diff --git a/fs/aufs/plink.c b/fs/aufs/plink.c -new file mode 100644 -index 0000000..af2246c ---- /dev/null -+++ b/fs/aufs/plink.c +diff -Nurp linux-4.4.3/fs/aufs/plink.c linux-4.4.3-aufs/fs/aufs/plink.c +--- linux-4.4.3/fs/aufs/plink.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/plink.c 2016-03-02 17:59:37.370498753 +0200 @@ -0,0 +1,515 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -23869,14 +23814,12 @@ index 0000000..af2246c + } + } +} -diff --git a/fs/aufs/poll.c b/fs/aufs/poll.c -new file mode 100644 -index 0000000..c324fc7 ---- /dev/null -+++ b/fs/aufs/poll.c +diff -Nurp linux-4.4.3/fs/aufs/poll.c linux-4.4.3-aufs/fs/aufs/poll.c +--- linux-4.4.3/fs/aufs/poll.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/poll.c 2016-03-02 17:59:37.370498753 +0200 @@ -0,0 +1,39 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -23914,14 +23857,12 @@ index 0000000..c324fc7 + AuTraceErr((int)mask); + return mask; +} -diff --git a/fs/aufs/posix_acl.c b/fs/aufs/posix_acl.c -new file mode 100644 -index 0000000..d9ce957 ---- /dev/null -+++ b/fs/aufs/posix_acl.c -@@ -0,0 +1,86 @@ +diff -Nurp linux-4.4.3/fs/aufs/posix_acl.c linux-4.4.3-aufs/fs/aufs/posix_acl.c +--- linux-4.4.3/fs/aufs/posix_acl.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/posix_acl.c 2016-03-02 17:59:37.371498760 +0200 +@@ -0,0 +1,85 @@ +/* -+ * Copyright (C) 2014-2015 Junjiro R. Okajima ++ * Copyright (C) 2014-2016 Junjiro R. Okajima + */ + +/* @@ -23929,7 +23870,6 @@ index 0000000..d9ce957 + */ + +#include -+#include +#include "aufs.h" + +struct posix_acl *aufs_get_acl(struct inode *inode, int type) @@ -24006,14 +23946,12 @@ index 0000000..d9ce957 + mutex_unlock(&inode->i_mutex); + return err; +} -diff --git a/fs/aufs/procfs.c b/fs/aufs/procfs.c -new file mode 100644 -index 0000000..ead2a00 ---- /dev/null -+++ b/fs/aufs/procfs.c +diff -Nurp linux-4.4.3/fs/aufs/procfs.c linux-4.4.3-aufs/fs/aufs/procfs.c +--- linux-4.4.3/fs/aufs/procfs.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/procfs.c 2016-03-02 17:59:37.371498760 +0200 @@ -0,0 +1,156 @@ +/* -+ * Copyright (C) 2010-2015 Junjiro R. Okajima ++ * Copyright (C) 2010-2016 Junjiro R. Okajima + */ + +/* @@ -24168,14 +24106,12 @@ index 0000000..ead2a00 +out: + return err; +} -diff --git a/fs/aufs/rdu.c b/fs/aufs/rdu.c -new file mode 100644 -index 0000000..f11d9bb ---- /dev/null -+++ b/fs/aufs/rdu.c +diff -Nurp linux-4.4.3/fs/aufs/rdu.c linux-4.4.3-aufs/fs/aufs/rdu.c +--- linux-4.4.3/fs/aufs/rdu.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/rdu.c 2016-03-02 17:59:37.371498760 +0200 @@ -0,0 +1,375 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -24549,14 +24485,12 @@ index 0000000..f11d9bb + return err; +} +#endif -diff --git a/fs/aufs/rwsem.h b/fs/aufs/rwsem.h -new file mode 100644 -index 0000000..171ee0c ---- /dev/null -+++ b/fs/aufs/rwsem.h +diff -Nurp linux-4.4.3/fs/aufs/rwsem.h linux-4.4.3-aufs/fs/aufs/rwsem.h +--- linux-4.4.3/fs/aufs/rwsem.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/rwsem.h 2016-03-02 17:59:37.371498760 +0200 @@ -0,0 +1,178 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -24733,14 +24667,12 @@ index 0000000..171ee0c + +#endif /* __KERNEL__ */ +#endif /* __AUFS_RWSEM_H__ */ -diff --git a/fs/aufs/sbinfo.c b/fs/aufs/sbinfo.c -new file mode 100644 -index 0000000..8f2ec55 ---- /dev/null -+++ b/fs/aufs/sbinfo.c +diff -Nurp linux-4.4.3/fs/aufs/sbinfo.c linux-4.4.3-aufs/fs/aufs/sbinfo.c +--- linux-4.4.3/fs/aufs/sbinfo.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/sbinfo.c 2016-03-02 17:59:37.371498760 +0200 @@ -0,0 +1,353 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -25092,14 +25024,12 @@ index 0000000..8f2ec55 + p = radix_tree_delete(&sbinfo->au_si_pid.tree, current->pid); + spin_unlock(&sbinfo->au_si_pid.tree_lock); +} -diff --git a/fs/aufs/spl.h b/fs/aufs/spl.h -new file mode 100644 -index 0000000..a66d39e ---- /dev/null -+++ b/fs/aufs/spl.h +diff -Nurp linux-4.4.3/fs/aufs/spl.h linux-4.4.3-aufs/fs/aufs/spl.h +--- linux-4.4.3/fs/aufs/spl.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/spl.h 2016-03-02 17:59:37.371498760 +0200 @@ -0,0 +1,98 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -25196,14 +25126,12 @@ index 0000000..a66d39e + +#endif /* __KERNEL__ */ +#endif /* __AUFS_SPL_H__ */ -diff --git a/fs/aufs/super.c b/fs/aufs/super.c -new file mode 100644 -index 0000000..98cfd64 ---- /dev/null -+++ b/fs/aufs/super.c +diff -Nurp linux-4.4.3/fs/aufs/super.c linux-4.4.3-aufs/fs/aufs/super.c +--- linux-4.4.3/fs/aufs/super.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/super.c 2016-03-02 17:59:37.372498767 +0200 @@ -0,0 +1,1026 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -26228,14 +26156,12 @@ index 0000000..98cfd64 + /* no need to __module_get() and module_put(). */ + .owner = THIS_MODULE, +}; -diff --git a/fs/aufs/super.h b/fs/aufs/super.h -new file mode 100644 -index 0000000..d151729 ---- /dev/null -+++ b/fs/aufs/super.h +diff -Nurp linux-4.4.3/fs/aufs/super.h linux-4.4.3-aufs/fs/aufs/super.h +--- linux-4.4.3/fs/aufs/super.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/super.h 2016-03-02 17:59:37.372498767 +0200 @@ -0,0 +1,628 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -26862,14 +26788,12 @@ index 0000000..d151729 + +#endif /* __KERNEL__ */ +#endif /* __AUFS_SUPER_H__ */ -diff --git a/fs/aufs/sysaufs.c b/fs/aufs/sysaufs.c -new file mode 100644 -index 0000000..29ac6fa ---- /dev/null -+++ b/fs/aufs/sysaufs.c +diff -Nurp linux-4.4.3/fs/aufs/sysaufs.c linux-4.4.3-aufs/fs/aufs/sysaufs.c +--- linux-4.4.3/fs/aufs/sysaufs.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/sysaufs.c 2016-03-02 17:59:37.372498767 +0200 @@ -0,0 +1,91 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -26959,14 +26883,12 @@ index 0000000..29ac6fa +out: + return err; +} -diff --git a/fs/aufs/sysaufs.h b/fs/aufs/sysaufs.h -new file mode 100644 -index 0000000..feb78fd ---- /dev/null -+++ b/fs/aufs/sysaufs.h +diff -Nurp linux-4.4.3/fs/aufs/sysaufs.h linux-4.4.3-aufs/fs/aufs/sysaufs.h +--- linux-4.4.3/fs/aufs/sysaufs.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/sysaufs.h 2016-03-02 17:59:37.372498767 +0200 @@ -0,0 +1,88 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -27053,14 +26975,12 @@ index 0000000..feb78fd + +#endif /* __KERNEL__ */ +#endif /* __SYSAUFS_H__ */ -diff --git a/fs/aufs/sysfs.c b/fs/aufs/sysfs.c -new file mode 100644 -index 0000000..ec8df8f ---- /dev/null -+++ b/fs/aufs/sysfs.c +diff -Nurp linux-4.4.3/fs/aufs/sysfs.c linux-4.4.3-aufs/fs/aufs/sysfs.c +--- linux-4.4.3/fs/aufs/sysfs.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/sysfs.c 2016-03-02 17:59:37.372498767 +0200 @@ -0,0 +1,340 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -27399,14 +27319,12 @@ index 0000000..ec8df8f + } + } +} -diff --git a/fs/aufs/sysrq.c b/fs/aufs/sysrq.c -new file mode 100644 -index 0000000..3a0182b ---- /dev/null -+++ b/fs/aufs/sysrq.c +diff -Nurp linux-4.4.3/fs/aufs/sysrq.c linux-4.4.3-aufs/fs/aufs/sysrq.c +--- linux-4.4.3/fs/aufs/sysrq.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/sysrq.c 2016-03-02 17:59:37.372498767 +0200 @@ -0,0 +1,144 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -27549,14 +27467,12 @@ index 0000000..3a0182b + if (unlikely(err)) + pr_err("err %d (ignored)\n", err); +} -diff --git a/fs/aufs/vdir.c b/fs/aufs/vdir.c -new file mode 100644 -index 0000000..db81f49 ---- /dev/null -+++ b/fs/aufs/vdir.c +diff -Nurp linux-4.4.3/fs/aufs/vdir.c linux-4.4.3-aufs/fs/aufs/vdir.c +--- linux-4.4.3/fs/aufs/vdir.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/vdir.c 2016-03-02 17:59:37.372498767 +0200 @@ -0,0 +1,875 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -28430,14 +28346,12 @@ index 0000000..db81f49 + /* smp_mb(); */ + return 0; +} -diff --git a/fs/aufs/vfsub.c b/fs/aufs/vfsub.c -new file mode 100644 -index 0000000..da0df5a ---- /dev/null -+++ b/fs/aufs/vfsub.c -@@ -0,0 +1,835 @@ +diff -Nurp linux-4.4.3/fs/aufs/vfsub.c linux-4.4.3-aufs/fs/aufs/vfsub.c +--- linux-4.4.3/fs/aufs/vfsub.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/vfsub.c 2016-03-02 17:59:37.373498774 +0200 +@@ -0,0 +1,853 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -28445,10 +28359,28 @@ index 0000000..da0df5a + */ + +#include ++#include +#include +#include ++#include "../fs/mount.h" +#include "aufs.h" + ++#ifdef CONFIG_AUFS_BR_FUSE ++int vfsub_test_mntns(struct vfsmount *mnt, struct super_block *h_sb) ++{ ++ struct nsproxy *ns; ++ ++ if (!au_test_fuse(h_sb) || !au_userns) ++ return 0; ++ ++ ns = current->nsproxy; ++ /* no {get,put}_nsproxy(ns) */ ++ return real_mount(mnt)->mnt_ns == ns->mnt_ns ? 0 : -EACCES; ++} ++#endif ++ ++/* ---------------------------------------------------------------------- */ ++ +int vfsub_update_h_iattr(struct path *h_path, int *did) +{ + int err; @@ -29271,14 +29203,12 @@ index 0000000..da0df5a + + return err; +} -diff --git a/fs/aufs/vfsub.h b/fs/aufs/vfsub.h -new file mode 100644 -index 0000000..4218da1 ---- /dev/null -+++ b/fs/aufs/vfsub.h -@@ -0,0 +1,274 @@ +diff -Nurp linux-4.4.3/fs/aufs/vfsub.h linux-4.4.3-aufs/fs/aufs/vfsub.h +--- linux-4.4.3/fs/aufs/vfsub.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/vfsub.h 2016-03-02 17:59:37.373498774 +0200 +@@ -0,0 +1,295 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -29292,6 +29222,7 @@ index 0000000..4218da1 + +#include +#include ++#include +#include +#include "debug.h" + @@ -29342,6 +29273,12 @@ index 0000000..4218da1 + || IS_IMMUTABLE(inode); +} + ++#ifdef CONFIG_AUFS_BR_FUSE ++int vfsub_test_mntns(struct vfsmount *mnt, struct super_block *h_sb); ++#else ++AuStubInt0(vfsub_test_mntns, struct vfsmount *mnt, struct super_block *h_sb); ++#endif ++ +/* ---------------------------------------------------------------------- */ + +int vfsub_update_h_iattr(struct path *h_path, int *did); @@ -29481,6 +29418,20 @@ index 0000000..4218da1 + /* no vfsub_update_h_iattr() since we don't have struct path */ +} + ++#ifdef CONFIG_FS_POSIX_ACL ++static inline int vfsub_acl_chmod(struct inode *h_inode, umode_t h_mode) ++{ ++ int err; ++ ++ err = posix_acl_chmod(h_inode, h_mode); ++ if (err == -EOPNOTSUPP) ++ err = 0; ++ return err; ++} ++#else ++AuStubInt0(vfsub_acl_chmod, struct inode *h_inode, umode_t h_mode); ++#endif ++ +long vfsub_splice_to(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags); @@ -29551,14 +29502,12 @@ index 0000000..4218da1 + +#endif /* __KERNEL__ */ +#endif /* __AUFS_VFSUB_H__ */ -diff --git a/fs/aufs/wbr_policy.c b/fs/aufs/wbr_policy.c -new file mode 100644 -index 0000000..53a01fb ---- /dev/null -+++ b/fs/aufs/wbr_policy.c +diff -Nurp linux-4.4.3/fs/aufs/wbr_policy.c linux-4.4.3-aufs/fs/aufs/wbr_policy.c +--- linux-4.4.3/fs/aufs/wbr_policy.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/wbr_policy.c 2016-03-02 17:59:37.373498774 +0200 @@ -0,0 +1,752 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -30309,14 +30258,12 @@ index 0000000..53a01fb + .fin = au_wbr_create_fin_mfs + } +}; -diff --git a/fs/aufs/whout.c b/fs/aufs/whout.c -new file mode 100644 -index 0000000..05ba085 ---- /dev/null -+++ b/fs/aufs/whout.c +diff -Nurp linux-4.4.3/fs/aufs/whout.c linux-4.4.3-aufs/fs/aufs/whout.c +--- linux-4.4.3/fs/aufs/whout.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/whout.c 2016-03-02 17:59:37.374498781 +0200 @@ -0,0 +1,1047 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -31362,14 +31309,12 @@ index 0000000..05ba085 + au_whtmp_rmdir_free(args); + } +} -diff --git a/fs/aufs/whout.h b/fs/aufs/whout.h -new file mode 100644 -index 0000000..b39acea ---- /dev/null -+++ b/fs/aufs/whout.h +diff -Nurp linux-4.4.3/fs/aufs/whout.h linux-4.4.3-aufs/fs/aufs/whout.h +--- linux-4.4.3/fs/aufs/whout.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/whout.h 2016-03-02 17:59:37.374498781 +0200 @@ -0,0 +1,72 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -31440,14 +31385,12 @@ index 0000000..b39acea + +#endif /* __KERNEL__ */ +#endif /* __AUFS_WHOUT_H__ */ -diff --git a/fs/aufs/wkq.c b/fs/aufs/wkq.c -new file mode 100644 -index 0000000..08870ec ---- /dev/null -+++ b/fs/aufs/wkq.c +diff -Nurp linux-4.4.3/fs/aufs/wkq.c linux-4.4.3-aufs/fs/aufs/wkq.c +--- linux-4.4.3/fs/aufs/wkq.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/wkq.c 2016-03-02 17:59:37.374498781 +0200 @@ -0,0 +1,200 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -31646,14 +31589,12 @@ index 0000000..08870ec + + return err; +} -diff --git a/fs/aufs/wkq.h b/fs/aufs/wkq.h -new file mode 100644 -index 0000000..8f01343 ---- /dev/null -+++ b/fs/aufs/wkq.h +diff -Nurp linux-4.4.3/fs/aufs/wkq.h linux-4.4.3-aufs/fs/aufs/wkq.h +--- linux-4.4.3/fs/aufs/wkq.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/wkq.h 2016-03-02 17:59:37.374498781 +0200 @@ -0,0 +1,78 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -31730,14 +31671,12 @@ index 0000000..8f01343 + +#endif /* __KERNEL__ */ +#endif /* __AUFS_WKQ_H__ */ -diff --git a/fs/aufs/xattr.c b/fs/aufs/xattr.c -new file mode 100644 -index 0000000..c1695b3 ---- /dev/null -+++ b/fs/aufs/xattr.c +diff -Nurp linux-4.4.3/fs/aufs/xattr.c linux-4.4.3-aufs/fs/aufs/xattr.c +--- linux-4.4.3/fs/aufs/xattr.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/xattr.c 2016-03-02 17:59:37.375498789 +0200 @@ -0,0 +1,331 @@ +/* -+ * Copyright (C) 2014-2015 Junjiro R. Okajima ++ * Copyright (C) 2014-2016 Junjiro R. Okajima + */ + +/* @@ -32067,14 +32006,12 @@ index 0000000..c1695b3 + /* sb->s_xattr = au_xattr_handlers; */ +} +#endif -diff --git a/fs/aufs/xino.c b/fs/aufs/xino.c -new file mode 100644 -index 0000000..90de8c5 ---- /dev/null -+++ b/fs/aufs/xino.c -@@ -0,0 +1,1283 @@ +diff -Nurp linux-4.4.3/fs/aufs/xino.c linux-4.4.3-aufs/fs/aufs/xino.c +--- linux-4.4.3/fs/aufs/xino.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/fs/aufs/xino.c 2016-03-02 17:59:37.376498796 +0200 +@@ -0,0 +1,1305 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +/* @@ -32115,6 +32052,9 @@ index 0000000..90de8c5 + +/* ---------------------------------------------------------------------- */ + ++static ssize_t xino_fwrite_wkq(vfs_writef_t func, struct file *file, void *buf, ++ size_t size, loff_t *pos); ++ +static ssize_t do_xino_fwrite(vfs_writef_t func, struct file *file, void *kbuf, + size_t size, loff_t *pos) +{ @@ -32124,14 +32064,26 @@ index 0000000..90de8c5 + void *k; + const char __user *u; + } buf; ++ int i; ++ const int prevent_endless = 10; + ++ i = 0; + buf.k = kbuf; + oldfs = get_fs(); + set_fs(KERNEL_DS); + do { -+ /* todo: signal_pending? */ + err = func(file, buf.u, size, pos); -+ } while (err == -EAGAIN || err == -EINTR); ++ if (err == -EINTR ++ && !au_wkq_test() ++ && fatal_signal_pending(current)) { ++ set_fs(oldfs); ++ err = xino_fwrite_wkq(func, file, kbuf, size, pos); ++ BUG_ON(err == -EINTR); ++ oldfs = get_fs(); ++ set_fs(KERNEL_DS); ++ } ++ } while (i++ < prevent_endless ++ && (err == -EAGAIN || err == -EINTR)); + set_fs(oldfs); + +#if 0 /* reserved for future use */ @@ -32157,35 +32109,42 @@ index 0000000..90de8c5 + *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos); +} + ++static ssize_t xino_fwrite_wkq(vfs_writef_t func, struct file *file, void *buf, ++ size_t size, loff_t *pos) ++{ ++ ssize_t err; ++ int wkq_err; ++ struct do_xino_fwrite_args args = { ++ .errp = &err, ++ .func = func, ++ .file = file, ++ .buf = buf, ++ .size = size, ++ .pos = pos ++ }; ++ ++ /* ++ * it breaks RLIMIT_FSIZE and normal user's limit, ++ * users should care about quota and real 'filesystem full.' ++ */ ++ wkq_err = au_wkq_wait(call_do_xino_fwrite, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ ++ return err; ++} ++ +ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf, + size_t size, loff_t *pos) +{ + ssize_t err; + -+ /* todo: signal block and no wkq? */ + if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) { + lockdep_off(); + err = do_xino_fwrite(func, file, buf, size, pos); + lockdep_on(); -+ } else { -+ /* -+ * it breaks RLIMIT_FSIZE and normal user's limit, -+ * users should care about quota and real 'filesystem full.' -+ */ -+ int wkq_err; -+ struct do_xino_fwrite_args args = { -+ .errp = &err, -+ .func = func, -+ .file = file, -+ .buf = buf, -+ .size = size, -+ .pos = pos -+ }; -+ -+ wkq_err = au_wkq_wait(call_do_xino_fwrite, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } ++ } else ++ err = xino_fwrite_wkq(func, file, buf, size, pos); + + return err; +} @@ -33356,10 +33315,9 @@ index 0000000..90de8c5 +out: + return err; +} -diff --git a/fs/dcache.c b/fs/dcache.c -index 5c33aeb..8aa7f26 100644 ---- a/fs/dcache.c -+++ b/fs/dcache.c +diff -Nurp linux-4.4.3/fs/dcache.c linux-4.4.3-aufs/fs/dcache.c +--- linux-4.4.3/fs/dcache.c 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs/fs/dcache.c 2016-03-02 17:59:37.376498796 +0200 @@ -1167,7 +1167,7 @@ enum d_walk_ret { * * The @enter() and @finish() callbacks are called with d_lock held. @@ -33369,11 +33327,50 @@ index 5c33aeb..8aa7f26 100644 enum d_walk_ret (*enter)(void *, struct dentry *), void (*finish)(void *)) { -diff --git a/fs/proc/base.c b/fs/proc/base.c -index bd3e9e6..fc42216 100644 ---- a/fs/proc/base.c -+++ b/fs/proc/base.c -@@ -1921,7 +1921,7 @@ static int proc_map_files_get_link(struct dentry *dentry, struct path *path) +diff -Nurp linux-4.4.3/fs/fcntl.c linux-4.4.3-aufs/fs/fcntl.c +--- linux-4.4.3/fs/fcntl.c 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs/fs/fcntl.c 2016-03-02 17:59:37.376498796 +0200 +@@ -29,7 +29,7 @@ + + #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME) + +-static int setfl(int fd, struct file * filp, unsigned long arg) ++int setfl(int fd, struct file * filp, unsigned long arg) + { + struct inode * inode = file_inode(filp); + int error = 0; +@@ -59,6 +59,8 @@ static int setfl(int fd, struct file * f + + if (filp->f_op->check_flags) + error = filp->f_op->check_flags(arg); ++ if (!error && filp->f_op->setfl) ++ error = filp->f_op->setfl(filp, arg); + if (error) + return error; + +diff -Nurp linux-4.4.3/fs/Kconfig linux-4.4.3-aufs/fs/Kconfig +--- linux-4.4.3/fs/Kconfig 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs/fs/Kconfig 2016-03-02 17:59:37.360498681 +0200 +@@ -221,6 +221,7 @@ source "fs/pstore/Kconfig" + source "fs/sysv/Kconfig" + source "fs/ufs/Kconfig" + source "fs/exofs/Kconfig" ++source "fs/aufs/Kconfig" + + endif # MISC_FILESYSTEMS + +diff -Nurp linux-4.4.3/fs/Makefile linux-4.4.3-aufs/fs/Makefile +--- linux-4.4.3/fs/Makefile 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs/fs/Makefile 2016-03-02 17:59:37.360498681 +0200 +@@ -126,3 +126,4 @@ obj-y += exofs/ # Multiple modules + obj-$(CONFIG_CEPH_FS) += ceph/ + obj-$(CONFIG_PSTORE) += pstore/ + obj-$(CONFIG_EFIVAR_FS) += efivarfs/ ++obj-$(CONFIG_AUFS_FS) += aufs/ +diff -Nurp linux-4.4.3/fs/proc/base.c linux-4.4.3-aufs/fs/proc/base.c +--- linux-4.4.3/fs/proc/base.c 2016-03-02 17:42:59.444713286 +0200 ++++ linux-4.4.3-aufs/fs/proc/base.c 2016-03-02 17:59:37.376498796 +0200 +@@ -1922,7 +1922,7 @@ static int proc_map_files_get_link(struc down_read(&mm->mmap_sem); vma = find_exact_vma(mm, vm_start, vm_end); if (vma && vma->vm_file) { @@ -33382,11 +33379,10 @@ index bd3e9e6..fc42216 100644 path_get(path); rc = 0; } -diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c -index f8595e8..cb8eda0 100644 ---- a/fs/proc/nommu.c -+++ b/fs/proc/nommu.c -@@ -45,7 +45,10 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region) +diff -Nurp linux-4.4.3/fs/proc/nommu.c linux-4.4.3-aufs/fs/proc/nommu.c +--- linux-4.4.3/fs/proc/nommu.c 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs/fs/proc/nommu.c 2016-03-02 17:59:37.377498803 +0200 +@@ -45,7 +45,10 @@ static int nommu_region_show(struct seq_ file = region->vm_file; if (file) { @@ -33398,11 +33394,10 @@ index f8595e8..cb8eda0 100644 dev = inode->i_sb->s_dev; ino = inode->i_ino; } -diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c -index 187b3b5..e03793e 100644 ---- a/fs/proc/task_mmu.c -+++ b/fs/proc/task_mmu.c -@@ -281,7 +281,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid) +diff -Nurp linux-4.4.3/fs/proc/task_mmu.c linux-4.4.3-aufs/fs/proc/task_mmu.c +--- linux-4.4.3/fs/proc/task_mmu.c 2016-03-02 17:42:59.444713286 +0200 ++++ linux-4.4.3-aufs/fs/proc/task_mmu.c 2016-03-02 17:59:37.377498803 +0200 +@@ -281,7 +281,10 @@ show_map_vma(struct seq_file *m, struct const char *name = NULL; if (file) { @@ -33414,7 +33409,7 @@ index 187b3b5..e03793e 100644 dev = inode->i_sb->s_dev; ino = inode->i_ino; pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT; -@@ -1505,7 +1508,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid) +@@ -1506,7 +1509,7 @@ static int show_numa_map(struct seq_file struct proc_maps_private *proc_priv = &numa_priv->proc_maps; struct vm_area_struct *vma = v; struct numa_maps *md = &numa_priv->md; @@ -33423,11 +33418,10 @@ index 187b3b5..e03793e 100644 struct mm_struct *mm = vma->vm_mm; struct mm_walk walk = { .hugetlb_entry = gather_hugetlb_stats, -diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c -index e0d64c9..7aa92db 100644 ---- a/fs/proc/task_nommu.c -+++ b/fs/proc/task_nommu.c -@@ -160,7 +160,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma, +diff -Nurp linux-4.4.3/fs/proc/task_nommu.c linux-4.4.3-aufs/fs/proc/task_nommu.c +--- linux-4.4.3/fs/proc/task_nommu.c 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs/fs/proc/task_nommu.c 2016-03-02 17:59:37.377498803 +0200 +@@ -160,7 +160,10 @@ static int nommu_vma_show(struct seq_fil file = vma->vm_file; if (file) { @@ -33439,11 +33433,10 @@ index e0d64c9..7aa92db 100644 dev = inode->i_sb->s_dev; ino = inode->i_ino; pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT; -diff --git a/fs/read_write.c b/fs/read_write.c -index 819ef3f..fd0414e 100644 ---- a/fs/read_write.c -+++ b/fs/read_write.c -@@ -494,6 +494,28 @@ ssize_t __vfs_write(struct file *file, const char __user *p, size_t count, +diff -Nurp linux-4.4.3/fs/read_write.c linux-4.4.3-aufs/fs/read_write.c +--- linux-4.4.3/fs/read_write.c 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs/fs/read_write.c 2016-03-02 17:59:37.377498803 +0200 +@@ -494,6 +494,28 @@ ssize_t __vfs_write(struct file *file, c } EXPORT_SYMBOL(__vfs_write); @@ -33472,10 +33465,9 @@ index 819ef3f..fd0414e 100644 ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos) { mm_segment_t old_fs; -diff --git a/fs/splice.c b/fs/splice.c -index 4cf700d..30a091d 100644 ---- a/fs/splice.c -+++ b/fs/splice.c +diff -Nurp linux-4.4.3/fs/splice.c linux-4.4.3-aufs/fs/splice.c +--- linux-4.4.3/fs/splice.c 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs/fs/splice.c 2016-03-02 17:59:37.377498803 +0200 @@ -1110,8 +1110,8 @@ EXPORT_SYMBOL(generic_splice_sendpage); /* * Attempt to initiate a splice from pipe to file. @@ -33487,7 +33479,7 @@ index 4cf700d..30a091d 100644 { ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); -@@ -1127,9 +1127,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, +@@ -1127,9 +1127,9 @@ static long do_splice_from(struct pipe_i /* * Attempt to initiate a splice from a file to a pipe. */ @@ -33500,10 +33492,9 @@ index 4cf700d..30a091d 100644 { ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); -diff --git a/include/linux/file.h b/include/linux/file.h -index f87d308..9a290b3 100644 ---- a/include/linux/file.h -+++ b/include/linux/file.h +diff -Nurp linux-4.4.3/include/linux/file.h linux-4.4.3-aufs/include/linux/file.h +--- linux-4.4.3/include/linux/file.h 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs/include/linux/file.h 2016-03-02 17:59:37.377498803 +0200 @@ -19,6 +19,7 @@ struct dentry; struct path; extern struct file *alloc_file(struct path *, fmode_t mode, @@ -33512,11 +33503,26 @@ index f87d308..9a290b3 100644 static inline void fput_light(struct file *file, int fput_needed) { -diff --git a/include/linux/fs.h b/include/linux/fs.h -index 3aa5142..8d48506 100644 ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -1672,6 +1672,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, +diff -Nurp linux-4.4.3/include/linux/fs.h linux-4.4.3-aufs/include/linux/fs.h +--- linux-4.4.3/include/linux/fs.h 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs/include/linux/fs.h 2016-03-02 17:59:37.378498810 +0200 +@@ -1233,6 +1233,7 @@ extern void fasync_free(struct fasync_st + /* can be called from interrupts */ + extern void kill_fasync(struct fasync_struct **, int, int); + ++extern int setfl(int fd, struct file * filp, unsigned long arg); + extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force); + extern void f_setown(struct file *filp, unsigned long arg, int force); + extern void f_delown(struct file *filp); +@@ -1619,6 +1620,7 @@ struct file_operations { + ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); + unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); + int (*check_flags)(int); ++ int (*setfl)(struct file *, unsigned long); + int (*flock) (struct file *, int, struct file_lock *); + ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); + ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); +@@ -1672,6 +1674,12 @@ ssize_t rw_copy_check_uvector(int type, struct iovec *fast_pointer, struct iovec **ret_pointer); @@ -33529,11 +33535,10 @@ index 3aa5142..8d48506 100644 extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *); extern ssize_t __vfs_write(struct file *, const char __user *, size_t, loff_t *); extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *); -diff --git a/include/linux/mm.h b/include/linux/mm.h -index 00bad77..cc616b0 100644 ---- a/include/linux/mm.h -+++ b/include/linux/mm.h -@@ -1183,6 +1183,28 @@ static inline int fixup_user_fault(struct task_struct *tsk, +diff -Nurp linux-4.4.3/include/linux/mm.h linux-4.4.3-aufs/include/linux/mm.h +--- linux-4.4.3/include/linux/mm.h 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs/include/linux/mm.h 2016-03-02 17:59:37.378498810 +0200 +@@ -1183,6 +1183,28 @@ static inline int fixup_user_fault(struc } #endif @@ -33562,10 +33567,9 @@ index 00bad77..cc616b0 100644 extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write); extern int access_remote_vm(struct mm_struct *mm, unsigned long addr, void *buf, int len, int write); -diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h -index f8d1492..c3a3760 100644 ---- a/include/linux/mm_types.h -+++ b/include/linux/mm_types.h +diff -Nurp linux-4.4.3/include/linux/mm_types.h linux-4.4.3-aufs/include/linux/mm_types.h +--- linux-4.4.3/include/linux/mm_types.h 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs/include/linux/mm_types.h 2016-03-02 17:59:37.378498810 +0200 @@ -272,6 +272,7 @@ struct vm_region { unsigned long vm_top; /* region allocated to here */ unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */ @@ -33582,11 +33586,10 @@ index f8d1492..c3a3760 100644 void * vm_private_data; /* was vm_pte (shared mem) */ #ifndef CONFIG_MMU -diff --git a/include/linux/splice.h b/include/linux/splice.h -index da2751d..2e0fca6 100644 ---- a/include/linux/splice.h -+++ b/include/linux/splice.h -@@ -83,4 +83,10 @@ extern void splice_shrink_spd(struct splice_pipe_desc *); +diff -Nurp linux-4.4.3/include/linux/splice.h linux-4.4.3-aufs/include/linux/splice.h +--- linux-4.4.3/include/linux/splice.h 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs/include/linux/splice.h 2016-03-02 17:59:37.378498810 +0200 +@@ -83,4 +83,10 @@ extern void splice_shrink_spd(struct spl extern void spd_release_page(struct splice_pipe_desc *, unsigned int); extern const struct pipe_buf_operations page_cache_pipe_buf_ops; @@ -33597,26 +33600,12 @@ index da2751d..2e0fca6 100644 + struct pipe_inode_info *pipe, size_t len, + unsigned int flags); #endif -diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild -index 628e6e6..6dd5765 100644 ---- a/include/uapi/linux/Kbuild -+++ b/include/uapi/linux/Kbuild -@@ -59,6 +59,7 @@ header-y += atmsvc.h - header-y += atm_tcp.h - header-y += atm_zatm.h - header-y += audit.h -+header-y += aufs_type.h - header-y += auto_fs4.h - header-y += auto_fs.h - header-y += auxvec.h -diff --git a/include/uapi/linux/aufs_type.h b/include/uapi/linux/aufs_type.h -new file mode 100644 -index 0000000..a06c985 ---- /dev/null -+++ b/include/uapi/linux/aufs_type.h +diff -Nurp linux-4.4.3/include/uapi/linux/aufs_type.h linux-4.4.3-aufs/include/uapi/linux/aufs_type.h +--- linux-4.4.3/include/uapi/linux/aufs_type.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/include/uapi/linux/aufs_type.h 2016-03-02 17:59:37.378498810 +0200 @@ -0,0 +1,406 @@ +/* -+ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ * Copyright (C) 2005-2016 Junjiro R. Okajima + */ + +#ifndef __AUFS_TYPE_H__ @@ -33643,7 +33632,7 @@ index 0000000..a06c985 + +#include + -+#define AUFS_VERSION "4.x-rcN" ++#define AUFS_VERSION "4.4" + +/* todo? move this to linux-2.6.19/include/magic.h */ +#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') @@ -34021,11 +34010,21 @@ index 0000000..a06c985 +#define AUFS_CTL_FHSM_FD _IOW(AuCtlType, AuCtl_FHSM_FD, int) + +#endif /* __AUFS_TYPE_H__ */ -diff --git a/kernel/fork.c b/kernel/fork.c -index fce002e..2230a0f 100644 ---- a/kernel/fork.c -+++ b/kernel/fork.c -@@ -464,7 +464,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) +diff -Nurp linux-4.4.3/include/uapi/linux/Kbuild linux-4.4.3-aufs/include/uapi/linux/Kbuild +--- linux-4.4.3/include/uapi/linux/Kbuild 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs/include/uapi/linux/Kbuild 2016-03-02 17:59:37.378498810 +0200 +@@ -59,6 +59,7 @@ header-y += atmsvc.h + header-y += atm_tcp.h + header-y += atm_zatm.h + header-y += audit.h ++header-y += aufs_type.h + header-y += auto_fs4.h + header-y += auto_fs.h + header-y += auxvec.h +diff -Nurp linux-4.4.3/kernel/fork.c linux-4.4.3-aufs/kernel/fork.c +--- linux-4.4.3/kernel/fork.c 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs/kernel/fork.c 2016-03-02 17:59:37.379498817 +0200 +@@ -465,7 +465,7 @@ static int dup_mmap(struct mm_struct *mm struct inode *inode = file_inode(file); struct address_space *mapping = file->f_mapping; @@ -34034,24 +34033,33 @@ index fce002e..2230a0f 100644 if (tmp->vm_flags & VM_DENYWRITE) atomic_dec(&inode->i_writecount); i_mmap_lock_write(mapping); -diff --git a/mm/Makefile b/mm/Makefile -index 2ed4319..e3a53f5 100644 ---- a/mm/Makefile -+++ b/mm/Makefile -@@ -21,7 +21,7 @@ obj-y := filemap.o mempool.o oom_kill.o \ - mm_init.o mmu_context.o percpu.o slab_common.o \ - compaction.o vmacache.o \ - interval_tree.o list_lru.o workingset.o \ -- debug.o $(mmu-y) -+ prfile.o debug.o $(mmu-y) +diff -Nurp linux-4.4.3/MAINTAINERS linux-4.4.3-aufs/MAINTAINERS +--- linux-4.4.3/MAINTAINERS 2016-03-02 17:42:59.404713024 +0200 ++++ linux-4.4.3-aufs/MAINTAINERS 2016-03-02 17:59:37.360498681 +0200 +@@ -2029,6 +2029,19 @@ F: include/linux/audit.h + F: include/uapi/linux/audit.h + F: kernel/audit* - obj-y += init-mm.o - -diff --git a/mm/filemap.c b/mm/filemap.c -index 1bb0076..8eaece8 100644 ---- a/mm/filemap.c -+++ b/mm/filemap.c -@@ -2128,7 +2128,7 @@ int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) ++AUFS (advanced multi layered unification filesystem) FILESYSTEM ++M: "J. R. Okajima" ++L: linux-unionfs@vger.kernel.org ++L: aufs-users@lists.sourceforge.net (members only) ++W: http://aufs.sourceforge.net ++T: git://github.com/sfjro/aufs4-linux.git ++S: Supported ++F: Documentation/filesystems/aufs/ ++F: Documentation/ABI/testing/debugfs-aufs ++F: Documentation/ABI/testing/sysfs-aufs ++F: fs/aufs/ ++F: include/uapi/linux/aufs_type.h ++ + AUXILIARY DISPLAY DRIVERS + M: Miguel Ojeda Sandonis + W: http://miguelojeda.es/auxdisplay.htm +diff -Nurp linux-4.4.3/mm/filemap.c linux-4.4.3-aufs/mm/filemap.c +--- linux-4.4.3/mm/filemap.c 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs/mm/filemap.c 2016-03-02 17:59:37.379498817 +0200 +@@ -2128,7 +2128,7 @@ int filemap_page_mkwrite(struct vm_area_ int ret = VM_FAULT_LOCKED; sb_start_pagefault(inode->i_sb); @@ -34060,11 +34068,22 @@ index 1bb0076..8eaece8 100644 lock_page(page); if (page->mapping != inode->i_mapping) { unlock_page(page); -diff --git a/mm/memory.c b/mm/memory.c -index c387430..d434404 100644 ---- a/mm/memory.c -+++ b/mm/memory.c -@@ -2035,7 +2035,7 @@ static inline int wp_page_reuse(struct mm_struct *mm, +diff -Nurp linux-4.4.3/mm/Makefile linux-4.4.3-aufs/mm/Makefile +--- linux-4.4.3/mm/Makefile 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs/mm/Makefile 2016-03-02 17:59:37.379498817 +0200 +@@ -21,7 +21,7 @@ obj-y := filemap.o mempool.o oom_kill. + mm_init.o mmu_context.o percpu.o slab_common.o \ + compaction.o vmacache.o \ + interval_tree.o list_lru.o workingset.o \ +- debug.o $(mmu-y) ++ prfile.o debug.o $(mmu-y) + + obj-y += init-mm.o + +diff -Nurp linux-4.4.3/mm/memory.c linux-4.4.3-aufs/mm/memory.c +--- linux-4.4.3/mm/memory.c 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs/mm/memory.c 2016-03-02 17:59:37.379498817 +0200 +@@ -2035,7 +2035,7 @@ static inline int wp_page_reuse(struct m } if (!page_mkwrite) @@ -34073,11 +34092,10 @@ index c387430..d434404 100644 } return VM_FAULT_WRITE; -diff --git a/mm/mmap.c b/mm/mmap.c -index 2ce04a6..f555c0a 100644 ---- a/mm/mmap.c -+++ b/mm/mmap.c -@@ -275,7 +275,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) +diff -Nurp linux-4.4.3/mm/mmap.c linux-4.4.3-aufs/mm/mmap.c +--- linux-4.4.3/mm/mmap.c 2016-03-02 17:42:59.457713370 +0200 ++++ linux-4.4.3-aufs/mm/mmap.c 2016-03-02 17:59:37.380498824 +0200 +@@ -275,7 +275,7 @@ static struct vm_area_struct *remove_vma if (vma->vm_ops && vma->vm_ops->close) vma->vm_ops->close(vma); if (vma->vm_file) @@ -34086,7 +34104,7 @@ index 2ce04a6..f555c0a 100644 mpol_put(vma_policy(vma)); kmem_cache_free(vm_area_cachep, vma); return next; -@@ -887,7 +887,7 @@ again: remove_next = 1 + (end > next->vm_end); +@@ -891,7 +891,7 @@ again: remove_next = 1 + (end > next-> if (remove_next) { if (file) { uprobe_munmap(next, next->vm_start, next->vm_end); @@ -34095,7 +34113,7 @@ index 2ce04a6..f555c0a 100644 } if (next->anon_vma) anon_vma_merge(vma, next); -@@ -1681,8 +1681,8 @@ out: +@@ -1685,8 +1685,8 @@ out: return addr; unmap_and_free_vma: @@ -34105,7 +34123,7 @@ index 2ce04a6..f555c0a 100644 /* Undo any partial mapping done by a device driver. */ unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end); -@@ -2488,7 +2488,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2483,7 +2483,7 @@ static int __split_vma(struct mm_struct goto out_free_mpol; if (new->vm_file) @@ -34114,7 +34132,7 @@ index 2ce04a6..f555c0a 100644 if (new->vm_ops && new->vm_ops->open) new->vm_ops->open(new); -@@ -2507,7 +2507,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2502,7 +2502,7 @@ static int __split_vma(struct mm_struct if (new->vm_ops && new->vm_ops->close) new->vm_ops->close(new); if (new->vm_file) @@ -34123,7 +34141,7 @@ index 2ce04a6..f555c0a 100644 unlink_anon_vmas(new); out_free_mpol: mpol_put(vma_policy(new)); -@@ -2649,7 +2649,6 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, +@@ -2644,7 +2644,6 @@ SYSCALL_DEFINE5(remap_file_pages, unsign struct vm_area_struct *vma; unsigned long populate = 0; unsigned long ret = -EINVAL; @@ -34131,8 +34149,8 @@ index 2ce04a6..f555c0a 100644 pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. " "See Documentation/vm/remap_file_pages.txt.\n", -@@ -2693,10 +2692,10 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, - munlock_vma_pages_range(vma, start, start + size); +@@ -2712,10 +2711,10 @@ SYSCALL_DEFINE5(remap_file_pages, unsign + } } - file = get_file(vma->vm_file); @@ -34144,7 +34162,7 @@ index 2ce04a6..f555c0a 100644 out: up_write(&mm->mmap_sem); if (populate) -@@ -2966,7 +2965,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, +@@ -2985,7 +2984,7 @@ struct vm_area_struct *copy_vma(struct v if (anon_vma_clone(new_vma, vma)) goto out_free_mempol; if (new_vma->vm_file) @@ -34153,11 +34171,10 @@ index 2ce04a6..f555c0a 100644 if (new_vma->vm_ops && new_vma->vm_ops->open) new_vma->vm_ops->open(new_vma); vma_link(mm, new_vma, prev, rb_link, rb_parent); -diff --git a/mm/nommu.c b/mm/nommu.c -index 92be862..29179f7 100644 ---- a/mm/nommu.c -+++ b/mm/nommu.c -@@ -671,7 +671,7 @@ static void __put_nommu_region(struct vm_region *region) +diff -Nurp linux-4.4.3/mm/nommu.c linux-4.4.3-aufs/mm/nommu.c +--- linux-4.4.3/mm/nommu.c 2016-01-11 01:01:32.000000000 +0200 ++++ linux-4.4.3-aufs/mm/nommu.c 2016-03-02 17:59:37.380498824 +0200 +@@ -671,7 +671,7 @@ static void __put_nommu_region(struct vm up_write(&nommu_region_sem); if (region->vm_file) @@ -34166,7 +34183,7 @@ index 92be862..29179f7 100644 /* IO memory and memory shared directly out of the pagecache * from ramfs/tmpfs mustn't be released here */ -@@ -829,7 +829,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma) +@@ -829,7 +829,7 @@ static void delete_vma(struct mm_struct if (vma->vm_ops && vma->vm_ops->close) vma->vm_ops->close(vma); if (vma->vm_file) @@ -34197,11 +34214,9 @@ index 92be862..29179f7 100644 kmem_cache_free(vm_area_cachep, vma); return ret; -diff --git a/mm/prfile.c b/mm/prfile.c -new file mode 100644 -index 0000000..b323b8a ---- /dev/null -+++ b/mm/prfile.c +diff -Nurp linux-4.4.3/mm/prfile.c linux-4.4.3-aufs/mm/prfile.c +--- linux-4.4.3/mm/prfile.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-4.4.3-aufs/mm/prfile.c 2016-03-02 17:59:37.380498824 +0200 @@ -0,0 +1,86 @@ +/* + * Mainly for aufs which mmap(2) diffrent file and wants to print different path diff --git a/kernel/kernel/files/patches/mageia/fs-ovl-allow-zero-size-xattr.patch b/kernel/kernel/files/patches/mageia/fs-ovl-allow-zero-size-xattr.patch deleted file mode 100644 index e506728f..00000000 --- a/kernel/kernel/files/patches/mageia/fs-ovl-allow-zero-size-xattr.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 97daf8b97ad6f913a34c82515be64dc9ac08d63e Mon Sep 17 00:00:00 2001 -From: Miklos Szeredi -Date: Tue, 10 Nov 2015 17:08:41 +0100 -Subject: [PATCH 1/6] ovl: allow zero size xattr - -When ovl_copy_xattr() encountered a zero size xattr no more xattrs were -copied and the function returned success. This is clearly not the desired -behavior. - -Signed-off-by: Miklos Szeredi -Cc: ---- - fs/overlayfs/copy_up.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c -index 871fcb6..394e87f 100644 ---- a/fs/overlayfs/copy_up.c -+++ b/fs/overlayfs/copy_up.c -@@ -54,7 +54,7 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new) - - for (name = buf; name < (buf + list_size); name += strlen(name) + 1) { - size = vfs_getxattr(old, name, value, XATTR_SIZE_MAX); -- if (size <= 0) { -+ if (size < 0) { - error = size; - goto out_free_value; - } --- -2.7.0 - diff --git a/kernel/kernel/files/patches/mageia/fs-ovl-check-dentry-positiveness-in-ovl_cleanup_whiteou.patch b/kernel/kernel/files/patches/mageia/fs-ovl-check-dentry-positiveness-in-ovl_cleanup_whiteou.patch deleted file mode 100644 index d2c30236..00000000 --- a/kernel/kernel/files/patches/mageia/fs-ovl-check-dentry-positiveness-in-ovl_cleanup_whiteou.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 84889d49335627bc770b32787c1ef9ebad1da232 Mon Sep 17 00:00:00 2001 -From: Konstantin Khlebnikov -Date: Mon, 16 Nov 2015 18:44:11 +0300 -Subject: [PATCH 6/6] ovl: check dentry positiveness in ovl_cleanup_whiteouts() - -This patch fixes kernel crash at removing directory which contains -whiteouts from lower layers. - -Cache of directory content passed as "list" contains entries from all -layers, including whiteouts from lower layers. So, lookup in upper dir -(moved into work at this stage) will return negative entry. Plus this -cache is filled long before and we can race with external removal. - -Example: - mkdir -p lower0/dir lower1/dir upper work overlay - touch lower0/dir/a lower0/dir/b - mknod lower1/dir/a c 0 0 - mount -t overlay none overlay -o lowerdir=lower1:lower0,upperdir=upper,workdir=work - rm -fr overlay/dir - -Signed-off-by: Konstantin Khlebnikov -Signed-off-by: Miklos Szeredi -Cc: # 3.18+ ---- - fs/overlayfs/readdir.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c -index 70e9af5..adcb139 100644 ---- a/fs/overlayfs/readdir.c -+++ b/fs/overlayfs/readdir.c -@@ -571,7 +571,8 @@ void ovl_cleanup_whiteouts(struct dentry *upper, struct list_head *list) - (int) PTR_ERR(dentry)); - continue; - } -- ovl_cleanup(upper->d_inode, dentry); -+ if (dentry->d_inode) -+ ovl_cleanup(upper->d_inode, dentry); - dput(dentry); - } - mutex_unlock(&upper->d_inode->i_mutex); --- -2.7.0 - diff --git a/kernel/kernel/files/patches/mageia/fs-ovl-root-copy-attr.patch b/kernel/kernel/files/patches/mageia/fs-ovl-root-copy-attr.patch deleted file mode 100644 index 73613b7e..00000000 --- a/kernel/kernel/files/patches/mageia/fs-ovl-root-copy-attr.patch +++ /dev/null @@ -1,33 +0,0 @@ -From ed06e069775ad9236087594a1c1667367e983fb5 Mon Sep 17 00:00:00 2001 -From: Miklos Szeredi -Date: Wed, 9 Dec 2015 16:11:59 +0100 -Subject: [PATCH 4/6] ovl: root: copy attr - -We copy i_uid and i_gid of underlying inode into overlayfs inode. Except -for the root inode. - -Fix this omission. - -Signed-off-by: Miklos Szeredi -Cc: ---- - fs/overlayfs/super.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c -index 32f3124..ec31711 100644 ---- a/fs/overlayfs/super.c -+++ b/fs/overlayfs/super.c -@@ -1079,6 +1079,9 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) - - root_dentry->d_fsdata = oe; - -+ ovl_copyattr(ovl_dentry_real(root_dentry)->d_inode, -+ root_dentry->d_inode); -+ - sb->s_magic = OVERLAYFS_SUPER_MAGIC; - sb->s_op = &ovl_super_operations; - sb->s_root = root_dentry; --- -2.7.0 - diff --git a/kernel/kernel/files/patches/mageia/fs-ovl-setattr-check-permissions-before-copy-up.patch b/kernel/kernel/files/patches/mageia/fs-ovl-setattr-check-permissions-before-copy-up.patch deleted file mode 100644 index 91014154..00000000 --- a/kernel/kernel/files/patches/mageia/fs-ovl-setattr-check-permissions-before-copy-up.patch +++ /dev/null @@ -1,65 +0,0 @@ -From cf9a6784f7c1b5ee2b9159a1246e327c331c5697 Mon Sep 17 00:00:00 2001 -From: Miklos Szeredi -Date: Fri, 11 Dec 2015 16:30:49 +0100 -Subject: [PATCH 5/6] ovl: setattr: check permissions before copy-up - -Without this copy-up of a file can be forced, even without actually being -allowed to do anything on the file. - -[Arnd Bergmann] include for PAGE_CACHE_SIZE (used by -MAX_LFS_FILESIZE definition). - -Signed-off-by: Miklos Szeredi -Cc: ---- - fs/overlayfs/inode.c | 13 +++++++++++++ - fs/overlayfs/super.c | 2 ++ - 2 files changed, 15 insertions(+) - -diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c -index 7654631..213a726 100644 ---- a/fs/overlayfs/inode.c -+++ b/fs/overlayfs/inode.c -@@ -45,6 +45,19 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr) - int err; - struct dentry *upperdentry; - -+ /* -+ * Check for permissions before trying to copy-up. This is redundant -+ * since it will be rechecked later by ->setattr() on upper dentry. But -+ * without this, copy-up can be triggered by just about anybody. -+ * -+ * We don't initialize inode->size, which just means that -+ * inode_newsize_ok() will always check against MAX_LFS_FILESIZE and not -+ * check for a swapfile (which this won't be anyway). -+ */ -+ err = inode_change_ok(dentry->d_inode, attr); -+ if (err) -+ return err; -+ - err = ovl_want_write(dentry); - if (err) - goto out; -diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c -index ec31711..b08bf4d 100644 ---- a/fs/overlayfs/super.c -+++ b/fs/overlayfs/super.c -@@ -9,6 +9,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -936,6 +937,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) - } - - sb->s_stack_depth = 0; -+ sb->s_maxbytes = MAX_LFS_FILESIZE; - if (ufs->config.upperdir) { - if (!ufs->config.workdir) { - pr_err("overlayfs: missing 'workdir'\n"); --- -2.7.0 - diff --git a/kernel/kernel/files/patches/mageia/fs-ovl-use-a-minimal-buffer-in-ovl_copy_xattr.patch b/kernel/kernel/files/patches/mageia/fs-ovl-use-a-minimal-buffer-in-ovl_copy_xattr.patch deleted file mode 100644 index 59eb828b..00000000 --- a/kernel/kernel/files/patches/mageia/fs-ovl-use-a-minimal-buffer-in-ovl_copy_xattr.patch +++ /dev/null @@ -1,89 +0,0 @@ -From e4ad29fa0d224d05e08b2858e65f112fd8edd4fe Mon Sep 17 00:00:00 2001 -From: Vito Caputo -Date: Sat, 24 Oct 2015 07:19:46 -0500 -Subject: [PATCH 2/6] ovl: use a minimal buffer in ovl_copy_xattr - -Rather than always allocating the high-order XATTR_SIZE_MAX buffer -which is costly and prone to failure, only allocate what is needed and -realloc if necessary. - -Fixes https://github.com/coreos/bugs/issues/489 - -Signed-off-by: Miklos Szeredi -Cc: ---- - fs/overlayfs/copy_up.c | 39 +++++++++++++++++++++++++-------------- - 1 file changed, 25 insertions(+), 14 deletions(-) - -diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c -index 394e87f..758012b 100644 ---- a/fs/overlayfs/copy_up.c -+++ b/fs/overlayfs/copy_up.c -@@ -22,9 +22,9 @@ - - int ovl_copy_xattr(struct dentry *old, struct dentry *new) - { -- ssize_t list_size, size; -- char *buf, *name, *value; -- int error; -+ ssize_t list_size, size, value_size = 0; -+ char *buf, *name, *value = NULL; -+ int uninitialized_var(error); - - if (!old->d_inode->i_op->getxattr || - !new->d_inode->i_op->getxattr) -@@ -41,29 +41,40 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new) - if (!buf) - return -ENOMEM; - -- error = -ENOMEM; -- value = kmalloc(XATTR_SIZE_MAX, GFP_KERNEL); -- if (!value) -- goto out; -- - list_size = vfs_listxattr(old, buf, list_size); - if (list_size <= 0) { - error = list_size; -- goto out_free_value; -+ goto out; - } - - for (name = buf; name < (buf + list_size); name += strlen(name) + 1) { -- size = vfs_getxattr(old, name, value, XATTR_SIZE_MAX); -+retry: -+ size = vfs_getxattr(old, name, value, value_size); -+ if (size == -ERANGE) -+ size = vfs_getxattr(old, name, NULL, 0); -+ - if (size < 0) { - error = size; -- goto out_free_value; -+ break; -+ } -+ -+ if (size > value_size) { -+ void *new; -+ -+ new = krealloc(value, size, GFP_KERNEL); -+ if (!new) { -+ error = -ENOMEM; -+ break; -+ } -+ value = new; -+ value_size = size; -+ goto retry; - } -+ - error = vfs_setxattr(new, name, value, size, 0); - if (error) -- goto out_free_value; -+ break; - } -- --out_free_value: - kfree(value); - out: - kfree(buf); --- -2.7.0 - diff --git a/kernel/kernel/files/patches/mageia/fs-xfs-Revert-xfs-clear-PF_NOFREEZE-for-xfsaild-kthread.patch b/kernel/kernel/files/patches/mageia/fs-xfs-Revert-xfs-clear-PF_NOFREEZE-for-xfsaild-kthread.patch deleted file mode 100644 index 5c483f7f..00000000 --- a/kernel/kernel/files/patches/mageia/fs-xfs-Revert-xfs-clear-PF_NOFREEZE-for-xfsaild-kthread.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 3e85286e75224fa3f08bdad20e78c8327742634e Mon Sep 17 00:00:00 2001 -From: Dave Chinner -Date: Tue, 19 Jan 2016 08:21:46 +1100 -Subject: [PATCH] Revert "xfs: clear PF_NOFREEZE for xfsaild kthread" - -This reverts commit 24ba16bb3d499c49974669cd8429c3e4138ab102 as it -prevents machines from suspending. This regression occurs when the -xfsaild is idle on entry to suspend, and so there s no activity to -wake it from it's idle sleep and hence see that it is supposed to -freeze. Hence the freezer times out waiting for it and suspend is -cancelled. - -There is no obvious fix for this short of freezing the filesystem -properly, so revert this change for now. - -cc: # 4.4 -Signed-off-by: Dave Chinner -Acked-by: Jiri Kosina -Reviewed-by: Brian Foster -Signed-off-by: Dave Chinner ---- - fs/xfs/xfs_trans_ail.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c -index aa67339..4f18fd9 100644 ---- a/fs/xfs/xfs_trans_ail.c -+++ b/fs/xfs/xfs_trans_ail.c -@@ -497,7 +497,6 @@ xfsaild( - long tout = 0; /* milliseconds */ - - current->flags |= PF_MEMALLOC; -- set_freezable(); - - while (!kthread_should_stop()) { - if (tout && tout <= 20) --- -2.7.1 - diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-Fix-drm_vblank_pre_post_modeset-regression-from-Linux-4.4.patch b/kernel/kernel/files/patches/mageia/gpu-drm-Fix-drm_vblank_pre_post_modeset-regression-from-Linux-4.4.patch deleted file mode 100644 index df761c07..00000000 --- a/kernel/kernel/files/patches/mageia/gpu-drm-Fix-drm_vblank_pre_post_modeset-regression-from-Linux-4.4.patch +++ /dev/null @@ -1,82 +0,0 @@ -From: Mario Kleiner -Subject: [PATCH 3/6] drm: Fix drm_vblank_pre/post_modeset regression from Linux 4.4 -Date: Fri, 12 Feb 2016 20:30:29 +0100 - -Changes to drm_update_vblank_count() in Linux 4.4 broke the -behaviour of the pre/post modeset functions as the new update -code doesn't deal with hw vblank counter resets inbetween calls -to drm_vblank_pre_modeset an drm_vblank_post_modeset, as it -should. - -This causes mistreatment of such hw counter resets as counter -wraparound, and thereby large forward jumps of the software -vblank counter which in turn cause vblank event dispatching -and vblank waits to fail/hang --> userspace clients hang. - -This symptom was reported on radeon-kms to cause a infinite -hang of KDE Plasma 5 shell's login procedure, preventing users -from logging in. - -Fix this by detecting when drm_update_vblank_count() is called -inside a pre->post modeset interval. If so, clamp valid vblank -increments to the safe values 0 and 1, pretty much restoring -the update behavior of the old update code of Linux 4.3 and -earlier. Also reset the last recorded hw vblank count at call -to drm_vblank_post_modeset() to be safe against hw that after -modesetting, dpms on etc. only fires its first vblank irq after -drm_vblank_post_modeset() was already called. - -Reported-by: Vlastimil Babka -Signed-off-by: Mario Kleiner -Reviewed-by: Daniel Vetter -Tested-by: Vlastimil Babka - -Cc: # 4.4+ -Cc: michel@daenzer.net -Cc: vbabka@suse.cz -Cc: ville.syrjala@linux.intel.com -Cc: daniel.vetter@ffwll.ch -Cc: dri-devel@lists.freedesktop.org -Cc: alexander.deucher@amd.com -Cc: christian.koenig@amd.com ---- - drivers/gpu/drm/drm_irq.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c -index 92ad62f..055b0fa 100644 ---- a/drivers/gpu/drm/drm_irq.c -+++ b/drivers/gpu/drm/drm_irq.c -@@ -222,6 +222,21 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe, - } - - /* -+ * Within a drm_vblank_pre_modeset - drm_vblank_post_modeset -+ * interval? If so then vblank irqs keep running and it will likely -+ * happen that the hardware vblank counter is not trustworthy as it -+ * might reset at some point in that interval and vblank timestamps -+ * are not trustworthy either in that interval. Iow. this can result -+ * in a bogus diff >> 1 which must be avoided as it would cause -+ * random large forward jumps of the software vblank counter. -+ */ -+ if (diff > 1 && (vblank->inmodeset & 0x2)) { -+ DRM_DEBUG_VBL("clamping vblank bump to 1 on crtc %u: diffr=%u" -+ " due to pre-modeset.\n", pipe, diff); -+ diff = 1; -+ } -+ -+ /* - * FIMXE: Need to replace this hack with proper seqlocks. - * - * Restrict the bump of the software vblank counter to a safe maximum -@@ -1575,6 +1590,7 @@ void drm_vblank_post_modeset(struct drm_device *dev, unsigned int pipe) - if (vblank->inmodeset) { - spin_lock_irqsave(&dev->vbl_lock, irqflags); - dev->vblank_disable_allowed = true; -+ drm_reset_vblank_timestamp(dev, pipe); - spin_unlock_irqrestore(&dev->vbl_lock, irqflags); - - if (vblank->inmodeset & 0x2) --- -1.9.1 - diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-Fix-treatment-of-drm_vblank_offdelay-in-drm_vblank_on-v2.patch b/kernel/kernel/files/patches/mageia/gpu-drm-Fix-treatment-of-drm_vblank_offdelay-in-drm_vblank_on-v2.patch deleted file mode 100644 index 246229bd..00000000 --- a/kernel/kernel/files/patches/mageia/gpu-drm-Fix-treatment-of-drm_vblank_offdelay-in-drm_vblank_on-v2.patch +++ /dev/null @@ -1,64 +0,0 @@ -From: Mario Kleiner -Subject: [PATCH 4/6] drm: Fix treatment of drm_vblank_offdelay in drm_vblank_on() (v2) -Date: Fri, 12 Feb 2016 20:30:30 +0100 - -drm_vblank_offdelay can have three different types of values: - -< 0 is to be always treated the same as dev->vblank_disable_immediate -= 0 is to be treated as "never disable vblanks" -> 0 is to be treated as disable immediate if kms driver wants it - that way via dev->vblank_disable_immediate. Otherwise it is - a disable timeout in msecs. - -This got broken in Linux 3.18+ for the implementation of -drm_vblank_on. If the user specified a value of zero which should -always reenable vblank irqs in this function, a kms driver could -override the users choice by setting vblank_disable_immediate -to true. This patch fixes the regression and keeps the user in -control. - -v2: Only reenable vblank if there are clients left or the user - requested to "never disable vblanks" via offdelay 0. Enabling - vblanks even in the "delayed disable" case (offdelay > 0) was - specifically added by Ville in commit cd19e52aee922 - ("drm: Kick start vblank interrupts at drm_vblank_on()"), - but after discussion it turns out that this was done by accident. - - Citing Ville: "I think it just ended up as a mess due to changing - some of the semantics of offdelay<0 vs. offdelay==0 vs. - disable_immediate during the review of the series. So yeah, given - how drm_vblank_put() works now, I'd just make this check for - offdelay==0." - -Signed-off-by: Mario Kleiner -Reviewed-by: Daniel Vetter - -Cc: # 3.18+ -Cc: michel@daenzer.net -Cc: vbabka@suse.cz -Cc: ville.syrjala@linux.intel.com -Cc: daniel.vetter@ffwll.ch -Cc: dri-devel@lists.freedesktop.org -Cc: alexander.deucher@amd.com -Cc: christian.koenig@amd.com ---- - drivers/gpu/drm/drm_irq.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c -index 055b0fa..8090989 100644 ---- a/drivers/gpu/drm/drm_irq.c -+++ b/drivers/gpu/drm/drm_irq.c -@@ -1494,8 +1494,7 @@ void drm_vblank_on(struct drm_device *dev, unsigned int pipe) - * re-enable interrupts if there are users left, or the - * user wishes vblank interrupts to be enabled all the time. - */ -- if (atomic_read(&vblank->refcount) != 0 || -- (!dev->vblank_disable_immediate && drm_vblank_offdelay == 0)) -+ if (atomic_read(&vblank->refcount) != 0 || drm_vblank_offdelay == 0) - WARN_ON(drm_vblank_enable(dev, pipe)); - spin_unlock_irqrestore(&dev->vbl_lock, irqflags); - } --- -1.9.1 - diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-No-Op-redundant-calls-to-drm_vblank_off-v2.patch b/kernel/kernel/files/patches/mageia/gpu-drm-No-Op-redundant-calls-to-drm_vblank_off-v2.patch deleted file mode 100644 index 480c88ba..00000000 --- a/kernel/kernel/files/patches/mageia/gpu-drm-No-Op-redundant-calls-to-drm_vblank_off-v2.patch +++ /dev/null @@ -1,76 +0,0 @@ -From: Mario Kleiner -Subject: [PATCH 1/6] drm: No-Op redundant calls to drm_vblank_off() (v2) -Date: Fri, 12 Feb 2016 20:30:27 +0100 - -Otherwise if a kms driver calls into drm_vblank_off() more than once -before calling drm_vblank_on() again, the redundant calls to -vblank_disable_and_save() will call drm_update_vblank_count() -while hw vblank counters and vblank timestamping are in a undefined -state during modesets, dpms off etc. - -At least with the legacy drm helpers it is not unusual to -get multiple calls to drm_vblank_off and drm_vblank_on, e.g., -half a dozen calls to drm_vblank_off and two calls to drm_vblank_on -were observed on radeon-kms during dpms-off -> dpms-on transition. - -We don't no-op calls from atomic modesetting drivers, as they -should do a proper job of tracking hw state. - -Fixes large jumps of the software maintained vblank counter due to -the hardware vblank counter resetting to zero during dpms off or -modeset, e.g., if radeon-kms is modified to use drm_vblank_off/on -instead of drm_vblank_pre/post_modeset(). - -This fixes a regression caused by the changes made to -drm_update_vblank_count() in Linux 4.4. - -v2: Don't no-op on atomic modesetting drivers, per suggestion - of Daniel Vetter. - -Signed-off-by: Mario Kleiner -Reviewed-by: Daniel Vetter - -Cc: # 4.4+ -Cc: michel@daenzer.net -Cc: vbabka@suse.cz -Cc: ville.syrjala@linux.intel.com -Cc: daniel.vetter@ffwll.ch -Cc: dri-devel@lists.freedesktop.org -Cc: alexander.deucher@amd.com -Cc: christian.koenig@amd.com ---- - drivers/gpu/drm/drm_irq.c | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c -index 607f493..1a18033 100644 ---- a/drivers/gpu/drm/drm_irq.c -+++ b/drivers/gpu/drm/drm_irq.c -@@ -1313,7 +1313,13 @@ void drm_vblank_off(struct drm_device *dev, unsigned int pipe) - spin_lock_irqsave(&dev->event_lock, irqflags); - - spin_lock(&dev->vbl_lock); -- vblank_disable_and_save(dev, pipe); -+ DRM_DEBUG_VBL("crtc %d, vblank enabled %d, inmodeset %d\n", -+ pipe, vblank->enabled, vblank->inmodeset); -+ -+ /* Avoid redundant vblank disables without previous drm_vblank_on(). */ -+ if (drm_core_check_feature(dev, DRIVER_ATOMIC) || !vblank->inmodeset) -+ vblank_disable_and_save(dev, pipe); -+ - wake_up(&vblank->queue); - - /* -@@ -1415,6 +1421,9 @@ void drm_vblank_on(struct drm_device *dev, unsigned int pipe) - return; - - spin_lock_irqsave(&dev->vbl_lock, irqflags); -+ DRM_DEBUG_VBL("crtc %d, vblank enabled %d, inmodeset %d\n", -+ pipe, vblank->enabled, vblank->inmodeset); -+ - /* Drop our private "prevent drm_vblank_get" refcount */ - if (vblank->inmodeset) { - atomic_dec(&vblank->refcount); --- -1.9.1 - diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-Prevent-vblank-counter-bumps-1-with-active-vblank-clients-v2.patch b/kernel/kernel/files/patches/mageia/gpu-drm-Prevent-vblank-counter-bumps-1-with-active-vblank-clients-v2.patch deleted file mode 100644 index c65efe96..00000000 --- a/kernel/kernel/files/patches/mageia/gpu-drm-Prevent-vblank-counter-bumps-1-with-active-vblank-clients-v2.patch +++ /dev/null @@ -1,120 +0,0 @@ -From: Mario Kleiner -Subject: [PATCH 2/6] drm: Prevent vblank counter bumps > 1 with active vblank clients. (v2) -Date: Fri, 12 Feb 2016 20:30:28 +0100 - -This fixes a regression introduced by the new drm_update_vblank_count() -implementation in Linux 4.4: - -Restrict the bump of the software vblank counter in drm_update_vblank_count() -to a safe maximum value of +1 whenever there is the possibility that -concurrent readers of vblank timestamps could be active at the moment, -as the current implementation of the timestamp caching and updating is -not safe against concurrent readers for calls to store_vblank() with a -bump of anything but +1. A bump != 1 would very likely return corrupted -timestamps to userspace, because the same slot in the cache could -be concurrently written by store_vblank() and read by one of those -readers in a non-atomic fashion and without the read-retry logic -detecting this collision. - -Concurrent readers can exist while drm_update_vblank_count() is called -from the drm_vblank_off() or drm_vblank_on() functions or other non-vblank- -irq callers. However, all those calls are happening with the vbl_lock -locked thereby preventing a drm_vblank_get(), so the vblank refcount -can't increase while drm_update_vblank_count() is executing. Therefore -a zero vblank refcount during execution of that function signals that -is safe for arbitrary counter bumps if called from outside vblank irq, -whereas a non-zero count is not safe. - -Whenever the function is called from vblank irq, we have to assume concurrent -readers could show up any time during its execution, even if the refcount -is currently zero, as vblank irqs are usually only enabled due to the -presence of readers, and because when it is called from vblank irq it -can't hold the vbl_lock to protect it from sudden bumps in vblank refcount. -Therefore also restrict bumps to +1 when the function is called from vblank -irq. - -Such bumps of more than +1 can happen at other times than reenabling -vblank irqs, e.g., when regular vblank interrupts get delayed by more -than 1 frame due to long held locks, long irq off periods, realtime -preemption on RT kernels, or system management interrupts. - -A better solution would be to rewrite the timestamp caching to use -full seqlocks to allow concurrent writes and reads for arbitrary -vblank counter increments. - -v2: Add code comment that this is essentially a hack and should - be replaced by a full seqlock implementation for caching of - timestamps. - -Signed-off-by: Mario Kleiner -Reviewed-by: Daniel Vetter - -Cc: # 4.4+ -Cc: michel@daenzer.net -Cc: vbabka@suse.cz -Cc: ville.syrjala@linux.intel.com -Cc: daniel.vetter@ffwll.ch -Cc: dri-devel@lists.freedesktop.org -Cc: alexander.deucher@amd.com -Cc: christian.koenig@amd.com ---- - drivers/gpu/drm/drm_irq.c | 43 +++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 43 insertions(+) - -diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c -index 1a18033..92ad62f 100644 ---- a/drivers/gpu/drm/drm_irq.c -+++ b/drivers/gpu/drm/drm_irq.c -@@ -221,6 +221,49 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe, - diff = (flags & DRM_CALLED_FROM_VBLIRQ) != 0; - } - -+ /* -+ * FIMXE: Need to replace this hack with proper seqlocks. -+ * -+ * Restrict the bump of the software vblank counter to a safe maximum -+ * value of +1 whenever there is the possibility that concurrent readers -+ * of vblank timestamps could be active at the moment, as the current -+ * implementation of the timestamp caching and updating is not safe -+ * against concurrent readers for calls to store_vblank() with a bump -+ * of anything but +1. A bump != 1 would very likely return corrupted -+ * timestamps to userspace, because the same slot in the cache could -+ * be concurrently written by store_vblank() and read by one of those -+ * readers without the read-retry logic detecting the collision. -+ * -+ * Concurrent readers can exist when we are called from the -+ * drm_vblank_off() or drm_vblank_on() functions and other non-vblank- -+ * irq callers. However, all those calls to us are happening with the -+ * vbl_lock locked to prevent drm_vblank_get(), so the vblank refcount -+ * can't increase while we are executing. Therefore a zero refcount at -+ * this point is safe for arbitrary counter bumps if we are called -+ * outside vblank irq, a non-zero count is not 100% safe. Unfortunately -+ * we must also accept a refcount of 1, as whenever we are called from -+ * drm_vblank_get() -> drm_vblank_enable() the refcount will be 1 and -+ * we must let that one pass through in order to not lose vblank counts -+ * during vblank irq off - which would completely defeat the whole -+ * point of this routine. -+ * -+ * Whenever we are called from vblank irq, we have to assume concurrent -+ * readers exist or can show up any time during our execution, even if -+ * the refcount is currently zero, as vblank irqs are usually only -+ * enabled due to the presence of readers, and because when we are called -+ * from vblank irq we can't hold the vbl_lock to protect us from sudden -+ * bumps in vblank refcount. Therefore also restrict bumps to +1 when -+ * called from vblank irq. -+ */ -+ if ((diff > 1) && (atomic_read(&vblank->refcount) > 1 || -+ (flags & DRM_CALLED_FROM_VBLIRQ))) { -+ DRM_DEBUG_VBL("clamping vblank bump to 1 on crtc %u: diffr=%u " -+ "refcount %u, vblirq %u\n", pipe, diff, -+ atomic_read(&vblank->refcount), -+ (flags & DRM_CALLED_FROM_VBLIRQ) != 0); -+ diff = 1; -+ } -+ - DRM_DEBUG_VBL("updating vblank count on crtc %u:" - " current=%u, diff=%u, hw=%u hw_last=%u\n", - pipe, vblank->count, diff, cur_vblank, vblank->last); --- -1.9.1 - diff --git a/kernel/kernel/files/patches/mageia/gpu-drm_nouveau_display-Enable-vblank-irqs-after-display-engine-is-on-again.patch b/kernel/kernel/files/patches/mageia/gpu-drm_nouveau_display-Enable-vblank-irqs-after-display-engine-is-on-again.patch deleted file mode 100644 index 1db4ce1c..00000000 --- a/kernel/kernel/files/patches/mageia/gpu-drm_nouveau_display-Enable-vblank-irqs-after-display-engine-is-on-again.patch +++ /dev/null @@ -1,57 +0,0 @@ -From: Mario Kleiner -Subject: [PATCH 6/6] drm/nouveau/display: Enable vblank irqs after display engine is on again. -Date: Fri, 12 Feb 2016 20:30:32 +0100 - -In the display resume path, move the calls to drm_vblank_on() -after the point when the display engine is running again. - -Since changes were made to drm_update_vblank_count() in Linux 4.4+ -to emulate hw vblank counters via vblank timestamping, the function -drm_vblank_on() now needs working high precision vblank timestamping -and therefore working scanout position queries at time of call. -These don't work before the display engine gets restarted, causing -miscalculation of vblank counter increments and thereby large forward -jumps in vblank count at display resume. These jumps can cause client -hangs on resume, or desktop hangs in the case of composited desktops. - -Fix this Linux 4.4 regression by reordering calls accordingly. - -Signed-off-by: Mario Kleiner -Cc: # 4.4+ -Cc: Ben Skeggs -Cc: ville.syrjala@linux.intel.com -Cc: daniel.vetter@ffwll.ch -Cc: dri-devel@lists.freedesktop.org ---- - drivers/gpu/drm/nouveau/nouveau_display.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c -index 18676b8..1f8e51b 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_display.c -+++ b/drivers/gpu/drm/nouveau/nouveau_display.c -@@ -634,10 +634,6 @@ nouveau_display_resume(struct drm_device *dev, bool runtime) - nv_crtc->lut.depth = 0; - } - -- /* Make sure that drm and hw vblank irqs get resumed if needed. */ -- for (head = 0; head < dev->mode_config.num_crtc; head++) -- drm_vblank_on(dev, head); -- - /* This should ensure we don't hit a locking problem when someone - * wakes us up via a connector. We should never go into suspend - * while the display is on anyways. -@@ -647,6 +643,10 @@ nouveau_display_resume(struct drm_device *dev, bool runtime) - - drm_helper_resume_force_mode(dev); - -+ /* Make sure that drm and hw vblank irqs get resumed if needed. */ -+ for (head = 0; head < dev->mode_config.num_crtc; head++) -+ drm_vblank_on(dev, head); -+ - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - --- -1.9.1 - diff --git a/kernel/kernel/files/patches/mageia/libata-Align-ata_device-s-id-on-a-cacheline.patch b/kernel/kernel/files/patches/mageia/libata-Align-ata_device-s-id-on-a-cacheline.patch new file mode 100644 index 00000000..2892b5f1 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/libata-Align-ata_device-s-id-on-a-cacheline.patch @@ -0,0 +1,39 @@ +From 4ee34ea3a12396f35b26d90a094c75db95080baa Mon Sep 17 00:00:00 2001 +From: Harvey Hunt +Date: Wed, 24 Feb 2016 15:16:43 +0000 +Subject: [PATCH] libata: Align ata_device's id on a cacheline + +The id buffer in ata_device is a DMA target, but it isn't explicitly +cacheline aligned. Due to this, adjacent fields can be overwritten with +stale data from memory on non coherent architectures. As a result, the +kernel is sometimes unable to communicate with an ATA device. + +Fix this by ensuring that the id buffer is cacheline aligned. + +This issue is similar to that fixed by Commit 84bda12af31f +("libata: align ap->sector_buf"). + +Signed-off-by: Harvey Hunt +Cc: linux-kernel@vger.kernel.org +Cc: # 2.6.18 +Signed-off-by: Tejun Heo +--- + include/linux/libata.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/libata.h b/include/linux/libata.h +index bec2abb..2c4ebef 100644 +--- a/include/linux/libata.h ++++ b/include/linux/libata.h +@@ -720,7 +720,7 @@ struct ata_device { + union { + u16 id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */ + u32 gscr[SATA_PMP_GSCR_DWORDS]; /* PMP GSCR block */ +- }; ++ } ____cacheline_aligned; + + /* DEVSLP Timing Variables from Identify Device Data Log */ + u8 devslp_timing[ATA_LOG_DEVSLP_SIZE]; +-- +2.7.2 + diff --git a/kernel/kernel/files/patches/mageia/libata-fix-HDIO_GET_32BIT-ioctl.patch b/kernel/kernel/files/patches/mageia/libata-fix-HDIO_GET_32BIT-ioctl.patch new file mode 100644 index 00000000..b6a453cf --- /dev/null +++ b/kernel/kernel/files/patches/mageia/libata-fix-HDIO_GET_32BIT-ioctl.patch @@ -0,0 +1,98 @@ +From 287e6611ab1eac76c2c5ebf6e345e04c80ca9c61 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Thu, 11 Feb 2016 14:16:27 +0100 +Subject: [PATCH] libata: fix HDIO_GET_32BIT ioctl + +As reported by Soohoon Lee, the HDIO_GET_32BIT ioctl does not +work correctly in compat mode with libata. + +I have investigated the issue further and found multiple problems +that all appeared with the same commit that originally introduced +HDIO_GET_32BIT handling in libata back in linux-2.6.8 and presumably +also linux-2.4, as the code uses "copy_to_user(arg, &val, 1)" to copy +a 'long' variable containing either 0 or 1 to user space. + +The problems with this are: + +* On big-endian machines, this will always write a zero because it + stores the wrong byte into user space. + +* In compat mode, the upper three bytes of the variable are updated + by the compat_hdio_ioctl() function, but they now contain + uninitialized stack data. + +* The hdparm tool calling this ioctl uses a 'static long' variable + to store the result. This means at least the upper bytes are + initialized to zero, but calling another ioctl like HDIO_GET_MULTCOUNT + would fill them with data that remains stale when the low byte + is overwritten. Fortunately libata doesn't implement any of the + affected ioctl commands, so this would only happen when we query + both an IDE and an ATA device in the same command such as + "hdparm -N -c /dev/hda /dev/sda" + +* The libata code for unknown reasons started using ATA_IOC_GET_IO32 + and ATA_IOC_SET_IO32 as aliases for HDIO_GET_32BIT and HDIO_SET_32BIT, + while the ioctl commands that were added later use the normal + HDIO_* names. This is harmless but rather confusing. + +This addresses all four issues by changing the code to use put_user() +on an 'unsigned long' variable in HDIO_GET_32BIT, like the IDE subsystem +does, and by clarifying the names of the ioctl commands. + +Signed-off-by: Arnd Bergmann +Reported-by: Soohoon Lee +Tested-by: Soohoon Lee +Cc: stable@vger.kernel.org +Signed-off-by: Tejun Heo +--- + drivers/ata/libata-scsi.c | 11 +++++------ + include/linux/ata.h | 4 ++-- + 2 files changed, 7 insertions(+), 8 deletions(-) + +diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c +index 7e959f9..e417e1a 100644 +--- a/drivers/ata/libata-scsi.c ++++ b/drivers/ata/libata-scsi.c +@@ -675,19 +675,18 @@ static int ata_ioc32(struct ata_port *ap) + int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev, + int cmd, void __user *arg) + { +- int val = -EINVAL, rc = -EINVAL; ++ unsigned long val; ++ int rc = -EINVAL; + unsigned long flags; + + switch (cmd) { +- case ATA_IOC_GET_IO32: ++ case HDIO_GET_32BIT: + spin_lock_irqsave(ap->lock, flags); + val = ata_ioc32(ap); + spin_unlock_irqrestore(ap->lock, flags); +- if (copy_to_user(arg, &val, 1)) +- return -EFAULT; +- return 0; ++ return put_user(val, (unsigned long __user *)arg); + +- case ATA_IOC_SET_IO32: ++ case HDIO_SET_32BIT: + val = (unsigned long) arg; + rc = 0; + spin_lock_irqsave(ap->lock, flags); +diff --git a/include/linux/ata.h b/include/linux/ata.h +index d2992bf..c1a2f34 100644 +--- a/include/linux/ata.h ++++ b/include/linux/ata.h +@@ -487,8 +487,8 @@ enum ata_tf_protocols { + }; + + enum ata_ioctls { +- ATA_IOC_GET_IO32 = 0x309, +- ATA_IOC_SET_IO32 = 0x324, ++ ATA_IOC_GET_IO32 = 0x309, /* HDIO_GET_32BIT */ ++ ATA_IOC_SET_IO32 = 0x324, /* HDIO_SET_32BIT */ + }; + + /* core structures */ +-- +2.7.2 + diff --git a/kernel/kernel/files/patches/mageia/series b/kernel/kernel/files/patches/mageia/series index 331e7847..9a73c795 100644 --- a/kernel/kernel/files/patches/mageia/series +++ b/kernel/kernel/files/patches/mageia/series @@ -14,6 +14,27 @@ ### ### Stable Queue ### +stable-use-d_seq-to-get-coherency-between-d_inode-and-d_flags.patch +stable-drivers-sh-restore-legacy-clock-domain-on-superh-platforms.patch +stable-btrfs-fix-deadlock-running-delayed-iputs-at-transaction-commit-time.patch +stable-btrfs-fix-no_space-in-write-and-rm-loop.patch +stable-btrfs-async-thread-fix-a-use-after-free-error-for-trace.patch +stable-drm-amdgpu-mask-out-wc-from-bo-on-unsupported-arches.patch +stable-block-initialize-max_dev_sectors-to-0.patch +stable-pci-keystone-fix-msi-code-that-retrieves-struct-pcie_port-pointer.patch +stable-parisc-fix-ptrace-syscall-number-and-return-value-modification.patch +stable-mips-kvm-fix-ioctl-error-handling.patch +stable-kvm-x86-update-tsc-multiplier-on-change.patch +stable-fbcon-set-a-default-value-to-blink-interval.patch +stable-cifs-fix-out-of-bounds-access-in-lease-parsing.patch +stable-cifs-fix-smb2-interim-response-processing-for-read-requests.patch +stable-fix-cifs_uniqueid_to_ino_t-function-for-s390x.patch +stable-vfio-fix-ioctl-error-handling.patch +stable-kvm-x86-fix-root-cause-for-missed-hardware-breakpoints.patch +stable-arm-arm64-kvm-fix-ioctl-error-handling.patch +stable-iommu-amd-apply-workaround-for-ats-write-permission-check.patch +stable-iommu-amd-fix-boot-warning-when-device-00-00.0-is-not-iommu-covered.patch +stable-iommu-vt-d-use-bus_notify_removed_device-in-hotplug-path.patch ### ### Arch x86 @@ -121,6 +142,14 @@ block-Make-CFQ-default-to-IOPS-mode-on-SSDs.patch # ahci ids ahci-add-new-Intel-device-IDs.patch +ata-Adding-Intel-Lewisburg-device-IDs-for-SATA.patch + +# fix unwanted automounting of partitions +ata-ahci-don-t-mark-HotPlugCapable-Ports-as-external.patch + +# libata fixes +libata-Align-ata_device-s-id-on-a-cacheline.patch +libata-fix-HDIO_GET_32BIT-ioctl.patch ### ### File-system @@ -131,15 +160,7 @@ fs-aufs-4.4.patch fs-aufs-4.4-modular.patch # ovl fixes -fs-ovl-allow-zero-size-xattr.patch -fs-ovl-use-a-minimal-buffer-in-ovl_copy_xattr.patch fs-ovl-move-super-block-magic-number-to-magic.h.patch -fs-ovl-root-copy-attr.patch -fs-ovl-setattr-check-permissions-before-copy-up.patch -fs-ovl-check-dentry-positiveness-in-ovl_cleanup_whiteou.patch - -# xfs trace fix (mga#17489) -fs-xfs-Revert-xfs-clear-PF_NOFREEZE-for-xfsaild-kthread.patch ### ### FireWire @@ -200,13 +221,6 @@ gpu-drm-0109-drm-vc4-Add-an-interface-for-capturing-the-GPU-state.patch gpu-drm-radeon-Update-radeon_get_vblank_counter_kms.patch gpu-drm-radeon-Drop-unnecessary-unsigned-int-0-check.patch -# vblank fixes -gpu-drm-No-Op-redundant-calls-to-drm_vblank_off-v2.patch -gpu-drm-Prevent-vblank-counter-bumps-1-with-active-vblank-clients-v2.patch -gpu-drm-Fix-drm_vblank_pre_post_modeset-regression-from-Linux-4.4.patch -gpu-drm-Fix-treatment-of-drm_vblank_offdelay-in-drm_vblank_on-v2.patch -gpu-drm_nouveau_display-Enable-vblank-irqs-after-display-engine-is-on-again.patch - ### ### Hardware Monitoring ### @@ -402,3 +416,7 @@ arm-0032-ARM-bcm2835-enable-auxiliary-spi-driver-in-defconfig.patch ### ### Tools ### + +### +### UAPI +### diff --git a/kernel/kernel/files/patches/mageia/stable-arm-arm64-kvm-fix-ioctl-error-handling.patch b/kernel/kernel/files/patches/mageia/stable-arm-arm64-kvm-fix-ioctl-error-handling.patch new file mode 100644 index 00000000..507fd847 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-arm-arm64-kvm-fix-ioctl-error-handling.patch @@ -0,0 +1,51 @@ +From 4cad67fca3fc952d6f2ed9e799621f07666a560f Mon Sep 17 00:00:00 2001 +From: "Michael S. Tsirkin" +Date: Sun, 28 Feb 2016 17:32:07 +0200 +Subject: arm/arm64: KVM: Fix ioctl error handling + +From: Michael S. Tsirkin + +commit 4cad67fca3fc952d6f2ed9e799621f07666a560f upstream. + +Calling return copy_to_user(...) in an ioctl will not +do the right thing if there's a pagefault: +copy_to_user returns the number of bytes not copied +in this case. + +Fix up kvm to do + return copy_to_user(...)) ? -EFAULT : 0; + +everywhere. + +Acked-by: Christoffer Dall +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Marc Zyngier +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/kvm/guest.c | 2 +- + arch/arm64/kvm/guest.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/arm/kvm/guest.c ++++ b/arch/arm/kvm/guest.c +@@ -155,7 +155,7 @@ static int get_timer_reg(struct kvm_vcpu + u64 val; + + val = kvm_arm_timer_get_reg(vcpu, reg->id); +- return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)); ++ return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)) ? -EFAULT : 0; + } + + static unsigned long num_core_regs(void) +--- a/arch/arm64/kvm/guest.c ++++ b/arch/arm64/kvm/guest.c +@@ -186,7 +186,7 @@ static int get_timer_reg(struct kvm_vcpu + u64 val; + + val = kvm_arm_timer_get_reg(vcpu, reg->id); +- return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)); ++ return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)) ? -EFAULT : 0; + } + + /** diff --git a/kernel/kernel/files/patches/mageia/stable-block-initialize-max_dev_sectors-to-0.patch b/kernel/kernel/files/patches/mageia/stable-block-initialize-max_dev_sectors-to-0.patch new file mode 100644 index 00000000..9546bf7a --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-block-initialize-max_dev_sectors-to-0.patch @@ -0,0 +1,36 @@ +From 5f009d3f8e6685fe8c6215082c1696a08b411220 Mon Sep 17 00:00:00 2001 +From: Keith Busch +Date: Wed, 10 Feb 2016 16:52:47 -0700 +Subject: block: Initialize max_dev_sectors to 0 + +From: Keith Busch + +commit 5f009d3f8e6685fe8c6215082c1696a08b411220 upstream. + +The new queue limit is not used by the majority of block drivers, and +should be initialized to 0 for the driver's requested settings to be used. + +Signed-off-by: Keith Busch +Acked-by: Martin K. Petersen +Reviewed-by: Sagi Grimberg +Reviewed-by: Christoph Hellwig +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + block/blk-settings.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/block/blk-settings.c ++++ b/block/blk-settings.c +@@ -91,8 +91,8 @@ void blk_set_default_limits(struct queue + lim->seg_boundary_mask = BLK_SEG_BOUNDARY_MASK; + lim->virt_boundary_mask = 0; + lim->max_segment_size = BLK_MAX_SEGMENT_SIZE; +- lim->max_sectors = lim->max_dev_sectors = lim->max_hw_sectors = +- BLK_SAFE_MAX_SECTORS; ++ lim->max_sectors = lim->max_hw_sectors = BLK_SAFE_MAX_SECTORS; ++ lim->max_dev_sectors = 0; + lim->chunk_sectors = 0; + lim->max_write_same_sectors = 0; + lim->max_discard_sectors = 0; diff --git a/kernel/kernel/files/patches/mageia/stable-btrfs-async-thread-fix-a-use-after-free-error-for-trace.patch b/kernel/kernel/files/patches/mageia/stable-btrfs-async-thread-fix-a-use-after-free-error-for-trace.patch new file mode 100644 index 00000000..25c4845c --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-btrfs-async-thread-fix-a-use-after-free-error-for-trace.patch @@ -0,0 +1,36 @@ +From 0a95b851370b84a4b9d92ee6d1fa0926901d0454 Mon Sep 17 00:00:00 2001 +From: Qu Wenruo +Date: Fri, 22 Jan 2016 09:28:38 +0800 +Subject: btrfs: async-thread: Fix a use-after-free error for trace + +From: Qu Wenruo + +commit 0a95b851370b84a4b9d92ee6d1fa0926901d0454 upstream. + +Parameter of trace_btrfs_work_queued() can be freed in its workqueue. +So no one use use that pointer after queue_work(). + +Fix the user-after-free bug by move the trace line before queue_work(). + +Reported-by: Dave Jones +Signed-off-by: Qu Wenruo +Reviewed-by: David Sterba +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/async-thread.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/btrfs/async-thread.c ++++ b/fs/btrfs/async-thread.c +@@ -328,8 +328,8 @@ static inline void __btrfs_queue_work(st + list_add_tail(&work->ordered_list, &wq->ordered_list); + spin_unlock_irqrestore(&wq->list_lock, flags); + } +- queue_work(wq->normal_wq, &work->normal_work); + trace_btrfs_work_queued(work); ++ queue_work(wq->normal_wq, &work->normal_work); + } + + void btrfs_queue_work(struct btrfs_workqueue *wq, diff --git a/kernel/kernel/files/patches/mageia/stable-btrfs-fix-deadlock-running-delayed-iputs-at-transaction-commit-time.patch b/kernel/kernel/files/patches/mageia/stable-btrfs-fix-deadlock-running-delayed-iputs-at-transaction-commit-time.patch new file mode 100644 index 00000000..2519f320 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-btrfs-fix-deadlock-running-delayed-iputs-at-transaction-commit-time.patch @@ -0,0 +1,238 @@ +From c2d6cb1636d235257086f939a8194ef0bf93af6e Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Fri, 15 Jan 2016 11:05:12 +0000 +Subject: Btrfs: fix deadlock running delayed iputs at transaction commit time + +From: Filipe Manana + +commit c2d6cb1636d235257086f939a8194ef0bf93af6e upstream. + +While running a stress test I ran into a deadlock when running the delayed +iputs at transaction time, which produced the following report and trace: + +[ 886.399989] ============================================= +[ 886.400871] [ INFO: possible recursive locking detected ] +[ 886.401663] 4.4.0-rc6-btrfs-next-18+ #1 Not tainted +[ 886.402384] --------------------------------------------- +[ 886.403182] fio/8277 is trying to acquire lock: +[ 886.403568] (&fs_info->delayed_iput_sem){++++..}, at: [] btrfs_run_delayed_iputs+0x36/0xbf [btrfs] +[ 886.403568] +[ 886.403568] but task is already holding lock: +[ 886.403568] (&fs_info->delayed_iput_sem){++++..}, at: [] btrfs_run_delayed_iputs+0x36/0xbf [btrfs] +[ 886.403568] +[ 886.403568] other info that might help us debug this: +[ 886.403568] Possible unsafe locking scenario: +[ 886.403568] +[ 886.403568] CPU0 +[ 886.403568] ---- +[ 886.403568] lock(&fs_info->delayed_iput_sem); +[ 886.403568] lock(&fs_info->delayed_iput_sem); +[ 886.403568] +[ 886.403568] *** DEADLOCK *** +[ 886.403568] +[ 886.403568] May be due to missing lock nesting notation +[ 886.403568] +[ 886.403568] 3 locks held by fio/8277: +[ 886.403568] #0: (sb_writers#11){.+.+.+}, at: [] __sb_start_write+0x5f/0xb0 +[ 886.403568] #1: (&sb->s_type->i_mutex_key#15){+.+.+.}, at: [] btrfs_file_write_iter+0x73/0x408 [btrfs] +[ 886.403568] #2: (&fs_info->delayed_iput_sem){++++..}, at: [] btrfs_run_delayed_iputs+0x36/0xbf [btrfs] +[ 886.403568] +[ 886.403568] stack backtrace: +[ 886.403568] CPU: 6 PID: 8277 Comm: fio Not tainted 4.4.0-rc6-btrfs-next-18+ #1 +[ 886.403568] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS by qemu-project.org 04/01/2014 +[ 886.403568] 0000000000000000 ffff88009f80f770 ffffffff8125d4fd ffffffff82af1fc0 +[ 886.403568] ffff88009f80f830 ffffffff8108e5f9 0000000200000000 ffff88009fd92290 +[ 886.403568] 0000000000000000 ffffffff82af1fc0 ffffffff829cfb01 00042b216d008804 +[ 886.403568] Call Trace: +[ 886.403568] [] dump_stack+0x4e/0x79 +[ 886.403568] [] __lock_acquire+0xd42/0xf0b +[ 886.403568] [] ? __module_address+0xdf/0x108 +[ 886.403568] [] lock_acquire+0x10d/0x194 +[ 886.403568] [] ? lock_acquire+0x10d/0x194 +[ 886.403568] [] ? btrfs_run_delayed_iputs+0x36/0xbf [btrfs] +[ 886.489542] [] down_read+0x3e/0x4d +[ 886.489542] [] ? btrfs_run_delayed_iputs+0x36/0xbf [btrfs] +[ 886.489542] [] btrfs_run_delayed_iputs+0x36/0xbf [btrfs] +[ 886.489542] [] btrfs_commit_transaction+0x8f5/0x96e [btrfs] +[ 886.489542] [] flush_space+0x435/0x44a [btrfs] +[ 886.489542] [] ? reserve_metadata_bytes+0x26a/0x384 [btrfs] +[ 886.489542] [] reserve_metadata_bytes+0x28d/0x384 [btrfs] +[ 886.489542] [] ? btrfs_block_rsv_refill+0x58/0x96 [btrfs] +[ 886.489542] [] btrfs_block_rsv_refill+0x70/0x96 [btrfs] +[ 886.489542] [] btrfs_evict_inode+0x394/0x55a [btrfs] +[ 886.489542] [] evict+0xa7/0x15c +[ 886.489542] [] iput+0x1d3/0x266 +[ 886.489542] [] btrfs_run_delayed_iputs+0x8f/0xbf [btrfs] +[ 886.489542] [] btrfs_commit_transaction+0x8f5/0x96e [btrfs] +[ 886.489542] [] ? signal_pending_state+0x31/0x31 +[ 886.489542] [] btrfs_alloc_data_chunk_ondemand+0x1d7/0x288 [btrfs] +[ 886.489542] [] btrfs_check_data_free_space+0x40/0x59 [btrfs] +[ 886.489542] [] btrfs_delalloc_reserve_space+0x1e/0x4e [btrfs] +[ 886.489542] [] btrfs_direct_IO+0x10c/0x27e [btrfs] +[ 886.489542] [] generic_file_direct_write+0xb3/0x128 +[ 886.489542] [] btrfs_file_write_iter+0x229/0x408 [btrfs] +[ 886.489542] [] ? __lock_is_held+0x38/0x50 +[ 886.489542] [] __vfs_write+0x7c/0xa5 +[ 886.489542] [] vfs_write+0xa0/0xe4 +[ 886.489542] [] SyS_write+0x50/0x7e +[ 886.489542] [] entry_SYSCALL_64_fastpath+0x12/0x6f +[ 1081.852335] INFO: task fio:8244 blocked for more than 120 seconds. +[ 1081.854348] Not tainted 4.4.0-rc6-btrfs-next-18+ #1 +[ 1081.857560] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. +[ 1081.863227] fio D ffff880213f9bb28 0 8244 8240 0x00000000 +[ 1081.868719] ffff880213f9bb28 00ffffff810fc6b0 ffffffff0000000a ffff88023ed55240 +[ 1081.872499] ffff880206b5d400 ffff880213f9c000 ffff88020a4d5318 ffff880206b5d400 +[ 1081.876834] ffffffff00000001 ffff880206b5d400 ffff880213f9bb40 ffffffff81482ba4 +[ 1081.880782] Call Trace: +[ 1081.881793] [] schedule+0x7f/0x97 +[ 1081.883340] [] rwsem_down_write_failed+0x2d5/0x325 +[ 1081.895525] [] ? trace_hardirqs_on_caller+0x16/0x1ab +[ 1081.897419] [] call_rwsem_down_write_failed+0x13/0x20 +[ 1081.899251] [] ? call_rwsem_down_write_failed+0x13/0x20 +[ 1081.901063] [] ? __down_write_nested.isra.0+0x1f/0x21 +[ 1081.902365] [] down_write+0x43/0x57 +[ 1081.903846] [] ? btrfs_alloc_data_chunk_ondemand+0x1f6/0x288 [btrfs] +[ 1081.906078] [] btrfs_alloc_data_chunk_ondemand+0x1f6/0x288 [btrfs] +[ 1081.908846] [] ? mark_held_locks+0x56/0x6c +[ 1081.910409] [] btrfs_check_data_free_space+0x40/0x59 [btrfs] +[ 1081.912482] [] btrfs_delalloc_reserve_space+0x1e/0x4e [btrfs] +[ 1081.914597] [] btrfs_direct_IO+0x10c/0x27e [btrfs] +[ 1081.919037] [] generic_file_direct_write+0xb3/0x128 +[ 1081.920754] [] btrfs_file_write_iter+0x229/0x408 [btrfs] +[ 1081.922496] [] ? __lock_is_held+0x38/0x50 +[ 1081.923922] [] __vfs_write+0x7c/0xa5 +[ 1081.925275] [] vfs_write+0xa0/0xe4 +[ 1081.926584] [] SyS_write+0x50/0x7e +[ 1081.927968] [] entry_SYSCALL_64_fastpath+0x12/0x6f +[ 1081.985293] INFO: lockdep is turned off. +[ 1081.986132] INFO: task fio:8249 blocked for more than 120 seconds. +[ 1081.987434] Not tainted 4.4.0-rc6-btrfs-next-18+ #1 +[ 1081.988534] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. +[ 1081.990147] fio D ffff880218febbb8 0 8249 8240 0x00000000 +[ 1081.991626] ffff880218febbb8 00ffffff81486b8e ffff88020000000b ffff88023ed75240 +[ 1081.993258] ffff8802120a9a00 ffff880218fec000 ffff88020a4d5318 ffff8802120a9a00 +[ 1081.994850] ffffffff00000001 ffff8802120a9a00 ffff880218febbd0 ffffffff81482ba4 +[ 1081.996485] Call Trace: +[ 1081.997037] [] schedule+0x7f/0x97 +[ 1081.998017] [] rwsem_down_write_failed+0x2d5/0x325 +[ 1081.999241] [] ? finish_wait+0x6d/0x76 +[ 1082.000306] [] call_rwsem_down_write_failed+0x13/0x20 +[ 1082.001533] [] ? call_rwsem_down_write_failed+0x13/0x20 +[ 1082.002776] [] ? __down_write_nested.isra.0+0x1f/0x21 +[ 1082.003995] [] down_write+0x43/0x57 +[ 1082.005000] [] ? btrfs_alloc_data_chunk_ondemand+0x1f6/0x288 [btrfs] +[ 1082.007403] [] btrfs_alloc_data_chunk_ondemand+0x1f6/0x288 [btrfs] +[ 1082.008988] [] btrfs_fallocate+0x7c1/0xc2f [btrfs] +[ 1082.010193] [] ? percpu_down_read+0x4e/0x77 +[ 1082.011280] [] ? __sb_start_write+0x5f/0xb0 +[ 1082.012265] [] ? __sb_start_write+0x5f/0xb0 +[ 1082.013021] [] vfs_fallocate+0x170/0x1ff +[ 1082.013738] [] ioctl_preallocate+0x89/0x9b +[ 1082.014778] [] do_vfs_ioctl+0x40a/0x4ea +[ 1082.015778] [] ? SYSC_newfstat+0x25/0x2e +[ 1082.016806] [] ? __fget_light+0x4d/0x71 +[ 1082.017789] [] SyS_ioctl+0x57/0x79 +[ 1082.018706] [] entry_SYSCALL_64_fastpath+0x12/0x6f + +This happens because we can recursively acquire the semaphore +fs_info->delayed_iput_sem when attempting to allocate space to satisfy +a file write request as shown in the first trace above - when committing +a transaction we acquire (down_read) the semaphore before running the +delayed iputs, and when running a delayed iput() we can end up calling +an inode's eviction handler, which in turn commits another transaction +and attempts to acquire (down_read) again the semaphore to run more +delayed iput operations. +This results in a deadlock because if a task acquires multiple times a +semaphore it should invoke down_read_nested() with a different lockdep +class for each level of recursion. + +Fix this by simplifying the implementation and use a mutex instead that +is acquired by the cleaner kthread before it runs the delayed iputs +instead of always acquiring a semaphore before delayed references are +run from anywhere. + +Fixes: d7c151717a1e (btrfs: Fix NO_SPACE bug caused by delayed-iput) +Signed-off-by: Filipe Manana +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/ctree.h | 2 +- + fs/btrfs/disk-io.c | 5 ++++- + fs/btrfs/extent-tree.c | 9 +++++---- + fs/btrfs/inode.c | 4 ---- + 4 files changed, 10 insertions(+), 10 deletions(-) + +--- a/fs/btrfs/ctree.h ++++ b/fs/btrfs/ctree.h +@@ -1572,7 +1572,7 @@ struct btrfs_fs_info { + + spinlock_t delayed_iput_lock; + struct list_head delayed_iputs; +- struct rw_semaphore delayed_iput_sem; ++ struct mutex cleaner_delayed_iput_mutex; + + /* this protects tree_mod_seq_list */ + spinlock_t tree_mod_seq_lock; +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -1796,7 +1796,10 @@ static int cleaner_kthread(void *arg) + goto sleep; + } + ++ mutex_lock(&root->fs_info->cleaner_delayed_iput_mutex); + btrfs_run_delayed_iputs(root); ++ mutex_unlock(&root->fs_info->cleaner_delayed_iput_mutex); ++ + again = btrfs_clean_one_deleted_snapshot(root); + mutex_unlock(&root->fs_info->cleaner_mutex); + +@@ -2556,8 +2559,8 @@ int open_ctree(struct super_block *sb, + mutex_init(&fs_info->delete_unused_bgs_mutex); + mutex_init(&fs_info->reloc_mutex); + mutex_init(&fs_info->delalloc_root_mutex); ++ mutex_init(&fs_info->cleaner_delayed_iput_mutex); + seqlock_init(&fs_info->profiles_lock); +- init_rwsem(&fs_info->delayed_iput_sem); + + INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots); + INIT_LIST_HEAD(&fs_info->space_info); +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -4100,11 +4100,12 @@ commit_trans: + if (ret) + return ret; + /* +- * make sure that all running delayed iput are +- * done ++ * The cleaner kthread might still be doing iput ++ * operations. Wait for it to finish so that ++ * more space is released. + */ +- down_write(&root->fs_info->delayed_iput_sem); +- up_write(&root->fs_info->delayed_iput_sem); ++ mutex_lock(&root->fs_info->cleaner_delayed_iput_mutex); ++ mutex_unlock(&root->fs_info->cleaner_delayed_iput_mutex); + goto again; + } else { + btrfs_end_transaction(trans, root); +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -3142,8 +3142,6 @@ void btrfs_run_delayed_iputs(struct btrf + if (empty) + return; + +- down_read(&fs_info->delayed_iput_sem); +- + spin_lock(&fs_info->delayed_iput_lock); + list_splice_init(&fs_info->delayed_iputs, &list); + spin_unlock(&fs_info->delayed_iput_lock); +@@ -3154,8 +3152,6 @@ void btrfs_run_delayed_iputs(struct btrf + iput(delayed->inode); + kfree(delayed); + } +- +- up_read(&root->fs_info->delayed_iput_sem); + } + + /* diff --git a/kernel/kernel/files/patches/mageia/stable-btrfs-fix-no_space-in-write-and-rm-loop.patch b/kernel/kernel/files/patches/mageia/stable-btrfs-fix-no_space-in-write-and-rm-loop.patch new file mode 100644 index 00000000..6197e535 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-btrfs-fix-no_space-in-write-and-rm-loop.patch @@ -0,0 +1,47 @@ +From e1746e8381cd2af421f75557b5cae3604fc18b35 Mon Sep 17 00:00:00 2001 +From: Zhao Lei +Date: Tue, 1 Dec 2015 18:39:40 +0800 +Subject: btrfs: Fix no_space in write and rm loop + +From: Zhao Lei + +commit e1746e8381cd2af421f75557b5cae3604fc18b35 upstream. + +I see no_space in v4.4-rc1 again in xfstests generic/102. +It happened randomly in some node only. +(one of 4 phy-node, and a kvm with non-virtio block driver) + +By bisect, we can found the first-bad is: + commit bdced438acd8 ("block: setup bi_phys_segments after splitting")' +But above patch only triggered the bug by making bio operation +faster(or slower). + +Main reason is in our space_allocating code, we need to commit +page writeback before wait it complish, this patch fixed above +bug. + +BTW, there is another reason for generic/102 fail, caused by +disable default mixed-blockgroup, I'll fix it in xfstests. + +Signed-off-by: Zhao Lei +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/extent-tree.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -4086,8 +4086,10 @@ commit_trans: + !atomic_read(&root->fs_info->open_ioctl_trans)) { + need_commit--; + +- if (need_commit > 0) ++ if (need_commit > 0) { ++ btrfs_start_delalloc_roots(fs_info, 0, -1); + btrfs_wait_ordered_roots(fs_info, -1); ++ } + + trans = btrfs_join_transaction(root); + if (IS_ERR(trans)) diff --git a/kernel/kernel/files/patches/mageia/stable-cifs-fix-out-of-bounds-access-in-lease-parsing.patch b/kernel/kernel/files/patches/mageia/stable-cifs-fix-out-of-bounds-access-in-lease-parsing.patch new file mode 100644 index 00000000..f29a9f19 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-cifs-fix-out-of-bounds-access-in-lease-parsing.patch @@ -0,0 +1,104 @@ +From deb7deff2f00bdbbcb3d560dad2a89ef37df837d Mon Sep 17 00:00:00 2001 +From: Justin Maggard +Date: Tue, 9 Feb 2016 15:52:08 -0800 +Subject: cifs: fix out-of-bounds access in lease parsing + +From: Justin Maggard + +commit deb7deff2f00bdbbcb3d560dad2a89ef37df837d upstream. + +When opening a file, SMB2_open() attempts to parse the lease state from the +SMB2 CREATE Response. However, the parsing code was not careful to ensure +that the create contexts are not empty or invalid, which can lead to out- +of-bounds memory access. This can be seen easily by trying +to read a file from a OSX 10.11 SMB3 server. Here is sample crash output: + +BUG: unable to handle kernel paging request at ffff8800a1a77cc6 +IP: [] SMB2_open+0x804/0x960 +PGD 8f77067 PUD 0 +Oops: 0000 [#1] SMP +Modules linked in: +CPU: 3 PID: 2876 Comm: cp Not tainted 4.5.0-rc3.x86_64.1+ #14 +Hardware name: NETGEAR ReadyNAS 314 /ReadyNAS 314 , BIOS 4.6.5 10/11/2012 +task: ffff880073cdc080 ti: ffff88005b31c000 task.ti: ffff88005b31c000 +RIP: 0010:[] [] SMB2_open+0x804/0x960 +RSP: 0018:ffff88005b31fa08 EFLAGS: 00010282 +RAX: 0000000000000015 RBX: 0000000000000000 RCX: 0000000000000006 +RDX: 0000000000000000 RSI: 0000000000000246 RDI: ffff88007eb8c8b0 +RBP: ffff88005b31fad8 R08: 666666203d206363 R09: 6131613030383866 +R10: 3030383866666666 R11: 00000000000002b0 R12: ffff8800660fd800 +R13: ffff8800a1a77cc2 R14: 00000000424d53fe R15: ffff88005f5a28c0 +FS: 00007f7c8a2897c0(0000) GS:ffff88007eb80000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b +CR2: ffff8800a1a77cc6 CR3: 000000005b281000 CR4: 00000000000006e0 +Stack: + ffff88005b31fa70 ffffffff88278789 00000000000001d3 ffff88005f5a2a80 + ffffffff00000003 ffff88005d029d00 ffff88006fde05a0 0000000000000000 + ffff88005b31fc78 ffff88006fde0780 ffff88005b31fb2f 0000000100000fe0 +Call Trace: + [] ? cifsConvertToUTF16+0x159/0x2d0 + [] smb2_open_file+0x98/0x210 + [] ? __kmalloc+0x1c/0xe0 + [] cifs_open+0x2a4/0x720 + [] do_dentry_open+0x1ff/0x310 + [] ? cifsFileInfo_get+0x30/0x30 + [] vfs_open+0x52/0x60 + [] path_openat+0x170/0xf70 + [] ? remove_wait_queue+0x48/0x50 + [] do_filp_open+0x79/0xd0 + [] ? __alloc_fd+0x3a/0x170 + [] do_sys_open+0x114/0x1e0 + [] SyS_open+0x19/0x20 + [] entry_SYSCALL_64_fastpath+0x12/0x6a +Code: 4d 8d 6c 07 04 31 c0 4c 89 ee e8 47 6f e5 ff 31 c9 41 89 ce 44 89 f1 48 c7 c7 28 b1 bd 88 31 c0 49 01 cd 4c 89 ee e8 2b 6f e5 ff <45> 0f b7 75 04 48 c7 c7 31 b1 bd 88 31 c0 4d 01 ee 4c 89 f6 e8 +RIP [] SMB2_open+0x804/0x960 + RSP +CR2: ffff8800a1a77cc6 +---[ end trace d9f69ba64feee469 ]--- + +Signed-off-by: Justin Maggard +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/smb2pdu.c | 24 ++++++++++++++---------- + 1 file changed, 14 insertions(+), 10 deletions(-) + +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -1109,21 +1109,25 @@ parse_lease_state(struct TCP_Server_Info + { + char *data_offset; + struct create_context *cc; +- unsigned int next = 0; ++ unsigned int next; ++ unsigned int remaining; + char *name; + + data_offset = (char *)rsp + 4 + le32_to_cpu(rsp->CreateContextsOffset); ++ remaining = le32_to_cpu(rsp->CreateContextsLength); + cc = (struct create_context *)data_offset; +- do { +- cc = (struct create_context *)((char *)cc + next); ++ while (remaining >= sizeof(struct create_context)) { + name = le16_to_cpu(cc->NameOffset) + (char *)cc; +- if (le16_to_cpu(cc->NameLength) != 4 || +- strncmp(name, "RqLs", 4)) { +- next = le32_to_cpu(cc->Next); +- continue; +- } +- return server->ops->parse_lease_buf(cc, epoch); +- } while (next != 0); ++ if (le16_to_cpu(cc->NameLength) == 4 && ++ strncmp(name, "RqLs", 4) == 0) ++ return server->ops->parse_lease_buf(cc, epoch); ++ ++ next = le32_to_cpu(cc->Next); ++ if (!next) ++ break; ++ remaining -= next; ++ cc = (struct create_context *)((char *)cc + next); ++ } + + return 0; + } diff --git a/kernel/kernel/files/patches/mageia/stable-cifs-fix-smb2-interim-response-processing-for-read-requests.patch b/kernel/kernel/files/patches/mageia/stable-cifs-fix-smb2-interim-response-processing-for-read-requests.patch new file mode 100644 index 00000000..49789516 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-cifs-fix-smb2-interim-response-processing-for-read-requests.patch @@ -0,0 +1,72 @@ +From 6cc3b24235929b54acd5ecc987ef11a425bd209e Mon Sep 17 00:00:00 2001 +From: Pavel Shilovsky +Date: Sat, 27 Feb 2016 11:58:18 +0300 +Subject: CIFS: Fix SMB2+ interim response processing for read requests + +From: Pavel Shilovsky + +commit 6cc3b24235929b54acd5ecc987ef11a425bd209e upstream. + +For interim responses we only need to parse a header and update +a number credits. Now it is done for all SMB2+ command except +SMB2_READ which is wrong. Fix this by adding such processing. + +Signed-off-by: Pavel Shilovsky +Tested-by: Shirish Pargaonkar +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/cifssmb.c | 21 ++++++++++++++++++--- + 1 file changed, 18 insertions(+), 3 deletions(-) + +--- a/fs/cifs/cifssmb.c ++++ b/fs/cifs/cifssmb.c +@@ -1396,11 +1396,10 @@ openRetry: + * current bigbuf. + */ + static int +-cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid) ++discard_remaining_data(struct TCP_Server_Info *server) + { + unsigned int rfclen = get_rfc1002_length(server->smallbuf); + int remaining = rfclen + 4 - server->total_read; +- struct cifs_readdata *rdata = mid->callback_data; + + while (remaining > 0) { + int length; +@@ -1414,10 +1413,20 @@ cifs_readv_discard(struct TCP_Server_Inf + remaining -= length; + } + +- dequeue_mid(mid, rdata->result); + return 0; + } + ++static int ++cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid) ++{ ++ int length; ++ struct cifs_readdata *rdata = mid->callback_data; ++ ++ length = discard_remaining_data(server); ++ dequeue_mid(mid, rdata->result); ++ return length; ++} ++ + int + cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) + { +@@ -1446,6 +1455,12 @@ cifs_readv_receive(struct TCP_Server_Inf + return length; + server->total_read += length; + ++ if (server->ops->is_status_pending && ++ server->ops->is_status_pending(buf, server, 0)) { ++ discard_remaining_data(server); ++ return -1; ++ } ++ + /* Was the SMB read successful? */ + rdata->result = server->ops->map_error(buf, false); + if (rdata->result != 0) { diff --git a/kernel/kernel/files/patches/mageia/stable-drivers-sh-restore-legacy-clock-domain-on-superh-platforms.patch b/kernel/kernel/files/patches/mageia/stable-drivers-sh-restore-legacy-clock-domain-on-superh-platforms.patch new file mode 100644 index 00000000..e0f47f2d --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drivers-sh-restore-legacy-clock-domain-on-superh-platforms.patch @@ -0,0 +1,39 @@ +From 0378ba4899d5fbd8494ed6580cbc81d7b44dbac6 Mon Sep 17 00:00:00 2001 +From: Geert Uytterhoeven +Date: Wed, 24 Feb 2016 09:43:23 +0100 +Subject: drivers: sh: Restore legacy clock domain on SuperH platforms + +From: Geert Uytterhoeven + +commit 0378ba4899d5fbd8494ed6580cbc81d7b44dbac6 upstream. + +CONFIG_ARCH_SHMOBILE is not only enabled for Renesas ARM platforms +(which are DT based and multi-platform), but also on a select set of +Renesas SuperH platforms (SH7722/SH7723/SH7724/SH7343/SH7366). Hence +since commit 0ba58de231066e47 ("drivers: sh: Get rid of +CONFIG_ARCH_SHMOBILE_MULTI"), the legacy clock domain is no longer +installed on these SuperH platforms, and module clocks may not be +enabled when needed, leading to driver failures. + +To fix this, add an additional check for CONFIG_OF. + +Fixes: 0ba58de231066e47 ("drivers: sh: Get rid of CONFIG_ARCH_SHMOBILE_MULTI"). +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Simon Horman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/sh/pm_runtime.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/sh/pm_runtime.c ++++ b/drivers/sh/pm_runtime.c +@@ -34,7 +34,7 @@ static struct pm_clk_notifier_block plat + + static int __init sh_pm_runtime_init(void) + { +- if (IS_ENABLED(CONFIG_ARCH_SHMOBILE)) { ++ if (IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_ARCH_SHMOBILE)) { + if (!of_find_compatible_node(NULL, NULL, + "renesas,cpg-mstp-clocks")) + return 0; diff --git a/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-mask-out-wc-from-bo-on-unsupported-arches.patch b/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-mask-out-wc-from-bo-on-unsupported-arches.patch new file mode 100644 index 00000000..fedcd4e3 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-mask-out-wc-from-bo-on-unsupported-arches.patch @@ -0,0 +1,46 @@ +From a187f17f0e15a046aa5d7263b35df55230d92779 Mon Sep 17 00:00:00 2001 +From: Oded Gabbay +Date: Sat, 30 Jan 2016 07:59:34 +0200 +Subject: drm/amdgpu: mask out WC from BO on unsupported arches +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Oded Gabbay + +commit a187f17f0e15a046aa5d7263b35df55230d92779 upstream. + +Reviewed-by: Christian König +Reviewed-by: Michel Dänzer +Signed-off-by: Oded Gabbay +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + #include "amdgpu.h" + #include "amdgpu_trace.h" + +@@ -261,6 +262,13 @@ int amdgpu_bo_create_restricted(struct a + AMDGPU_GEM_DOMAIN_OA); + + bo->flags = flags; ++ ++ /* For architectures that don't support WC memory, ++ * mask out the WC flag from the BO ++ */ ++ if (!drm_arch_can_wc_memory()) ++ bo->flags &= ~AMDGPU_GEM_CREATE_CPU_GTT_USWC; ++ + amdgpu_fill_placement_to_bo(bo, placement); + /* Kernel allocation are uninterruptible */ + r = ttm_bo_init(&adev->mman.bdev, &bo->tbo, size, type, diff --git a/kernel/kernel/files/patches/mageia/stable-fbcon-set-a-default-value-to-blink-interval.patch b/kernel/kernel/files/patches/mageia/stable-fbcon-set-a-default-value-to-blink-interval.patch new file mode 100644 index 00000000..4f006707 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-fbcon-set-a-default-value-to-blink-interval.patch @@ -0,0 +1,66 @@ +From a1e533ec07d583d01349ef13c0c965b8633e1b91 Mon Sep 17 00:00:00 2001 +From: Jean-Philippe Brucker +Date: Mon, 15 Feb 2016 18:41:33 +0000 +Subject: fbcon: set a default value to blink interval + +From: Jean-Philippe Brucker + +commit a1e533ec07d583d01349ef13c0c965b8633e1b91 upstream. + +Since commit 27a4c827c34ac4256a190cc9d24607f953c1c459 + fbcon: use the cursor blink interval provided by vt + +two attempts have been made at fixing a possible hang caused by +cursor_timer_handler. That function registers a timer to be triggered at +"jiffies + fbcon_ops.cur_blink_jiffies". + +A new case had been encountered during initialisation of clcd-pl11x: + + fbcon_fb_registered + do_fbcon_takeover + + -> do_register_con_driver + fbcon_startup + (A) add_cursor_timer (with cur_blink_jiffies = 0) + + -> do_bind_con_driver + visual_init + fbcon_init + (B) cur_blink_jiffies = msecs_to_jiffies(vc->vc_cur_blink_ms); + +If we take an softirq anywhere between A and B (and we do), +cursor_timer_handler executes indefinitely. + +Instead of patching all possible paths that lead to this case one at a +time, fix the issue at the source and initialise cur_blink_jiffies to +200ms when allocating fbcon_ops. This was its default value before +aforesaid commit. fbcon_cursor or fbcon_init will refine this value +downstream. + +Signed-off-by: Jean-Philippe Brucker +Tested-by: Scot Doyle +Signed-off-by: Tomi Valkeinen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/video/console/fbcon.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/video/console/fbcon.c ++++ b/drivers/video/console/fbcon.c +@@ -709,6 +709,7 @@ static int con2fb_acquire_newinfo(struct + } + + if (!err) { ++ ops->cur_blink_jiffies = HZ / 5; + info->fbcon_par = ops; + + if (vc) +@@ -956,6 +957,7 @@ static const char *fbcon_startup(void) + ops->currcon = -1; + ops->graphics = 1; + ops->cur_rotate = -1; ++ ops->cur_blink_jiffies = HZ / 5; + info->fbcon_par = ops; + p->con_rotate = initial_rotation; + set_blitting_type(vc, info); diff --git a/kernel/kernel/files/patches/mageia/stable-fix-cifs_uniqueid_to_ino_t-function-for-s390x.patch b/kernel/kernel/files/patches/mageia/stable-fix-cifs_uniqueid_to_ino_t-function-for-s390x.patch new file mode 100644 index 00000000..966e1f1f --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-fix-cifs_uniqueid_to_ino_t-function-for-s390x.patch @@ -0,0 +1,63 @@ +From 1ee9f4bd1a97026a7b2d7ae9f1f74b45680d0003 Mon Sep 17 00:00:00 2001 +From: Yadan Fan +Date: Mon, 29 Feb 2016 14:44:57 +0800 +Subject: Fix cifs_uniqueid_to_ino_t() function for s390x + +From: Yadan Fan + +commit 1ee9f4bd1a97026a7b2d7ae9f1f74b45680d0003 upstream. + +This issue is caused by commit 02323db17e3a7 ("cifs: fix +cifs_uniqueid_to_ino_t not to ever return 0"), when BITS_PER_LONG +is 64 on s390x, the corresponding cifs_uniqueid_to_ino_t() +function will cast 64-bit fileid to 32-bit by using (ino_t)fileid, +because ino_t (typdefed __kernel_ino_t) is int type. + +It's defined in arch/s390/include/uapi/asm/posix_types.h + + #ifndef __s390x__ + + typedef unsigned long __kernel_ino_t; + ... + #else /* __s390x__ */ + + typedef unsigned int __kernel_ino_t; + +So the #ifdef condition is wrong for s390x, we can just still use +one cifs_uniqueid_to_ino_t() function with comparing sizeof(ino_t) +and sizeof(u64) to choose the correct execution accordingly. + +Signed-off-by: Yadan Fan +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/cifsfs.h | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +--- a/fs/cifs/cifsfs.h ++++ b/fs/cifs/cifsfs.h +@@ -31,19 +31,15 @@ + * so that it will fit. We use hash_64 to convert the value to 31 bits, and + * then add 1, to ensure that we don't end up with a 0 as the value. + */ +-#if BITS_PER_LONG == 64 + static inline ino_t + cifs_uniqueid_to_ino_t(u64 fileid) + { ++ if ((sizeof(ino_t)) < (sizeof(u64))) ++ return (ino_t)hash_64(fileid, (sizeof(ino_t) * 8) - 1) + 1; ++ + return (ino_t)fileid; ++ + } +-#else +-static inline ino_t +-cifs_uniqueid_to_ino_t(u64 fileid) +-{ +- return (ino_t)hash_64(fileid, (sizeof(ino_t) * 8) - 1) + 1; +-} +-#endif + + extern struct file_system_type cifs_fs_type; + extern const struct address_space_operations cifs_addr_ops; diff --git a/kernel/kernel/files/patches/mageia/stable-iommu-amd-apply-workaround-for-ats-write-permission-check.patch b/kernel/kernel/files/patches/mageia/stable-iommu-amd-apply-workaround-for-ats-write-permission-check.patch new file mode 100644 index 00000000..2b6ca214 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-iommu-amd-apply-workaround-for-ats-write-permission-check.patch @@ -0,0 +1,78 @@ +From 358875fd52ab8f00f66328cbf1a1d2486f265829 Mon Sep 17 00:00:00 2001 +From: Jay Cornwall +Date: Wed, 10 Feb 2016 15:48:01 -0600 +Subject: iommu/amd: Apply workaround for ATS write permission check + +From: Jay Cornwall + +commit 358875fd52ab8f00f66328cbf1a1d2486f265829 upstream. + +The AMD Family 15h Models 30h-3Fh (Kaveri) BIOS and Kernel Developer's +Guide omitted part of the BIOS IOMMU L2 register setup specification. +Without this setup the IOMMU L2 does not fully respect write permissions +when handling an ATS translation request. + +The IOMMU L2 will set PTE dirty bit when handling an ATS translation with +write permission request, even when PTE RW bit is clear. This may occur by +direct translation (which would cause a PPR) or by prefetch request from +the ATC. + +This is observed in practice when the IOMMU L2 modifies a PTE which maps a +pagecache page. The ext4 filesystem driver BUGs when asked to writeback +these (non-modified) pages. + +Enable ATS write permission check in the Kaveri IOMMU L2 if BIOS has not. + +Signed-off-by: Jay Cornwall +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/amd_iommu_init.c | 29 +++++++++++++++++++++++++++++ + 1 file changed, 29 insertions(+) + +--- a/drivers/iommu/amd_iommu_init.c ++++ b/drivers/iommu/amd_iommu_init.c +@@ -1016,6 +1016,34 @@ static void amd_iommu_erratum_746_workar + } + + /* ++ * Family15h Model 30h-3fh (IOMMU Mishandles ATS Write Permission) ++ * Workaround: ++ * BIOS should enable ATS write permission check by setting ++ * L2_DEBUG_3[AtsIgnoreIWDis](D0F2xF4_x47[0]) = 1b ++ */ ++static void amd_iommu_ats_write_check_workaround(struct amd_iommu *iommu) ++{ ++ u32 value; ++ ++ if ((boot_cpu_data.x86 != 0x15) || ++ (boot_cpu_data.x86_model < 0x30) || ++ (boot_cpu_data.x86_model > 0x3f)) ++ return; ++ ++ /* Test L2_DEBUG_3[AtsIgnoreIWDis] == 1 */ ++ value = iommu_read_l2(iommu, 0x47); ++ ++ if (value & BIT(0)) ++ return; ++ ++ /* Set L2_DEBUG_3[AtsIgnoreIWDis] = 1 */ ++ iommu_write_l2(iommu, 0x47, value | BIT(0)); ++ ++ pr_info("AMD-Vi: Applying ATS write check workaround for IOMMU at %s\n", ++ dev_name(&iommu->dev->dev)); ++} ++ ++/* + * This function clues the initialization function for one IOMMU + * together and also allocates the command buffer and programs the + * hardware. It does NOT enable the IOMMU. This is done afterwards. +@@ -1284,6 +1312,7 @@ static int iommu_init_pci(struct amd_iom + } + + amd_iommu_erratum_746_workaround(iommu); ++ amd_iommu_ats_write_check_workaround(iommu); + + iommu->iommu_dev = iommu_device_create(&iommu->dev->dev, iommu, + amd_iommu_groups, "ivhd%d", diff --git a/kernel/kernel/files/patches/mageia/stable-iommu-amd-fix-boot-warning-when-device-00-00.0-is-not-iommu-covered.patch b/kernel/kernel/files/patches/mageia/stable-iommu-amd-fix-boot-warning-when-device-00-00.0-is-not-iommu-covered.patch new file mode 100644 index 00000000..3d0cee23 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-iommu-amd-fix-boot-warning-when-device-00-00.0-is-not-iommu-covered.patch @@ -0,0 +1,92 @@ +From 38e45d02ea9f194b89d6bf41e52ccafc8e2c2b47 Mon Sep 17 00:00:00 2001 +From: Suravee Suthikulpanit +Date: Tue, 23 Feb 2016 13:03:30 +0100 +Subject: iommu/amd: Fix boot warning when device 00:00.0 is not iommu covered + +From: Suravee Suthikulpanit + +commit 38e45d02ea9f194b89d6bf41e52ccafc8e2c2b47 upstream. + +The setup code for the performance counters in the AMD IOMMU driver +tests whether the counters can be written. It tests to setup a counter +for device 00:00.0, which fails on systems where this particular device +is not covered by the IOMMU. + +Fix this by not relying on device 00:00.0 but only on the IOMMU being +present. + +Signed-off-by: Suravee Suthikulpanit +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/amd_iommu_init.c | 34 ++++++++++++++++++++++------------ + 1 file changed, 22 insertions(+), 12 deletions(-) + +--- a/drivers/iommu/amd_iommu_init.c ++++ b/drivers/iommu/amd_iommu_init.c +@@ -228,6 +228,10 @@ static int amd_iommu_enable_interrupts(v + static int __init iommu_go_to_state(enum iommu_init_state state); + static void init_device_table_dma(void); + ++static int iommu_pc_get_set_reg_val(struct amd_iommu *iommu, ++ u8 bank, u8 cntr, u8 fxn, ++ u64 *value, bool is_write); ++ + static inline void update_last_devid(u16 devid) + { + if (devid > amd_iommu_last_bdf) +@@ -1170,8 +1174,8 @@ static void init_iommu_perf_ctr(struct a + amd_iommu_pc_present = true; + + /* Check if the performance counters can be written to */ +- if ((0 != amd_iommu_pc_get_set_reg_val(0, 0, 0, 0, &val, true)) || +- (0 != amd_iommu_pc_get_set_reg_val(0, 0, 0, 0, &val2, false)) || ++ if ((0 != iommu_pc_get_set_reg_val(iommu, 0, 0, 0, &val, true)) || ++ (0 != iommu_pc_get_set_reg_val(iommu, 0, 0, 0, &val2, false)) || + (val != val2)) { + pr_err("AMD-Vi: Unable to write to IOMMU perf counter.\n"); + amd_iommu_pc_present = false; +@@ -2312,22 +2316,15 @@ u8 amd_iommu_pc_get_max_counters(u16 dev + } + EXPORT_SYMBOL(amd_iommu_pc_get_max_counters); + +-int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr, u8 fxn, ++static int iommu_pc_get_set_reg_val(struct amd_iommu *iommu, ++ u8 bank, u8 cntr, u8 fxn, + u64 *value, bool is_write) + { +- struct amd_iommu *iommu; + u32 offset; + u32 max_offset_lim; + +- /* Make sure the IOMMU PC resource is available */ +- if (!amd_iommu_pc_present) +- return -ENODEV; +- +- /* Locate the iommu associated with the device ID */ +- iommu = amd_iommu_rlookup_table[devid]; +- + /* Check for valid iommu and pc register indexing */ +- if (WARN_ON((iommu == NULL) || (fxn > 0x28) || (fxn & 7))) ++ if (WARN_ON((fxn > 0x28) || (fxn & 7))) + return -ENODEV; + + offset = (u32)(((0x40|bank) << 12) | (cntr << 8) | fxn); +@@ -2351,3 +2348,16 @@ int amd_iommu_pc_get_set_reg_val(u16 dev + return 0; + } + EXPORT_SYMBOL(amd_iommu_pc_get_set_reg_val); ++ ++int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr, u8 fxn, ++ u64 *value, bool is_write) ++{ ++ struct amd_iommu *iommu = amd_iommu_rlookup_table[devid]; ++ ++ /* Make sure the IOMMU PC resource is available */ ++ if (!amd_iommu_pc_present || iommu == NULL) ++ return -ENODEV; ++ ++ return iommu_pc_get_set_reg_val(iommu, bank, cntr, fxn, ++ value, is_write); ++} diff --git a/kernel/kernel/files/patches/mageia/stable-iommu-vt-d-use-bus_notify_removed_device-in-hotplug-path.patch b/kernel/kernel/files/patches/mageia/stable-iommu-vt-d-use-bus_notify_removed_device-in-hotplug-path.patch new file mode 100644 index 00000000..9250c977 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-iommu-vt-d-use-bus_notify_removed_device-in-hotplug-path.patch @@ -0,0 +1,68 @@ +From e6a8c9b337eed56eb481e1b4dd2180c25a1e5310 Mon Sep 17 00:00:00 2001 +From: Joerg Roedel +Date: Mon, 29 Feb 2016 23:49:47 +0100 +Subject: iommu/vt-d: Use BUS_NOTIFY_REMOVED_DEVICE in hotplug path + +From: Joerg Roedel + +commit e6a8c9b337eed56eb481e1b4dd2180c25a1e5310 upstream. + +In the PCI hotplug path of the Intel IOMMU driver, replace +the usage of the BUS_NOTIFY_DEL_DEVICE notifier, which is +executed before the driver is unbound from the device, with +BUS_NOTIFY_REMOVED_DEVICE, which runs after that. + +This fixes a kernel BUG being triggered in the VT-d code +when the device driver tries to unmap DMA buffers and the +VT-d driver already destroyed all mappings. + +Reported-by: Stefani Seibold +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/dmar.c | 5 +++-- + drivers/iommu/intel-iommu.c | 4 ++-- + 2 files changed, 5 insertions(+), 4 deletions(-) + +--- a/drivers/iommu/dmar.c ++++ b/drivers/iommu/dmar.c +@@ -329,7 +329,8 @@ static int dmar_pci_bus_notifier(struct + /* Only care about add/remove events for physical functions */ + if (pdev->is_virtfn) + return NOTIFY_DONE; +- if (action != BUS_NOTIFY_ADD_DEVICE && action != BUS_NOTIFY_DEL_DEVICE) ++ if (action != BUS_NOTIFY_ADD_DEVICE && ++ action != BUS_NOTIFY_REMOVED_DEVICE) + return NOTIFY_DONE; + + info = dmar_alloc_pci_notify_info(pdev, action); +@@ -339,7 +340,7 @@ static int dmar_pci_bus_notifier(struct + down_write(&dmar_global_lock); + if (action == BUS_NOTIFY_ADD_DEVICE) + dmar_pci_bus_add_dev(info); +- else if (action == BUS_NOTIFY_DEL_DEVICE) ++ else if (action == BUS_NOTIFY_REMOVED_DEVICE) + dmar_pci_bus_del_dev(info); + up_write(&dmar_global_lock); + +--- a/drivers/iommu/intel-iommu.c ++++ b/drivers/iommu/intel-iommu.c +@@ -4367,7 +4367,7 @@ int dmar_iommu_notify_scope_dev(struct d + rmrru->devices_cnt); + if(ret < 0) + return ret; +- } else if (info->event == BUS_NOTIFY_DEL_DEVICE) { ++ } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) { + dmar_remove_dev_scope(info, rmrr->segment, + rmrru->devices, rmrru->devices_cnt); + } +@@ -4387,7 +4387,7 @@ int dmar_iommu_notify_scope_dev(struct d + break; + else if(ret < 0) + return ret; +- } else if (info->event == BUS_NOTIFY_DEL_DEVICE) { ++ } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) { + if (dmar_remove_dev_scope(info, atsr->segment, + atsru->devices, atsru->devices_cnt)) + break; diff --git a/kernel/kernel/files/patches/mageia/stable-kvm-x86-fix-root-cause-for-missed-hardware-breakpoints.patch b/kernel/kernel/files/patches/mageia/stable-kvm-x86-fix-root-cause-for-missed-hardware-breakpoints.patch new file mode 100644 index 00000000..19c33135 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-kvm-x86-fix-root-cause-for-missed-hardware-breakpoints.patch @@ -0,0 +1,56 @@ +From 70e4da7a8ff62f2775337b705f45c804bb450454 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 26 Feb 2016 12:28:40 +0100 +Subject: KVM: x86: fix root cause for missed hardware breakpoints + +From: Paolo Bonzini + +commit 70e4da7a8ff62f2775337b705f45c804bb450454 upstream. + +Commit 172b2386ed16 ("KVM: x86: fix missed hardware breakpoints", +2016-02-10) worked around a case where the debug registers are not loaded +correctly on preemption and on the first entry to KVM_RUN. + +However, Xiao Guangrong pointed out that the root cause must be that +KVM_DEBUGREG_BP_ENABLED is not being set correctly. This can indeed +happen due to the lazy debug exit mechanism, which does not call +kvm_update_dr7. Fix it by replacing the existing loop (more or less +equivalent to kvm_update_dr0123) with calls to all the kvm_update_dr* +functions. + +Fixes: 172b2386ed16a9143d9a456aae5ec87275c61489 +Reviewed-by: Xiao Guangrong +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/x86.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -2736,7 +2736,6 @@ void kvm_arch_vcpu_load(struct kvm_vcpu + } + + kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu); +- vcpu->arch.switch_db_regs |= KVM_DEBUGREG_RELOAD; + } + + void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) +@@ -6545,12 +6544,12 @@ static int vcpu_enter_guest(struct kvm_v + * KVM_DEBUGREG_WONT_EXIT again. + */ + if (unlikely(vcpu->arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT)) { +- int i; +- + WARN_ON(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP); + kvm_x86_ops->sync_dirty_debug_regs(vcpu); +- for (i = 0; i < KVM_NR_DB_REGS; i++) +- vcpu->arch.eff_db[i] = vcpu->arch.db[i]; ++ kvm_update_dr0123(vcpu); ++ kvm_update_dr6(vcpu); ++ kvm_update_dr7(vcpu); ++ vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_RELOAD; + } + + /* diff --git a/kernel/kernel/files/patches/mageia/stable-kvm-x86-update-tsc-multiplier-on-change.patch b/kernel/kernel/files/patches/mageia/stable-kvm-x86-update-tsc-multiplier-on-change.patch new file mode 100644 index 00000000..ea436218 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-kvm-x86-update-tsc-multiplier-on-change.patch @@ -0,0 +1,56 @@ +From 2680d6da455b636dd006636780c0f235c6561d70 Mon Sep 17 00:00:00 2001 +From: Owen Hofmann +Date: Tue, 1 Mar 2016 13:36:13 -0800 +Subject: kvm: x86: Update tsc multiplier on change. + +From: Owen Hofmann + +commit 2680d6da455b636dd006636780c0f235c6561d70 upstream. + +vmx.c writes the TSC_MULTIPLIER field in vmx_vcpu_load, but only when a +vcpu has migrated physical cpus. Record the last value written and +update in vmx_vcpu_load on any change, otherwise a cpu migration must +occur for TSC frequency scaling to take effect. + +Fixes: ff2c3a1803775cc72dc6f624b59554956396b0ee +Signed-off-by: Owen Hofmann +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/vmx.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -595,6 +595,8 @@ struct vcpu_vmx { + /* Support for PML */ + #define PML_ENTITY_NUM 512 + struct page *pml_pg; ++ ++ u64 current_tsc_ratio; + }; + + enum segment_cache_field { +@@ -2062,14 +2064,16 @@ static void vmx_vcpu_load(struct kvm_vcp + rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp); + vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */ + +- /* Setup TSC multiplier */ +- if (cpu_has_vmx_tsc_scaling()) +- vmcs_write64(TSC_MULTIPLIER, +- vcpu->arch.tsc_scaling_ratio); +- + vmx->loaded_vmcs->cpu = cpu; + } + ++ /* Setup TSC multiplier */ ++ if (kvm_has_tsc_control && ++ vmx->current_tsc_ratio != vcpu->arch.tsc_scaling_ratio) { ++ vmx->current_tsc_ratio = vcpu->arch.tsc_scaling_ratio; ++ vmcs_write64(TSC_MULTIPLIER, vmx->current_tsc_ratio); ++ } ++ + vmx_vcpu_pi_load(vcpu, cpu); + } + diff --git a/kernel/kernel/files/patches/mageia/stable-mips-kvm-fix-ioctl-error-handling.patch b/kernel/kernel/files/patches/mageia/stable-mips-kvm-fix-ioctl-error-handling.patch new file mode 100644 index 00000000..aa79661b --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-mips-kvm-fix-ioctl-error-handling.patch @@ -0,0 +1,49 @@ +From 0178fd7dcc4451fcb90bec5e91226586962478d2 Mon Sep 17 00:00:00 2001 +From: "Michael S. Tsirkin" +Date: Sun, 28 Feb 2016 17:35:59 +0200 +Subject: mips/kvm: fix ioctl error handling + +From: Michael S. Tsirkin + +commit 0178fd7dcc4451fcb90bec5e91226586962478d2 upstream. + +Returning directly whatever copy_to_user(...) or copy_from_user(...) +returns may not do the right thing if there's a pagefault: +copy_to_user/copy_from_user return the number of bytes not copied in +this case, but ioctls need to return -EFAULT instead. + +Fix up kvm on mips to do + return copy_to_user(...)) ? -EFAULT : 0; +and + return copy_from_user(...)) ? -EFAULT : 0; + +everywhere. + +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/kvm/mips.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/mips/kvm/mips.c ++++ b/arch/mips/kvm/mips.c +@@ -702,7 +702,7 @@ static int kvm_mips_get_reg(struct kvm_v + } else if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U128) { + void __user *uaddr = (void __user *)(long)reg->addr; + +- return copy_to_user(uaddr, vs, 16); ++ return copy_to_user(uaddr, vs, 16) ? -EFAULT : 0; + } else { + return -EINVAL; + } +@@ -732,7 +732,7 @@ static int kvm_mips_set_reg(struct kvm_v + } else if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U128) { + void __user *uaddr = (void __user *)(long)reg->addr; + +- return copy_from_user(vs, uaddr, 16); ++ return copy_from_user(vs, uaddr, 16) ? -EFAULT : 0; + } else { + return -EINVAL; + } diff --git a/kernel/kernel/files/patches/mageia/stable-parisc-fix-ptrace-syscall-number-and-return-value-modification.patch b/kernel/kernel/files/patches/mageia/stable-parisc-fix-ptrace-syscall-number-and-return-value-modification.patch new file mode 100644 index 00000000..ef7b3cca --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-parisc-fix-ptrace-syscall-number-and-return-value-modification.patch @@ -0,0 +1,94 @@ +From 98e8b6c9ac9d1b1e9d1122dfa6783d5d566bb8f7 Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Tue, 19 Jan 2016 16:08:49 +0100 +Subject: parisc: Fix ptrace syscall number and return value modification + +From: Helge Deller + +commit 98e8b6c9ac9d1b1e9d1122dfa6783d5d566bb8f7 upstream. + +Mike Frysinger reported that his ptrace testcase showed strange +behaviour on parisc: It was not possible to avoid a syscall and the +return value of a syscall couldn't be changed. + +To modify a syscall number, we were missing to save the new syscall +number to gr20 which is then picked up later in assembly again. + +The effect that the return value couldn't be changed is a side-effect of +another bug in the assembly code. When a process is ptraced, userspace +expects each syscall to report entrance and exit of a syscall. If a +syscall number was given which doesn't exist, we jumped to the normal +syscall exit code instead of informing userspace that the (non-existant) +syscall exits. This unexpected behaviour confuses userspace and thus the +bug was misinterpreted as if we can't change the return value. + +This patch fixes both problems and was tested on 64bit kernel with +32bit userspace. + +Signed-off-by: Helge Deller +Cc: Mike Frysinger +Tested-by: Mike Frysinger +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/kernel/ptrace.c | 16 +++++++++++----- + arch/parisc/kernel/syscall.S | 5 ++++- + 2 files changed, 15 insertions(+), 6 deletions(-) + +--- a/arch/parisc/kernel/ptrace.c ++++ b/arch/parisc/kernel/ptrace.c +@@ -269,14 +269,19 @@ long compat_arch_ptrace(struct task_stru + + long do_syscall_trace_enter(struct pt_regs *regs) + { +- long ret = 0; +- + /* Do the secure computing check first. */ + secure_computing_strict(regs->gr[20]); + + if (test_thread_flag(TIF_SYSCALL_TRACE) && +- tracehook_report_syscall_entry(regs)) +- ret = -1L; ++ tracehook_report_syscall_entry(regs)) { ++ /* ++ * Tracing decided this syscall should not happen or the ++ * debugger stored an invalid system call number. Skip ++ * the system call and the system call restart handling. ++ */ ++ regs->gr[20] = -1UL; ++ goto out; ++ } + + #ifdef CONFIG_64BIT + if (!is_compat_task()) +@@ -290,7 +295,8 @@ long do_syscall_trace_enter(struct pt_re + regs->gr[24] & 0xffffffff, + regs->gr[23] & 0xffffffff); + +- return ret ? : regs->gr[20]; ++out: ++ return regs->gr[20]; + } + + void do_syscall_trace_exit(struct pt_regs *regs) +--- a/arch/parisc/kernel/syscall.S ++++ b/arch/parisc/kernel/syscall.S +@@ -343,7 +343,7 @@ tracesys_next: + #endif + + comiclr,>>= __NR_Linux_syscalls, %r20, %r0 +- b,n .Lsyscall_nosys ++ b,n .Ltracesys_nosys + + LDREGX %r20(%r19), %r19 + +@@ -359,6 +359,9 @@ tracesys_next: + be 0(%sr7,%r19) + ldo R%tracesys_exit(%r2),%r2 + ++.Ltracesys_nosys: ++ ldo -ENOSYS(%r0),%r28 /* set errno */ ++ + /* Do *not* call this function on the gateway page, because it + makes a direct call to syscall_trace. */ + diff --git a/kernel/kernel/files/patches/mageia/stable-pci-keystone-fix-msi-code-that-retrieves-struct-pcie_port-pointer.patch b/kernel/kernel/files/patches/mageia/stable-pci-keystone-fix-msi-code-that-retrieves-struct-pcie_port-pointer.patch new file mode 100644 index 00000000..e598869f --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-pci-keystone-fix-msi-code-that-retrieves-struct-pcie_port-pointer.patch @@ -0,0 +1,78 @@ +From 79e3f4a853ed161cd4c06d84b50beebf961a47c6 Mon Sep 17 00:00:00 2001 +From: Murali Karicheri +Date: Mon, 29 Feb 2016 17:18:22 -0600 +Subject: PCI: keystone: Fix MSI code that retrieves struct pcie_port pointer + +From: Murali Karicheri + +commit 79e3f4a853ed161cd4c06d84b50beebf961a47c6 upstream. + +Commit cbce7900598c ("PCI: designware: Make driver arch-agnostic") changed +the host bridge sysdata pointer from the ARM pci_sys_data to the DesignWare +pcie_port structure, and changed pcie-designware.c to reflect that. But it +did not change the corresponding code in pci-keystone-dw.c, so it caused +crashes on Keystone: + + Unable to handle kernel NULL pointer dereference at virtual address 00000030 + pgd = c0003000 + [00000030] *pgd=80000800004003, *pmd=00000000 + Internal error: Oops: 206 [#1] PREEMPT SMP ARM + CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.4.2-00139-gb74f926 #2 + Hardware name: Keystone + PC is at ks_dw_pcie_msi_irq_unmask+0x24/0x58 + +Change pci-keystone-dw.c to expect sysdata to be the struct pcie_port +pointer. + +[bhelgaas: changelog] +Fixes: cbce7900598c ("PCI: designware: Make driver arch-agnostic") +Signed-off-by: Murali Karicheri +Signed-off-by: Bjorn Helgaas +CC: Zhou Wang +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/host/pci-keystone-dw.c | 11 +++-------- + 1 file changed, 3 insertions(+), 8 deletions(-) + +--- a/drivers/pci/host/pci-keystone-dw.c ++++ b/drivers/pci/host/pci-keystone-dw.c +@@ -58,11 +58,6 @@ + + #define to_keystone_pcie(x) container_of(x, struct keystone_pcie, pp) + +-static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys) +-{ +- return sys->private_data; +-} +- + static inline void update_reg_offset_bit_pos(u32 offset, u32 *reg_offset, + u32 *bit_pos) + { +@@ -108,7 +103,7 @@ static void ks_dw_pcie_msi_irq_ack(struc + struct pcie_port *pp; + + msi = irq_data_get_msi_desc(d); +- pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi)); ++ pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi); + ks_pcie = to_keystone_pcie(pp); + offset = d->irq - irq_linear_revmap(pp->irq_domain, 0); + update_reg_offset_bit_pos(offset, ®_offset, &bit_pos); +@@ -146,7 +141,7 @@ static void ks_dw_pcie_msi_irq_mask(stru + u32 offset; + + msi = irq_data_get_msi_desc(d); +- pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi)); ++ pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi); + ks_pcie = to_keystone_pcie(pp); + offset = d->irq - irq_linear_revmap(pp->irq_domain, 0); + +@@ -167,7 +162,7 @@ static void ks_dw_pcie_msi_irq_unmask(st + u32 offset; + + msi = irq_data_get_msi_desc(d); +- pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi)); ++ pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi); + ks_pcie = to_keystone_pcie(pp); + offset = d->irq - irq_linear_revmap(pp->irq_domain, 0); + diff --git a/kernel/kernel/files/patches/mageia/stable-use-d_seq-to-get-coherency-between-d_inode-and-d_flags.patch b/kernel/kernel/files/patches/mageia/stable-use-d_seq-to-get-coherency-between-d_inode-and-d_flags.patch new file mode 100644 index 00000000..b68d85b9 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-use-d_seq-to-get-coherency-between-d_inode-and-d_flags.patch @@ -0,0 +1,100 @@ +From a528aca7f359f4b0b1d72ae406097e491a5ba9ea Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Mon, 29 Feb 2016 12:12:46 -0500 +Subject: use ->d_seq to get coherency between ->d_inode and ->d_flags + +From: Al Viro + +commit a528aca7f359f4b0b1d72ae406097e491a5ba9ea upstream. + +Games with ordering and barriers are way too brittle. Just +bump ->d_seq before and after updating ->d_inode and ->d_flags +type bits, so that verifying ->d_seq would guarantee they are +coherent. + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/dcache.c | 20 +++++--------------- + include/linux/dcache.h | 4 +--- + 2 files changed, 6 insertions(+), 18 deletions(-) + +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -269,9 +269,6 @@ static inline int dname_external(const s + return dentry->d_name.name != dentry->d_iname; + } + +-/* +- * Make sure other CPUs see the inode attached before the type is set. +- */ + static inline void __d_set_inode_and_type(struct dentry *dentry, + struct inode *inode, + unsigned type_flags) +@@ -279,28 +276,18 @@ static inline void __d_set_inode_and_typ + unsigned flags; + + dentry->d_inode = inode; +- smp_wmb(); + flags = READ_ONCE(dentry->d_flags); + flags &= ~(DCACHE_ENTRY_TYPE | DCACHE_FALLTHRU); + flags |= type_flags; + WRITE_ONCE(dentry->d_flags, flags); + } + +-/* +- * Ideally, we want to make sure that other CPUs see the flags cleared before +- * the inode is detached, but this is really a violation of RCU principles +- * since the ordering suggests we should always set inode before flags. +- * +- * We should instead replace or discard the entire dentry - but that sucks +- * performancewise on mass deletion/rename. +- */ + static inline void __d_clear_type_and_inode(struct dentry *dentry) + { + unsigned flags = READ_ONCE(dentry->d_flags); + + flags &= ~(DCACHE_ENTRY_TYPE | DCACHE_FALLTHRU); + WRITE_ONCE(dentry->d_flags, flags); +- smp_wmb(); + dentry->d_inode = NULL; + } + +@@ -370,9 +357,11 @@ static void dentry_unlink_inode(struct d + __releases(dentry->d_inode->i_lock) + { + struct inode *inode = dentry->d_inode; ++ ++ raw_write_seqcount_begin(&dentry->d_seq); + __d_clear_type_and_inode(dentry); + hlist_del_init(&dentry->d_u.d_alias); +- dentry_rcuwalk_invalidate(dentry); ++ raw_write_seqcount_end(&dentry->d_seq); + spin_unlock(&dentry->d_lock); + spin_unlock(&inode->i_lock); + if (!inode->i_nlink) +@@ -1757,8 +1746,9 @@ static void __d_instantiate(struct dentr + spin_lock(&dentry->d_lock); + if (inode) + hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry); ++ raw_write_seqcount_begin(&dentry->d_seq); + __d_set_inode_and_type(dentry, inode, add_flags); +- dentry_rcuwalk_invalidate(dentry); ++ raw_write_seqcount_end(&dentry->d_seq); + spin_unlock(&dentry->d_lock); + fsnotify_d_instantiate(dentry, inode); + } +--- a/include/linux/dcache.h ++++ b/include/linux/dcache.h +@@ -409,9 +409,7 @@ static inline bool d_mountpoint(const st + */ + static inline unsigned __d_entry_type(const struct dentry *dentry) + { +- unsigned type = READ_ONCE(dentry->d_flags); +- smp_rmb(); +- return type & DCACHE_ENTRY_TYPE; ++ return dentry->d_flags & DCACHE_ENTRY_TYPE; + } + + static inline bool d_is_miss(const struct dentry *dentry) diff --git a/kernel/kernel/files/patches/mageia/stable-vfio-fix-ioctl-error-handling.patch b/kernel/kernel/files/patches/mageia/stable-vfio-fix-ioctl-error-handling.patch new file mode 100644 index 00000000..9b803d1e --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-vfio-fix-ioctl-error-handling.patch @@ -0,0 +1,116 @@ +From 8160c4e455820d5008a1116d2dca35f0363bb062 Mon Sep 17 00:00:00 2001 +From: "Michael S. Tsirkin" +Date: Sun, 28 Feb 2016 16:31:39 +0200 +Subject: vfio: fix ioctl error handling + +From: Michael S. Tsirkin + +commit 8160c4e455820d5008a1116d2dca35f0363bb062 upstream. + +Calling return copy_to_user(...) in an ioctl will not +do the right thing if there's a pagefault: +copy_to_user returns the number of bytes not copied +in this case. + +Fix up vfio to do + return copy_to_user(...)) ? + -EFAULT : 0; + +everywhere. + +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Alex Williamson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/vfio/pci/vfio_pci.c | 9 ++++++--- + drivers/vfio/platform/vfio_platform_common.c | 9 ++++++--- + drivers/vfio/vfio_iommu_type1.c | 6 ++++-- + 3 files changed, 16 insertions(+), 8 deletions(-) + +--- a/drivers/vfio/pci/vfio_pci.c ++++ b/drivers/vfio/pci/vfio_pci.c +@@ -446,7 +446,8 @@ static long vfio_pci_ioctl(void *device_ + info.num_regions = VFIO_PCI_NUM_REGIONS; + info.num_irqs = VFIO_PCI_NUM_IRQS; + +- return copy_to_user((void __user *)arg, &info, minsz); ++ return copy_to_user((void __user *)arg, &info, minsz) ? ++ -EFAULT : 0; + + } else if (cmd == VFIO_DEVICE_GET_REGION_INFO) { + struct pci_dev *pdev = vdev->pdev; +@@ -520,7 +521,8 @@ static long vfio_pci_ioctl(void *device_ + return -EINVAL; + } + +- return copy_to_user((void __user *)arg, &info, minsz); ++ return copy_to_user((void __user *)arg, &info, minsz) ? ++ -EFAULT : 0; + + } else if (cmd == VFIO_DEVICE_GET_IRQ_INFO) { + struct vfio_irq_info info; +@@ -555,7 +557,8 @@ static long vfio_pci_ioctl(void *device_ + else + info.flags |= VFIO_IRQ_INFO_NORESIZE; + +- return copy_to_user((void __user *)arg, &info, minsz); ++ return copy_to_user((void __user *)arg, &info, minsz) ? ++ -EFAULT : 0; + + } else if (cmd == VFIO_DEVICE_SET_IRQS) { + struct vfio_irq_set hdr; +--- a/drivers/vfio/platform/vfio_platform_common.c ++++ b/drivers/vfio/platform/vfio_platform_common.c +@@ -219,7 +219,8 @@ static long vfio_platform_ioctl(void *de + info.num_regions = vdev->num_regions; + info.num_irqs = vdev->num_irqs; + +- return copy_to_user((void __user *)arg, &info, minsz); ++ return copy_to_user((void __user *)arg, &info, minsz) ? ++ -EFAULT : 0; + + } else if (cmd == VFIO_DEVICE_GET_REGION_INFO) { + struct vfio_region_info info; +@@ -240,7 +241,8 @@ static long vfio_platform_ioctl(void *de + info.size = vdev->regions[info.index].size; + info.flags = vdev->regions[info.index].flags; + +- return copy_to_user((void __user *)arg, &info, minsz); ++ return copy_to_user((void __user *)arg, &info, minsz) ? ++ -EFAULT : 0; + + } else if (cmd == VFIO_DEVICE_GET_IRQ_INFO) { + struct vfio_irq_info info; +@@ -259,7 +261,8 @@ static long vfio_platform_ioctl(void *de + info.flags = vdev->irqs[info.index].flags; + info.count = vdev->irqs[info.index].count; + +- return copy_to_user((void __user *)arg, &info, minsz); ++ return copy_to_user((void __user *)arg, &info, minsz) ? ++ -EFAULT : 0; + + } else if (cmd == VFIO_DEVICE_SET_IRQS) { + struct vfio_irq_set hdr; +--- a/drivers/vfio/vfio_iommu_type1.c ++++ b/drivers/vfio/vfio_iommu_type1.c +@@ -999,7 +999,8 @@ static long vfio_iommu_type1_ioctl(void + + info.iova_pgsizes = vfio_pgsize_bitmap(iommu); + +- return copy_to_user((void __user *)arg, &info, minsz); ++ return copy_to_user((void __user *)arg, &info, minsz) ? ++ -EFAULT : 0; + + } else if (cmd == VFIO_IOMMU_MAP_DMA) { + struct vfio_iommu_type1_dma_map map; +@@ -1032,7 +1033,8 @@ static long vfio_iommu_type1_ioctl(void + if (ret) + return ret; + +- return copy_to_user((void __user *)arg, &unmap, minsz); ++ return copy_to_user((void __user *)arg, &unmap, minsz) ? ++ -EFAULT : 0; + } + + return -ENOTTY; diff --git a/kernel/kernel/pspec.xml b/kernel/kernel/pspec.xml index 1d4be546..206e09f8 100644 --- a/kernel/kernel/pspec.xml +++ b/kernel/kernel/pspec.xml @@ -28,10 +28,35 @@ - patches/linux/patch-4.4.2.xz - + patches/linux/patch-4.4.4.xz + + patches/mageia/stable-use-d_seq-to-get-coherency-between-d_inode-and-d_flags.patch + patches/mageia/stable-drivers-sh-restore-legacy-clock-domain-on-superh-platforms.patch + patches/mageia/stable-btrfs-fix-deadlock-running-delayed-iputs-at-transaction-commit-time.patch + patches/mageia/stable-btrfs-fix-no_space-in-write-and-rm-loop.patch + patches/mageia/stable-btrfs-async-thread-fix-a-use-after-free-error-for-trace.patch + patches/mageia/stable-drm-amdgpu-mask-out-wc-from-bo-on-unsupported-arches.patch + patches/mageia/stable-block-initialize-max_dev_sectors-to-0.patch + patches/mageia/stable-pci-keystone-fix-msi-code-that-retrieves-struct-pcie_port-pointer.patch + patches/mageia/stable-parisc-fix-ptrace-syscall-number-and-return-value-modification.patch + patches/mageia/stable-mips-kvm-fix-ioctl-error-handling.patch + patches/mageia/stable-kvm-x86-update-tsc-multiplier-on-change.patch + patches/mageia/stable-fbcon-set-a-default-value-to-blink-interval.patch + patches/mageia/stable-cifs-fix-out-of-bounds-access-in-lease-parsing.patch + patches/mageia/stable-cifs-fix-smb2-interim-response-processing-for-read-requests.patch + patches/mageia/stable-fix-cifs_uniqueid_to_ino_t-function-for-s390x.patch + patches/mageia/stable-vfio-fix-ioctl-error-handling.patch + patches/mageia/stable-kvm-x86-fix-root-cause-for-missed-hardware-breakpoints.patch + patches/mageia/stable-arm-arm64-kvm-fix-ioctl-error-handling.patch + patches/mageia/stable-iommu-amd-apply-workaround-for-ats-write-permission-check.patch + patches/mageia/stable-iommu-amd-fix-boot-warning-when-device-00-00.0-is-not-iommu-covered.patch + patches/mageia/stable-iommu-vt-d-use-bus_notify_removed_device-in-hotplug-path.patch + patches/mageia/ata-Adding-Intel-Lewisburg-device-IDs-for-SATA.patch + patches/mageia/ata-ahci-don-t-mark-HotPlugCapable-Ports-as-external.patch + patches/mageia/libata-Align-ata_device-s-id-on-a-cacheline.patch + patches/mageia/libata-fix-HDIO_GET_32BIT-ioctl.patch patches/mageia/x86-pci-toshiba-equium-a60-assign-busses.patch patches/mageia/x86-boot-video-80x25-if-break.patch patches/mageia/x86-default_poweroff_up_machines.patch @@ -59,13 +84,7 @@ patches/mageia/block-Make-CFQ-default-to-IOPS-mode-on-SSDs.patch patches/mageia/fs-aufs-4.4.patch patches/mageia/fs-aufs-4.4-modular.patch - patches/mageia/fs-ovl-allow-zero-size-xattr.patch - patches/mageia/fs-ovl-use-a-minimal-buffer-in-ovl_copy_xattr.patch patches/mageia/fs-ovl-move-super-block-magic-number-to-magic.h.patch - patches/mageia/fs-ovl-root-copy-attr.patch - patches/mageia/fs-ovl-setattr-check-permissions-before-copy-up.patch - patches/mageia/fs-ovl-check-dentry-positiveness-in-ovl_cleanup_whiteou.patch - patches/mageia/fs-xfs-Revert-xfs-clear-PF_NOFREEZE-for-xfsaild-kthread.patch patches/mageia/firewire-ieee1394-module-aliases.patch patches/mageia/char-agp-intel-new-Q57-id.patch patches/mageia/gpu-drm-mach64.patch @@ -103,11 +122,6 @@ patches/mageia/gpu-drm-0109-drm-vc4-Add-an-interface-for-capturing-the-GPU-state.patch patches/mageia/gpu-drm-radeon-Update-radeon_get_vblank_counter_kms.patch patches/mageia/gpu-drm-radeon-Drop-unnecessary-unsigned-int-0-check.patch - patches/mageia/gpu-drm-No-Op-redundant-calls-to-drm_vblank_off-v2.patch - patches/mageia/gpu-drm-Prevent-vblank-counter-bumps-1-with-active-vblank-clients-v2.patch - patches/mageia/gpu-drm-Fix-drm_vblank_pre_post_modeset-regression-from-Linux-4.4.patch - patches/mageia/gpu-drm-Fix-treatment-of-drm_vblank_offdelay-in-drm_vblank_on-v2.patch - patches/mageia/gpu-drm_nouveau_display-Enable-vblank-irqs-after-display-engine-is-on-again.patch patches/mageia/input-i8042-quirks-for-Fujitsu-Lifebook-A544-and-Lif.patch patches/mageia/net-sis190-fix-list-usage.patch patches/mageia/net-netfilter-IFWLOG.patch @@ -224,9 +238,9 @@ - 2016-02-18 - 4.4.2 - Version bump to 4.4.2 https://www.kernel.org/pub/linux/kernel/v4.x/ChangeLog-4.4.2 + 2016-03-06 + 4.4.4 + Version bump to 4.4.4 https://www.kernel.org/pub/linux/kernel/v4.x/ChangeLog-4.4.4 security systemRestart