odin@ucscb.UCSC.EDU (60200000) (11/02/88)
Over the past few days I have been fighting with a strange guru on my Amiga 2000. It would show up on various occasions: when mounting JH0: (my Amiga partition of an IBM hard drive), or after my startup-sequence was done, I end up in Matt Dillon's shell 2.07 and when I quit it would guru. Then I even got it twice when I tried to erase a file while doing some routine file maintenance on my BBS (which brings up another question later). The guru numbers were: 1) 8700000B.265F48F1 2) 87000008.265F48F1 ShowGuru says that they are DEADEND, generated by the DOS LIBRARY and 1) is "key out of range" and 2) is "key already free". I made a totally new startup disk from scratch and I have not received a guru since then. Could someone enlighten me as to what could have caused this so that I know what to look for in the future. It took me quite a while to make a new boot disk (my backup didn't work either) and if there an easier way, I would like to know. Any help would be appreciated greatly (Mail, of course). Thank you in advance. Now here is my other question: After one of the above mentioned gurus a strange thing happened. A file appeared in the directory I had been working in and I can't move it or rename it or copy it or do anything to it except that it shows up in the listing. Also, I had a directory called 'temp' and now whenever I make a directory called 'temp' in that directory, it doesn't show up. Anyone care to comment? I don't know what to do. Any help would again be greatly appreciated. Thanks, Jon <<=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=>> | Jon Granrose odin@ucscb.UCSC.EDU | | OR | | Opinions?!? That'll be the day... ~!ucbvax!ucscc!ucscb!odin| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cmcmanis%pepper@Sun.COM (Chuck McManis) (11/03/88)
In article <5332@saturn.ucsc.edu> odin@ucscb.UCSC.EDU (Jon Granrose) writes: > Over the past few days I have been fighting with a strange guru on my >Amiga 2000... > 1) 8700000B.265F48F1 > 2) 87000008.265F48F1 >ShowGuru says that they are DEADEND, generated by the DOS LIBRARY and 1) is >"key out of range" and 2) is "key already free". These are "disk corrupt" GURU messages. They mean that the structure of your disk (whichever one you touched last) is corrupt and these are the GURUs that the filesystem tasks (0x265F4851) throws up to warn you about it. If this disk ever tried to validate it would fail and you would get the infamous "Use DiskDoctor to Fix" message. Of course if you have a MicroBotics StarDrive you will find a little program I wrote called MDFixer in the system drawer that will also fix it. Run it through "Verify FileSystem" and it will tell you where if finds problems, use the "Rebuild FileSystem" button to make it healthy again (I usually go for the Interactive option because that way if it finds a corrupted file you will only lose a couple of blocks from it rather than the whole file.) If the problem appeared "spontaneously" after a while I would guess you are using either "cheap" (read single sided or "generic" disks) or you have a very old disk (check for lines on the media where the heads rest). Otherwise it may just be flaky hardware. (Side note, if you don't have MDFixer, DiskSalv 1.3 will also fix up the disk for you) > I made a totally new startup disk from scratch and I have not received > a guru since then. You just can't use DiskCopy because that will copy corruptions like this in place. So you need to copy the individual files. Of course you can't do that until you have fixed the corruptions. > Could someone enlighten me as to what could have caused this so that > I know what to look for in the future. The two most often causes of this are bad medium (the disk) or sudden loss of power/control during a write. (eg you power off or reboot when the disk is being written) > After one of the above mentioned gurus a strange thing happened. A file >appeared in the directory I had been working in and I can't move it or rename >it or copy it or do anything to it except that it shows up in the listing. Guess what, you still have a corrupt disk. This happens when a file is in the hashtable at the "wrong" place. See the usenet tutorial on the file system. (Either Bob Page or Kim Devaughn did it) Then you can use something like Sectorama or Disked to get to that file and either delete it or move it to it's "correct" place. >Also, I had a directory called 'temp' and now whenever I make a directory >called 'temp' in that directory, it doesn't show up. Anyone care to comment? >I don't know what to do. Any help would again be greatly appreciated. Fix up the disk structure. All sorts of weird things happen when it is broken. Sorry I can't tell you exactly what is causing it. If you are using single sided disks this is a good time to stop using them :-) --Chuck McManis uucp: {anywhere}!sun!cmcmanis BIX: cmcmanis ARPAnet: cmcmanis@sun.com These opinions are my own and no one elses, but you knew that didn't you.
martens@tennis.cis.ohio-state.edu (Jeffrey Martens) (11/03/88)
In article <75804@sun.uucp> cmcmanis@sun.UUCP (Chuck McManis) writes: [ lots of stuff deleted ] >in the hashtable at the "wrong" place. See the usenet tutorial on the >file system. (Either Bob Page or Kim Devaughn did it) Then you can use [ more stuff deleted ] Usenet tutorial on the file system? Is this a tutorial on the Amiga file system? If so, how is it accessed? Thanks. --Jeff (martens@banjo.cis.ohio-state.edu)
page@swan.ulowell.edu (Bob Page) (11/04/88)
Chuck McManis: >usenet tutorial on the file system. (Either Bob Page or Kim Devaughn did it) Kim posted it - it was done by Dwayne Miller. I posted a long message on how to use Sectorama to delete a bad file header block. I'll include it here again. Jeffrey Martens replies: >Is this a tutorial on the Amiga file system? If so, how is it accessed? Here. Enjoy. (I have not read it and cannot vouch for its accuracy): You'll have to use an editor to break this into the two files. ..Bob --------------------------- (fs tutorial) --------------------------- [ "You really have to be brain-dead to microwave your cheese." ] I happened upon the attached last night on a local BBS, and think it's one of the best tutorials on the existing file system, etc. that I've seen! Not only does it pull together alot of information in one place, but it also provides practical info on how to *use* a sector editor utility (like Sectorama, etc.) effectively. A real nice job and alot of thanks to the author, Dwayne Miller! /kim # This is a shell archive. Remove anything before this line, then # unpack it by saving it in a file and typing "sh file". (Files # unpacked will be owned by you and have default permissions.) # # This archive contains: # disk.tutorial echo x - disk.tutorial cat > "disk.tutorial" << '//E*O*F disk.tutorial//' An Explanation of AmigaDOS Storage Device Structure In order for you to use a disk editor to its full disk-saving/disk-altering potential, you must first understand the structure of an AmigaDOS device. References will be made to a P.D. disk editor called 'Sectorama', though the basic information and principals presented in this doc will be applicable to all disk editors. Note that to avoid confusion and to provide immediately applicable info, the block formats presented in this doc are specifically for 512 byte blocks. For larger blocks, the size of the Hash Table will vary and all info after the hash table will be displaced ahead of the hash table so the secondary-type word is at the end of the block. All devices I know of to this point use a 512 byte block. This document is basically written in two parts. The first part is an explanation of what each word in each type of block, how various types of blocks are structured, and how all these blocks relate to one another on an AmigaDOS storage device. The second part is an explanation of how to do things with a disk editor such as sectorama. I) BLOCK BASICS ============ Generally, each block on an AmigaDOS device contains a checksum, a header key whose value is the disk address of the block, and a block type which tells you what type of block this is so you know what format that particular block uses. Note that when I use the term, 'block', I am referring to a 512 byte chunk of storage space on an AmigaDOS device. For example, on a floppy or hard drive, a block refers to a 512 byte sector. In VDO: and RAM:, a block refers to 512 contiguous bytes somewhere in memory. Also note that the size of each datum in a block is a 32 bit word. For all blocks, the first six words are as follows: +--------------------+ 0 | Block Type | +--------------------+ 1 | Header Key | +--------------------+ 2 | Number or count | +--------------------+ 3 | Table or Data size | +--------------------+ 4 | First or next data | +--------------------+ 5 | Checksum | +--------------------+ : : Block Type - This identifies the general size and structure of this block. It currently has one of three values: T.SHORT = 00000002 This indicates the block is at the head of a list (i.e. a HEADER BLOCK). T.LIST = 00000010 This indicates the block is a LIST BLOCK. A list block is a member of a linked list list blocks and contains a table of pointers to data blocks. T.DATA = 00000008 This indicates the block is a DATA BLOCK. A data block is simply a block that contains data and will be described later in this doc. Header Key - This 32-bit word is the device's address for this block. It is a pointer to this block. Number or Count - If this not a data block, this is a total count of data blocks (and, hence, the highest sequence number of any data block) pointed-to by this block. - If this block is a data block, this number is the sequence number of this data block. That is, it tells us this data block is the n'th member of a list of data blocks. Table or Data Size - This is a count of how many 32-bit words there are in the table or data starting at word # 6 in this block. First or Next Data - This is a pointer to the data block following this block. If this block is a header or a list block, then this pointer will point to the first data block in a list of data blocks. Checksum - When this number and the values of all other words in this block are added up, the sum must be zero. This is how bad blocks are detected by AmigaDOS. For all types of blocks excepting data blocks, the last four words have the following format: : : +----------------+ 7C | Hashchain | +----------------+ 7D | Parent | +----------------+ 7E | Extension | +----------------+ 7F | Secondary Type | +----------------+ Hashchain - points to the next entry on this hash chain. Parent - pointer to the parent directory. The parent directory is the directory block which either points to this block or points to a linked list (i.e. hash chain) of which this block is a member. Extension - pointer to the next extension block which essentially extends the table which starts at word # 6 of this block. Secondary Type - This exactly identifies what kind of block this is. This tells us exactly what function and structure this block has. The possible codes in this word are: ST.ROOT = 00000001 This identifies the ROOT BLOCK, which is the device's 'root directory'. This block ultimately points to all the files and directories on the storage device. ST.USERDIR = 00000002 This identifies a USER DIRECTORY BLOCK which points to all the files and directories which have been defined for this directory. ST.FILE = FFFFFFFD This identifies either a FILE HEADER BLOCK, if the block type at word # 1 is T.SHORT, or a FILE LIST BLOCK if the block type is T.LIST. A FILE HEADER BLOCK points to all the data blocks that make up the file. If there are too many data blocks to be pointed to by this block, a list of FILE LIST BLOCKS is pointed-to by the extension pointer at word # 7E. A FILE LIST BLOCK simply extends the table and points to the next FILE LIST BLOCK if more data block pointers are required. Note that the above-mentioned word definitions are not applicable to some block types and functions. Where their function is non-applicable, their value is usually set at zero. II) THE ROOT BLOCK ============== The block that ultimately points to everything on the disk is called the 'Root Block'. This block usually resides in the exact center of a storage device to minimize the distance a read/write head of a floppy or hard disk must move when travelling from an outer cylinder to the Root Block. The format of the Root Block is as follows: symbolic usual value value +----------------------+ 0 | T.SHORT = 00000002 | Indicates this is a 512 byte header block +----------------------+ 1 | 0 = 00000000 | Header Key (Always zero in a root block) +----------------------+ 2 | 0 = 00000000 | Highest sequence number in chain (0 for root) +----------------------+ 3 | HT SIZE = 00000048 | Hashtable size (=blocksize-56 = 512/4-56 words) +----------------------+ 4 | 0 = 00000000 | +----------------------+ 5 | CHECKSUM = ? | Checksum for this block ----+----------------------+ { 6 | | { | Hash Table | { to : : { : : { 4D | | ----+----------------------+ 4E | BMFLAG = FFFFFFFF | True (all F's) if device or disk bitmap valid ----+----------------------+ { 4F | | { | Bitmap Pages | { to : : { : : { 68 | | ----+----------------------+ 69 | DAYS = ? | Volume last altered date and time. +----------------------+ Date is in packed format. 6A | MINS = ? | Time is rated in minutes and ticks. +----------------------+ One tick is 1/60th of a second. 6B | TICKS = ? | ----+----------------------+ { 6C | | Volume name as a BCPL string of 30 characters { | Disk Name | or less, though the amount of space to store { to : : this string always remains the same size. { : : { 78 | | ----+----------------------+ 79 |CREATEDAYS = ? | Date and time when this volume was created. +----------------------+ Format here, as well as all date/time data 7A |CREATEMINS = ? | presented in other types of blocks are in the +----------------------+ format shown for the above volume last altered 7B |CREATETICKS= ? | date and time. +----------------------+ 7C | 0 = 00000000 | Next entry on this hash chain (0 for root) +----------------------+ 7D | 0 = 00000000 | Parent directory (always 0 for root) +----------------------+ 7E | 0 = 00000000 | Extension (always 0 for root) +----------------------+ 7F | ST.ROOT = 00000001 | Secondary type indicates this is a Root Block +----------------------+ -> What the heck is a HASH TABLE? A HASH TABLE is a table of pointers to files and to lists of files. To locate a particular file in the table, the name of the file is used to calculate where in the table it is to be located. This location may not be unique to the name of this file. In this case, the pointer will point to a linked list of file headers which must be traversed until the file header for the file we're searching for is found. This linked list is referred to as a HASH CHAIN. The actual searching-out of files will be discussed in more practical terms in the practical portion of this document. -> What things are pointed-to by pointers in a HASH TABLE? Each non-zero pointers in the hash table points to either a FILE HEADER BLOCK or a USER DIRECTORY BLOCK which, in turn, may have a hash chain pointer which will point to the next file header block or user directory block in the hash chain. -> What are bitmap pages? The words in the list of bitmap pages point to 512 byte blocks which simply map-out which blocks on the device are used, and which are free for usage. I don't yet understand how the bitmaps are set-up or maintained, but as soon as I find out, I'll slip the info into this document. -> What is a BCPL string? This is a string of bytes where the first byte indicates the number of characters in the string (say, 'n' characters), the next 'n' characters contain the ASCII values for the string, and the rest of the string is ignored. For example, on my Workbench disk, a hex dump of the string looks like this: 09576F72 6B62656E 63686F72 6B62656E .Workbenchorkben 63680000 00000000 00000000 00000000 ch.............. 00000000 00000000 ........ Where the 09 at the beginning specifies that only the next nine characters are valid characters of the string and the rest are ignored. Note that for the root block, zeros are always in the Header Key, Sequence Number, Hash cain, Parent, and Extension fields. This is because a ROOT BLOCK is always at a specific spot on the device (for a disk, it is exactly cenetered between the outer- and inner-most cylinders), it never require hash table extensions, it is not pointed-to by a hash table and is not part of a hash list, and it does not have a parent directory. III) USER DIRECTORY BLOCKS ===================== A user directory block is created when a new directory is made in a storage device. It contains its own name and protection status, its parent directory, as well as a hash table pointing to files and user directories that have been placed into this directory. The hash table functions exactly the same way as that in the ROOT BLOCK. The format of a USER DIRECTORY BLOCK is as follows: symbolic usual value value +----------------------+ 0 | T.SHORT = 00000002 | Indicates this is a 512 byte header block +----------------------+ 1 | OWN KEY = ? | Header Key (pointer to this very block) +----------------------+ 2 | 0 = 00000000 | Highest sequence number in chain (always zero) +----------------------+ 3 | 0 = 00000000 | +----------------------+ 4 | 0 = 00000000 | +----------------------+ 5 | CHECKSUM = ? | Checksum for this block ----+----------------------+ { 6 | | { | Hash Table | { to : : { : : { 4D | | ----+----------------------+ 4E | SPARE = 00000000 | 4F | SPARE = 00000000 | +----------------------+ 50 | PROTECT = ? | Protection bits (Read/Write/Execute/Delete) +----------------------+ 51 | 0 = 00000000 | Unused (always zero) ----+----------------------+ { 52 | | { | COMMENT | Stored as a BCPL string { to : : (up to 90 characters) { : : { 68 | | ----+----------------------+ 69 | DAYS = ? | Directory creation date and time. +----------------------+ 6A | MINS = ? | +----------------------+ 6B | TICKS = ? | ----+----------------------+ { 6C | | { | Directory Name | Directory name as a BCPL { to : : (up to 30 characters) { : : { 7B | | ----+----------------------+ 7C |HASHCHAIN = ? | Next entry with same hash value +----------------------+ 7D | PARENT = ? | Back pointer to parent directory +----------------------+ 7E | 0 = 00000000 | Extension (always 0 for root) +----------------------+ 7F | ST.ROOT = 00000002 | Secondary type indicates this is a Root Block +----------------------+ IV) FILE HEADER BLOCK ================= This block is the first block of any given file. It contains file information such as the name, size, protection status, creation date, and a pointer to the parent directory block of the file. It also contains a table of pointers to all the data blocks that make up the file. If there are more data blocks than there are pointers in the table of data block pointers (at words # 6 to 4D), an extension pointer is provided to a FILE LIST BLOCK which contains a similar table of data block pointers. If the file list block still doesn't provide enough pointers, it will provide yet another extension pointer to another FILE LIST BLOCK. This list of FILE LIST BLOCKS extends until enough pointers are provided to point to all the data blocks of the file. symbolic usual value value +----------------------+ 0 | T.SHORT = 00000002 | Indicates this is a 512 byte header block +----------------------+ 1 | OWN KEY = ? | Header Key (pointer to this very block) +----------------------+ 2 |HIGHEST SEQ= ? | Number of data blocks pointed-to by this block +----------------------+ 3 |DATA SIZE = ? | +----------------------+ 4 |FIRST DATA = ? | Pointer to the first data block of the file +----------------------+ 5 | CHECKSUM = ? | Checksum for this block ----+----------------------+ { 6 | : | { : : : List of pointers to data blocks { to : : : (i.e. Data block keys) { | DATA BLOCK 3 | { | DATA BLOCK 2 | { 4D | DATA BLOCK 1 | ----+----------------------+ 4E | SPARE = 00000000 | 4F | SPARE = 00000000 | +----------------------+ 50 | PROTECT = ? | Protection bits (Read/Write/Execute/Delete) +----------------------+ 51 | BYTESIZE = ? | Total size of file in bytes ----+----------------------+ { 52 | | { | COMMENT | Stored as a BCPL string { to : : (up to 90 characters) { : : { 68 | | ----+----------------------+ 69 | DAYS = ? | File creation date and time. +----------------------+ 6A | MINS = ? | +----------------------+ 6B | TICKS = ? | ----+----------------------+ { 6C | | { | File Name | File name as a BCPL string { to : : (up to 30 characters) { : : { 7B | | ----+----------------------+ 7C |HASHCHAIN = ? | Next entry with same hash value +----------------------+ 7D | PARENT = ? | Back pointer to parent directory +----------------------+ 7E |EXTENSION = ? | Pointer to a FILE LIST BLOCK (if required) +----------------------+ 7F | ST.ROOT = FFFFFFFD | Secondary type indicates this is a Root Block +----------------------+ V) FILE LIST BLOCK =============== This type of block is used to extend the table of data block keys (pointers) of a FILE HEADER BLOCK when the table in the FILE HEADER BLOCK hasn't enough pointers to point to all the file's data blocks. If a FILE LIST BLOCK doesn't have enough pointers to point to the rest of the file's data blocks, the EXTENSION pointer of the block will point to yet another FILE LIST BLOCK. The extension list continues until enough pointers are provided for all the data blocks in the file. symbolic usual value value +----------------------+ 0 | T.LIST = 00000010 | Indicates this is a file list block +----------------------+ 1 | OWN KEY = ? | Header Key (pointer to this very block) +----------------------+ 2 |BLOCK COUNT= ? | Number of data blocks pointed-to by this block +----------------------+ 3 |DATA SIZE = 00000000 | +----------------------+ 4 |FIRST DATA = ? | Pointer to the first data block of the file +----------------------+ 5 | CHECKSUM = ? | Checksum for this block ----+----------------------+ { 6 | : | { : : : Extended list of pointers to data blocks { to : : : (i.e. Data block keys) { | DATA BLOCK 3 | { | DATA BLOCK 2 | { 4D | DATA BLOCK 1 | ----+----------------------+ { 4E | | { | unused | unused (all zeros) { to : : { : : { 7B | | ----+----------------------+ 7C | 0 = 00000000 | Next in hash list (always zero for list block) +----------------------+ 7D | PARENT = ? | Points to the file header block of this file +----------------------+ 7E |EXTENSION = ? | Points to the next FILE LIST BLOCK (if required) +----------------------+ 7F | ST.ROOT = FFFFFFFD | Secondary type indicates this is a Root Block +----------------------+ VI) DATA BLOCK ========== A data block contains data from a file and is pointed-to by preceding data blocks and by a pointer in a table in either a FILE HEADER BLOCK or a FILE LIST BLOCK. Thus, the data block can be accessed directly from a header or list block of a file, or sequentially by following the linked list of data blocks. Each data block also points to the FILE HEADER BLOCK which describes the file which contains this data block. A sequence number is also present in a data block, and indicates that this data block is the n'th data block in the list of the file's data blocks. symbolic usual value value +----------------------+ 0 | T.DATA = 00000008 | Indicates this is a data block +----------------------+ 1 | HEADER = ? | Header key pointing to the file header block. +----------------------+ 2 | SEQ NUM = ? | Sequence number +----------------------+ 3 | DATA SIZE = 00000000 | Number of words of data in this block +----------------------+ 4 | NEXT DATA = ? | Pointer to the next data block +----------------------+ 5 | CHECKSUM = ? | Checksum for this block ----+----------------------+ { 6 | | { | DATA | { to : : { : : { 7F | | +----------------------+ VII) HOW DO THE BLOCKS FIT TOGETHER? =============================== The ROOT BLOCK is located at a fixed location, exactly between the highest and lowest addresses available on a storage device. The ROOT BLOCK contains a table of pointers (the hash table) to linked lists (hash chains) of USER DIRECTORY BLOCKS and FILE HEADER BLOCKS which describe user directories and files accessible from the root directory. A USER DIRECTORY BLOCK contains the name and protection status of a user directory, as well as a hash table containing pointers to hash chains of USER DIRECTORY BLOCKS and FILE HEADER BLOCKS which describe user directories and files accessible from that user directory. Since the USER DIRECTORY itself is a member of a hash chain, it also contains pointers to its parent directory block and to the next USER DIRECTORY BLOCK or FILE HEADER BLOCK in the header chain. A FILE HEADER BLOCK contains information describing the file it represents, as well as a table of pointers to DATA BLOCKS that make up the file. If there aren't enough pointers in this table to point to all the file's DATA BLOCKS, an EXTENSION pointer points to a list of FILE LIST BLOCKS which extend the table. Since the FILE HEADER BLOCK is a member of a hash chain, it contains pointers to its parent directory and to the next USER DIRECTORY BLOCK or FILE HEADER BLOCK in the header chain. A FILE LIST BLOCK contains a table of pointers to DATA BLOCKS and extends the table of the FILE HEADER BLOCK or FILE LIST BLOCK which points to this FILE LIST BLOCK. If there aren't enough pointers in this table to point to the remainder of the file's DATA BLOCKS, an EXTENSION pointer in the FILE LIST BLOCK points to the next FILE LIST BLOCK to extend its data block table. A DATA BLOCK's main content is data. It is part of a linked list of DATA BLOCKS and includes a pointer to the next DATA BLOCK in the list. It also includes a sequence number indicating that this DATA BLOCK is the n'th DATA BLOCK in the list. Each DATA BLOCK is pointed-to both by the preceding DATA BLOCK in the list, and by a pointer in a data block table in either a FILE HEADER BLOCK or a FILE LIST BLOCK. Each DATA BLOCK also contains a pointer to the FILE HEADER BLOCK which describes the file which the DATA BLOCK is a member of. Confused? Don't worry, practical stuff is coming up next... VIII) UNDERSTANDING YOUR DISK EDITOR ============================== Before we begin playing with a disk editor, I recommend that you create a backup of a densely populated disk, like your workbench, so that if a wrong key is pressed while looking through the backup, you haven't done damage to your one and only copy. a) A Look at Sectorama =================== For those of you lucky enough to have a copy of sectorama handy, fire it up and I can explain what all those obscure thingies on the right side and of the top line of the screen mean and where, from the block you are looking at, the information was taken. The lower right hand portion of the display identifies the storage device currently being examined by this sectorama display. It gives us the device name (as a volume name), the device unit number, and the filename of the device driver that communicates with the device. The display section immediately above this info contains hardware- dependant information. The middle column shows us the the sector, track cylinder, surface, and block numbers of the block currently being displayed. This information is all given in decimal values. All these statistics are all determined by a set of info used by the device driver. For a floppy, for example, it these tell us on which cylinder the read/write head is currently positioned over, which sector on which surface (top or bottom) is being read by the read/write head, and the hardware-specific track and block numbers for that sector. The rightmost column are device statistics. These tell us how many of each category there are on this device. Note that by pointing at any of the figures in the center column of this section, you can change the current values. By changing sector, surface, or block number, you can examine any sector of the device immediately. The section immediately above the hardware information contains information about (and from) the block currently being displayed: Date -refers to the creation date which is taken from word # 69. Time -is calculated from words # 6A (to get hours and minutes) and # 6B (to get seconds). Highest Seq # -is taken from word # 2 and refers to the number of words used in the table starting at word # 6. Data Size -refers to the size of the table at word # 6. Protect -refers to the protection status of a user directory block or a file header block and is taken from the value at word # 50 File Bytes -refers to the size of a file in kilobytes. This value is 1/1000'th the value of word # 51. The section at the upper right corner of the display is a list of keyboard commands with current values beside them. All except the checksum are pointers to other blocks in the device. The checksum is the current block's checksum value taken from word # 5. This value must be recalculated every time you make an alteration to a block. The pointers shown beside each command are as follows: R-Go Root -points to the root directory of this disk. This pointer is a constant value which has been calculate for this storage device. P-Go Parent -points to a FILE HEADER BLOCK's or USER DIRECTORY BLOCK's parent directory block. This pointer is taken from word # 7D. C-Go Hash Chain -points to the next FILE HEADER BLOCK or USER DIRECTORY BLOCK in this blocks hash chain. This pointer is taken from word # 7C. X-Go Extension -points to the next FILE LIST BLOCK in an extension chain. This pointer is taken from word # 7E. H-Go Header -for DATA BLOCKS, this points to the FILE HEADER BLOCK to which this DATA BLOCK belongs. -for other blocks, this points to the block currently being examined. -in both cases, this pointer is taken from word # 1. For all the above commands, if you type the letter to initiate the command, sectorama will jump to the block corresponding to the pointer displayed beside the command. At the top of the display are three more information displays. On the left is the block number of the block currently being displayed. Next to that is the Type of the block being displayed. The block type is determined by word # 0, which contains the block type, and word # 7F, which contains the secondary type. Next to the block type is the Name of the block. This name may be a volume name or a directory name or a file name, depending on if this block is a ROOT BLOCK, a USER DIRECTORY BLOCK, or a FILE HEADER BLOCK, respectively. b) Sectorama commands ================== All the sectorama commands are adequately described in the documentation file that accompanies it. c) A Practical Session =================== i) Touring a floppy, a summary --------------------------- I suggest that as you progress through this little step-by-step blathering that each time you come across a new type of block, you compare the data being displayed by sectorama to the block descriptions shown above so that you become more familiar about where things are located in each type of block. The steps for performing the operations summarized below with Sectorama are described in detail, with a running commentary, in section ii) Touring a floppy with Sectorama. For following these steps with any other disk editor, I suggest that you quickly read through the Sectorama tour to familiarize yourself with what is being attempted, then attempt the summarized steps below to familiarize yourself with your disk editor and AmigaDOS. Steps 1 thru 8 will guide you from a disk's ROOT BLOCK, into a file and through all the data blocks in that file. A quick summary of these steps is as follows: Steps 9 thru 14 show you how to alter a block and write it to disk. _A step-by-step of the tour, in summary is as follows: / 1. Run the disk editor. | | 1a. (Load the root block. This is done automatically by Sectorama.) | | 2. Locate the 'c' directory by using the hash function. Part< 3. Load the USER DIRECTORY BLOCK for the c directory. 1a | 4. Locate the 'dir' command file by using the hash function. | 5. Load the FILE HEADER BLOCK for the 'dir' file. | 6. Load the first DATA BLOCK of the 'dir' file. | 7. Load and examine each consecutive DATA BLOCK of the 'dir' file until | the last DATA BLOCK in the file has been loaded and examined. \_8. Load the FILE HEADER BLOCK pointed-to by the final DATA BLOCK. _ / 9. Locate and select the first word in the comment filed of the FILE | HEADER BLOCK for the 'dir' file. | 10. Edit the ASCII values of the comment field. Part< 11. Edit the hexadecimal value of the first byte of the first word of 1b | the comment field to insert the string length of the comment | created in step 10. | 12. Re-calculate the checksum for this block. | 13. Write the altered block to disk. \_14. Quit the disk editor. ii) Touring a floppy with Sectorama... ---------------------------------- 1. O.K., get your disk editor up and running (if it isn't already) and begin examining a back-up copy of your workbench disk. For sectorama, the CLI command line for this if the disk was in df0: would look like: 1> run sec df0: What you will see on your display (in neato-keen hi-res) is data of the ROOT BLOCK of df0:. On top of the display is 'Type=ROOT DIR' which indicates that the block currently being displayed is a ROOT BLOCK. 2. Now that we are at the ROOT BLOCK, lets find the c directory. The first step for this is to find out what value we get when we use the hash function on the string 'c'. To do this you must envoke the hash function by picking 'COMPUTE HASH VALUE' under the SEARCH menu, then typing the file or directory name, in this case the letter c followed by a <RETURN>. This highlights the block address of the hash chain which contains the c directory. 3. Now that you've found the possible whereabouts of the c directory jump to it by hitting the j key. If (more likely than not) on top of the display is 'Name=c' then the display is currently displaying the contents of the c directory and the top of the display has 'Type=DIRECTORY' indicating that what is being displayed is a USER DIRECTORY BLOCK, which is essentially the c directory of df0:. 4. Now that we're at the c directory, let's look at a file containing loadable/executable code for a well-known function... say, the file called 'dir'. Envoke the hash function as before using the string dir. The block address of the hash chain that contains the dir file will be highlighted. 5. Press the j key to jump to the beginning of the hash chain which will have (again, more likely than not) 'Type=FILE Name=dir' displayed above the table of block data. The Type=FILE indicates that this is the header block for the file indicated by Name=dir. This is a fairly short file, so that all the block addresses for the DATA BLOCKS for this file are included in this block and that no extension blocks are required for this file, which is why the block address beside 'X-Go Extension=' is 00000000. Also notice that the block address beside 'D-Go Next Data' is the same as the last entry in the data table of this block (at word # 4D according to my version of dir). This is because data blocks are arranged in this table starting at the end of the table and working towards the beginning. 6. Let's take a look at the first DATA BLOCK, then, by hitting the d key to 'Go Next Data'. What will be displayed is the first DATA BLOCK of the dir file. On top of the display will be 'Type=DATA BLOCK' confirming that fact. Note that word # 04, which has the same value as is displayed beside D-Go Next Data =, points to the next DATA BLOCK for this file. 7. Let's traverse the entire list of DATA BLOCKS to see what the last one in the list looks like. You can do this by hitting the D key about 16 times or so. While you do this, note that the value beside H-Go Header = stays constant for each data block while all the other values remain constant. The value beside H-Go Header = points to the FILE HEADER BLOCK which owns the DATA BLOCK. If this ever changes as you are traversing a list of DATA BLOCKS, you KNOW there is a problem with the file. Also note that as you jump from block to block, the HISTORY list at the bottom of the display keeps track of your last eight jumps. This is a valuable feature when you overshoot a problem area and need to know where you've been in previous jumps. Also note that for each successive DATA BLOCK that you display, the sequence number displayed in the middle of the right part of the screen is incremented by one. This helps you figure out exactly where you are in the file you are looking through. If ever this sequence number jumps up or down by more that one, you know the DATA BLOCK is out of its proper sequence. 8. Once you've reach the end of the DATA BLOCK list, you will find that hitting the D key will now only cause the display to flash, indicating that this is indeed the end of the DATA BLOCK list for this file. Lets jump back to the FILE HEADER BLOCK for the 'dir' file by hitting the h key (for H-Go Header). 9. Now that we've jumped around the disk doing some block reading, let's get more adventurous. Let's modify a block on the disk. By comparing the FILE HEADER BLOCK description above, we note that the comment field in this block begins at word # 52 and ends at word # 68. Move your pointer to word # 52 and click your left mouse button to highlight it. 10. Next, press the A key to enter ASCII edit mode (the command list on the right of the display describes it as Edir ASCII). Now type a space and then some sort of short comment, being careful not to type past word #68. For example, I typed the comment ' dir, oh dir' beginning in word #52. Note that the delete key and backspace key do not work normally in this mode, and actually produce their own special ascii values. To re-type something, you must either move your pointer to the desired location and click, or use your cursor keys to move the highlighter to the desired character, then type your correction. To exit this edit mode, simply hit <RETURN>. 11. To make our comment a proper BCPL string, we must put a character count at word # 52. Count how many characters there are in your string and convert this number to hexadecimal. Next, enter the hexadecimal edit mode by hitting the e key (for Edit), type your two-digit hexadecimal value and hit return. For example, in my 'dir, oh dir' comment there are eleven characters. Eleven converts to 0B in hexadecimal, so I edit word #52, type 0B, and hit return. 12. Since we've altered the contents of this block, the checksum for this block is no longer valid. We must hit the k key to calculate a new checksum. When you have done this, you will note that the value beside K-Checksum = and at word # 05 have changed to the newly calculated checksum. 13. Note that any changes you have made so far haven't been written to disk at all. Nothing is ever written to disk until you actually write it by hitting the u key to 'Update block'. To incorporate your new file comment for the file called 'dir', hit the u key. 14. Then quit Sectorama, and list df0:c/dir to see the change that you've just made. Note that you may have to list the whole c directory to see the change since AmigaDOS keeps track of which sectors of which device it currently has in buffers, and will avoid fetching your modified sector if it is currently in df0:'s buffer. What we've just done is to examine a disk, seek-out a specific file, look through the file's data, then modify the FILE HEADER BLOCK of that file. What we haven't seen yet are two important data structures which we will look for now. Specifically, these structures are the hash chain, and the file list. 1. to 3. Same as steps 1. to 3. above. (Locate & load the c directory) 4. Now calculate the hash value for Echo using the Calculate Hash Value function. Write the highlighted number down. 5. Calculate the hash value for Quit using the same hash function used in step 4. 6. Calculate the hash value for Why using the hash function. You will find that the value you have written down for the value calculated for Why, Quit, and Echo are all identical, implying that if you jump to this number, you will have access to all three files. What this really means is that the FILE HEADER BLOCKS of these three files are members of the same hash chain. 7. Jump to the first file in the hash chain by hitting the j key. I cannot say exactly which FILE HEADER BLOCK you will be shown, since that depends on in what order the files in the chain were created on this disk. Note that the value beside P-Go Parent = is that of the USER DIRECTORY BLOCK of the directory containing this file, namely the c directory. 8. Note that the block address beside C-Go Hash Chain = is non-zero. At least, if the files Echo, Quit, and Why are in the c directory on this disk, the value will be non-zero. Otherwise, this demonstration will not be successful. To display the header of the next file or directory in this hash chain, hit the c key (indicated by C-Go Hash Chain). 9. Note that the value beside P-Go Parent hasn't changed. This is because all members of a hash chain always belong to the same directory. To traverse the hash chain and find the last FILE HEADER BLOCK or USER DIRECTORY BLOCK in the chain, keep hitting the c key until the value beside C-Go Hash Chain becomes zero. When this happens, further presses of the c key will merely cause the display to flash, indicating you are at the end of the hash chain. 10. Jump back to the ROOT BLOCK by hitting the r key. To find what an extension file looks like, we must look for a large file... one where the amount of data is large enough that more pointers are available in a FILE HEADER BLOCK's DATA BLOCK pointer table. A DATA BLOCK pointer table usually has 72 available entries. Since each BLOCK is 512 bytes long, we need a file that is over 72 x 512 = 36864 bytes long. The Preferences file is about twice that length, so let's take a look at it. 11. Calculate the hash value for Preferences using the hash function. 12. Jump to the FILE HEADER BLOCK for the Preferences file by hitting the j key. You will note that all the entries in the DATA BLOCK pointer table in this FILE HEADER BLOCK are used-up. You will find the rest of the pointers required to point to the rest of the DATA BLOCKS for this file in the file list. The block number of the first FILE LIST BLOCK in the file list is shown beside X-Go Extension. 13. Hit the x key to jump to the first FILE LIST BLOCK. Note that the block number displayed beside P-Go Parent is the same as the block number of the FILE HEADER BLOCK to which this FILE LIST BLOCK belongs. Also note that the value beside X-Go Extension is now zero. If the required even more DATA BLOCKS, that is, if the file was longer than about 73kbytes, the value beside X-Go Extension would point to the next FILE LIST BLOCK in the file list. So, that pretty well wraps-up the tour. We've seen all the data structures used by AmigaDOS and have had a chance to modify a block. There are a number of implications of AmigaDOS structure that this document hasn't covered, but these things will become apparent as you are given the opportunity to apply the disk editor. I hope the information forwarded by this document will help you solve or at least understand problems that may occur from time to time when storing things on AmigaDOS compatible devices. A Trouble-shooting Example -------------------------- This information was recently invaluable to me as I discovered a problem with my hard drive recently that could have blossomed into a fairly major disaster. A file was written on top of another file. I kept getting a read/write error when I tried to copy the over-written file to another device. So, I examined the hard drive with Sectorama. I used the hash function to locate which hash chain the file was stored under, traversed the hash chain until I found the file header block of the file in question. I then traversed the list of data blocks for the file by hitting the d key repeatedly. The list seemed to be intact since I was able to follow the list to its last block. I then hit the h key to display the file header block again. It was the file header block of an entirely different file! So, I jump back to the root, jumped to the file I was originally investigating, and again traversed the data block list while watching the value beside H-Go Header for any changes. About half-way through the file the value changed. I noted the block number of that data block, hit the h key to jump to the wrong file header block again, and noted that the block number of the erroneous data block was listed. I went back to the root block and back to the original file header block and found that the same erroneous data block was listed here, too. I checked all the files on the hard disk, and found that only one file was unreadable. Thus, that file had been overwritten. This implied that somehow the bitmap of the disk was erroneous since the data block used by the file was claimed by another file. I had to backup-up new files, format the hard drive to prevent further calamity, and copy back all the files. That cured the whole problem. I had a directory problem a while ago that I now know how to fix recover from with a disk editor. The directory of a device wrapped around so that when I executed a list command, I got an endless repetition of the same files, while other files on the disk would never be listed. When I listed the ignored files by naming them directly, they would show up. If I executed a dir command, the storage device was searched and searched and searched until the computer crashed. I believe that is due to dir's method of collecting all files in a directory for sorting until the end of the directory is reached, which, in this case, it never did. Solving this is a matter of copying all files possible to another device. This means individually copying all the files since wildcards cause a directory search which, in this case, would never end. The files you cannot see can be searched-out with Sectorama using wildcards since Sectorama provides full-disk searches without consulting a directory. After finding and copying all your files to another device, I'd recommend formatting the device to remove anything that might cause a relapse of the problem. If you have any corrections, comments, or suggestions about the above document, please send them to me or tell me about them. You can reach me at: // \X/ Tesseract BBS (306)757-5699 (24 hours, 8N1, 300 or 1200 baud) address: Dwayne Miller 770 Robinson Street Regina, Saskatchewan, Canada (Yup, way up there!) S4T 2M1 voice: (306)525-1652 P.S. Sectorama was written by David Joiner of MicroIllusions and is commonly available, often named 'sec.arc' or 'sector.arc' or 'sectoram.arc' etc. //E*O*F disk.tutorial// echo Possible errors detected by \'wc\' [hopefully none]: temp=/tmp/shar$$ trap "rm -f $temp; exit" 0 1 2 3 15 cat > $temp <<\!!! 973 7291 46762 disk.tutorial !!! wc disk.tutorial | sed 's=[^ ]*/==' | diff -bw $temp - exit 0 -- UUCP: kim@amdahl.amdahl.com or: {sun,decwrl,hplabs,pyramid,ihnp4,uunet,oliveb,cbosgd,ames}!amdahl!kim DDD: 408-746-8462 USPS: Amdahl Corp. M/S 249, 1250 E. Arques Av, Sunnyvale, CA 94086 CIS: 76535,25 ---------------- (how to delete a file with sectorama) -------------------- [Note DiskDoctor knows about FFS in release 1.3 and is less cavalier about tossing good files. ..Bob] From: page@swan.ulowell.edu (Bob Page) Newsgroups: comp.sys.amiga Subject: Re: Help! my hard disk won't validate Summary: How to delete a file with Sectorama -- clip and save Message-ID: <8525@swan.ulowell.edu> Date: 10 Aug 88 16:11:41 GMT References: <3661@louie.udel.EDU> Reply-To: page@swan.ulowell.edu (Bob Page) Organization: University of Lowell, Computer Science Dept. Lines: 99 hoge%afsc02.decnet@hqafsc-vax.arpa (AFSC02::HOGE) wrote: >We'll now I've got a bad file on the drive and it won't validate. Don't use DiskDoctor, I don't think it yet knows about the fast file system. In any case, it's not too smart and takes too much memory (like 2MB to deal with a 20MB hard disk). The best way to do fix your drive is to back up the disk and restore it. Failing that, here is the canonical method for using Sectorama to delete a file. This works with both old and fast file systems. 0. Get Sectorama, on fish disk 102, or via ftp on swan.ulowell.edu in amiga/dos/fs/sectorama.1of1 (you'll need to uudecode it). You need to have the topaz11 font (delivered with WB1.2) in your fonts: directory. v 1. Type 'sec dh0:' (or whatever the device name is of your partition). You should see the Root block of the partition. 2. Type right-amiga h to hash a file. In the string requester (which you have to click on) type the name of the directory closest to the root that holds the file, file and hit return. (for example, if your file was in dh0:work/book/chapter1/sec4, type 'work' without the quotes.) The case is important! The highlighted part of the screen should move to a place on the screen. If the numbers are '00000000' you did something wrong, try it again. 3. Type 'j' to jump to that disk block. If the name of the directory (look at the top of the screen) is not right, type 'h' to follow the hash chain until you get the right name. If you hit the end of the chain and didn't find the directory, you messed up somehow. Type 'r' (go to Root block) and start over at #2. 4. Follow the directions in #2-3, continuing down the directory path, one level at a time until you are in the directory ABOVE where the bad file is. Write down this block number. It's in hex; you may need to convert it to decimal later. 5. Now use #2 to find the start of the file (also called the file header). If you have to type 'h' to follow a hash chain, write down each block number you visit. Here are three possibilities you have: example 1 example 2 example 3 chapter1 chapter1 chapter1 | | | | | | V V V foo --> bar --> sec1.1 sec1.1 foo --> sec1.1 --> bar (end of hash chain) (no hash chain) (middle of hash chain) 6. You should now be at the file header block. Look in the 'Next Hash Block' field. If there's a non-zero number there, there are blocks in the hash chain after your block (example 3); write this number down. If the number is zero and you didn't follow a hash chain to get to the file header block, we're looking at example 2. Otherwise we're using example 1. 7. Now go back to the LAST block you wrote down (not the 'hash' value you wrote down in step 6) (click the mouse pointer in the top left of the screen, where it tells you what the block number is, then type the number of the block in decimal). 7.1 If you're now looking at a directory block (example 2 or 3): hash the filename (right-amiga h) once again, but don't 'j' there. 7.2 If you're looking at a file header block (example 1 or 3): find (by inspection) the 'next hash chain block' somewhere in the 'playing field' on the left (not the info on the right). It's near the bottom of the screen. Click there but don't 'j' there. Edit the highlighted field and write in the hex block number you wrote down in step 6, even if it was all zeros. 8. Now type 'k' to update the block's checksum, then 'U' to Update the block on disk (it must be upper case). You can write to the disk even though DOS can't because Sectorama is talking to the device driver, not to the DOS file system. I always type 'U' twice, just to make sure. 9. Exit sectorama (use the menu option), then type: DiskChange dh0: (this assumes you have DiskChange around someplace, it comes with WB1.2) to start the re-validation. Commodore utilities assume all disk devices will support the trackdisk.device non-standard commands (but not the extended commands) although this has never been documented anyplace. Let's hope your driver supports them. After a while your disk should complete validation. If it doesn't, you either did something wrong or there are more problems that you didn't fix. DISCLAIMER: This isn't a primer on the file system (you'll have to wait for my book :-)), and doesn't tell you what you're doing, just how to do it. All this does is help you locate a file and unlink it from its parent directory, effectively deleting it. I typed this from memory; I don't have an Amiga handy, so use this information at your own risk. I'd be interested in any comments you have. ..Bob -- Bob Page, U of Lowell CS Dept. page@swan.ulowell.edu ulowell!page "What a wonder is USENET; such wholesale production of conjecture from such a trifling investment in fact." -- Carl S. Gutekunst -- Bob Page, U of Lowell CS Dept. page@swan.ulowell.edu ulowell!page Have five nice days.
tlm@pur-phy (Timothy Lee Meisenheimer) (11/04/88)
Speaking of fixing up corrupted disks..... Is there something I'm missing when using the lasted version of Sectorama? I can repare the block etc. but when I tell it to write out to disk nothing is changed! I'll reread the block and it has the same garbage it used to have. I finally gave up and reformatted as there wasn't anything crucial on it. But for the future and for scoping out the file system I'd like to know how to change some bytes in the blocks. tlm@newton.physics.purdue.edu