Project 2 Preliminary Documentation 1. Introduction Design and implement a simple file system using the disk driver from previous project. I/O system interface – provided by my driver project: read_block(int i, char *p) write_block(int i, char *p). FS can access the emulated disk using only these functions. Also, develop test/presentation shell 2. Data Structures I’ve used a double array for Descriptor: DES[index][n]; and for OFT table, I use array, which looks like this: OFT[j] (this gives us the oft entry at index j. then, for bitmap, I use an arrary of two integer, as what professor suggested. 3. System Architecture What are the main functions? create(symbolic_file_name): return ok/error destroy(symbolic_file_name) : return ok/error open(symbolic_file_name): return index close(index): return ok/error read(index, mem_area, count): return #bytes read write(index, mem_area, count): return #bytes written lseek(index, pos) : return ok/error directory: return ok/error findnewblock: return index of new block or error What is the calling hierarchy? create calls lseek, write, read destroy calls lseek, write, read open calls lseek, read write calls find new block 4. Test Cases The tests of the file system will assume the following sizes of the disk and the internal data structures: Disk: 4 cylinders, 2 surfaces, 8 sectors/track, 64 Bytes/sector File name: maximum of 4 characters, no extension Number of files: not more than 10 Number of open files: 3 plus the directory, i.e., the size of the OFT is exactly 4 entries. (The directory should be opened automatically when the file system starts and remain open until the file system is shut down.). I’ll use the test cases provided first to test my design. If my program reads the following input file: in 4 2 8 64 disk cr foo op foo wr 1 x 60 wr 1 y 10 sk 1 55 rd 1 10 cl 1 dr in 4 2 8 64 disk op foo q it should produce a file that looks something like this: output Warning: disk does not exist, initialized to blank file foo created file foo opened, index=1 60 bytes written 10 bytes written current position is 55 10 bytes read: xxxxxyyyyy file 1 closed files: foo 70 Warning: disk does not exist, initialized to blank error: file foo does not exist program terminated 5. Pseudo Code (for preliminary documentation) Create(int file_name): int DesIndex = 1; char memory[100]; /* find a free file Descriptor between DES[1] to DES[23] */ while (true) do if DesIndex is 24 then return ERROR: NO FREE FILE DESCRIPTOR; end if; if DES[DesIndex][0] is negative then Des[DesIndex][0] = 0; /* set length of file to 0 */ break; end if; DesIndex++; end while; /* start reading from OFT[0] 4 bytes at a time into memory */ /* Directory is already in OFT, so we don’t need to open it */ /* check if there already exits a file with file_name */ lseek(0, 0); while (OFT[0].currentPos< OFT[0].length) do read(0, m, 4); if m is file_name then return ERROR:FILE ALREADY EXITS; end while; /* find an empty directory entry */ lseek(0, 0); while (OFT[0].currentPos< OFT[0].length) do read(0, m, 4) if m is EMPTY AND m%2 is 0 then /* first int of the pair */ lseek(0, OFT[0].currentPos-4); write(0, file_name, 4); write(0, DesIndex, 4); return OK; end if; end while; return ERROR: NO EMPTY DIRECTORY ENTRY; end Create; Destroy (int file_name): int fname; int dIndex; boolean fdFound = false; /* find index of file descriptor of file_name and remove dir entry*/ lseek(0, 0); while (OFT[0].currentPos< OFT[0].length) do read(0, (char*)fname, 4); if fname is file_name and OFT[0].currentPos%2=0 then read(0, (char*)dIndex, 4); /* get the file descriptr index */ lseek(0, OFT[0].currentPos-8); write(0, EMPTY, 4); /* remove directory entry */ write(0, EMPTY, 4); /* remove directory entry */ fdFound = true; break while; end if; end while; if fdFound is false then return ERROR: NO FILE DIRECTORY FOUND; /* update bit map */ totalBlock = DES[dIndex][0] / 64 bytes + 2; blockNumInDF = 1; while blockNumInFD <= totalBlock do BitMapNum = DES[dIndex][blockNumInFD] / 64 BitMapOffset = DES[dIndex][blockNumInFD] % 64 BM[BitMapNum] = BM[BitMapNum] & MASK2[BitMapOffset] end while; /* free file descriptor */ Des[dIndex][1] = EMPTY; Des[dIndex][2] = EMPTY; Des[dIndex][3] = EMPTY; return OK; end Destroy; Open (int file_name): int fname; int dIndex; boolean fdFound = false; /* search directory to find index of file descriptor of file_name */ lseek(0, 0); while (OFT[0].currentPos< OFT[0].length) do read(0, (char*)fname, 4); if fname is file_name and OFT[0].currentPos%2=0 then read(0, (char*)dIndex, 4); /* get the file descriptr index */ fdFound = true; break while; end if; end while; if fdFound is false then return ERROR: NO FILE DIRECTORY FOUND; /* allocate and update a free OFT entry */ oftIndex = 1; while (true) do if oftIndex is 4 then return ERROR: NO FREE OFT ENTRY end if; if OFT[oftIndex].length is EMPTY then /* update OFT entry */ if DES[dIndex][1] is not EMPTY then read_block(DES[dIndex][1], OFT[oftIndex].buffer); end if; OFT[oftIndex].currentPos = 0; OFT[oftIndex].index = dIndex; OFT[oftIndex].length = DES[dIndex][0]; break while; end if; oftIndex++; end while; return oftIndex; end Open Close (int oftIndex): if oftIndex > 3 then return ERROR: OFT INDEX IS LARGER THAN 3 /* calculate the block pointer in FD */ blockNumberInFD = OFT[oftIndex].length / bufferSize + 2; /* write buffer to disk */ writeblock(DES[OFT[oftIndex].index][blockNumberInFD], OFT[oftIndex].buffer); /* update file length */ DES[OFT[oftIndex].index][0] = OFT[oftIndex].length; /* free OFT entry */ OFT[oftIndex].length = EMPTY return OK; end Close; Read (oftIndex, memory, count): int startCount = 0; /* computer position in buffer */ posInBuffer = OFT[oftIndex].currentPos % bufferSize; while(true) do /* count reached */ if startCount == count or OFT[oftIndex].currentPos == OFT[oftIndex].length then return OK; end if; if posInBuffer is 64 bytes then /* end of buffer is reached */ /* calculate the block pointer in FD */ blockNumberInFD = OFT[oftIndex].currentPos / bufferSize + 1; /* set buffer position to start of the buffer */ posInBuffer = 0; /* write buffer to disk */ writeblock(DES[OFT[oftIndex].index][blockNumberInFD++], OFT[oftIndex].buffer); readblock( DES[OFT[oftIndex].index][blockNumberInFD], OFT[oftIndex].buffer); end if; memory[startCount] = (OFT[oftIndex].buffer)[posInBuffer]; posInBuffer ++; OFT[oftIndex].currentPos++; startCount++; End while; End Read; Write (oftIndex, memory, count): int startPos = 0; /* computer position in buffer */ posInBuffer = OFT[oftIndex].currentPos % bufferSize; while(true) do /* check to see if count is reached */ if startPos is count then return OK; end if; /* if current position in buffer exceeds bufferSize */ if posInBuffer = 64 then /* update current buffer position */ posInBuffer = 0; /* calculate the block number in file directory */ blockNumberInFD = OFT[optIndex].length / bufferSize + 1; /* check if block already exists in FD */ if DES[OFT.index][blockNumberInFD] is EMPTY then /* find a new block using bit map */ newDiskBlockIndex = findNewBlock(); else newDiskBlockIndex = DES[OFT.index][blockNumberInFD]; end if; /* write buffer into block */ writeblock(newDiskBlockIndex, OFT[oftIndex].buffer); end if; /* write one byte from memory to buffer */ (OFT[oftIndex].buffer)[posInBuffer] = memory[startPos]; startPos++; OFT[optIndex].length++; OFT[optIndex].currentPos++; end while; end write; Lseek (oftIndex, newPos) : /* calculate the block number in FD for newPos */ blockNumberOfNewPos = newPos / bufferSize + 1; /* calculate the block number in buffer */ blockNumberOfBuffer = OFT[oftIndex].currentPos / bufferSize +1; if blockNumberOfNewPos != blockNumberOfBuffer then /* write the buffer to disk */ writeblock(blockNumberOfBuffer, OFT[oftIndex].buffer); /* read buffer from disk */ readblock(blockNumberOfNewPos, OFT[oftIndex].buffer); end if; OFT[oftIndex].currentPos = newPos; return OK; end lseek; Directory : int file_name; int file_index_in_FD; /* read the directory file */ lseek(0,0); while(OFT[0].currentPos < OFT[0].length) do /* print file_name and file length for each directory entry */ read(0, file_name, 4); read(0, file_index_in_FD, 4); print file_name; print DES[file_index_in_FD][0]; end while; end Directory; findNewBlock(): for (i=0; i<2; i++) for (j=0; j<16; j++) /* search BM from the beginning /* check each bit in BM[i] for “0” test = BM[i] & MASK[j]) if (test == 0) then /* bit j of BM[i] is “0” */ return i*16+J; end if; end for; end for; return ERROR: NO FREE DISK SPACE; end findNewBlock; Lin He (52924739) Project 2: File System Preliminary Documentation ICS145B SQ2005 Due. 04/25/05