Browse Source

Plan 9 from Bell Labs 2003-01-09

David du Colombier 19 years ago
parent
commit
a9fe9057c2
65 changed files with 26159 additions and 6 deletions
  1. 71 3
      dist/replica/plan9.db
  2. 77 0
      dist/replica/plan9.log
  3. 1164 0
      sys/doc/fossil.ms
  4. BIN
      sys/doc/fossil.pdf
  5. 5401 0
      sys/doc/fossil.ps
  6. 34 0
      sys/lib/sysconfig/fl/boot
  7. 7 0
      sys/lib/sysconfig/fl/flproto
  8. 8 0
      sys/lib/sysconfig/fl/venti.conf
  9. 428 0
      sys/man/4/fossil
  10. 806 0
      sys/man/8/fossilcons
  11. 2 1
      sys/src/9/pc/devether.c
  12. 122 0
      sys/src/9/pc/pcfl
  13. 30 0
      sys/src/9/port/dev.c
  14. 2 2
      sys/src/9/port/devfs.c
  15. 209 0
      sys/src/cmd/fossil/9.h
  16. 126 0
      sys/src/cmd/fossil/9auth.c
  17. 121 0
      sys/src/cmd/fossil/9dir.c
  18. 126 0
      sys/src/cmd/fossil/9excl.c
  19. 286 0
      sys/src/cmd/fossil/9fid.c
  20. 1460 0
      sys/src/cmd/fossil/9fsys.c
  21. 177 0
      sys/src/cmd/fossil/9lstn.c
  22. 1118 0
      sys/src/cmd/fossil/9p.c
  23. 109 0
      sys/src/cmd/fossil/9ping.c
  24. 415 0
      sys/src/cmd/fossil/9proc.c
  25. 195 0
      sys/src/cmd/fossil/9srv.c
  26. 960 0
      sys/src/cmd/fossil/9user.c
  27. 112 0
      sys/src/cmd/fossil/Ccli.c
  28. 417 0
      sys/src/cmd/fossil/Ccmd.c
  29. 390 0
      sys/src/cmd/fossil/Ccons.c
  30. 41 0
      sys/src/cmd/fossil/Clog.c
  31. 441 0
      sys/src/cmd/fossil/archive.c
  32. 19 0
      sys/src/cmd/fossil/build
  33. 40 0
      sys/src/cmd/fossil/buildsh
  34. 421 0
      sys/src/cmd/fossil/bwatch.c
  35. 2000 0
      sys/src/cmd/fossil/cache.c
  36. 298 0
      sys/src/cmd/fossil/dat.h
  37. 25 0
      sys/src/cmd/fossil/deadlock
  38. 332 0
      sys/src/cmd/fossil/disk.c
  39. 86 0
      sys/src/cmd/fossil/dump.c
  40. 36 0
      sys/src/cmd/fossil/error.c
  41. 31 0
      sys/src/cmd/fossil/error.h
  42. 1648 0
      sys/src/cmd/fossil/file.c
  43. 657 0
      sys/src/cmd/fossil/flchk.c
  44. 553 0
      sys/src/cmd/fossil/flfmt.c
  45. 13 0
      sys/src/cmd/fossil/flproto
  46. 98 0
      sys/src/cmd/fossil/fns.h
  47. 186 0
      sys/src/cmd/fossil/fossil-acid
  48. 94 0
      sys/src/cmd/fossil/fossil.c
  49. 819 0
      sys/src/cmd/fossil/fs.c
  50. 48 0
      sys/src/cmd/fossil/fs.h
  51. 17 0
      sys/src/cmd/fossil/history
  52. 121 0
      sys/src/cmd/fossil/invariants
  53. 96 0
      sys/src/cmd/fossil/mkfile
  54. 39 0
      sys/src/cmd/fossil/nobwatch.c
  55. 226 0
      sys/src/cmd/fossil/pack.c
  56. 84 0
      sys/src/cmd/fossil/periodic.c
  57. 958 0
      sys/src/cmd/fossil/source.c
  58. 271 0
      sys/src/cmd/fossil/srcload.c
  59. 11 0
      sys/src/cmd/fossil/stdinc.h
  60. 19 0
      sys/src/cmd/fossil/trunc.c
  61. 13 0
      sys/src/cmd/fossil/unpack
  62. 746 0
      sys/src/cmd/fossil/vac.c
  63. 107 0
      sys/src/cmd/fossil/vac.h
  64. 1127 0
      sys/src/cmd/fossil/view.c
  65. 65 0
      sys/src/cmd/fossil/walk.c

+ 71 - 3
dist/replica/plan9.db

@@ -198,6 +198,10 @@
 386/bin/file - 775 sys sys 1039758559 117145
 386/bin/fmt - 775 sys sys 1039758560 63811
 386/bin/fortune - 775 sys sys 1039758560 66329
+386/bin/fossil - 20000000775 sys sys 1042005470 0
+386/bin/fossil/flchk - 775 sys sys 1042005470 226919
+386/bin/fossil/flfmt - 775 sys sys 1042005471 225502
+386/bin/fossil/fossil - 775 sys sys 1042005469 329196
 386/bin/freq - 775 sys sys 1039758560 60443
 386/bin/fs - 20000000775 sys sys 954380769 0
 386/bin/fs/32vfs - 775 sys sys 1039758560 96155
@@ -2798,11 +2802,13 @@ n/c - 20000000555 sys sys 1015089577 0
 n/c: - 20000000555 sys sys 952641484 0
 n/d: - 20000000555 sys sys 958016621 0
 n/dist - 20000000555 sys sys 1020896384 0
+n/fossil - 20000000775 sys sys 1042005455 0
 n/ftp - 20000000555 sys sys 959261485 0
 n/kfs - 20000000555 sys sys 954008414 0
 n/kremvax - 20000000555 sys sys 985197951 0
 n/paq - 20000000555 sys sys 1017722329 0
 n/sid - 20000000555 sys sys 959261486 0
+n/snap - 20000000775 sys sys 1042005458 0
 n/sources - 20000000555 sys sys 1021926252 0
 n/sourcesdump - 20000000775 sys sys 1041013207 0
 n/sourcessnap - 20000000775 sys sys 1041013207 0
@@ -3040,6 +3046,9 @@ sys/doc/contents.ms - 664 sys sys 1019916701 4920
 sys/doc/contents.ps - 664 sys sys 1019916845 232629
 sys/doc/docfonts - 664 sys sys 1038117516 208
 sys/doc/fonts - 664 sys sys 944959649 137
+sys/doc/fossil.ms - 664 sys sys 1042044710 31440
+sys/doc/fossil.pdf - 664 sys sys 1042044711 65284
+sys/doc/fossil.ps - 664 sys sys 1042044711 110396
 sys/doc/fs - 20000000775 sys sys 945616779 0
 sys/doc/fs/fs.html - 664 sys sys 1020013937 21345
 sys/doc/fs/fs.pdf - 664 sys sys 1020384351 47177
@@ -4153,6 +4162,10 @@ sys/lib/sysconfig/auth/files/rewrite - 664 sys sys 1016833537 428
 sys/lib/sysconfig/auth/files/tcp566 - 775 sys sys 1016833537 36
 sys/lib/sysconfig/auth/files/tcp567 - 775 sys sys 1016833537 34
 sys/lib/sysconfig/auth/mkfile - 664 sys sys 1016833657 2937
+sys/lib/sysconfig/fl - 20000000775 sys sys 1042004836 0
+sys/lib/sysconfig/fl/boot - 775 sys sys 1042004836 773
+sys/lib/sysconfig/fl/flproto - 664 sys sys 1042004836 129
+sys/lib/sysconfig/fl/venti.conf - 664 sys sys 1042004837 139
 sys/lib/sysconfig/proto - 20000000775 sys sys 959740591 0
 sys/lib/sysconfig/proto/allproto - 664 sys sys 945018241 2
 sys/lib/sysconfig/proto/armpaqproto - 664 sys sys 1037173885 2270
@@ -4712,6 +4725,7 @@ sys/man/4/dossrv - 664 sys sys 1015024813 4176
 sys/man/4/execnet - 664 sys sys 1019866708 1069
 sys/man/4/exportfs - 664 sys sys 1018386776 3746
 sys/man/4/factotum - 664 sys sys 1021579982 13900
+sys/man/4/fossil - 664 sys sys 1042005418 8705
 sys/man/4/fs - 664 sys sys 1019058716 3387
 sys/man/4/ftpfs - 664 sys sys 1018386777 4113
 sys/man/4/import - 664 sys sys 1034195346 2204
@@ -4809,6 +4823,7 @@ sys/man/8/cpurc - 664 sys sys 971455510 1275
 sys/man/8/cron - 664 sys sys 944959679 1750
 sys/man/8/dhcpd - 664 sys sys 1032654987 5237
 sys/man/8/drawterm - 664 sys sys 958419689 2458
+sys/man/8/fossilcons - 664 sys sys 1042005415 12630
 sys/man/8/fs - 664 sys sys 1037805200 13843
 sys/man/8/fsconfig - 664 sys sys 1037805200 7966
 sys/man/8/httpd - 664 sys sys 1037690024 4516
@@ -5058,7 +5073,7 @@ sys/src/9/pc/cga.c - 664 sys sys 1015014513 1843
 sys/src/9/pc/clock.c - 664 sys sys 1032052912 899
 sys/src/9/pc/dat.h - 664 sys sys 1032052913 6070
 sys/src/9/pc/devarch.c - 664 sys sys 1036812831 16158
-sys/src/9/pc/devether.c - 664 sys sys 1026847635 10042
+sys/src/9/pc/devether.c - 664 sys sys 1042004805 10072
 sys/src/9/pc/devfloppy.c - 664 sys sys 1015014514 19930
 sys/src/9/pc/devi82365.c - 664 sys sys 1020284820 19987
 sys/src/9/pc/devlm78.c - 664 sys sys 1026847635 6038
@@ -5117,6 +5132,7 @@ sys/src/9/pc/pcauth - 664 sys sys 1039753496 600
 sys/src/9/pc/pccd - 664 sys sys 1039753495 1278
 sys/src/9/pc/pccpu - 664 sys sys 1039803186 785
 sys/src/9/pc/pcdisk - 664 sys sys 1039764711 1369
+sys/src/9/pc/pcfl - 664 sys sys 1042004821 1563
 sys/src/9/pc/pcflop - 664 sys sys 1032749195 1353
 sys/src/9/pc/pci.c - 664 sys sys 1032052921 23359
 sys/src/9/pc/pcmciamodem.c - 664 sys sys 1036812832 1499
@@ -5174,7 +5190,7 @@ sys/src/9/port/cache.c - 664 sys sys 1014931171 9242
 sys/src/9/port/chan.c - 664 sys sys 1031706300 28370
 sys/src/9/port/cis.c - 664 sys sys 1014931171 8087
 sys/src/9/port/debugalloc.c - 664 sys sys 1014931171 10402
-sys/src/9/port/dev.c - 664 sys sys 1032990930 6881
+sys/src/9/port/dev.c - 664 sys sys 1042004688 8082
 sys/src/9/port/devaudio.c - 664 sys sys 1026847546 21137
 sys/src/9/port/devbridge.c - 664 sys sys 1026847546 24311
 sys/src/9/port/devcap.c - 664 sys sys 1032052801 4070
@@ -5182,7 +5198,7 @@ sys/src/9/port/devcons.c - 664 sys sys 1036812998 20919
 sys/src/9/port/devdraw.c - 664 sys sys 1039753332 41987
 sys/src/9/port/devdup.c - 664 sys sys 1014931172 2332
 sys/src/9/port/devenv.c - 664 sys sys 1019762849 6562
-sys/src/9/port/devfs.c - 664 sys sys 1041971958 10698
+sys/src/9/port/devfs.c - 664 sys sys 1042044133 10702
 sys/src/9/port/devkprof.c - 664 sys sys 1014931173 3111
 sys/src/9/port/devloopback.c - 664 sys sys 1018721201 14968
 sys/src/9/port/devmnt.c - 664 sys sys 1041443399 21588
@@ -6966,6 +6982,58 @@ sys/src/cmd/fax/subr.c - 664 sys sys 1015090401 1245
 sys/src/cmd/file.c - 664 sys sys 1038186733 20196
 sys/src/cmd/fmt.c - 664 sys sys 1025298248 3897
 sys/src/cmd/fortune.c - 664 sys sys 1035832953 1674
+sys/src/cmd/fossil - 20000000775 sys sys 1042005512 0
+sys/src/cmd/fossil/9.h - 664 sys sys 1042005502 3379
+sys/src/cmd/fossil/9auth.c - 664 sys sys 1042005502 2389
+sys/src/cmd/fossil/9dir.c - 664 sys sys 1042005502 1995
+sys/src/cmd/fossil/9excl.c - 664 sys sys 1042005502 1887
+sys/src/cmd/fossil/9fid.c - 664 sys sys 1042005502 5236
+sys/src/cmd/fossil/9fsys.c - 664 sys sys 1042005503 26731
+sys/src/cmd/fossil/9lstn.c - 664 sys sys 1042005503 2865
+sys/src/cmd/fossil/9p.c - 664 sys sys 1042005503 21328
+sys/src/cmd/fossil/9ping.c - 664 sys sys 1042005503 1563
+sys/src/cmd/fossil/9proc.c - 664 sys sys 1042005503 7358
+sys/src/cmd/fossil/9srv.c - 664 sys sys 1042005504 3215
+sys/src/cmd/fossil/9user.c - 664 sys sys 1042005504 17476
+sys/src/cmd/fossil/Ccli.c - 664 sys sys 1042005504 1624
+sys/src/cmd/fossil/Ccmd.c - 664 sys sys 1042005504 7169
+sys/src/cmd/fossil/Ccons.c - 664 sys sys 1042005504 6524
+sys/src/cmd/fossil/Clog.c - 664 sys sys 1042005505 591
+sys/src/cmd/fossil/archive.c - 664 sys sys 1042005505 9083
+sys/src/cmd/fossil/build - 664 sys sys 1042005505 449
+sys/src/cmd/fossil/buildsh - 775 sys sys 1042005505 561
+sys/src/cmd/fossil/bwatch.c - 664 sys sys 1042005505 6754
+sys/src/cmd/fossil/cache.c - 664 sys sys 1042005506 40534
+sys/src/cmd/fossil/dat.h - 664 sys sys 1042005506 7775
+sys/src/cmd/fossil/deadlock - 775 sys sys 1042005506 413
+sys/src/cmd/fossil/disk.c - 664 sys sys 1042005506 5634
+sys/src/cmd/fossil/dump.c - 664 sys sys 1042005506 1340
+sys/src/cmd/fossil/error.c - 664 sys sys 1042005507 1367
+sys/src/cmd/fossil/error.h - 664 sys sys 1042005507 744
+sys/src/cmd/fossil/file.c - 664 sys sys 1042005507 27500
+sys/src/cmd/fossil/flchk.c - 664 sys sys 1042005507 13670
+sys/src/cmd/fossil/flfmt.c - 664 sys sys 1042005507 10314
+sys/src/cmd/fossil/flproto - 664 sys sys 1042005508 210
+sys/src/cmd/fossil/fns.h - 664 sys sys 1042005508 2950
+sys/src/cmd/fossil/fossil-acid - 664 sys sys 1042005508 3965
+sys/src/cmd/fossil/fossil.c - 664 sys sys 1042005508 1256
+sys/src/cmd/fossil/fs.c - 664 sys sys 1042005508 16962
+sys/src/cmd/fossil/fs.h - 664 sys sys 1042005509 1222
+sys/src/cmd/fossil/history - 664 sys sys 1042005509 482
+sys/src/cmd/fossil/invariants - 664 sys sys 1042005509 4073
+sys/src/cmd/fossil/mkfile - 664 sys sys 1042005509 1589
+sys/src/cmd/fossil/nobwatch.c - 664 sys sys 1042005509 329
+sys/src/cmd/fossil/pack.c - 664 sys sys 1042005510 4683
+sys/src/cmd/fossil/periodic.c - 664 sys sys 1042005510 1091
+sys/src/cmd/fossil/source.c - 664 sys sys 1042005510 18124
+sys/src/cmd/fossil/srcload.c - 664 sys sys 1042005510 4178
+sys/src/cmd/fossil/stdinc.h - 664 sys sys 1042005510 155
+sys/src/cmd/fossil/trunc.c - 664 sys sys 1042005511 280
+sys/src/cmd/fossil/unpack - 775 sys sys 1042005511 286
+sys/src/cmd/fossil/vac.c - 664 sys sys 1042005511 12497
+sys/src/cmd/fossil/vac.h - 664 sys sys 1042005511 2782
+sys/src/cmd/fossil/view.c - 664 sys sys 1042005512 19708
+sys/src/cmd/fossil/walk.c - 664 sys sys 1042005512 963
 sys/src/cmd/freq.c - 664 sys sys 944961364 1682
 sys/src/cmd/getflags - 20000000775 sys sys 954036865 0
 sys/src/cmd/getflags/funcgetflags.c - 664 sys sys 944960998 4621

+ 77 - 0
dist/replica/plan9.log

@@ -16913,3 +16913,80 @@
 1041971572 11 c sys/man/7/INDEX - 664 sys sys 1041971551 89
 1041971572 12 c sys/man/8/INDEX - 664 sys sys 1041971551 2472
 1041973373 0 c sys/src/9/port/devfs.c - 664 sys sys 1041971958 10698
+1042005689 0 a 386/bin/fossil - 20000000775 sys sys 1042005470 0
+1042005689 1 a 386/bin/fossil/flchk - 775 sys sys 1042005470 226919
+1042005689 2 a 386/bin/fossil/flfmt - 775 sys sys 1042005471 225502
+1042005689 3 a 386/bin/fossil/fossil - 775 sys sys 1042005469 329196
+1042005689 4 a n/fossil - 20000000775 sys sys 1042005455 0
+1042005689 5 a n/snap - 20000000775 sys sys 1042005458 0
+1042005689 6 a sys/doc/fossil.ms - 664 sys sys 1042005621 30983
+1042005689 7 a sys/doc/fossil.ps - 664 sys sys 1042005622 105122
+1042005689 8 a sys/lib/sysconfig/fl - 20000000775 sys sys 1042004836 0
+1042005689 9 a sys/lib/sysconfig/fl/boot - 775 sys sys 1042004836 773
+1042005689 10 a sys/lib/sysconfig/fl/flproto - 664 sys sys 1042004836 129
+1042005689 11 a sys/lib/sysconfig/fl/venti.conf - 664 sys sys 1042004837 139
+1042005689 12 a sys/man/4/fossil - 664 sys sys 1042005418 8705
+1042005689 13 a sys/man/8/fossilcons - 664 sys sys 1042005415 12630
+1042005689 14 c sys/src/9/pc/devether.c - 664 sys sys 1042004805 10072
+1042005689 15 a sys/src/9/pc/pcfl - 664 sys sys 1042004821 1563
+1042005689 16 c sys/src/9/port/dev.c - 664 sys sys 1042004688 8082
+1042005689 17 a sys/src/cmd/fossil - 20000000775 sys sys 1042005512 0
+1042005689 18 a sys/src/cmd/fossil/9.h - 664 sys sys 1042005502 3379
+1042005689 19 a sys/src/cmd/fossil/9auth.c - 664 sys sys 1042005502 2389
+1042005689 20 a sys/src/cmd/fossil/9dir.c - 664 sys sys 1042005502 1995
+1042005689 21 a sys/src/cmd/fossil/9excl.c - 664 sys sys 1042005502 1887
+1042005689 22 a sys/src/cmd/fossil/9fid.c - 664 sys sys 1042005502 5236
+1042005689 23 a sys/src/cmd/fossil/9fsys.c - 664 sys sys 1042005503 26731
+1042005689 24 a sys/src/cmd/fossil/9lstn.c - 664 sys sys 1042005503 2865
+1042005689 25 a sys/src/cmd/fossil/9p.c - 664 sys sys 1042005503 21328
+1042005689 26 a sys/src/cmd/fossil/9ping.c - 664 sys sys 1042005503 1563
+1042005689 27 a sys/src/cmd/fossil/9proc.c - 664 sys sys 1042005503 7358
+1042005689 28 a sys/src/cmd/fossil/9srv.c - 664 sys sys 1042005504 3215
+1042005689 29 a sys/src/cmd/fossil/9user.c - 664 sys sys 1042005504 17476
+1042005689 30 a sys/src/cmd/fossil/Ccli.c - 664 sys sys 1042005504 1624
+1042005689 31 a sys/src/cmd/fossil/Ccmd.c - 664 sys sys 1042005504 7169
+1042005689 32 a sys/src/cmd/fossil/Ccons.c - 664 sys sys 1042005504 6524
+1042005689 33 a sys/src/cmd/fossil/Clog.c - 664 sys sys 1042005505 591
+1042005689 34 a sys/src/cmd/fossil/archive.c - 664 sys sys 1042005505 9083
+1042005689 35 a sys/src/cmd/fossil/build - 664 sys sys 1042005505 449
+1042005689 36 a sys/src/cmd/fossil/buildsh - 775 sys sys 1042005505 561
+1042005689 37 a sys/src/cmd/fossil/bwatch.c - 664 sys sys 1042005505 6754
+1042005689 38 a sys/src/cmd/fossil/cache.c - 664 sys sys 1042005506 40534
+1042005689 39 a sys/src/cmd/fossil/dat.h - 664 sys sys 1042005506 7775
+1042005689 40 a sys/src/cmd/fossil/deadlock - 775 sys sys 1042005506 413
+1042005689 41 a sys/src/cmd/fossil/disk.c - 664 sys sys 1042005506 5634
+1042005689 42 a sys/src/cmd/fossil/dump.c - 664 sys sys 1042005506 1340
+1042005689 43 a sys/src/cmd/fossil/error.c - 664 sys sys 1042005507 1367
+1042005689 44 a sys/src/cmd/fossil/error.h - 664 sys sys 1042005507 744
+1042005689 45 a sys/src/cmd/fossil/file.c - 664 sys sys 1042005507 27500
+1042005689 46 a sys/src/cmd/fossil/flchk.c - 664 sys sys 1042005507 13670
+1042005689 47 a sys/src/cmd/fossil/flfmt.c - 664 sys sys 1042005507 10314
+1042005689 48 a sys/src/cmd/fossil/flproto - 664 sys sys 1042005508 210
+1042005689 49 a sys/src/cmd/fossil/fns.h - 664 sys sys 1042005508 2950
+1042005689 50 a sys/src/cmd/fossil/fossil-acid - 664 sys sys 1042005508 3965
+1042005689 51 a sys/src/cmd/fossil/fossil.c - 664 sys sys 1042005508 1256
+1042005689 52 a sys/src/cmd/fossil/fs.c - 664 sys sys 1042005508 16962
+1042005689 53 a sys/src/cmd/fossil/fs.h - 664 sys sys 1042005509 1222
+1042005689 54 a sys/src/cmd/fossil/history - 664 sys sys 1042005509 482
+1042005689 55 a sys/src/cmd/fossil/invariants - 664 sys sys 1042005509 4073
+1042005689 56 a sys/src/cmd/fossil/mkfile - 664 sys sys 1042005509 1589
+1042005689 57 a sys/src/cmd/fossil/nobwatch.c - 664 sys sys 1042005509 329
+1042005689 58 a sys/src/cmd/fossil/pack.c - 664 sys sys 1042005510 4683
+1042005689 59 a sys/src/cmd/fossil/periodic.c - 664 sys sys 1042005510 1091
+1042005689 60 a sys/src/cmd/fossil/source.c - 664 sys sys 1042005510 18124
+1042005689 61 a sys/src/cmd/fossil/srcload.c - 664 sys sys 1042005510 4178
+1042005689 62 a sys/src/cmd/fossil/stdinc.h - 664 sys sys 1042005510 155
+1042005689 63 a sys/src/cmd/fossil/trunc.c - 664 sys sys 1042005511 280
+1042005689 64 a sys/src/cmd/fossil/unpack - 775 sys sys 1042005511 286
+1042005689 65 a sys/src/cmd/fossil/vac.c - 664 sys sys 1042005511 12497
+1042005689 66 a sys/src/cmd/fossil/vac.h - 664 sys sys 1042005511 2782
+1042005689 67 a sys/src/cmd/fossil/view.c - 664 sys sys 1042005512 19708
+1042005689 68 a sys/src/cmd/fossil/walk.c - 664 sys sys 1042005512 963
+1042005689 69 a sys/src/cmd/fossil/words - 664 sys sys 1042005512 1166
+1042006506 0 a sys/doc/fossil.pdf - 664 sys sys 1042006244 65276
+1042006506 1 c sys/doc/fossil.ps - 664 sys sys 1042006244 110324
+1042006877 0 d sys/src/cmd/fossil/words - 664 sys sys 1042005512 0
+1042045363 0 c sys/doc/fossil.ms - 664 sys sys 1042044710 31440
+1042045363 1 c sys/doc/fossil.pdf - 664 sys sys 1042044711 65284
+1042045363 2 c sys/doc/fossil.ps - 664 sys sys 1042044711 110396
+1042045363 3 c sys/src/9/port/devfs.c - 664 sys sys 1042044133 10702

+ 1164 - 0
sys/doc/fossil.ms

@@ -0,0 +1,1164 @@
+... .FP times
+... .fp 1 R R.nomath
+... .fp 5 CW LucidaSansCW83
+.TL
+Fossil, an Archival File Server
+.AU
+Sean Quinlan
+Jim McKie
+Russ Cox
+jmk,rsc@plan9.bell-labs.com
+.AB
+This paper describes the internals and 
+operation of Fossil, an archival file server built for Plan 9.
+Fossil has not yet replaced the current Plan 9 file server
+and
+.CW kfs ,
+but that is our eventual intent.
+Both fossil and this documentation are
+works in progress.  Comments on either are most welcome.
+.AE
+.de HP
+.LP
+..
+.NH 1
+Introduction
+.HP
+Fossil is an archival file server built for Plan 9.
+In a typical configuration, it maintains a traditional file system
+in a local disk partition and periodically archives snapshots of the file system
+to a Venti server.  These archives are made available through
+a file system interface.
+Fossil can also be run without a Venti server, in which case the
+snapshots (if any) occupy local disk space.
+.PP
+The bulk of this paper explains the underlying data structures:
+Venti trees, the Venti archival file system format, and finally Fossil's
+file system format.
+The end of the paper discusses the architecture of the Fossil server.
+.PP
+The presentation of the data structures is very detailed, perhaps
+too detailed for most readers.
+The intent is to record all the details necessary to make structural
+changes to the file system format.
+Feel free to jump ahead when boredom strikes.
+.NH 1
+Venti trees and directory hierarchies
+.HP
+Venti [3] is an archival block storage server.
+Once a block is stored, it can be retrieved by presenting the 20-byte
+SHA1 hash of its contents, called a
+.I score .
+Blocks on Venti have a maximum length of about 56 kilobytes,
+though in practice smaller blocks are used.
+To store a byte stream of arbitrary length, Venti uses a hash tree.
+Conceptually, the data stream is broken into fixed-size (say,
+.I dsize -byte)
+chunks, which are stored on the Venti server.
+The resulting scores are concatenated into a new pointer stream, which is
+broken into fixed size (say,
+.I psize -byte)
+chunks, which are stored on the Venti server.
+.I Psize "" (
+is different from
+.I dsize
+so that we can ensure that each pointer block holds an
+integral number of pointers.)
+This yields a new pointer stream, and so on, until there is a single block
+and finally a single score describing the entire tree.
+The resulting structure looks like:
+.PS
+.ps 8
+.vs 10
+boxht=0.1
+boxwid=0.1
+
+B0: box invis wid 1 "\f(CWVtDataType\fP"
+move right 0.1
+L0a: box wid 0.2
+move right 0.1
+L0b: box wid 0.2
+move right 0.1
+L0c: box invis wid 0.2 "..."
+move right 0.1
+
+L0d: box wid 0.2
+move right 0.1
+L0e: box wid 0.2
+move right 0.2
+L0f: box invis wid 0.2 "..."
+move right 0.2
+
+L0g: box wid 0.2
+move right 0.1
+L0h: box wid 0.2
+move right 0.1
+L0i: box invis wid 0.2 "..."
+move right 0.1
+
+L0j: box wid 0.2
+move right 0.1
+L0k: box wid 0.2
+move right 0.1
+L0l: box invis wid 0.2 "..."
+move right 0.1
+L0m: box wid 0.2
+
+define boxppddd {
+	line from 0.2<$1.nw,$1.ne> to 0.2<$1.sw,$1.se>
+	line from 0.4<$1.nw,$1.ne> to 0.4<$1.sw,$1.se>
+	X: box invis at 0.1<$1.nw,$1.ne>
+	Y: box invis at 0.1<$1.sw,$1.se>
+	line -> from 0.5<X,Y> to $2.nw
+	X: box invis at 0.3<$1.nw,$1.ne>
+	Y: box invis at 0.3<$1.sw,$1.se>
+	line -> from 0.5<X,Y> to $3.nw
+	"..." at 0.7<$1.w,$1.e>
+}
+
+define boxppdddp {
+	line from 0.2<$1.nw,$1.ne> to 0.2<$1.sw,$1.se>
+	line from 0.4<$1.nw,$1.ne> to 0.4<$1.sw,$1.se>
+	line from 0.8<$1.nw,$1.ne> to 0.8<$1.sw,$1.se>
+	X: box invis at 0.1<$1.nw,$1.ne>
+	Y: box invis at 0.1<$1.sw,$1.se>
+	line -> from 0.5<X,Y> to $2.nw
+	X: box invis at 0.3<$1.nw,$1.ne>
+	Y: box invis at 0.3<$1.sw,$1.se>
+	line -> from 0.5<X,Y> to $3.nw
+	"..." at 0.6<$1.w,$1.e>
+	X: box invis at 0.9<$1.nw,$1.ne>
+	Y: box invis at 0.9<$1.sw,$1.se>
+	line -> from 0.5<X,Y> to $4.nw
+}
+
+define boxpdddp {
+	line from 0.2<$1.nw,$1.ne> to 0.2<$1.sw,$1.se>
+	line from 0.8<$1.nw,$1.ne> to 0.8<$1.sw,$1.se>
+	X: box invis at 0.1<$1.nw,$1.ne>
+	Y: box invis at 0.1<$1.sw,$1.se>
+	line -> from 0.5<X,Y> to $2.nw
+	"..." at 0.5<$1.w,$1.e>
+	X: box invis at 0.9<$1.nw,$1.ne>
+	Y: box invis at 0.9<$1.sw,$1.se>
+	line -> from 0.5<X,Y> to $3.nw
+}
+
+bhd=0.4
+L1abc: box wid 0.5 at 0.5<L0a, L0b>+(0,bhd)
+boxppddd(L1abc, L0a, L0b)
+L1def: box wid 0.5 at 0.5<L0d, L0e>+(0,bhd)
+boxppddd(L1def, L0d, L0e)
+L1ghi: box wid 0.5 at 0.5<L0g, L0h>+(0,bhd)
+boxppddd(L1ghi, L0g, L0h)
+L1jklm: box wid 0.5 at 0.5<L0j, L0k>+(0,bhd)
+boxppdddp(L1jklm, L0j, L0k, L0m)
+B1: box invis wid 1 "\f(CWVtPointerType0\fP" at B0+(0,bhd)
+
+L2abcdef: box wid 0.5 at 0.5<L1abc,L1def>+(0,bhd)
+boxppddd(L2abcdef, L1abc, L1def)
+L2ghijklm: box wid 0.5 at 0.5<L1ghi,L1jklm>+(0,bhd)
+boxpdddp(L2ghijklm, L1ghi, L1jklm)
+B2: box invis wid 1 "\f(CWVtPointerType1\fP" at B1+(0,bhd)
+
+L3atom: box wid 0.5 at 0.5<L2abcdef, L2ghijklm>+(0,bhd)
+boxpdddp(L3atom, L2abcdef, L2ghijklm)
+B3: box invis wid 1 "\f(CWVtPointerType2\fP" at B2+(0,bhd)
+.PE
+.LP
+The leaves are the original data stream.  Those blocks have type
+.CW VtDataType .
+The first pointer stream has type
+.CW VtPointerType0 ,
+the next has type
+.CW VtPointerType1 ,
+and so on.
+The figure ends with a single block of type
+.CW VtPointerType2 ,
+but in general trees can have height up to
+.CW VtPointerType6 .
+For a
+.I dsize
+of 8192 bytes
+and
+.I psize
+of 8180 bytes (409 pointers),
+this gives a maximum stream size of approximately 10 zettabytes
+(2\s-2\u73\d\s+2 or 10\s-2\u22\d\s+2 bytes).
+.PP
+Data block are truncated to remove trailing runs of zeros before
+storage to Venti; they are zero-filled back to
+.I dsize
+bytes after retrieval from Venti.
+SImilarly, trailing runs of pointers to zero-length blocks are
+removed from and added back to pointer blocks.
+These simple rules happen to make it particularly efficient to store
+large runs of zeros, as might occur in a data stream with ``holes:''
+the zero-length block itself can be interpreted as a tree of any
+depth encoding an all-zero data stream.
+.PP
+Reconstructing the data stream requires the score and type of the
+topmost block in the tree, the data chunk size, the pointer chunk size,
+and the data stream size.
+(From the data stream size and the chunk sizes we could derive the
+depth of the tree and thus the type of the topmost block, but it is convenient
+to allow trees that are deeper than necessary.)
+This information is kept in a 40-byte structure called a
+.CW VtEntry :
+.P1
+VtEntry:
+.ta +\w'    'u +\w'            'u
+	gen[4]	\fRgeneration number\fP
+	psize[2]	\fRsize of pointer blocks\fP
+	dsize[2]	\fRsize of data blocks\fP
+	flags[1]
+	zero[5]
+	size[6]	\fRlength of file\fP
+	score[20]	\fRscore of root block in tree\fP
+.P2
+(In this notation,
+.CW name[sz]
+indicates a
+.CW sz -byte
+field called
+.CW name .
+Integers are stored in big-endian order.
+.CW Size
+really is a 48-bit field.)
+.CW Flags
+is made up of the following bit fields.
+.I or ' `
+of the following flags:
+.P1
+.ta +\w'      'u +\w'                      'u
+0x01	VtEntryActive	\fRentry is allocated\fP
+0x02	VtEntryDir	\fRentry describes a Venti directory (q.v.)\fP
+0x1C	VtEntryDepthMask	\fRmask for tree depth\fP
+0x20	VtEntryLocal	\fRreserved (q.v.)\fP
+.P2
+.LP
+The depth of the described tree is stored in the 5 bits indicated:
+a tree with a topmost node of type
+.CW VtPointerType3
+has depth 4.
+.PP
+With
+.CW VtEntry
+we can build more complicated data structures,
+ones with multiple or nested data streams.
+A data stream consisting of
+.CW VtEntry
+structures is called a Venti directory.
+It is identical in structure to the Venti data stream
+we described earlier except that the bottom-level type is
+.CW VtDirType ,
+and
+the
+.CW VtEntry
+describing a Venti directory has the
+.CW VtEntryDir
+flag bit set.
+The
+.I dsize
+for a Venti directory
+is a multiple of 40 so that each data chunk holds
+an integer number of
+.CW VtEntry
+structures.
+By analogy with Venti directories,
+we call the original data stream a
+Venti file.
+Note that Venti files are assumed
+.I not
+to contain pointers to other Venti blocks.
+The only pointers to Venti blocks occur in 
+.CW VtEntry
+structures in
+Venti directories
+(and in the internal hash tree structure of the
+individual files and directories).
+Note also that these directories are nothing more than pointer lists.
+In particular, there are no names or metadata like in a file system.
+.PP
+To make it easier to pass hierarchies between applications,
+the root of a hierarchy is described in a 300-byte structure
+called a
+.CW VtRoot :
+.P1
+VtRoot:
+.ta +\w'    'u +\w'                'u
+	version[2]	\f(CW2\fP
+	name[128]	\fRname of structure (just a comment)\fP
+	type[128]	\fRstring describing structure (\f(CWvac\fR)\f(CW
+	score[20]	\fRpointer to \f(CWVtDirType\fP block\f(CW
+	blockSize[2]	\fRmaximum block size in structure\fP
+	prev[20]	\fRprevious \f(CWVtRoot\fP in chain, if any\fP
+.P2
+.LP
+This structure is stored to Venti and its score is passed
+between applications, typically in the form
+``\fItype\f(CW:\fIrootscore\fR,''
+where
+.I type
+is the type field from the
+.CW VtRoot
+structure, and
+.I rootscore
+is the score of the
+.CW VtRoot
+block.
+.CW VtRoot
+structures can be chained together using the
+.I prev
+field to encode an archival history
+of the data structure.
+.PP
+For example, a small Venti hierarchy might look like:
+.PS
+.ps 8
+.vs 10
+boxwid=0.1
+boxht=0.1
+f=0.9
+mb=0.16
+
+VtRoot: [
+	right
+	B1: box
+	move right 0.1
+	"\f(CWVtRoot\fP" ljust
+]
+
+Root: [
+	right
+	B1: box fill f
+	B2: box fill f
+	B3: box fill f
+	move right 0.1
+] with .nw at VtRoot.sw+(0.2,-.1)
+Level1: [
+	RootMeta: [
+		box wid mb
+	]
+	MetaSource: [
+		right
+		B1: box wid 5*mb
+	] with .nw at RootMeta.sw+(0,-.1)
+
+	Source: [
+		right
+		B1: box fill f
+		B2: box fill f
+		B3: box fill f
+		B4: box fill f
+		B5: box fill f
+		B6: box fill f
+		B7: box fill f
+		B8: box fill f
+	] with .nw at MetaSource.sw+(0,-.1)
+	SB1: box invis at Source.B1
+	SB2: box invis at Source.B2
+	SB3: box invis at Source.B3
+] with .nw at Root.sw+(0.4,-.1)
+Level2: [
+	MetaSource: [
+		right
+		B1: box wid 5*mb
+	] 
+	Source: [
+		right
+		B1: box fill f
+		B2: box fill f
+		B3: box fill f
+		B4: box fill f
+		B5: box fill f
+		B6: box fill f
+		B7: box fill f
+		B8: box fill f
+	] with .nw at MetaSource.sw+(0,-.1)
+	File: box wid 0.8 with .nw at Source.sw+(0,-.1)
+] with .nw at Level1.sw+(0.6,-.1)
+
+line -> from VtRoot.B1 down boxwid/2+0.1+boxwid/2 then to Root.w
+line -> from Root.B3 down boxwid/2+0.1+boxwid/2 then to Level1.RootMeta.w
+line -> from Root.B2 down boxwid/2+0.1+boxwid+0.1+boxwid/2 then to Level1.MetaSource.w
+line -> from Root.B1 down boxwid/2+0.1+boxwid+0.1+boxwid+0.1+boxwid/2 then to Level1.Source.w
+
+line -> from Level1.SB3 down boxwid/2+0.1+boxwid/2 then to Level2.MetaSource.w
+line -> from Level1.SB2 down boxwid/2+0.1+boxwid+0.1+boxwid/2 then to Level2.Source.w
+line -> from Level1.SB1 down boxwid/2+0.1+boxwid+0.1+boxwid+0.1+boxwid/2 then to Level2.File.w
+
+[
+	KEY: box wid 1.5 invis "Key"
+	line from KEY.sw to KEY.se
+	k = -.1
+	kk=0.5
+	A: [
+		box wid 4*boxwid
+		"Venti file" ljust with .w at last box .w+(kk,0)
+	] with .nw at KEY.sw+(0,2*k)
+	B: [
+		box fill f
+		"Venti entry (\f(CWVtEntry\fP)" ljust with .w at last box .w+(kk,0)
+	] with .nw at A.sw+(0,k)
+	C: [
+		right
+		CC: box fill f
+		box fill f
+		box fill f
+		box fill f
+		"Venti directory" ljust with .w at CC.w+(kk,0)
+	] with .nw at B.sw+(0,k)
+	D: [
+		line -> right 3*boxwid
+		"Venti pointer (score)" ljust with .w at last line .w+(kk, 0)
+	] with .nw at C.sw+(0,k)
+] with .nw at VtRoot.nw+(3,0)
+.PE
+.LP
+Venti files are shown as white boxes, while directories are shown
+as shaded boxes.  Each shaded square represents a
+.CW VtEntry .
+Arrows represent pointers from
+.CW VtEntry
+structures to other
+Venti files or directories.
+.PP
+The hierarchical structure provided by Venti files and directories
+can be used as the base for more complicated data structures.
+Because this structure captures all the information
+about pointers to other blocks, tools written to traverse
+Venti hierarchies can traverse the more complicated
+data structures as well.
+For example,
+.I venti/copy
+(see
+.I ventiaux (8))
+copies a Venti hierarchy from one Venti server to another,
+given the root
+.CW VtEntry .
+Because the traditional file system described in later sections is
+layered on a Venti hierarchy, 
+.I venti/copy
+can copy it without fully understanding its structure.
+.NH 1
+Vac file system format
+.HP
+The Venti archive format
+.I vac
+builds a traditional file system using a Venti hierarchy.
+Each vac file is implemented as a Venti file;
+each vac directory is implemented as a Venti
+directory and a Venti file to provide traditional file system metadata.
+The metadata is stored in a structure called a
+.CW DirEntry :
+.P1
+DirEntry:
+.ta +\w'    'u +\w'            'u
+	magic[4]	\f(CW0x1c4d9072\fP (DirMagic)\fP
+	version[2]	\f(CW9\fP
+	elem[s]	\fRname (final path element only)\fP
+	entry[4]	\fRentry number for Venti file or directory\fP
+	gen[4]	\fRgeneration number\fP
+	mentry[4]	\fRentry number for Venti file holding metadata\fP
+	mgen[4]	\fRgeneration number\fP
+	qid[8]	\fRunique file serial number\fP
+	uid[s]	\fRowner\fP
+	gid[s]	\fRgroup\fP
+	mid[s]	\fRlast modified by\fP
+	mtime[4]	\fRlast modification time\fP
+	ctime[4]	\fRcreation time\fP
+	atime[4]	\fRlast access time\fP
+	mode[4]	\fRmode bits\fP
+.P2
+The notation
+.CW name[s]
+denotes a string stored as a two-byte length
+and then that many bytes.
+The above describes Version 9 of the 
+.CW DirEntry
+format.  Versions 7 and 8 are very similar; they can be
+read by the current
+.I vac
+source code but are not written.
+Earlier versions were not widespread.
+A
+.CW DirEntry
+may be followed by optional extension sections, though none
+are currently used.
+The
+.CW mode
+bits include bits commonly used by
+Unix and Windows, in addition to those used by Plan 9.
+.PP
+The
+.CW entry
+field is an index into the parallel Venti directory.
+The
+.CW gen
+field must match the
+.CW gen 
+field in the corresponding
+.CW VtEntry
+in the directory;
+it is used to detect
+stale indices.
+Similarly,
+.CW mentry
+and
+.CW mgen
+are the index and generation number
+for the metadata Venti file,
+if the
+.CW DirEntry
+describes a vac directory.
+.PP
+The relation between Venti files and directories and
+vac files and directories can be seen in this figure:
+.PS
+.ps 8
+.vs 10
+boxwid=0.1
+boxht=0.1
+f=0.9
+mb=0.16
+
+VtRoot: [
+	right
+	B1: box
+	move right 0.1
+	"\f(CWVtRoot\fP" ljust
+]
+
+SuperRoot: [
+	right
+	B1: box fill f
+	move right 0.1
+	"fs root block" ljust
+] with .nw at VtRoot.sw + (0.2, -.2)
+Root: [
+	right
+	B1: box fill f
+	B2: box fill f
+	B3: box fill f
+	move right 0.1
+	"root directory info block" ljust
+] with .nw at SuperRoot.sw+(0.2, -.2)
+Level1: [
+	RootMeta: [
+		box wid mb
+		move right 0.1
+		"root metadata" ljust
+	]
+	MetaSource: [
+		right
+		B1: box wid mb
+		B2: box wid mb
+		B3: box wid mb
+		B4: box wid mb
+		B5: box wid mb
+	] with .nw at RootMeta.sw+(0,-.2)
+	MB1: box wid mb invis at MetaSource.B1
+	MB2: box wid mb invis at MetaSource.B2
+	MB3: box wid mb invis at MetaSource.B3
+	MB4: box wid mb invis at MetaSource.B4
+	MB5: box wid mb invis at MetaSource.B5
+
+	Source: [
+		right
+		B1: box fill f
+		B2: box fill f
+		B3: box fill f
+		B4: box fill f
+		B5: box fill f
+		B6: box fill f
+		B7: box fill f
+		B8: box fill f
+	] with .nw at MetaSource.sw+(0,-.1)
+	SB1: box invis at Source.B1
+	SB2: box invis at Source.B2
+	SB3: box invis at Source.B3
+	SB4: box invis at Source.B4
+	SB5: box invis at Source.B5
+	SB6: box invis at Source.B6
+	SB7: box invis at Source.B7
+	SB8: box invis at Source.B8
+] with .nw at Root.sw+(0.4,-.2)
+Level2: [
+	MetaSource: [
+		right
+		B1: box wid mb
+		B2: box wid mb
+		B3: box wid mb
+		B4: box wid mb
+		B5: box wid mb
+	] 
+	Source: [
+		right
+		B1: box fill f
+		B2: box fill f
+		B3: box fill f
+		B4: box fill f
+		B5: box fill f
+		B6: box fill f
+		B7: box fill f
+		B8: box fill f
+	] with .nw at MetaSource.sw+(0,-.1)
+	File: box wid 0.8 with .nw at Source.sw+(0,-.2)
+] with .nw at Level1.sw+(0.6,-.2)
+
+line -> from VtRoot.B1 down boxwid/2+0.2+boxwid/2 then to SuperRoot.w
+line -> from SuperRoot.B1 down boxwid/2+0.2+boxwid/2 then to Root.w
+line -> from Root.B3 down boxwid/2+0.2+boxwid/2 then to Level1.RootMeta.w
+line -> from Root.B2 down boxwid/2+0.2+boxwid+0.2+boxwid/2 then to Level1.MetaSource.w
+line -> from Root.B1 down boxwid/2+0.2+boxwid+0.1+boxwid+0.2+boxwid/2 then to Level1.Source.w
+
+line -> from Level1.SB3 down boxwid/2+0.2+boxwid/2 then to Level2.MetaSource.w
+line -> from Level1.SB2 down boxwid/2+0.2+boxwid+0.1+boxwid/2 then to Level2.Source.w
+line -> from Level1.SB1 down boxwid/2+0.2+boxwid+0.1+boxwid+0.2+boxwid/2 then to Level2.File.w
+
+arrowwid = arrowwid/2
+arrowht = arrowht/2
+line -> from Level1.MB1 to Level1.SB1.n
+line -> from Level1.MB2 to Level1.SB2.n
+line -> from Level1.MB2 to Level1.SB3.n
+line -> from Level1.MB4 to Level1.SB7.n
+line -> from Level1.MB5 to Level1.SB5.n
+arrowwid = arrowwid * 2
+arrowht = arrowht * 2
+
+box dashed with .nw at Level1.MetaSource.nw+(-.05,.05) wid 0.8+.05*2 ht .3+.05*2
+box dashed with .nw at Level2.MetaSource.nw+(-.05,.05) wid 0.8+.05*2 ht .3+.05*2
+box dotted with .nw at Level2.File.nw+(-.05,.05) wid 0.8+0.05*2 ht .1+.05*2
+
+[
+	KEY: box wid 1.5 invis "Key"
+	line from KEY.sw to KEY.se
+	k = -.1
+	kk=0.5
+	A: [
+		box wid 4*boxwid
+		"Venti file" ljust with .w at last box .w+(kk,0)
+	] with .nw at KEY.sw+(0,2*k)
+	B: [
+		box fill f
+		"Venti entry (\f(CWEntry\fP)" ljust with .w at last box .w+(kk,0)
+	] with .nw at A.sw+(0,k)
+	C: [
+		right
+		CC: box fill f
+		box fill f
+		box fill f
+		box fill f
+		"Venti directory" ljust with .w at CC.w+(kk,0)
+	] with .nw at B.sw+(0,k)
+	D: [
+		line -> right 3*boxwid
+		"Venti pointer (score)" ljust with .w at last line .w+(kk, 0)
+	] with .nw at C.sw+(0,k)
+	DD: [
+		box dotted wid 4*boxwid
+		"Vac file" ljust with .w at last box .w+(kk,0)
+	] with .nw at D.sw+(0,k)
+	E: [
+		box wid mb
+		"Vac entry (\f(CWDirEntry\fP)" ljust with .w at last box .w+(kk,0)
+	] with .nw at DD.sw+(0,k)
+	G: [
+		box dashed wid 4*boxwid
+		"Vac directory" ljust with .w at last box .w+(kk,0)
+	] with .nw at E.sw+(0,k)
+	H: [
+		arrowwid = arrowwid/2
+		arrowht = arrowht/2
+		line -> right 1.5*boxwid
+		"Vac pointer (integer index)" ljust with .w at last line .w+(kk, 0)
+		arrowwid = arrowwid * 2
+		arrowht = arrowht * 2
+	] with .nw at G.sw+(0,k)
+] with .nw at VtRoot.nw+(3,0)
+.PE
+.LP
+In reality, the story is slightly more complicated.
+The metadata file in a Vac directory
+is not just the concatenation of
+.CW DirEntry
+structures.
+Instead, it is the concatenation of
+.CW MetaBlocks .
+A
+.CW MetaBlock
+contains some number of
+.CW DirEntry
+structures along with a sorted index to make it easy
+to look for a particular
+.CW DirEntry
+by its
+.CW elem 
+field.
+The details are in the source code.
+.PP
+As shown in the diagram,
+the root directory of the file system is summarized by
+three
+.CW VtEntry
+structures describing
+the Venti directory for the children of the root,
+the Venti file for the metadata describing the children of the root,
+and a Venti file holding metadata for the root directory itself.
+These
+.CW VtEntry
+structures are placed in a Venti directory of their own,
+described by the single 
+.CW VtEntry
+in the
+root block.
+.NH 1
+Fossil file system format
+.HP
+Fossil uses the vac format, with some small changes.
+The changes only affect the data on the local disk; the data
+archived to Venti is exactly in vac format.
+.PP
+Blocks stored on local disk may contain scores pointing at local disk
+blocks or at Venti blocks. 
+Local block addresses are stored as 20-byte scores in which the first 16 bytes
+are all zero and the last 4 bytes specify a block number in the disk.
+Before a block is archived, all the
+blocks it points to must be archived, and the local scores in the block
+must be changed to Venti scores.
+Using block addresses rather than content hashes for local data
+makes the local file system easier to manage: if a local block's contents
+change, the pointer to the block does not need to change.
+.NH 2
+Snapshots
+.HP
+Fossil is an archival file server.
+It takes periodic snapshots of the file system,
+which are made accessible through the file system.
+Specifically, the active file system is presented in
+.CW /active .
+Ephemeral snapshots (those that are kept on local disk and eventually deleted)
+are presented in
+\f(CW/snapshot/\fIyyyy\f(CW/\fImmdd\f(CW/\fIhhmm\fR,
+where
+.I yyyy
+is the full year,
+.I mm
+is the month number,
+.I dd
+is the day number,
+.I hh
+is the hour,
+and
+.I mm
+is the minute.
+Archival snapshots (those that are archived to Venti and persist forever)
+are presented in
+\f(CW/archive/\fIyyyy\f(CW/\fImmdds\fR,
+where
+.I yyyy ,
+.I mm ,
+and
+.I dd
+are year, month, and day as before,
+and
+.I s
+is a sequence number if more than one
+archival snapshot is done in a day.
+For the first snapshot,
+.I s
+is null.
+For the subsequent snapshots,
+.I s
+is
+.CW .1 ,
+.CW .2 ,
+.CW .3 ,
+etc.
+.PP
+To implement the snapshots, the file server maintains a
+current
+.I epoch
+for the active file system.
+Each local block has a label that records, among other things,
+the epoch in which the block was allocated.
+If a block was allocated in an epoch earlier than the current one,
+it is immutable and treated as copy-on-write.
+Taking a snapshot can be accomplished by
+recording the address of the current root block and then 
+incrementing the epoch number.
+Notice that the copy-on-write method makes
+snapshots both time efficient and space efficient.
+The only time cost is waiting for all current file system
+requests to finish and then incrementing a counter.
+After a snapshot, blocks only get copied when they are
+next modified, so the per-snapshot
+space requirement is proportional
+to the amount of new data rather than the total
+size of the file system.
+.PP
+The blocks in the archival snapshots are moved to Venti,
+but the blocks in the ephemeral snapshots take up space
+in the local disk file.
+To allow reclamation of this disk space, the file system
+maintains a 
+.I low
+.I epoch ,
+which is the epoch of the earliest ephemeral snapshot
+still available.
+Fossil only allows access to snapshots with epoch numbers
+between the 
+low epoch and the current epoch
+(also called the high epoch).
+Incrementing the low epoch thus makes old
+snapshots inaccessible.
+The space required to store those snapshots can then
+be reclaimed, as described below.
+.NH 2
+Local blocks
+.HP
+The bulk of the local disk file is the local blocks.
+Each block has a 14-byte label associated with it, of the format:
+.P1
+Label:
+.ta +\w'    'u +\w'                'u
+	state[1]	\fRblock state\fP
+	type[1]	\fRblock type\fP
+	epoch[4]	\fRallocation epoch\fP
+	epochClose[4]	\fRclose epoch\fP
+	tag[4]	\fRrandom tag\fP
+.P2
+.LP
+The
+.CW type
+is an analogue of the block types described earlier,
+though different names are used, to distinguish between
+pointers blocks in a hash tree for a data stream
+and pointer blocks for a directory stream.
+The
+.CW epoch
+was mentioned in the last section.
+The other fields are explained below.
+.PP
+There are two distinguished blocks states
+.CW BsFree
+.CW 0x00 ) (
+and
+.CW BsBad
+.CW 0xFF ), (
+which mark blocks that are available for allocation
+and blocks that are bad and should be avoided.
+If
+.CW state
+is not one of these values, it is a bitwise
+.I or ' `
+of the following flags:
+.P1
+.ta +\w'      'u +\w'                'u
+0x01	BsAlloc	\fRblock is in use\fP
+0x02	BsCopied	\fRblock has been copied\fP
+0x04	BsVenti	\fRblock has been stored on Venti\fP
+0x08	BsClosed	\fRblock has been unlinked from active file system\fP
+.P2
+.LP
+The flags are explained as they arise in the discussions below.
+.PP
+It is convenient to store some extra fields in the
+.CW VtEntry
+structure when it describes a Venti file or directory
+stored on local disk.
+Specifically, we set the
+.CW VtEntryLocal
+flag bit
+and then use the bytes 7-16 of the score (which would
+otherwise be zero, since it is a local score) to hold these fields:
+.P1
+.ta +\w'    'u +\w'                'u
+	archive[1]	\fRboolean: this is an archival snapshot\fP
+	snap[4]	\fRepoch number if root of snapshot\fP
+	tag[4]	\fRrandom tag\fP
+.P2
+.LP
+The extended
+.CW VtEntry
+structure is called an
+.CW Entry .
+The
+.CW tag
+field
+in the
+.CW Label
+and the
+.CW Entry
+is used to identify dangling pointers or other file system corruption:
+all the local blocks in a hash tree must
+have tags matching the tag in the
+.CW Entry .
+If this
+.CW Entry
+points at the root of a snapshot,
+the
+.CW snap
+field is the epoch of the snapshot.
+If the snapshot is intended to be archived to Venti,
+the
+.CW archive
+field is non-zero.
+.NH 2
+Block reclamation
+.HP
+The blocks in the active file system form a tree: each
+block has only one parent.
+Once a copy-on-write block 
+.I b
+is replaced by its copy, it is no longer
+needed by the active file system.
+At this point,
+.I b
+is unlinked from the active file system.
+We say that
+.I b
+is now
+.I closed :
+it is needed only for snapshots.
+When a block is closed, the
+.CW BsClosed
+bit is set in its state, and the current epoch (called the block's closing epoch)
+is stored in the
+.CW epochClose
+label field.
+(Open blocks have an
+.CW epochClose
+of
+.CW ~0 ).
+.PP
+A block is referenced by snapshots with epochs
+between the block's allocation epoch and its closing epoch.
+Once the file system's low epoch grows to be greater than or equal to the block's
+closing epoch, the block is no longer needed for any snapshots
+and can be reused.
+.PP
+In a typical configuration, where nightly archival snapshots
+are taken and written to Venti, it is desirable to reclaim
+the space occupied by now-archived blocks if possible.
+To do this, Fossil keeps track of whether the pointers
+in each block are unique to that block.
+When a block
+.I bb
+is allocated, a pointer to
+.I bb
+is written into exactly one active block (say,
+.I b ).
+In the absence of snapshots, the pointer to
+.I bb
+will remain unique to
+.I b ,
+so that if the pointer is zeroed,
+.I bb
+can be immediately reused.
+Snapshots complicate this invariant:
+when
+.I b
+is copied-on-write, all its pointers
+are no longer unique to it.
+At time of the copy, the
+.CW BsCopied
+state bit in the block's label
+is set to note the duplication of the pointers contained within.
+.NH 2
+Disk layout
+.HP
+The file system header describes the file system layout and has this format:
+.P1
+.ta +\w'    'u +\w'                'u
+Header:
+	magic[4]	\fR0x3776AE89 (HeaderMagic)\fP
+	version[2]	\fR1 (HeaderVersion)\fP
+	blockSize[2]	\fIfile system block size\fP
+	super[4]	\fRblock offset of super block\fP
+	label[4]	\fRblock offset of labels\fP
+	data[4]	\fRdata blocks\fP
+	end[4]	\fRend of file system\fP
+.P2
+.LP
+The corresponding file system layout is:
+.PS
+.ps 8
+.vs 9
+boxwid=0.75
+boxht=0.15
+Empty: box "empty" ht 0.25
+Header: box "header" with .n at Empty.s
+Empty2: box "empty" with .n at Header.s
+Super: box "super block" with .n at Empty2.s
+Label: box "label" "blocks" with .n at Super.s ht 0.25
+Data: box "data" "blocks" with .n at Label.s ht 0.3
+"  0" ljust at Empty.ne
+"  128kB" ljust at Header.ne
+"  \f5super\fP \(mu \f(CWblockSize\fP" ljust at Super.ne
+"  \f5label\fP \(mu \f(CWblockSize\fP" ljust at Label.ne
+"  \f5data\fP \(mu \f(CWblockSize\fP" ljust at Data.ne
+"  \f5end\fP \(mu \f(CWblockSize\fP" ljust at Data.se
+"" at (-1,0)
+"" at (6,0)
+.PE
+.LP
+The numbers to the right of the blocks are byte offsets
+of the boundaries.
+.LP
+The super block describes the file system itself and looks like:
+.P1
+.ta +\w'    'u +\w'                'u
+Super:
+	magic[4]	\fR0x2340A3B1 (SuperMagic)\fP
+	version[2]	\fR1 (SuperVersion)\fP
+	epochLow[4]	\fRfile system low epoch\fP
+	epochHigh[4]	\fRfile system high (active) epoch\fP
+	qid[8]	\fRnext qid to allocate\fP
+	active[4]	\fRdata block number: root of active file system\fP
+	next[4]	\fRdata block number: root of next file system to archive\fP
+	current[4]	\fRdata block number: root of file system currently being archived\fP
+	last[20]	\fRVenti score of last successful archive\fP
+	name[128]	\fRname of file system (just a comment)\fP
+.P2
+.LP
+.NH 1
+Fossil server
+.HP
+The Fossil server is a user-space program that runs on a standard Plan 9 kernel.
+.NH 2
+Process structure
+.PP
+The file server is structured as a set of processes synchronizing
+mostly through message passing along queues.
+The processes are given names, which can be seen in the output of
+.CW ps 
+.CW -a .
+.PP
+.CW Listen
+processes announce on various network addresses.
+A
+.CW con
+process handles each incoming connection, reading 9P requests
+and adding them to a central message queue.
+.CW Msg
+processes remove 9P requests from the queue,
+handle them, and write the responses to the appropriate
+file descriptors.
+.PP
+The
+.CW disk
+process handles disk I/O requests made by the other processes.
+The
+.CW flush
+process writes dirty blocks from the in-memory block cache to disk.
+The
+.CW unlink
+process frees previously linked blocks once the blocks that point at them
+have been written to disk.
+.PP
+A
+.CW consI
+reads from each console file (typically a pipe posted in
+.CW /srv ),
+adding the typed characters to the input queue.
+The
+.CW cons
+process echoes input and runs the commands, saving
+output in a ring buffer.
+Because there is only one
+.CW cons
+process, only one console command may be executing at a time.
+A
+.CW consO
+process copies this ring buffer to the each console file.
+.PP
+The
+.CW periodic
+process runs periodic events, like
+flushing the root metadata to disk or
+taking snapshots of the file system.
+.NH 2
+Block cache
+.HP
+Fossil maintains an in-memory block cache which 
+holds both local disk blocks and Venti blocks.
+Cache eviction follows a least recently used policy.
+Dirty blocks are restricted to at most half the cache.
+This can be changed by editing
+.CW DirtyPercentage
+in 
+.CW dat.h .
+.PP
+The block cache uses soft updates [1] to ensure that the on-disk
+file system is always self-consistent.
+Thus there is no
+.I halt
+console command
+and no need to check a file system 
+that was shut down without halting.
+.NH 2
+Archiving
+.HP
+A background process writes blocks in archival snapshots to Venti.
+Although
+.CW /archive/\fIyyyy\fP/\fImmdds\fR
+is a copy of only
+.CW /active
+at the time of the snapshot,
+the archival process archives the
+entire file tree rather than just
+the subtree rooted at
+.CW /active .
+The snapshots
+.CW /snapshot/\fIyyyy\fP/\fImmdd\fP/\fIhhmm
+are stored as empty directories.
+Once all the blocks have been archived,
+a 
+.CW VtRoot
+header for the file system is archived.
+The score of that header is recorded in
+.CW super.score
+and also printed on the file server console.
+The score can used by
+.I flfmt
+to restore a file system (see
+.I fossil (4)).
+.NH 2
+Contrast with the old file server
+.HP
+The most obvious difference between Fossil and the 
+old Plan 9 file server [2] is that Fossil uses a Venti server as 
+its archival storage in place of a WORM juke box.
+There are a few other architectural differences to be 
+aware of.
+.PP
+Fossil is a user-level program run on a standard kernel.
+.PP
+Fossil does not have any way to concatenate, stripe, or
+mirror disk files.  For functionality similar to the old file server's
+configuration strings, use the experimental file stack device 
+(see
+.I devfs (3)).
+.PP
+Fossil speaks only 9P2000.  Old 9P (aka 9P1) is not supported.
+.PP
+... XXX words about converting an old file system to fossil?
+.NH 1
+References
+.LP
+[1] Gregory R. Ganger, Marshall Kirk McKusick, Craig A. N. Soules,
+and Yale N. Patt.
+``Soft Updates: A Solution to the Metadata Update Problem
+in File Systems,''
+.I "ACM Transactions on Computer Systems" ,
+Vol 18., No. 2, May 2000, pp. 127\-153.
+.LP
+[2] Sean Quinlan, ``A Cached WORM File System,''
+.I "Software\(emPractice and Experience" ,
+Vol 21., No 12., December 1991, pp. 1289\-1299.
+.LP
+[3] Sean Quinlan and Sean Dorward, ``Venti: A New Approach to Archival Storage,''
+.I "Usenix Conference on File and Storage Technologies" ,
+2002.

BIN
sys/doc/fossil.pdf


+ 5401 - 0
sys/doc/fossil.ps

@@ -0,0 +1,5401 @@
+%!PS-Adobe-2.0
+%%Version: 0.1
+%%DocumentFonts: (atend)
+%%Pages: (atend)
+%%EndComments
+%
+% Version 3.3.2 prologue for troff files.
+%
+
+/#copies 1 store
+/aspectratio 1 def
+/formsperpage 1 def
+/landscape false def
+/linewidth .3 def
+/magnification 1 def
+/margin 0 def
+/orientation 0 def
+/resolution 720 def
+/rotation 1 def
+/xoffset 0 def
+/yoffset 0 def
+
+/roundpage true def
+/useclippath true def
+/pagebbox [0 0 612 792] def
+
+/R  /Times-Roman def
+/I  /Times-Italic def
+/B  /Times-Bold def
+/BI /Times-BoldItalic def
+/H  /Helvetica def
+/HI /Helvetica-Oblique def
+/HB /Helvetica-Bold def
+/HX /Helvetica-BoldOblique def
+/CW /Courier def
+/CO /Courier def
+/CI /Courier-Oblique def
+/CB /Courier-Bold def
+/CX /Courier-BoldOblique def
+/PA /Palatino-Roman def
+/PI /Palatino-Italic def
+/PB /Palatino-Bold def
+/PX /Palatino-BoldItalic def
+/Hr /Helvetica-Narrow def
+/Hi /Helvetica-Narrow-Oblique def
+/Hb /Helvetica-Narrow-Bold def
+/Hx /Helvetica-Narrow-BoldOblique def
+/KR /Bookman-Light def
+/KI /Bookman-LightItalic def
+/KB /Bookman-Demi def
+/KX /Bookman-DemiItalic def
+/AR /AvantGarde-Book def
+/AI /AvantGarde-BookOblique def
+/AB /AvantGarde-Demi def
+/AX /AvantGarde-DemiOblique def
+/NR /NewCenturySchlbk-Roman def
+/NI /NewCenturySchlbk-Italic def
+/NB /NewCenturySchlbk-Bold def
+/NX /NewCenturySchlbk-BoldItalic def
+/ZD /ZapfDingbats def
+/ZI /ZapfChancery-MediumItalic def
+/S  /S def
+/S1 /S1 def
+/GR /Symbol def
+
+/inch {72 mul} bind def
+/min {2 copy gt {exch} if pop} bind def
+
+/setup {
+	counttomark 2 idiv {def} repeat pop
+
+	landscape {/orientation 90 orientation add def} if
+	/scaling 72 resolution div def
+	linewidth setlinewidth
+	1 setlinecap
+
+	pagedimensions
+	xcenter ycenter translate
+	orientation rotation mul rotate
+	width 2 div neg height 2 div translate
+	xoffset inch yoffset inch neg translate
+	margin 2 div dup neg translate
+	magnification dup aspectratio mul scale
+	scaling scaling scale
+
+	addmetrics
+	0 0 moveto
+} def
+
+/pagedimensions {
+	useclippath userdict /gotpagebbox known not and {
+		/pagebbox [clippath pathbbox newpath] def
+		roundpage currentdict /roundpagebbox known and {roundpagebbox} if
+	} if
+	pagebbox aload pop
+	4 -1 roll exch 4 1 roll 4 copy
+	landscape {4 2 roll} if
+	sub /width exch def
+	sub /height exch def
+	add 2 div /xcenter exch def
+	add 2 div /ycenter exch def
+	userdict /gotpagebbox true put
+} def
+
+/addmetrics {
+	/Symbol /S null Sdefs cf
+	/Times-Roman /S1 StandardEncoding dup length array copy S1defs cf
+} def
+
+/pagesetup {
+	/page exch def
+	currentdict /pagedict known currentdict page known and {
+		page load pagedict exch get cvx exec
+	} if
+} def
+
+/decodingdefs [
+	{counttomark 2 idiv {y moveto show} repeat}
+	{neg /y exch def counttomark 2 idiv {y moveto show} repeat}
+	{neg moveto {2 index stringwidth pop sub exch div 0 32 4 -1 roll widthshow} repeat}
+	{neg moveto {spacewidth sub 0.0 32 4 -1 roll widthshow} repeat}
+	{counttomark 2 idiv {y moveto show} repeat}
+	{neg setfunnytext}
+] def
+
+/setdecoding {/t decodingdefs 3 -1 roll get bind def} bind def
+
+/w {neg moveto show} bind def
+/m {neg dup /y exch def moveto} bind def
+/done {/lastpage where {pop lastpage} if} def
+
+/f {
+	dup /font exch def findfont exch
+	dup /ptsize exch def scaling div dup /size exch def scalefont setfont
+	linewidth ptsize mul scaling 10 mul div setlinewidth
+	/spacewidth ( ) stringwidth pop def
+} bind def
+
+/changefont {
+	/fontheight exch def
+	/fontslant exch def
+	currentfont [
+		1 0
+		fontheight ptsize div fontslant sin mul fontslant cos div
+		fontheight ptsize div
+		0 0
+	] makefont setfont
+} bind def
+
+/sf {f} bind def
+
+/cf {
+	dup length 2 idiv
+	/entries exch def
+	/chtab exch def
+	/newencoding exch def
+	/newfont exch def
+
+	findfont dup length 1 add dict
+	/newdict exch def
+	{1 index /FID ne {newdict 3 1 roll put}{pop pop} ifelse} forall
+
+	newencoding type /arraytype eq {newdict /Encoding newencoding put} if
+
+	newdict /Metrics entries dict put
+	newdict /Metrics get
+	begin
+		chtab aload pop
+		1 1 entries {pop def} for
+		newfont newdict definefont pop
+	end
+} bind def
+
+%
+% A few arrays used to adjust reference points and character widths in some
+% of the printer resident fonts. If square roots are too high try changing
+% the lines describing /radical and /radicalex to,
+%
+%	/radical	[0 -75 550 0]
+%	/radicalex	[-50 -75 500 0]
+%
+% Move braceleftbt a bit - default PostScript character is off a bit.
+%
+
+/Sdefs [
+	/bracketlefttp		[201 500]
+	/bracketleftbt		[201 500]
+	/bracketrighttp		[-81 380]
+	/bracketrightbt		[-83 380]
+	/braceleftbt		[203 490]
+	/bracketrightex		[220 -125 500 0]
+	/radical		[0 0 550 0]
+	/radicalex		[-50 0 500 0]
+	/parenleftex		[-20 -170 0 0]
+	/integral		[100 -50 500 0]
+	/infinity		[10 -75 730 0]
+] def
+
+/S1defs [
+	/underscore		[0 80 500 0]
+	/endash			[7 90 650 0]
+] def
+%
+% Version 3.3.2 drawing procedures for dpost. Automatically pulled in when
+% needed.
+%
+
+/inpath false def
+/savematrix matrix def
+
+/Dl {
+	inpath
+		{neg lineto pop pop}
+		{newpath neg moveto neg lineto stroke}
+	ifelse
+} bind def
+
+/De {
+	/y1 exch 2 div def
+	/x1 exch 2 div def
+	/savematrix savematrix currentmatrix def
+	neg exch x1 add exch translate
+	x1 y1 scale
+	0 0 1 0 360
+	inpath
+		{1 0 moveto arc savematrix setmatrix}
+		{newpath arc savematrix setmatrix stroke}
+	ifelse
+} bind def
+
+/Da {
+	/dy2 exch def
+	/dx2 exch def
+	/dy1 exch def
+	/dx1 exch def
+	dy1 add neg exch dx1 add exch
+	dx1 dx1 mul dy1 dy1 mul add sqrt
+	dy1 dx1 neg atan
+	dy2 neg dx2 atan
+	inpath
+		{arc}
+		{newpath arc stroke}
+	ifelse
+} bind def
+
+/DA {
+	/dy2 exch def
+	/dx2 exch def
+	/dy1 exch def
+	/dx1 exch def
+	dy1 add neg exch dx1 add exch
+	dx1 dx1 mul dy1 dy1 mul add sqrt
+	dy1 dx1 neg atan
+	dy2 neg dx2 atan
+	inpath
+		{arcn}
+		{newpath arcn stroke}
+	ifelse
+} bind def
+
+/Ds {
+	/y2 exch def
+	/x2 exch def
+	/y1 exch def
+	/x1 exch def
+	/y0 exch def
+	/x0 exch def
+	x0 5 x1 mul add 6 div
+	y0 5 y1 mul add -6 div
+	x2 5 x1 mul add 6 div
+	y2 5 y1 mul add -6 div
+	x1 x2 add 2 div
+	y1 y2 add -2 div
+	inpath
+		{curveto}
+		{newpath x0 x1 add 2 div y0 y1 add -2 div moveto curveto stroke}
+	ifelse
+} bind def
+%
+% Tries to round clipping path dimensions, as stored in array pagebbox, so they
+% match one of the known sizes in the papersizes array. Lower left coordinates
+% are always set to 0.
+%
+
+/roundpagebbox {
+    7 dict begin
+	/papersizes [8.5 inch 11 inch 14 inch 17 inch] def
+
+	/mappapersize {
+		/val exch def
+		/slop .5 inch def
+		/diff slop def
+		/j 0 def
+		0 1 papersizes length 1 sub {
+			/i exch def
+			papersizes i get val sub abs
+			dup diff le {/diff exch def /j i def} {pop} ifelse
+		} for
+		diff slop lt {papersizes j get} {val} ifelse
+	} def
+
+	pagebbox 0 0 put
+	pagebbox 1 0 put
+	pagebbox dup 2 get mappapersize 2 exch put
+	pagebbox dup 3 get mappapersize 3 exch put
+    end
+} bind def
+
+%%EndProlog
+%%BeginSetup
+mark
+%
+% Encoding vector and redefinition of findfont for the ISO Latin1 standard.
+% The 18 characters missing from ROM based fonts on older printers are noted
+% below.
+%
+
+/ISOLatin1Encoding [
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/space
+	/exclam
+	/quotedbl
+	/numbersign
+	/dollar
+	/percent
+	/ampersand
+	/quoteright
+	/parenleft
+	/parenright
+	/asterisk
+	/plus
+	/comma
+	/minus
+	/period
+	/slash
+	/zero
+	/one
+	/two
+	/three
+	/four
+	/five
+	/six
+	/seven
+	/eight
+	/nine
+	/colon
+	/semicolon
+	/less
+	/equal
+	/greater
+	/question
+	/at
+	/A
+	/B
+	/C
+	/D
+	/E
+	/F
+	/G
+	/H
+	/I
+	/J
+	/K
+	/L
+	/M
+	/N
+	/O
+	/P
+	/Q
+	/R
+	/S
+	/T
+	/U
+	/V
+	/W
+	/X
+	/Y
+	/Z
+	/bracketleft
+	/backslash
+	/bracketright
+	/asciicircum
+	/underscore
+	/quoteleft
+	/a
+	/b
+	/c
+	/d
+	/e
+	/f
+	/g
+	/h
+	/i
+	/j
+	/k
+	/l
+	/m
+	/n
+	/o
+	/p
+	/q
+	/r
+	/s
+	/t
+	/u
+	/v
+	/w
+	/x
+	/y
+	/z
+	/braceleft
+	/bar
+	/braceright
+	/asciitilde
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/.notdef
+	/dotlessi
+	/grave
+	/acute
+	/circumflex
+	/tilde
+	/macron
+	/breve
+	/dotaccent
+	/dieresis
+	/.notdef
+	/ring
+	/cedilla
+	/.notdef
+	/hungarumlaut
+	/ogonek
+	/caron
+	/space
+	/exclamdown
+	/cent
+	/sterling
+	/currency
+	/yen
+	/brokenbar		% missing
+	/section
+	/dieresis
+	/copyright
+	/ordfeminine
+	/guillemotleft
+	/logicalnot
+	/hyphen
+	/registered
+	/macron
+	/degree			% missing
+	/plusminus		% missing
+	/twosuperior		% missing
+	/threesuperior		% missing
+	/acute
+	/mu			% missing
+	/paragraph
+	/periodcentered
+	/cedilla
+	/onesuperior		% missing
+	/ordmasculine
+	/guillemotright
+	/onequarter		% missing
+	/onehalf		% missing
+	/threequarters		% missing
+	/questiondown
+	/Agrave
+	/Aacute
+	/Acircumflex
+	/Atilde
+	/Adieresis
+	/Aring
+	/AE
+	/Ccedilla
+	/Egrave
+	/Eacute
+	/Ecircumflex
+	/Edieresis
+	/Igrave
+	/Iacute
+	/Icircumflex
+	/Idieresis
+	/Eth			% missing
+	/Ntilde
+	/Ograve
+	/Oacute
+	/Ocircumflex
+	/Otilde
+	/Odieresis
+	/multiply		% missing
+	/Oslash
+	/Ugrave
+	/Uacute
+	/Ucircumflex
+	/Udieresis
+	/Yacute			% missing
+	/Thorn			% missing
+	/germandbls
+	/agrave
+	/aacute
+	/acircumflex
+	/atilde
+	/adieresis
+	/aring
+	/ae
+	/ccedilla
+	/egrave
+	/eacute
+	/ecircumflex
+	/edieresis
+	/igrave
+	/iacute
+	/icircumflex
+	/idieresis
+	/eth			% missing
+	/ntilde
+	/ograve
+	/oacute
+	/ocircumflex
+	/otilde
+	/odieresis
+	/divide			% missing
+	/oslash
+	/ugrave
+	/uacute
+	/ucircumflex
+	/udieresis
+	/yacute			% missing
+	/thorn			% missing
+	/ydieresis
+] def
+
+/NewFontDirectory FontDirectory maxlength dict def
+
+%
+% Apparently no guarantee findfont is defined in systemdict so the obvious
+%
+%	systemdict /findfont get exec
+%
+% can generate an error. So far the only exception is a VT600 (version 48.0).
+%
+
+userdict /@RealFindfont known not {
+	userdict begin
+		/@RealFindfont systemdict begin /findfont load end def
+	end
+} if
+
+/findfont {
+	dup NewFontDirectory exch known not {
+		dup
+		%dup systemdict /findfont get exec	% not always in systemdict
+		dup userdict /@RealFindfont get exec
+		dup /Encoding get StandardEncoding eq {
+			dup length dict begin
+				{1 index /FID ne {def}{pop pop} ifelse} forall
+				/Encoding ISOLatin1Encoding def
+				currentdict
+			end
+			/DummyFontName exch definefont
+		} if
+		NewFontDirectory 3 1 roll put
+	} if
+	NewFontDirectory exch get
+} bind def
+
+%%Patch from lp
+%%EndPatch from lp
+
+setup
+%%EndSetup
+%%Page: 1 1
+/saveobj save def
+mark
+1 pagesetup
+12 /LucidaSans-Demi f
+(Fossil, an Archival) 1975 1230 w
+(File) 3138 1230 w
+(Server) 3395 1230 w
+10 /LucidaSans-Italic f
+(Sean Quinlan) 2557 1470 w
+(Jim McKie) 2643 1590 w
+(Russ Cox) 2663 1710 w
+(jmk,rsc@plan9.bell-labs.com) 2168 1830 w
+(ABSTRACT) 2626 2270 w
+10 /LucidaSansUnicode00 f
+(This) 1330 2530 w
+(paper) 1608 2530 w
+(describes) 1959 2530 w
+(the) 2493 2530 w
+(internals) 2721 2530 w
+(and) 3217 2530 w
+(operation) 3471 2530 w
+(of) 4010 2530 w
+(Fossil,) 4182 2530 w
+(an) 4563 2530 w
+(archival) 1080 2650 w
+(file) 1487 2650 w
+(server) 1671 2650 w
+(built) 2001 2650 w
+(for) 2254 2650 w
+(Plan) 2426 2650 w
+(9.) 2660 2650 w
+(Fossil) 2820 2650 w
+(has not yet replaced the current) 3128 2650 w
+(Plan 9 file server and) 1080 2770 w
+10 /LucidaTypewriter f
+(kfs) 2132 2770 w
+10 /LucidaSansUnicode00 f
+(, but that is our eventual intent.) 2348 2770 w
+(Both) 3958 2770 w
+(fossil) 4209 2770 w
+(and) 4500 2770 w
+(this) 1080 2890 w
+(documentation) 1295 2890 w
+(are) 2059 2890 w
+(works) 2246 2890 w
+(in) 2569 2890 w
+(progress.) 2695 2890 w
+(Comments) 3220 2890 w
+(on) 3777 2890 w
+(either) 3935 2890 w
+(are) 4251 2890 w
+(most) 4438 2890 w
+(welcome.) 1080 3010 w
+10 /LucidaSans-Demi f
+(1.) 720 3370 w
+(Introduction) 873 3370 w
+10 /LucidaSansUnicode00 f
+(Fossil) 720 3526 w
+(is) 1032 3526 w
+(an) 1149 3526 w
+(archival) 1303 3526 w
+(file) 1714 3526 w
+(server) 1902 3526 w
+(built) 2236 3526 w
+(for) 2494 3526 w
+(Plan) 2671 3526 w
+(9.) 2910 3526 w
+(In) 3075 3526 w
+(a) 3204 3526 w
+(typical) 3297 3526 w
+(configuration,) 3651 3526 w
+(it) 4370 3526 w
+(maintains) 4474 3526 w
+(a) 4985 3526 w
+(traditional) 720 3646 w
+(file) 1254 3646 w
+(system) 1441 3646 w
+(in) 1817 3646 w
+(a) 1944 3646 w
+(local) 2035 3646 w
+(disk) 2296 3646 w
+(partition) 2533 3646 w
+(and) 2983 3646 w
+(periodically) 3199 3646 w
+(archives) 3792 3646 w
+(snapshots) 4224 3646 w
+(of) 4752 3646 w
+(the) 4885 3646 w
+(file) 720 3766 w
+(system) 914 3766 w
+(to) 1297 3766 w
+(a) 1438 3766 w
+(Venti) 1536 3766 w
+(server.) 1828 3766 w
+(These) 2232 3766 w
+(archives) 2563 3766 w
+(are) 3003 3766 w
+(made) 3198 3766 w
+(available) 3508 3766 w
+(through) 3975 3766 w
+(a) 4406 3766 w
+(file) 4505 3766 w
+(system) 4700 3766 w
+(interface.) 720 3886 w
+(Fossil) 1247 3886 w
+(can) 1561 3886 w
+(also) 1768 3886 w
+(be) 2003 3886 w
+(run) 2161 3886 w
+(without) 2365 3886 w
+(a) 2769 3886 w
+(Venti) 2863 3886 w
+(server,) 3151 3886 w
+(in) 3518 3886 w
+(which) 3647 3886 w
+(case) 3966 3886 w
+(the) 4217 3886 w
+(snapshots) 4410 3886 w
+(\(if) 4941 3886 w
+(any\) occupy local disk space.) 720 4006 w
+(The) 970 4162 w
+(bulk) 1203 4162 w
+(of) 1468 4162 w
+(this) 1619 4162 w
+(paper) 1851 4162 w
+(explains) 2182 4162 w
+(the) 2641 4162 w
+(underlying) 2849 4162 w
+(data) 3420 4162 w
+(structures:) 3683 4162 w
+(Venti) 4257 4162 w
+(trees,) 4559 4162 w
+(the) 4885 4162 w
+(Venti) 720 4282 w
+(archival) 1007 4282 w
+(file) 1419 4282 w
+(system) 1608 4282 w
+(format,) 1986 4282 w
+(and) 2380 4282 w
+(finally) 2598 4282 w
+(Fossil) 2929 4282 w
+10 /LucidaSansUnicode20 f
+(\031) 3204 4282 w
+10 /LucidaSansUnicode00 f
+(s) 3236 4282 w
+(file) 3324 4282 w
+(system) 3512 4282 w
+(format.) 3889 4282 w
+(The) 4314 4282 w
+(end) 4532 4282 w
+(of) 4750 4282 w
+(the) 4885 4282 w
+(paper discusses the architecture of the Fossil server.) 720 4402 w
+(The) 970 4558 w
+(presentation) 1196 4558 w
+(of) 1851 4558 w
+(the) 1994 4558 w
+(data) 2195 4558 w
+(structures) 2451 4558 w
+(is) 2986 4558 w
+(very) 3112 4558 w
+(detailed,) 3359 4558 w
+(perhaps) 3825 4558 w
+(too) 4262 4558 w
+(detailed) 4467 4558 w
+(for) 4901 4558 w
+(most) 720 4678 w
+(readers.) 1025 4678 w
+(The) 1514 4678 w
+(intent) 1757 4678 w
+(is) 2102 4678 w
+(to) 2244 4678 w
+(record) 2404 4678 w
+(all) 2779 4678 w
+(the) 2954 4678 w
+(details) 3171 4678 w
+(necessary) 3553 4678 w
+(to) 4090 4678 w
+(make) 4250 4678 w
+(structural) 4574 4678 w
+(changes to the file system format.) 720 4798 w
+(Feel free to jump ahead when boredom strikes.) 2443 4798 w
+10 /LucidaSans-Demi f
+(2.) 720 5038 w
+(Venti trees and directory hierarchies) 873 5038 w
+10 /LucidaSansUnicode00 f
+(Venti) 720 5194 w
+([3]) 1007 5194 w
+(is) 1174 5194 w
+(an) 1292 5194 w
+(archival) 1447 5194 w
+(block) 1859 5194 w
+(storage) 2159 5194 w
+(server.) 2560 5194 w
+(Once) 2959 5194 w
+(a) 3245 5194 w
+(block) 3339 5194 w
+(is) 3640 5194 w
+(stored,) 3759 5194 w
+(it) 4139 5194 w
+(can) 4244 5194 w
+(be) 4451 5194 w
+(retrieved) 4609 5194 w
+(by) 720 5314 w
+(presenting) 882 5314 w
+(the) 1448 5314 w
+(20-byte) 1649 5314 w
+(SHA1) 2087 5314 w
+(hash) 2393 5314 w
+(of) 2669 5314 w
+(its) 2813 5314 w
+(contents,) 2976 5314 w
+(called) 3471 5314 w
+(a) 3800 5314 w
+10 /LucidaSans-Italic f
+(score) 3901 5314 w
+10 /LucidaSansUnicode00 f
+(.) 4158 5314 w
+(Blocks) 4268 5314 w
+(on) 4622 5314 w
+(Venti) 4791 5314 w
+(have) 720 5434 w
+(a) 994 5434 w
+(maximum) 1098 5434 w
+(length) 1633 5434 w
+(of) 1990 5434 w
+(about) 2137 5434 w
+(56) 2464 5434 w
+(kilobytes,) 2639 5434 w
+(though) 3156 5434 w
+(in) 3551 5434 w
+(practice) 3691 5434 w
+(smaller) 4123 5434 w
+(blocks) 4526 5434 w
+(are) 4888 5434 w
+(used.) 720 5554 w
+(To) 1055 5554 w
+(store) 1218 5554 w
+(a) 1503 5554 w
+(byte) 1597 5554 w
+(stream) 1844 5554 w
+(of) 2216 5554 w
+(arbitrary) 2353 5554 w
+(length,) 2806 5554 w
+(Venti) 3184 5554 w
+(uses) 3471 5554 w
+(a) 3729 5554 w
+(hash) 3822 5554 w
+(tree.) 4090 5554 w
+(Conceptually,) 4382 5554 w
+(the) 720 5674 w
+(data) 913 5674 w
+(stream) 1161 5674 w
+(is) 1532 5674 w
+(broken) 1651 5674 w
+(into) 2031 5674 w
+(fixed-size) 2259 5674 w
+(\(say,) 2795 5674 w
+10 /LucidaSans-Italic f
+(dsize) 3057 5674 w
+10 /LucidaSansUnicode00 f
+(-byte\)) 3303 5674 w
+(chunks,) 3641 5674 w
+(which) 4058 5674 w
+(are) 4378 5674 w
+(stored) 4569 5674 w
+(on) 4917 5674 w
+(the) 720 5794 w
+(Venti) 932 5794 w
+(server.) 1238 5794 w
+(The) 1656 5794 w
+(resulting) 1894 5794 w
+(scores) 2380 5794 w
+(are) 2748 5794 w
+(concatenated) 2957 5794 w
+(into) 3660 5794 w
+(a) 3906 5794 w
+(new) 4018 5794 w
+(pointer) 4270 5794 w
+(stream,) 4675 5794 w
+(which) 720 5914 w
+(is) 1042 5914 w
+(broken) 1163 5914 w
+(into) 1545 5914 w
+(fixed) 1775 5914 w
+(size) 2062 5914 w
+(\(say,) 2296 5914 w
+10 /LucidaSans-Italic f
+(psize) 2560 5914 w
+10 /LucidaSansUnicode00 f
+(-byte\)) 2806 5914 w
+(chunks,) 3146 5914 w
+(which) 3565 5914 w
+(are) 3887 5914 w
+(stored) 4080 5914 w
+(on) 4430 5914 w
+(the) 4594 5914 w
+(Venti) 4791 5914 w
+(server.) 720 6034 w
+(\() 1114 6034 w
+10 /LucidaSans-Italic f
+(Psize) 1147 6034 w
+10 /LucidaSansUnicode00 f
+(is) 1423 6034 w
+(different from) 1536 6034 w
+10 /LucidaSans-Italic f
+(dsize) 2250 6034 w
+10 /LucidaSansUnicode00 f
+(so that we can ensure that each pointer block holds) 2528 6034 w
+(an integral number) 720 6154 w
+(of) 1682 6154 w
+(pointers.\)) 1813 6154 w
+(This) 2343 6154 w
+(yields) 2581 6154 w
+(a) 2894 6154 w
+(new) 2982 6154 w
+(pointer) 3210 6154 w
+(stream,) 3592 6154 w
+(and) 3990 6154 w
+(so) 4203 6154 w
+(on,) 4348 6154 w
+(until) 4536 6154 w
+(there) 4788 6154 w
+(is) 720 6274 w
+(a) 854 6274 w
+(single) 963 6274 w
+(block) 1306 6274 w
+(and) 1622 6274 w
+(finally) 1856 6274 w
+(a) 2203 6274 w
+(single) 2312 6274 w
+(score) 2655 6274 w
+(describing) 2968 6274 w
+(the) 3528 6274 w
+(entire) 3736 6274 w
+(tree.) 4070 6274 w
+(The) 4377 6274 w
+(resulting) 4611 6274 w
+(structure looks like:) 720 6394 w
+cleartomark
+showpage
+saveobj restore
+%%EndPage: 1 1
+%%Page: 2 2
+/saveobj save def
+mark
+2 pagesetup
+10 /LucidaSansUnicode00 f
+(\255 2 \255) 2783 480 w
+8 /LucidaTypewriter f
+(VtDataType) 1114 1772 w
+1836 1792 1836 1720 Dl
+1836 1720 1980 1720 Dl
+1980 1720 1980 1792 Dl
+1980 1792 1836 1792 Dl
+2052 1792 2052 1720 Dl
+2052 1720 2196 1720 Dl
+2196 1720 2196 1792 Dl
+2196 1792 2052 1792 Dl
+8 /LucidaSansUnicode00 f
+(...) 2301 1772 w
+2484 1792 2484 1720 Dl
+2484 1720 2628 1720 Dl
+2628 1720 2628 1792 Dl
+2628 1792 2484 1792 Dl
+2700 1792 2700 1720 Dl
+2700 1720 2844 1720 Dl
+2844 1720 2844 1792 Dl
+2844 1792 2700 1792 Dl
+(...) 3021 1772 w
+3276 1792 3276 1720 Dl
+3276 1720 3420 1720 Dl
+3420 1720 3420 1792 Dl
+3420 1792 3276 1792 Dl
+3492 1792 3492 1720 Dl
+3492 1720 3636 1720 Dl
+3636 1720 3636 1792 Dl
+3636 1792 3492 1792 Dl
+(...) 3741 1772 w
+3924 1792 3924 1720 Dl
+3924 1720 4068 1720 Dl
+4068 1720 4068 1792 Dl
+4068 1792 3924 1792 Dl
+4140 1792 4140 1720 Dl
+4140 1720 4284 1720 Dl
+4284 1720 4284 1792 Dl
+4284 1792 4140 1792 Dl
+(...) 4389 1772 w
+4572 1792 4572 1720 Dl
+4572 1720 4716 1720 Dl
+4716 1720 4716 1792 Dl
+4716 1792 4572 1792 Dl
+1836 1504 1836 1432 Dl
+1836 1432 2196 1432 Dl
+2196 1432 2196 1504 Dl
+2196 1504 1836 1504 Dl
+1908 1432 1908 1504 Dl
+1980 1432 1980 1504 Dl
+1872 1468 1836 1720 Dl
+1828 1645 1835 1719 Dl
+1864 1651 1836 1719 Dl
+1944 1468 2052 1720 Dl
+2007 1660 2051 1719 Dl
+2040 1646 2051 1719 Dl
+(...) 2049 1484 w
+2484 1504 2484 1432 Dl
+2484 1432 2844 1432 Dl
+2844 1432 2844 1504 Dl
+2844 1504 2484 1504 Dl
+2556 1432 2556 1504 Dl
+2628 1432 2628 1504 Dl
+2520 1468 2484 1720 Dl
+2476 1645 2483 1719 Dl
+2512 1651 2484 1719 Dl
+2592 1468 2700 1720 Dl
+2655 1660 2699 1719 Dl
+2688 1646 2699 1719 Dl
+(...) 2697 1484 w
+3276 1504 3276 1432 Dl
+3276 1432 3636 1432 Dl
+3636 1432 3636 1504 Dl
+3636 1504 3276 1504 Dl
+3348 1432 3348 1504 Dl
+3420 1432 3420 1504 Dl
+3312 1468 3276 1720 Dl
+3268 1645 3275 1719 Dl
+3304 1651 3276 1719 Dl
+3384 1468 3492 1720 Dl
+3447 1660 3491 1719 Dl
+3480 1646 3491 1719 Dl
+(...) 3489 1484 w
+3924 1504 3924 1432 Dl
+3924 1432 4284 1432 Dl
+4284 1432 4284 1504 Dl
+4284 1504 3924 1504 Dl
+3996 1432 3996 1504 Dl
+4068 1432 4068 1504 Dl
+4212 1432 4212 1504 Dl
+3960 1468 3924 1720 Dl
+3916 1645 3923 1719 Dl
+3952 1651 3924 1719 Dl
+4032 1468 4140 1720 Dl
+4095 1660 4139 1719 Dl
+4128 1646 4139 1719 Dl
+(...) 4101 1484 w
+4248 1468 4572 1720 Dl
+4504 1689 4571 1719 Dl
+4525 1661 4571 1719 Dl
+8 /LucidaTypewriter f
+(VtPointerType0) 998 1484 w
+2160 1216 2160 1144 Dl
+2160 1144 2520 1144 Dl
+2520 1144 2520 1216 Dl
+2520 1216 2160 1216 Dl
+2232 1144 2232 1216 Dl
+2304 1144 2304 1216 Dl
+2196 1180 1836 1432 Dl
+1884 1375 1836 1431 Dl
+1905 1405 1836 1431 Dl
+2268 1180 2484 1432 Dl
+2423 1388 2483 1431 Dl
+2450 1365 2483 1431 Dl
+8 /LucidaSansUnicode00 f
+(...) 2373 1196 w
+3600 1216 3600 1144 Dl
+3600 1144 3960 1144 Dl
+3960 1144 3960 1216 Dl
+3960 1216 3600 1216 Dl
+3672 1144 3672 1216 Dl
+3888 1144 3888 1216 Dl
+3636 1180 3276 1432 Dl
+3324 1375 3276 1431 Dl
+3345 1405 3276 1431 Dl
+(...) 3741 1196 w
+3924 1180 3924 1432 Dl
+3906 1360 3924 1432 Dl
+3942 1360 3924 1432 Dl
+8 /LucidaTypewriter f
+(VtPointerType1) 998 1196 w
+2880 928 2880 856 Dl
+2880 856 3240 856 Dl
+3240 856 3240 928 Dl
+3240 928 2880 928 Dl
+2952 856 2952 928 Dl
+3168 856 3168 928 Dl
+2916 892 2160 1144 Dl
+2222 1104 2160 1143 Dl
+2234 1138 2160 1143 Dl
+8 /LucidaSansUnicode00 f
+(...) 3021 908 w
+3204 892 3600 1144 Dl
+3529 1120 3599 1143 Dl
+3548 1090 3599 1144 Dl
+8 /LucidaTypewriter f
+(VtPointerType2) 998 908 w
+10 /LucidaSansUnicode00 f
+(The) 720 2013 w
+(leaves) 947 2013 w
+(are) 1292 2013 w
+(the) 1490 2013 w
+(original) 1691 2013 w
+(data) 2105 2013 w
+(stream.) 2361 2013 w
+(Those) 2804 2013 w
+(blocks) 3143 2013 w
+(have) 3502 2013 w
+(type) 3773 2013 w
+10 /LucidaTypewriter f
+(VtDataType) 4028 2013 w
+10 /LucidaSansUnicode00 f
+(.) 4748 2013 w
+(The) 4859 2013 w
+(first) 720 2133 w
+(pointer) 1058 2133 w
+(stream) 1550 2133 w
+(has) 2025 2133 w
+(type) 2335 2133 w
+10 /LucidaTypewriter f
+(VtPointerType0) 2685 2133 w
+10 /LucidaSansUnicode00 f
+(,) 3693 2133 w
+(the) 3867 2133 w
+(next) 4164 2133 w
+(has) 4522 2133 w
+(type) 4832 2133 w
+10 /LucidaTypewriter f
+(VtPointerType1) 720 2253 w
+10 /LucidaSansUnicode00 f
+(,) 1728 2253 w
+(and) 1842 2253 w
+(so) 2104 2253 w
+(on.) 2298 2253 w
+(The) 2567 2253 w
+(figure) 2830 2253 w
+(ends) 3199 2253 w
+(with) 3513 2253 w
+(a) 3800 2253 w
+(single) 3937 2253 w
+(block) 4308 2253 w
+(of) 4652 2253 w
+(type) 4832 2253 w
+10 /LucidaTypewriter f
+(VtPointerType2) 720 2373 w
+10 /LucidaSansUnicode00 f
+(,) 1728 2373 w
+(but) 1807 2373 w
+(in) 2015 2373 w
+(general) 2152 2373 w
+(trees) 2559 2373 w
+(can) 2846 2373 w
+(have) 3060 2373 w
+(height) 3331 2373 w
+(up) 3685 2373 w
+(to) 3856 2373 w
+10 /LucidaTypewriter f
+(VtPointerType6) 4000 2373 w
+10 /LucidaSansUnicode00 f
+(.) 5008 2373 w
+(For) 720 2493 w
+(a) 911 2493 w
+10 /LucidaSans-Italic f
+(dsize) 1001 2493 w
+10 /LucidaSansUnicode00 f
+(of) 1282 2493 w
+(8192) 1415 2493 w
+(bytes) 1702 2493 w
+(and) 1996 2493 w
+10 /LucidaSans-Italic f
+(psize) 2211 2493 w
+10 /LucidaSansUnicode00 f
+(of) 2492 2493 w
+(8180) 2625 2493 w
+(bytes) 2912 2493 w
+(\(409) 3206 2493 w
+(pointers\),) 3463 2493 w
+(this) 3963 2493 w
+(gives) 4177 2493 w
+(a) 4463 2493 w
+(maximum) 4554 2493 w
+(stream size of approximately 10 zettabytes \(2) 720 2613 w
+8 /LucidaSansUnicode00 f
+(73) 2954 2573 w
+10 /LucidaSansUnicode00 f
+(or 10) 3086 2613 w
+8 /LucidaSansUnicode00 f
+(22) 3346 2573 w
+10 /LucidaSansUnicode00 f
+(bytes\).) 3478 2613 w
+(Data) 970 2769 w
+(block) 1233 2769 w
+(are) 1536 2769 w
+(truncated) 1729 2769 w
+(to) 2234 2769 w
+(remove) 2373 2769 w
+(trailing) 2773 2769 w
+(runs) 3158 2769 w
+(of) 3415 2769 w
+(zeros) 3554 2769 w
+(before) 3861 2769 w
+(storage) 4216 2769 w
+(to) 4620 2769 w
+(Venti;) 4759 2769 w
+(they) 720 2889 w
+(are) 962 2889 w
+(zero-filled) 1149 2889 w
+(back) 1700 2889 w
+(to) 1961 2889 w
+10 /LucidaSans-Italic f
+(dsize) 2093 2889 w
+10 /LucidaSansUnicode00 f
+(bytes) 2373 2889 w
+(after) 2666 2889 w
+(retrieval) 2926 2889 w
+(from) 3356 2889 w
+(Venti.) 3622 2889 w
+(SImilarly,) 3969 2889 w
+(trailing) 4446 2889 w
+(runs) 4824 2889 w
+(of) 720 3009 w
+(pointers) 858 3009 w
+(to) 1298 3009 w
+(zero-length) 1436 3009 w
+(blocks) 2057 3009 w
+(are) 2410 3009 w
+(removed) 2602 3009 w
+(from) 3064 3009 w
+(and) 3336 3009 w
+(added) 3557 3009 w
+(back) 3898 3009 w
+(to) 4166 3009 w
+(pointer) 4305 3009 w
+(blocks.) 4695 3009 w
+(These) 720 3129 w
+(simple) 1048 3129 w
+(rules) 1409 3129 w
+(happen) 1687 3129 w
+(to) 2087 3129 w
+(make) 2224 3129 w
+(it) 2525 3129 w
+(particularly) 2630 3129 w
+(efficient) 3213 3129 w
+(to) 3646 3129 w
+(store) 3783 3129 w
+(large) 4068 3129 w
+(runs) 4350 3129 w
+(of) 4605 3129 w
+(zeros,) 4742 3129 w
+(as) 720 3249 w
+(might) 864 3249 w
+(occur) 1185 3249 w
+(in) 1489 3249 w
+(a) 1618 3249 w
+(data) 1711 3249 w
+(stream) 1959 3249 w
+(with) 2330 3249 w
+10 /LucidaSansUnicode20 f
+(\030\030) 2573 3249 w
+10 /LucidaSansUnicode00 f
+(holes:) 2637 3249 w
+10 /LucidaSansUnicode20 f
+(\031\031) 2928 3249 w
+10 /LucidaSansUnicode00 f
+(the) 3030 3249 w
+(zero-length) 3223 3249 w
+(block) 3842 3249 w
+(itself) 4142 3249 w
+(can) 4419 3249 w
+(be) 4625 3249 w
+(inter\255) 4782 3249 w
+(preted as a tree of any depth encoding an all-zero data stream.) 720 3369 w
+(Reconstructing) 970 3525 w
+(the) 1728 3525 w
+(data) 1916 3525 w
+(stream) 2159 3525 w
+(requires) 2525 3525 w
+(the) 2957 3525 w
+(score) 3145 3525 w
+(and) 3439 3525 w
+(type) 3653 3525 w
+(of) 3895 3525 w
+(the) 4027 3525 w
+(topmost) 4216 3525 w
+(block) 4653 3525 w
+(in) 4949 3525 w
+(the) 720 3645 w
+(tree,) 917 3645 w
+(the) 1181 3645 w
+(data) 1377 3645 w
+(chunk) 1628 3645 w
+(size,) 1964 3645 w
+(the) 2230 3645 w
+(pointer) 2426 3645 w
+(chunk) 2816 3645 w
+(size,) 3152 3645 w
+(and) 3418 3645 w
+(the) 3639 3645 w
+(data) 3835 3645 w
+(stream) 4086 3645 w
+(size.) 4460 3645 w
+(\(From) 4758 3645 w
+(the) 720 3765 w
+(data) 909 3765 w
+(stream) 1153 3765 w
+(size) 1520 3765 w
+(and) 1747 3765 w
+(the) 1961 3765 w
+(chunk) 2150 3765 w
+(sizes) 2479 3765 w
+(we) 2758 3765 w
+(could) 2926 3765 w
+(derive) 3227 3765 w
+(the) 3559 3765 w
+(depth) 3749 3765 w
+(of) 4065 3765 w
+(the) 4198 3765 w
+(tree) 4388 3765 w
+(and) 4613 3765 w
+(thus) 4828 3765 w
+(the) 720 3885 w
+(type) 918 3885 w
+(of) 1169 3885 w
+(the) 1310 3885 w
+(topmost) 1508 3885 w
+(block,) 1954 3885 w
+(but) 2291 3885 w
+(it) 2496 3885 w
+(is) 2605 3885 w
+(convenient) 2728 3885 w
+(to) 3299 3885 w
+(allow) 3440 3885 w
+(trees) 3734 3885 w
+(that) 4018 3885 w
+(are) 4252 3885 w
+(deeper) 4447 3885 w
+(than) 4824 3885 w
+(necessary.\)) 720 4005 w
+(This information is kept in a 40-byte structure called a) 1324 4005 w
+10 /LucidaTypewriter f
+(VtEntry) 4024 4005 w
+10 /LucidaSansUnicode00 f
+(:) 4528 4005 w
+9 /LucidaTypewriter f
+(VtEntry:) 1008 4175 w
+(gen[4]) 1268 4285 w
+9 /LucidaSansUnicode00 f
+(generation) 2048 4285 w
+(number) 2546 4285 w
+9 /LucidaTypewriter f
+(psize[2]) 1268 4395 w
+9 /LucidaSansUnicode00 f
+(size) 2048 4395 w
+(of) 2250 4395 w
+(pointer) 2367 4395 w
+(blocks) 2710 4395 w
+9 /LucidaTypewriter f
+(dsize[2]) 1268 4505 w
+9 /LucidaSansUnicode00 f
+(size) 2048 4505 w
+(of) 2250 4505 w
+(data) 2367 4505 w
+(blocks) 2586 4505 w
+9 /LucidaTypewriter f
+(flags[1]) 1268 4615 w
+(zero[5]) 1268 4725 w
+(size[6]) 1268 4835 w
+9 /LucidaSansUnicode00 f
+(length) 2048 4835 w
+(of) 2354 4835 w
+(file) 2471 4835 w
+9 /LucidaTypewriter f
+(score[20]) 1268 4945 w
+9 /LucidaSansUnicode00 f
+(score) 2048 4945 w
+(of) 2311 4945 w
+(root) 2428 4945 w
+(block) 2637 4945 w
+(in) 2902 4945 w
+(tree) 3013 4945 w
+10 /LucidaSansUnicode00 f
+(\(In) 720 5125 w
+(this) 877 5125 w
+(notation,) 1089 5125 w
+10 /LucidaTypewriter f
+(name[sz]) 1558 5125 w
+10 /LucidaSansUnicode00 f
+(indicates) 2167 5125 w
+(a) 2633 5125 w
+10 /LucidaTypewriter f
+(sz) 2722 5125 w
+10 /LucidaSansUnicode00 f
+(-byte) 2866 5125 w
+(field) 3166 5125 w
+(called) 3414 5125 w
+10 /LucidaTypewriter f
+(name) 3731 5125 w
+10 /LucidaSansUnicode00 f
+(.) 4019 5125 w
+(Integers) 4117 5125 w
+(are) 4545 5125 w
+(stored) 4731 5125 w
+(in) 720 5245 w
+(big-endian) 846 5245 w
+(order.) 1420 5245 w
+10 /LucidaTypewriter f
+(Size) 1781 5245 w
+10 /LucidaSansUnicode00 f
+(really) 2104 5245 w
+(is) 2401 5245 w
+(a) 2516 5245 w
+(48-bit) 2606 5245 w
+(field.\)) 2954 5245 w
+10 /LucidaTypewriter f
+(Flags) 3300 5245 w
+10 /LucidaSansUnicode00 f
+(is) 3695 5245 w
+(made) 3810 5245 w
+(up) 4112 5245 w
+(of) 4272 5245 w
+(the) 4404 5245 w
+(following) 4593 5245 w
+(bit fields.) 720 5365 w
+10 /LucidaSansUnicode20 f
+(\030) 1242 5365 w
+10 /LucidaSans-Italic f
+(or) 1274 5365 w
+10 /LucidaSansUnicode20 f
+(\031) 1379 5365 w
+10 /LucidaSansUnicode00 f
+(of the following flags:) 1443 5365 w
+9 /LucidaTypewriter f
+(0x01) 1008 5535 w
+(VtEntryActive) 1398 5535 w
+9 /LucidaSansUnicode00 f
+(entry) 2828 5535 w
+(is) 3080 5535 w
+(allocated) 3181 5535 w
+9 /LucidaTypewriter f
+(0x02) 1008 5645 w
+(VtEntryDir) 1398 5645 w
+9 /LucidaSansUnicode00 f
+(entry) 2828 5645 w
+(describes) 3080 5645 w
+(a) 3524 5645 w
+(Venti) 3603 5645 w
+(directory) 3856 5645 w
+(\(q.v.\)) 4273 5645 w
+9 /LucidaTypewriter f
+(0x1C) 1008 5755 w
+(VtEntryDepthMask) 1398 5755 w
+9 /LucidaSansUnicode00 f
+(mask) 2828 5755 w
+(for) 3089 5755 w
+(tree) 3243 5755 w
+(depth) 3442 5755 w
+9 /LucidaTypewriter f
+(0x20) 1008 5865 w
+(VtEntryLocal) 1398 5865 w
+9 /LucidaSansUnicode00 f
+(reserved) 2828 5865 w
+(\(q.v.\)) 3231 5865 w
+10 /LucidaSansUnicode00 f
+(The) 720 6081 w
+(depth) 940 6081 w
+(of) 1261 6081 w
+(the) 1399 6081 w
+(described) 1594 6081 w
+(tree) 2107 6081 w
+(is) 2337 6081 w
+(stored) 2457 6081 w
+(in) 2806 6081 w
+(the) 2937 6081 w
+(5) 3132 6081 w
+(bits) 3235 6081 w
+(indicated:) 3455 6081 w
+(a) 3972 6081 w
+(tree) 4067 6081 w
+(with) 4297 6081 w
+(a) 4542 6081 w
+(topmost) 4637 6081 w
+(node of type) 720 6201 w
+10 /LucidaTypewriter f
+(VtPointerType3) 1364 6201 w
+10 /LucidaSansUnicode00 f
+(has depth 4.) 2404 6201 w
+(With) 970 6357 w
+10 /LucidaTypewriter f
+(VtEntry) 1220 6357 w
+10 /LucidaSansUnicode00 f
+(we) 1760 6357 w
+(can) 1929 6357 w
+(build) 2133 6357 w
+(more) 2415 6357 w
+(complicated) 2703 6357 w
+(data) 3328 6357 w
+(structures,) 3575 6357 w
+(ones) 4133 6357 w
+(with) 4400 6357 w
+(multiple) 4642 6357 w
+(or) 720 6477 w
+(nested) 870 6477 w
+(data) 1243 6477 w
+(streams.) 1501 6477 w
+(A) 1997 6477 w
+(data) 2114 6477 w
+(stream) 2372 6477 w
+(consisting) 2753 6477 w
+(of) 3296 6477 w
+10 /LucidaTypewriter f
+(VtEntry) 3441 6477 w
+10 /LucidaSansUnicode00 f