From d8fa817589bd725c75992ab9d2d75112eb174140 Mon Sep 17 00:00:00 2001 From: husky Date: Sun, 27 Aug 2023 14:36:28 -0700 Subject: [PATCH] add infinite_dbas post --- blog/index.html | 1 + blog/posts/infinite_dbas/graph.png | Bin 0 -> 4101 bytes blog/posts/infinite_dbas/index.html | 130 +++++++++++++++++++++ blog/posts/infinite_dbas/infinite_dbas.png | Bin 0 -> 9548 bytes 4 files changed, 131 insertions(+) create mode 100644 blog/posts/infinite_dbas/graph.png create mode 100644 blog/posts/infinite_dbas/index.html create mode 100644 blog/posts/infinite_dbas/infinite_dbas.png diff --git a/blog/index.html b/blog/index.html index f590cc5..488d46a 100644 --- a/blog/index.html +++ b/blog/index.html @@ -15,6 +15,7 @@ diff --git a/blog/posts/infinite_dbas/graph.png b/blog/posts/infinite_dbas/graph.png new file mode 100644 index 0000000000000000000000000000000000000000..720118e2cce057a73e4e542b98f9657460112b43 GIT binary patch literal 4101 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 Y5>M|pH^L4&p%cK#-r26e#y9rA044`9cmMzZ literal 0 HcmV?d00001 diff --git a/blog/posts/infinite_dbas/index.html b/blog/posts/infinite_dbas/index.html new file mode 100644 index 0000000..936f29f --- /dev/null +++ b/blog/posts/infinite_dbas/index.html @@ -0,0 +1,130 @@ + + + vore microcomputers development blog - The Simple but Awful Result of Making a Miscalculation: Week 3 of VoreStation Development + + + + + +
+
+ vore microcomputers logo + +

The Simple but Awful Result of Making a Miscalculation: Week 3 of VoreStation Development

+
2023-08-27
+

written by Niko Chow-Stuart (Lead Developer)

+ + drawing of the vap mascot attempting to lift a heavy briefcase, with papers falling out. the briefcase is labeled 0.7 KiloBytes. + +

+ quick note before i start: as mentioned on our social media pages, we've decided to change the (official) + rate of these blog posts to one every two weeks. this is mainly because i feel that i'm not able to + accomplish enough work within a single week to warrant a blog post, in addition to the fact that we've + already been missing the weekly deadline for the past two weeks. +
+ anyways, onto the actual post! +
+
+ almost the instant after posting the previous blog post, i posted a follow-up on my personal social media + pages, stating that i had made a miscalculation in the design of the filesystem. unfortunately, this + miscalculation was a rather large one, and as such, i've had to spend the past two weeks reworking the + parts of the filesystem that were affected by it. +
+
+ as you may have already seen, the miscalculation in question was regarding the design of direct and indirect + block pointers in the inodes. originally, i had decided on a design of either 12 direct blocks, or 9 direct + blocks and 3 indirect blocks. however, after a very short amount of running the numbers through a + calculator (which should've been done way earlier), i realised that this design would (assuming a relatively + average block size of 512 bytes) limit the maximum file size to less than a megabyte. this is obviously + undesirable, and as such, i decided to rework things to be a bit more future-proof. +
+
+ the new design is a bit more complex, in that it essentially allows for an unlimited number of direct blocks + and indirect blocks. the way that this works is that each indirect block can specify (for each pointer) + whether the pointer is an indirect block or a direct block. this means that the maximum file size is now + limited by the maximum number of indirect datablocks, which theroetically could be up to around 2^64 blocks, + although reaching this limit would require an incredibly large amount of storage space. +
+
+ one potential issue with this design is that it requires a lot of work to index the blocks of a file. say + you wanted to access the second block of a file, you would have to read the first indirect block, then + depending on the pointer type of the first pointer listed, either skip it (if its a datablock), or read + that datablock just to figure out if the second pointer is stored in that datablock or the next one. this + also would mean that you'd need to essentially do this forever until you reach the datablock you want, + which is a big performance hit. however, i've decided to add one extra feature to the pointer listing to + account for this. +
+
+ each pointer is accompanied by a u8 value, which is either 0 or 1. depending on that value, the pointer + either points to a datablock or an indirect block. importantly, immediately after that u8 comes a 56-bit + integer (thus in total, flags + u56 is a u64), which contains absolute number of datablocks that this indirect block points to (undefined if its + not an indirect pointer). this means that, if you want to access the second block of a file, you can + simply read the first indirect block, and then skip the first pointer if you know that the second block is + not stored in that indirect block (i.e. if the u56 value is less than or equal to 1). this should hopefully + drastically improve performance, while keeping the design relatively simple. (either that or i'll regret my + confidence in however long until i can test it). +
+
+ in an ideal implementation, blocks are layed out by attempting to create a tree of + indirect blocks that is as balanced as possible. this means that, if you have a file that is 5 blocks long + (assuming a block size that can contain only two blocks for the purpose of this example), the blocks will + be layed out like this: +
+ a graph showing the layout of blocks. one block is at the top, with two blocks below it. data blocks 1 and 2 are below the first block, data blocks 3 and 4 are below the second block. data block 5 is attached directly to the end of the root block +
+ please note my uncertainty when i say this, but i'm pretty sure that this is how the implementation + i've written works. in practice, it may actually add a useless indirect block in between the root and datablock 5, + but i'm not sure. i'll have to look over the code again (and probably rewrite it to be better). +
+
+ overall, this is pretty much all the work i've done over the past two weeks. trying to get the idea of this + into my head was somewhat tricky at first, and as such that took me quite a bit of the implementation time. + notably, a big issue with this implementation is that files can no longer easily be non-entirely updated via + a journaled multiblock write. this is because of the complexity of this structure, and i may end up either + changing the way the multiblock write works or adding another type of write to account for this. +
+
+ all changes to the source code should be public by the time this is up, as always you can view it at + our git. +
+
+ that should be it for this week's blog post! i'm hoping that i'll be able to get back on track with the + development of the filesystem, and hopefully by next time i'll have gotten the B-Tree implementation for + directories working! (i'm not sure if i'll actually be able to get it working by then, but i'll try my best!) +
+
+ donations to our libera pay are of course appreciated as always (: +
+ + +
+ besides that, i'll see you all in two weeks! +

+ +
+ +
+ +
+
+ image of xenia, an anthropomorphic fox who was a contender for the linux mascot + image made by @cathodegaytube! +
+
+
+ + diff --git a/blog/posts/infinite_dbas/infinite_dbas.png b/blog/posts/infinite_dbas/infinite_dbas.png new file mode 100644 index 0000000000000000000000000000000000000000..8dacbc92d737b6f215a6a7c6b015d7fb6e5e0911 GIT binary patch literal 9548 zcmb`tcTiJZ^e%i7A_PH5C{m;Z0t$lCLZdl zQQ~c(V${O3cdGXhygvPBdEV)K;I#;luia$(=YoXv`IJbv#zuV0zfp-5r5vS^C^}?n zVJdGR_^})}LW>bfEzZ-p7DxSaNx`}M#xkCuW4mibZoOG@-b1Vs2=fkWIcPb7( z;y}mi%W6jh0?KKo5iyrb1f@^^tju0rWNY%g`TRJg}l8k2hfOD@^w+Mr=I*rR==H5sM}G+!*uu(vg4aS*%t7rkh_L z7^d*#%**lMXiB>ULcM`({$;fdRogzhz=ID({U^M=;YlZ@L&m1ZCcDQO>U|4T7Lk14 zm^xz{F3>H^4n_ugz~RwvPQ&{b;0UX?;e9^G^!+5A_@Sq(=u-WKns9^vLFBg2LNy_ z0Dz&u*h7Hf1_y8e?EmTG|CizakE=4ntoQi#cPRVI^OT)3>;YdHO#US;Ec-yH{5CLb z3RQZVDfa^hR5HPuZMG=sd!Lu&@HO^%%YK`~!NLL;fx{_L#(d)8q2}Ql_03X7n9GMC zQufS2fbwHZFry^Ovw5~*is73^YZ;pMFGjlq1ME89Bx*%iZc1L|IM$Aiw9j~5%GHQ~E@fbza5z&diq!s?Hhpg0&I z4$eZcDOhj9bbo7HL!D5*y?1^lXLN%t!zIH_b9PG)V7@$&vU;wjx!Zy2Ts^uH!qRJD z??*cov`Bj}zx-m4iV;>ghQNJgyvFy@Fh}Y9c#wTa zr+uSxY6G7(Bb26Y)VJ|HM^@kLjN5cY)5T#fjSV;?R+w|Cq^C7mgb%yMc_@JsRM>S5 zff3cs2Bxo%gf#N?z>9VGwNt<8DGX+v9W|^m&7(Z3-2H8PbHbWH|gukp-IAj zGvhuWFDn-m7&TA)f>(Nd_{KN}Lum)DsoZw96lfD z;4K3UiRp1oZy&3{M+WQD!zEy9s`tnaiddVdat-POWQD$Y;Na zg|*4gb&h30HE@U4dBg0&{-~7i4bAMrD;@;H?67xufSn7FSsEyk+Cq#5{34H|0svm1~cp1G?y^c4`Orh3W>&rXxW`nBx=GM1_2s zjTj6-c_Y(we58Nm9;+s7LW{C(@$}BZX4U*<*Lq6Gn9&I2*<3c>Vr@1I4=nMR zrB2~hudUb_5T9%f8U9?{s7SfU?9Aw<2@cS^A^_PZWFH?d+x8~E;gS+JUM(Dw2Z{X=%QS$@-@yAu**$u1BfzVr*Xny)E$6c-$2FIa~f_P zA##ahK8-_jOCy0?aLbRgUR`8y(XqY`9X!TBmX*BZ4wY8hDjF$jef;kZqbn#$l5&$= zlMM(_*&g5zJUVB)LLzvKQUK5Eg#|)gA)-QN1I_~1rE7GtWAQe^VDNP|4unhZ%*xQZRj#7!p!&6n z>O5NPAuoDwTWr#cz4YI2(XS|C9ihDw|579|F^nH<&X zP9Tip(;C#Yi~0Mg*?6<;p~Re&KkFa2Fjb3R`;+ zdY(ylEz{@+)AtYQF++7-x`iHF3_r~HWKVE;g72BQL4?($YUIOAlp)aVpOcFxW6p1n zPh;#{cq63Km66xJ=AeNH)+w)8xqC{Y#TJxf;*zj?arP(^K=9b+^13I#UI?e~^__uX zj8gN@guTdto*jY6K&o#9?Ig6fW;Y3yF+Ywc=nZy`v_McP1oC^EvOXJFw_v19n22ks z3I;ftOnR-EQMBZ5LABZrw=G)^-dNL#2(kD;RthlHCqNkTy4?XM6R*-4i?DX1`%}~ISqUby_+d%C-UKkpDE`oIt8D zjWZDKN=18nsXFD&s(i21 z`H>mExr}(UATzZmtpil2kjTW}aoTHb4h<9MSR#AY^0>G;d^W&?b zg_kzngp~@NYQT(kSGNsJpH=W!QaTaMK{7?JE(BD%-t4g!_~o60h^)X+#%3uCK@FN0 zv#;941MWzSDYU$$(VR|RKe+UbRZ)Wt2e8+_Na2c*EOQ$`!-SVWI>^BrfpjR}^hk5n z%V}o{CGQ=B00WQv^-1{o&;mk4{e$^^hB@_eK=|0AFzldqpx|8FSi|H(c7 zFNkdC?(k{g!}P|6(hgNag!2@;ODi0uHA@d+9E@U_yk8=Bplq15l1G<+Wme}R3Ze2m>&^Hn#rG>tGn zDO0zRM%H-Bnt_+L!)Z@Zmz*h?U&i)^3SzVYXs`a~bvDYuP_57Y z?)z3pC=8`VqbD%TuYp?iRA3Nb5g?5AmVr^Gi}i{#lQ(BD61}l(+Duk)S*ALxVF%-x zY*&bf^%cv{f(^JAA@9`DIDmWP6l-x1*LQMob6V=v91U=YO@D$s)ReEgF-LtR^xAmF z{Q+prAK#o?XT7&5p89r0b4;M}z0%=jSv>3EuU`{1p~z|h2+UkB9$7Pt&Qg!;ikAX? z`6_`ZP*7eL?S@y518Ws#pN+$EhpBEhpU&pi#=L_Q&Fjhw-;ypA^qT0PF~} z{@G~6T?ZIKt2o%IoFCN2zc1wYz(G6`2bidoi(^p5a~qTOfw;}gzu)1h^WU!&z8iF` z`>JvAss3HN6DU#)9ZeakqIWX_8&Aw+K$%f`h~r_P{!>n=%Py8WPvukx0I0-@e92*v zr`vALuj*=!XD`i};9Bjg+`}fI;{csjQBYfRSw<2=TfG1WL4^OON3<9NbPbAuI}RQm zwGBSYzrZrSYpU&2u{6;`4|D_ovuo`&ItYwJ{B;I3flUS~Gp@x-$a8?Fh-$O_cQCb~ z0!!PcVwk{_%Ny=z#*7SLFRimc5xB-t;gY?&L%J6do>TA=>M3v=$)$P7Me0rq};2!!cDFj!z_XJ?C{ zSJiiI4iDcN)osSL(J1p~7eIp;CN(xZNfa_KiRzmZE!qoxGRX9YdWC`khL@%Z_vRN9x3Bn{rsf*F@lGSw9sK5)<|3dWWcB8K3qJT(x~Pd=7C zX;jJtM_u?g*0!0hwA;3j1VEQQtNyIv6(U?ek)A+2*JIjt(q8JwU!&_HKA64IHe0qM zGvH85{MeG76<(}&*L@NYqSl@+J;D3l+bEi1y8r8oQin~P+US4sas<&>@X!dX?LN)y zOk_qlXl|2H8YSFOkp6J>SFrUq{|*xbPI{otVKpm(z!5V4v{nJhuvQMOr^;ZswJ@2$ zj%)H~f|r&F-{z=4>3$6a7=cjL1RI z_IR=KUFnwKj-aEN#?~BOSpr0*e7#(Twv9`%2&-Cah zM$LBJa7QZKU0rbD88Z}tdH}aMQ8}8ifW$VuCkp>WC0jN^Zo{ATBV>7vYl(r?t4tuC zW*~|MoTvnA^{F1gE8s2?(ZgfriGuf!q6ctbg?9!3kkfx6`~Rn#(k0PkEw7=eIhM@C zY<~g;+;Qv=Hh|Mr0>oT!wYf6G$8v-pqC~*^&(vna(=#`Eym7EihFPpVycv!n(aC(v z#kS~3#G4mjq#95@oVhD>tnh_Cio|FElUnhd4DvpCDH*N`1EB>G&aH3j3QN!imCE(X zo#T!K!xLtkJLEO){4Uh|@yR5{r~^z@@-EIR%G>8V)z;J6Ujb^qFEXe537_Z7J}| zW$^K+O*O1|{n4p!Qlo7AxU)7lM-iTgL@?&rMz_#^7yqYyMGC_lu6tOwQO`OvMg8v% zmb@AP2QCIF2GG?#Y;+`588lQm*CGJ!d%^yJ+nYKZ=!lG1)6))==l|EcGkOL$5ZAs(5N}D zEzaPQeAl18&^S6AB0U7;C|ddDf|CClAAo9^cV8pen%*=)9<6lY!6Gq-&7z=~lL?yO zd}H*_O5Z;q3La&VtJ7YI^dnSiUUMG%Z%)e59C@F84~3%%Ikgrw5!~2Wyum&gQ8}Ls z*I4?us;&d&uS{2{dpkRico1h5pzvod`6Hw)4l{76i9+>%N=zKSS%x9jSm0W?n56QR z9v(GN10O}7eSw1`c~c5|p~nBEChxvIL(6DVXOOXyZQLo))F8*hg zi=eX}Og3|Z-n_uGR!r${dmxMgx0Q!*Z#f&h*%h7{{{|j3$8n!k51i9i$a@)ib6;xh zi7}JzecKTja1gb)=S8d)b|c^T6emIe=Sp$iFFR}qT;1G1kaXCr6Aj;=nhgyP55FS9 z>7^q@;*rfpY{{GkTmy%Z(u3U7%aQ`tC~P-|)et6b_5I9?jQ!G51|P z>XP!*wHC89GEoHo?Sed9OY0Bso;CGMWIumEXXf9rgkoejeJq#*vj+N5wrI0tCb;7S zxh{|y`3&4RAtdFph&9*gE$8~W4J9;Y@qSnQQO?qhwVTflIvG)BTE%CgUVufXm|L*G z2S0Oz?kNu)zc10LN=(bBtBXB?oA001P6&zR`A#2sl3l`i%r;Tl4IS^D4PruO=CSKN z6CDCS5-V-Mxg5$2uatdb?~ov;VrvkyBQcNimH|3v>t8eFd6 zK&gCU2IbIr~VU)jsX_5D)HTwE6Nx zC>t!nctE2(YQV3kPs>@rs@b*Ij_@&WAaNI6jJ%>MFe4B-um%ZKVdFQymS;*Nz^^2d z2jN2VrNYW8+(&NoMKFj&2JIP=zLt9N>}yqVmth+I9bJMSWNpzW8sEF5f0|!Die+(J zGE_&<4T!K$i_4B9gw<;E&)75-ikDf33ZIC63F^;(0d@;oORMxsoC^^>RxcQV;kX|U z;%j`acO|(|up6@#Edtje30^kHdo*Zx=3Sf?ct6=ivZ+2n7mvFvixz=- zn!j^V^-^Ev6z6BKu9Ej>FUS(8|9Qc?S>99OAY?W$gX^I(28fW>0lWMMQ}>7ppPuyX z%~9ZdIgd}vg9gZ;MXe9*p6hGALOBznO?z^snCZcz0$ju-$AU^$U$Y82WTo0?%#eV^ z?3oAK?yj-|%p9b_4|QCghZ|nlt+lm}4X3^P$=_(py^2lZu!%)SLzU**OY$-x`7xfp z#@_9#*iPO!_|Jpp&1B+e2vc1;DA+D%LIxRC5o2qlWWC+ODpm~Mdig(%JFS34Z7##*7WO_hQ&z`Hm#; zh77IUYf?f{lLQM|@2$kyElAlc>^7DhzVgeBMQY~I!^hyLXQyz128ZJf26hXQYGwmV z9x-=UEQoIb8RY{j$8+`_$S)1tvbo97zg8T~M>SWwnJOdr_ZPWUvY~zVm#=E+|40jj zg8=Sw-pRG*vGL#5{-MgHUln1u3PKEy6H`}qeP(>+Q9#6uaLHj^U3l5{F0pR%$qbjg z!Q#PP{xP=z%A^|A`RMjU*pct9PlP(Fj}KTh6=|0J(kDR7!koB)s;HH%n^*5eEy*^O zj*FB&PQ!#J+v>mZ68FfLklcu%T{zZe25@aM4(aa(u2F0Fak?cPVcQGoLS;o>v$v4Qr^F2y;H zSYg^=8d=_&=>Z}TjIA5rbGPt{<@!%3>sH%zOQ~*Gn@TtjmD@e+YiE5Bhl`aFLZoY-m7(XpbDvDT-n?R zoYo5_%NrA!`gc3%Z-zPv5k+C8cFYAh`&_2m%h>@J*8Ti#DZ_!BL9K(CsZ|yPU&~u9 zMEWnUSb<|*0tX=nU`up9Oz;V{+S?gVS^fj=N1q#EtB^6RrtPIn$;}Yc6Iupptc$X|pp|TDb_3>JA?RH}mz#?Z^y2 z#r6%AL=Xn#L+LNs%YLo}DjTL$U+*w&lsOFFoEu3bRw#WpU_H}U3)iyyy;>yf(35>A z7}+rGC8uHLSgwb7wJU%mlr?WsiwVw=NC@0mI2^{cQYtUk$10}zu z@ORRhGgnTVN+!}C&AqiAd};dOxwg5(pN~%T{I@%AfE*J+->TJ}rRRGmGkINfVpk zb8-XTO|!^vZB;^8}SZ~DEHB#CYU7Bpy zwG=H4?7hNl0sDlt6;{cL=J5~3OnLzH9mkhKF`qNcMy-_b>EFA;`MUCEq&zDvm1`2! z{HYZu!R~=KTEdJYw@`a>t4C4hFD)j*<;9(NLw&-ryFE8Q;T(91K+z z#JII}!HE^Ee(gJ4Tw#L0RkiNg!w{#zc7bN#lw3=uQXCcpK~Ic*VF-}UKKa^8_&}!C zBNGYo!8x9%RF;{#TV3kEgpQRsZ56g>A?aV2Ge3a5x1GJMuDc-2P3SFkzpJOG=WtIc z*uRS1wyzk(g{#ny4`80xS&0VeIWB~|e=xy6lAvI};kdq42mdJBixR}Sptgj6OnJ{u zg*+uz9hDK!BiC2jZ_Tihm;8duPEZDidN4Z<2Q?xnU)BazQhpL=9Q7>rTP>^Ez z)WCB;ITUjll-3>bYC7lysbTTBNHTM^i7QXfhg#eumaCpT+x|DoC{t$xG6)6k$+C-m_5ORGby;^0y8 zGZ?&|WQM-DTmVCSqOosrzzgXBelZPLB^h@9KE8m=y<-lZ3Q>714Ajwn5CV$Q)6=3Z zBJl+g*;q4`sA`UpqY^46S>C#qHv)6itkC|Y%0xe-d2s(DNaiVRh!ICG3GZmcrU(c? z#(z3*E6ku*1tLL;cKVj@1+vscI!4uPOX~A=Hn7k;olKe)T@Vn9>(Mc}t^2ji18NtO z5o&Ej2g{MOfm%ns6Z353Z*+5#j^a`}@o59fJAh@~S3X6ugC6td zK|W*2Lc!ygO*1~+YAT4F4VPPK5H&KWrLhx~jK#V*FdfxO)Wo*=Vl1a0G4}sulNn9vNdQUjFOc(9(JYo)aXAt>jcL zRm;VVhr~199Tny=qTajteQ;E-)9fuV-xP6$tvvjPy5_gbPBk1Lq|ZxrIi-(3NKtNJ(eN_Ffa F{}*EG7c>9> literal 0 HcmV?d00001