1 /* 2 * fundamental constants and types of the implementation 3 * changing any of these changes the layout on disk 4 */ 5 enum { 6 SUPER_ADDR = 2, /* block address of superblock */ 7 ROOT_ADDR = 3, /* block address of root directory */ 8 }; 9 10 /* more fundamental types */ 11 typedef vlong Wideoff; /* type to widen Off to for printing; ≥ as wide as Off */ 12 typedef short Userid; /* signed internal representation of user-id */ 13 typedef long Timet; /* in seconds since epoch */ 14 typedef vlong Devsize; /* in bytes */ 15 16 17 /* macros */ 18 #define NEXT(x, l) (((x)+1) % (l)) 19 #define PREV(x, l) ((x) == 0? (l)-1: (x)-1) 20 #define HOWMANY(x, y) (((x)+((y)-1)) / (y)) 21 #define ROUNDUP(x, y) (HOWMANY((x), (y)) * (y)) 22 23 #define TK2MS(t) (((ulong)(t)*1000)/HZ) /* ticks to ms - beware rounding */ 24 #define MS2TK(t) (((ulong)(t)*HZ)/1000) /* ms to ticks - beware rounding */ 25 #define TK2SEC(t) ((t)/HZ) /* ticks to seconds */ 26 27 /* constants that don't affect disk layout */ 28 enum { 29 MAXDAT = 8192, /* max allowable data message */ 30 MAXMSG = 128, /* max protocol message sans data */ 31 32 MB = 1024*1024, 33 34 HZ = 1, /* clock frequency */ 35 }; 36 37 /* 38 * tunable parameters 39 */ 40 enum { 41 Maxword = 256, /* max bytes per command-line word */ 42 NTLOCK = 200, /* number of active file Tlocks */ 43 }; 44 45 typedef struct Auth Auth; 46 typedef struct Bp Bp; 47 typedef struct Bucket Bucket; 48 typedef struct Cache Cache; 49 typedef struct Centry Centry; 50 typedef struct Chan Chan; 51 typedef struct Command Command; 52 typedef struct Conf Conf; 53 typedef struct Cons Cons; 54 typedef struct Dentry Dentry; 55 typedef struct Device Device; 56 typedef struct Fbuf Fbuf; 57 typedef struct File File; 58 typedef struct Filsys Filsys; 59 typedef struct Filter Filter; 60 typedef struct Flag Flag; 61 typedef struct Hiob Hiob; 62 typedef struct Iobuf Iobuf; 63 typedef struct Lock Lock; 64 typedef struct Msgbuf Msgbuf; 65 typedef struct QLock QLock; 66 typedef struct Qid9p1 Qid9p1; 67 typedef struct Queue Queue; 68 typedef union Rabuf Rabuf; 69 typedef struct Rendez Rendez; 70 typedef struct Rtc Rtc; 71 typedef struct Startsb Startsb; 72 typedef struct Super1 Super1; 73 typedef struct Superb Superb; 74 typedef struct Tag Tag; 75 typedef struct Time Time; 76 typedef struct Tlock Tlock; 77 typedef struct Tm Tm; 78 typedef struct Uid Uid; 79 typedef struct Wpath Wpath; 80 81 #pragma incomplete Auth 82 83 struct Tag 84 { 85 short pad; /* make tag end at a long boundary */ 86 short tag; 87 Off path; 88 }; 89 90 /* DONT TOUCH, this is the disk structure */ 91 struct Qid9p1 92 { 93 Off path; /* was long */ 94 ulong version; /* should be Off */ 95 }; 96 97 /* DONT TOUCH, this is the disk structure */ 98 struct Super1 99 { 100 Off fstart; 101 Off fsize; 102 Off tfree; 103 Off qidgen; /* generator for unique ids */ 104 /* 105 * Stuff for WWC device 106 */ 107 Off cwraddr; /* cfs root addr */ 108 Off roraddr; /* dump root addr */ 109 Off last; /* last super block addr */ 110 Off next; /* next super block addr */ 111 }; 112 113 /* DONT TOUCH, this is the disk structure */ 114 struct Centry 115 { 116 ushort age; 117 short state; 118 Off waddr; /* worm addr */ 119 }; 120 121 /* DONT TOUCH, this is the disk structure */ 122 struct Dentry 123 { 124 char name[NAMELEN]; 125 Userid uid; 126 Userid gid; 127 ushort mode; 128 #define DALLOC 0x8000 129 #define DDIR 0x4000 130 #define DAPND 0x2000 131 #define DLOCK 0x1000 132 #define DREAD 0x4 133 #define DWRITE 0x2 134 #define DEXEC 0x1 135 Userid muid; 136 Qid9p1 qid; 137 Off size; 138 Off dblock[NDBLOCK]; 139 Off iblocks[NIBLOCK]; 140 long atime; 141 long mtime; 142 }; 143 144 /* 145 * derived constants 146 */ 147 enum { 148 BUFSIZE = RBUFSIZE - sizeof(Tag), 149 DIRPERBUF = BUFSIZE / sizeof(Dentry), 150 INDPERBUF = BUFSIZE / sizeof(Off), 151 FEPERBUF = (BUFSIZE-sizeof(Super1)-sizeof(Off)) / sizeof(Off), 152 SMALLBUF = MAXMSG, 153 LARGEBUF = MAXMSG+MAXDAT+256, 154 RAGAP = (300*1024)/BUFSIZE, /* readahead parameter */ 155 BKPERBLK = 10, 156 CEPERBK = (BUFSIZE - BKPERBLK*sizeof(Off)) / 157 (sizeof(Centry)*BKPERBLK), 158 }; 159 160 /* 161 * send/recv queue structure 162 */ 163 struct Queue 164 { 165 QLock; /* to manipulate values */ 166 Rendez empty; 167 Rendez full; 168 169 int waitedfor; /* flag */ 170 char* name; /* for debugging */ 171 172 int size; /* size of queue */ 173 int loc; /* circular pointer */ 174 int count; /* how many in queue */ 175 void* args[1]; /* list of saved pointers, [->size] */ 176 }; 177 178 struct Device 179 { 180 uchar type; 181 uchar init; 182 Device* link; /* link for mcat/mlev/mirror */ 183 Device* dlink; /* link all devices */ 184 void* private; 185 Devsize size; 186 union { 187 struct { /* disk, (l)worm in j.j, sides */ 188 int ctrl; /* disks only */ 189 int targ; 190 int lun; /* not implemented in sd(3) */ 191 192 int mapped; 193 char* file; /* ordinary file or dir instead */ 194 195 int fd; 196 char* sddir; /* /dev/sdXX name, for juke drives */ 197 char* sddata; /* /dev/sdXX/data or other file */ 198 } wren; 199 struct { /* mcat mlev mirror */ 200 Device* first; 201 Device* last; 202 int ndev; 203 } cat; 204 struct { /* cw */ 205 Device* c; /* cache device */ 206 Device* w; /* worm device */ 207 Device* ro; /* dump - readonly */ 208 } cw; 209 struct { /* juke */ 210 Device* j; /* (robotics, worm drives) - wrens */ 211 Device* m; /* (sides) - r or l devices */ 212 } j; 213 struct { /* ro */ 214 Device* parent; 215 } ro; 216 struct { /* fworm */ 217 Device* fw; 218 } fw; 219 struct { /* part */ 220 Device* d; 221 long base; /* percentages */ 222 long size; 223 } part; 224 struct { /* byte-swapped */ 225 Device* d; 226 } swab; 227 }; 228 }; 229 230 typedef struct Sidestarts { 231 Devsize sstart; /* blocks before start of side */ 232 Devsize s1start; /* blocks before start of next side */ 233 } Sidestarts; 234 235 union Rabuf { 236 struct { 237 Device* dev; 238 Off addr; 239 }; 240 Rabuf* link; 241 }; 242 243 struct Hiob 244 { 245 Iobuf* link; 246 Lock; 247 }; 248 249 /* a 9P connection */ 250 struct Chan 251 { 252 char type; /* major driver type i.e. Dev* */ 253 int (*protocol)(Msgbuf*); /* version */ 254 int msize; /* version */ 255 char whochan[50]; 256 char whoname[NAMELEN]; 257 void (*whoprint)(Chan*); 258 ulong flags; 259 int chan; /* overall channel #, mostly for printing */ 260 int nmsgs; /* outstanding messages, set under flock -- for flush */ 261 262 Timet whotime; 263 int nfile; /* used by cmd_files */ 264 265 RWLock reflock; 266 Chan* next; /* link list of chans */ 267 Queue* send; 268 Queue* reply; 269 270 uchar authinfo[64]; 271 272 void* pdata; /* sometimes is a Netconn* */ 273 }; 274 275 struct Filsys 276 { 277 char* name; /* name of filsys */ 278 char* conf; /* symbolic configuration */ 279 Device* dev; /* device that filsys is on */ 280 int flags; 281 #define FREAM (1<<0) /* mkfs */ 282 #define FRECOVER (1<<1) /* install last dump */ 283 #define FEDIT (1<<2) /* modified */ 284 }; 285 286 struct Startsb 287 { 288 char* name; 289 Off startsb; 290 }; 291 292 struct Time 293 { 294 Timet lasttoy; 295 Timet offset; 296 }; 297 298 /* 299 * array of qids that are locked 300 */ 301 struct Tlock 302 { 303 Device* dev; 304 Timet time; 305 Off qpath; 306 File* file; 307 }; 308 309 struct Cons 310 { 311 ulong flags; /* overall flags for all channels */ 312 QLock; /* generic qlock for mutex */ 313 int uid; /* botch -- used to get uid on cons_create */ 314 int gid; /* botch -- used to get gid on cons_create */ 315 int nuid; /* number of uids */ 316 int ngid; /* number of gids */ 317 Off offset; /* used to read files, c.f. fchar */ 318 int chano; /* generator for channel numbers */ 319 Chan* chan; /* console channel */ 320 Filsys* curfs; /* current filesystem */ 321 322 int profile; /* are we profiling? */ 323 long* profbuf; 324 ulong minpc; 325 ulong maxpc; 326 ulong nprofbuf; 327 328 long nlarge; /* number of large message buffers */ 329 long nsmall; /* ... small ... */ 330 long nwormre; /* worm read errors */ 331 long nwormwe; /* worm write errors */ 332 long nwormhit; /* worm read cache hits */ 333 long nwormmiss; /* worm read cache non-hits */ 334 int noage; /* dont update cache age, dump and check */ 335 long nwrenre; /* disk read errors */ 336 long nwrenwe; /* disk write errors */ 337 long nreseq; /* cache bucket resequence */ 338 339 // Filter work[3]; /* thruput in messages */ 340 // Filter rate[3]; /* thruput in bytes */ 341 // Filter bhit[3]; /* getbufs that hit */ 342 // Filter bread[3]; /* getbufs that miss and read */ 343 // Filter brahead[3]; /* messages to readahead */ 344 // Filter binit[3]; /* getbufs that miss and dont read */ 345 }; 346 347 struct File 348 { 349 QLock; 350 Qid qid; 351 Wpath* wpath; 352 Chan* cp; /* null means a free slot */ 353 Tlock* tlock; /* if file is locked */ 354 File* next; /* in cp->flist */ 355 Filsys* fs; 356 Off addr; 357 long slot; /* ordinal # of Dentry with a directory block */ 358 Off lastra; /* read ahead address */ 359 ulong fid; 360 Userid uid; 361 Auth *auth; 362 char open; 363 #define FREAD 1 364 #define FWRITE 2 365 #define FREMOV 4 366 367 Off doffset; /* directory reading */ 368 ulong dvers; 369 long dslot; 370 }; 371 372 struct Wpath 373 { 374 Wpath* up; /* pointer upwards in path */ 375 Off addr; /* directory entry addr */ 376 long slot; /* directory entry slot */ 377 short refs; /* number of files using this structure */ 378 }; 379 380 struct Iobuf 381 { 382 QLock; 383 Device* dev; 384 Iobuf* fore; /* for lru */ 385 Iobuf* back; /* for lru */ 386 char* iobuf; /* only active while locked */ 387 char* xiobuf; /* "real" buffer pointer */ 388 Off addr; 389 int flags; 390 }; 391 392 struct Uid 393 { 394 Userid uid; /* user id */ 395 Userid lead; /* leader of group */ 396 Userid *gtab; /* group table */ 397 int ngrp; /* number of group entries */ 398 char name[NAMELEN]; /* user name */ 399 }; 400 401 /* DONT TOUCH, this is the disk structure */ 402 struct Fbuf 403 { 404 Off nfree; 405 Off free[FEPERBUF]; 406 }; 407 408 /* DONT TOUCH, this is the disk structure */ 409 struct Superb 410 { 411 Fbuf fbuf; 412 Super1; 413 }; 414 415 struct Conf 416 { 417 ulong nmach; /* processors */ 418 ulong mem; /* total physical bytes of memory */ 419 ulong nuid; /* distinct uids */ 420 ulong nserve; /* server processes */ 421 ulong nfile; /* number of fid -- system wide */ 422 ulong nwpath; /* number of active paths, derived from nfile */ 423 ulong gidspace; /* space for gid names -- derived from nuid */ 424 425 ulong nlgmsg; /* number of large message buffers */ 426 ulong nsmmsg; /* number of small message buffers */ 427 428 Off recovcw; /* recover addresses */ 429 Off recovro; 430 Off firstsb; 431 Off recovsb; 432 433 ulong configfirst; /* configure before starting normal operation */ 434 char *confdev; 435 char *devmap; /* name of config->file device mapping file */ 436 437 ulong nauth; /* number of Auth structs */ 438 uchar nodump; /* no periodic dumps */ 439 uchar dumpreread; /* read and compare in dump copy */ 440 }; 441 442 enum { 443 Mbmagic = 0xb0ffe3, 444 }; 445 446 /* 447 * message buffers 448 * 2 types, large and small 449 */ 450 struct Msgbuf 451 { 452 ulong magic; 453 short count; 454 short flags; 455 #define LARGE (1<<0) 456 #define FREE (1<<1) 457 #define BFREE (1<<2) 458 #define BTRACE (1<<7) 459 Chan* chan; /* file server conn within a net. conn */ 460 Msgbuf* next; 461 uintptr param; /* misc. use; keep Conn* here */ 462 463 int category; 464 uchar* data; /* rp or wp: current processing point */ 465 uchar* xdata; /* base of allocation */ 466 }; 467 468 /* 469 * message buffer categories 470 */ 471 enum 472 { 473 Mxxx = 0, 474 Mbeth1, 475 Mbreply1, 476 Mbreply2, 477 Mbreply3, 478 Mbreply4, 479 MAXCAT, 480 }; 481 482 enum { PRINTSIZE = 256 }; 483 484 struct 485 { 486 Lock; 487 int machs; 488 int exiting; 489 } active; 490 491 struct Command 492 { 493 char* arg0; 494 char* help; 495 void (*func)(int, char*[]); 496 }; 497 498 struct Flag 499 { 500 char* arg0; 501 char* help; 502 ulong flag; 503 }; 504 505 struct Rtc 506 { 507 int sec; 508 int min; 509 int hour; 510 int mday; 511 int mon; 512 int year; 513 }; 514 515 typedef struct 516 { 517 /* constants during a given truncation */ 518 Dentry *d; 519 Iobuf *p; /* the block containing *d */ 520 int uid; 521 Off newsize; 522 Off lastblk; /* last data block of file to keep */ 523 524 /* variables */ 525 Off relblk; /* # of current data blk within file */ 526 int pastlast; /* have we walked past lastblk? */ 527 int err; 528 } Truncstate; 529 530 /* 531 * cw device 532 */ 533 534 /* DONT TOUCH, this is the disk structure */ 535 struct Cache 536 { 537 Off maddr; /* cache map addr */ 538 Off msize; /* cache map size in buckets */ 539 Off caddr; /* cache addr */ 540 Off csize; /* cache size */ 541 Off fsize; /* current size of worm */ 542 Off wsize; /* max size of the worm */ 543 Off wmax; /* highwater write */ 544 545 Off sbaddr; /* super block addr */ 546 Off cwraddr; /* cw root addr */ 547 Off roraddr; /* dump root addr */ 548 549 Timet toytime; /* somewhere convienent */ 550 Timet time; 551 }; 552 553 /* DONT TOUCH, this is the disk structure */ 554 struct Bucket 555 { 556 long agegen; /* generator for ages in this bkt */ 557 Centry entry[CEPERBK]; 558 }; 559 560 /* DONT TOUCH, this is in disk structures */ 561 enum { Labmagic = 0xfeedfacedeadbeefULL, }; 562 563 /* DONT TOUCH, this is the disk structure */ 564 typedef struct Label Label; 565 struct Label /* label block on Devlworms, in last block */ 566 { 567 uvlong magic; 568 ushort ord; /* side number within Juke */ 569 char service[64]; /* documentation only */ 570 }; 571 572 typedef struct Map Map; 573 struct Map { 574 char *from; 575 Device *fdev; 576 char *to; 577 Device *tdev; 578 Map *next; 579 }; 580 581 /* 582 * scsi i/o 583 */ 584 enum 585 { 586 SCSIread = 0, 587 SCSIwrite = 1, 588 }; 589 590 /* 591 * Process states 592 */ 593 enum 594 { 595 Dead = 0, 596 Moribund, 597 Zombie, 598 Ready, 599 Scheding, 600 Running, 601 Queueing, 602 Sending, 603 Recving, 604 MMUing, 605 Exiting, 606 Inwait, 607 Wakeme, 608 Broken, 609 }; 610 611 /* 612 * devnone block numbers 613 */ 614 enum 615 { 616 Cwio1 = 1, 617 Cwio2, 618 Cwxx1, 619 Cwxx2, 620 Cwxx3, 621 Cwxx4, 622 Cwdump1, 623 Cwdump2, 624 Cuidbuf, 625 Cckbuf, 626 }; 627 628 /* 629 * error codes generated from the file server 630 */ 631 enum 632 { 633 Ebadspc = 1, 634 Efid, 635 Echar, 636 Eopen, 637 Ecount, 638 Ealloc, 639 Eqid, 640 Eaccess, 641 Eentry, 642 Emode, 643 Edir1, 644 Edir2, 645 Ephase, 646 Eexist, 647 Edot, 648 Eempty, 649 Ebadu, 650 Enoattach, 651 Ewstatb, 652 Ewstatd, 653 Ewstatg, 654 Ewstatl, 655 Ewstatm, 656 Ewstato, 657 Ewstatp, 658 Ewstatq, 659 Ewstatu, 660 Ewstatv, 661 Ename, 662 Ewalk, 663 Eronly, 664 Efull, 665 Eoffset, 666 Elocked, 667 Ebroken, 668 Eauth, 669 Eauth2, 670 Efidinuse, 671 Etoolong, 672 Econvert, 673 Eversion, 674 Eauthdisabled, 675 Eauthnone, 676 Eauthfile, 677 Eedge, 678 MAXERR 679 }; 680 681 /* 682 * device types 683 */ 684 enum 685 { 686 Devnone = 0, 687 Devcon, /* console */ 688 Devwren, /* disk drive */ 689 Devworm, /* scsi optical drive */ 690 Devlworm, /* scsi optical drive (labeled) */ 691 Devfworm, /* fake read-only device */ 692 Devjuke, /* scsi jukebox */ 693 Devcw, /* cache with worm */ 694 Devro, /* readonly worm */ 695 Devmcat, /* multiple cat devices */ 696 Devmlev, /* multiple interleave devices */ 697 Devnet, /* network connection */ 698 Devpart, /* partition */ 699 Devfloppy, /* floppy drive */ 700 Devswab, /* swab data between mem and device */ 701 Devmirr, /* mirror devices */ 702 MAXDEV 703 }; 704 705 /* 706 * tags on block 707 */ 708 /* DONT TOUCH, this is in disk structures */ 709 /* also, the order from Tdir to Tmaxind is exploited in indirck() & isdirty() */ 710 enum 711 { 712 Tnone = 0, 713 Tsuper, /* the super block */ 714 #ifdef COMPAT32 715 Tdir, /* directory contents */ 716 Tind1, /* points to blocks */ 717 Tind2, /* points to Tind1 */ 718 #else 719 Tdirold, 720 Tind1old, 721 Tind2old, 722 #endif 723 Tfile, /* file contents; also defined in disk.h */ 724 Tfree, /* in free list */ 725 Tbuck, /* cache fs bucket */ 726 Tvirgo, /* fake worm virgin bits */ 727 Tcache, /* cw cache things */ 728 Tconfig, /* configuration block */ 729 #ifndef COMPAT32 730 /* Tdir & indirect blocks are last, to allow for greater depth */ 731 Tdir, /* directory contents */ 732 Tind1, /* points to blocks */ 733 Tind2, /* points to Tind1 */ 734 Tind3, /* points to Tind2 */ 735 Tind4, /* points to Tind3 */ 736 Maxtind, 737 #endif 738 /* gap for more indirect block depth in future */ 739 Tlabel = 32, /* Devlworm label in last block */ 740 MAXTAG, 741 742 #ifdef COMPAT32 743 Tmaxind = Tind2, 744 #else 745 Tmaxind = Maxtind - 1, 746 #endif 747 }; 748 749 /* 750 * flags to getbuf 751 */ 752 enum 753 { 754 Brd = (1<<0), /* read the block if miss */ 755 Bprobe = (1<<1), /* return null if miss */ 756 Bmod = (1<<2), /* buffer is dirty, needs writing */ 757 Bimm = (1<<3), /* write immediately on putbuf */ 758 Bres = (1<<4), /* reserved, never renamed */ 759 }; 760 761 Conf conf; 762 Cons cons; 763 764 #pragma varargck type "Z" Device* 765 #pragma varargck type "T" Timet 766 #pragma varargck type "I" uchar* 767 #pragma varargck type "E" uchar* 768 #pragma varargck type "G" int 769 770 extern char *annstrs[]; 771 extern Biobuf bin; 772 extern Map *devmap; 773 extern int (*fsprotocol[])(Msgbuf*); 774