25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

34KB

Developing Your Own 32-Bit Operating System — Chapter-14: File System Service

  • Source: /library/Developing Your Own 32-Bit Operating System/source-file.pdf
  • PDF pages: 223–242
  • Pages without text: 223

File System Service

I
202 Part III m MMURTL-Specific Details The file system included with MMURTL is compatible with the MS-DOS FAT (File Alloca- tion Table) file system. This means that MMURTL can read and write MS-DOS disks (both hard and floppy). This was done so that you could use MMURTL without reformatting your hard disks or working from floppies. It certainly wasn't done because I liked the design or the filename length limitations. MS-DOS has the unenviable task of being compatible with its previous versions. This ties its hands, so to speak. Better file systems (disk formats) are in use, but none is as widespread. The internal management of a file system is no trivial matter. Because you are simply accessing one that was designed by someone else, there isn't anything new about the format, just how you access it. I have tried to follow the simplicity motto, and I limited the number of functions to what is necessary for decent operation. The service name is “FILESYS”. File Specifications A filename consists of one to eight characters, a period, then up to three more characters, for example, filename, txt. A full file specification for the FAT-compatible file system consists of a drive letter identifier followed by a colon, then the path — which is each directory separated by the backslash charac- ter— and finally the filename itself. Here's an example: C:\Dir1\Dir2\Dir3\Filename . txt Network File Request Routing File system requests are routed based on the full file specification. A filename that is prefixed with a node name, and optionally, a network name, will be routed to the service with the same name. A full network file specification consists of three parts. The first part is the network name enclosed in brackets [ ]. The second part is the network's node name enclosed in braces { }. The third part is the filename as previously described. A com- plete network filename looks like this: [network ]{Node}C: \Dir1 \Dir2\Filename . txt If the network name is omitted from the specification, and a node name is specified, the de- fault name NETWORK is used. The network name matches the name of the network service when it was installed, hence the default system service name for a network routing service is network. This also means that net- work names are limited to eight characters. Even though service names must be capitalized and space padded, this is not necessary with network names because the file system fixes them.

Chapter 14 ■ File System Service When a network file is opened, the network service receives the request from the file system. The file handle returned will be unique on the system that originated the request. The filename across a network may not be limited to the MS-DOS file naming conventions described here. This depends on the type of file system on the node being accessed. H File Handles When a file is opened in any mode or type, a number called a file handle is returned to you. Make no assumptions about this number. The file handle is used in all subsequent file opera- tions on that file. This number is how you refer to that file until the file is closed. A file handle is a 32-bit unsigned number (dword). File Open Modes A file may be opened for reading and writing, or just reading alone. These two modes are called Modify (read and write) and Read (read-only). Only a single user may open a file in Modify mode. This user is granted exclusive access to the file while it is open. Multiple users may open and access a read-mode file. When a file is opened in Read mode, it may not be opened in Modify mode by any user. File Access Type A file may be opened in Block or Stream mode. Block Mode Block mode operation is the fastest file access method because no internal buffering is required. The data is moved in whole blocks by the fastest means determined by the device driver. No internal file buffers are allocated by the file system in Block mode. The only restriction is that whole blocks must be read or written. The standard block size is 512 bytes for disk devices. Block mode operation allows use of the following file system functions: ReadBlock() WriteBlock() CloseFile() GetFileSize() SetFileSize() DeleteFile()

H Part III ■ MMURTL-Specific Details Stream Mode In Stream mode, the file system allocates an internal buffer to use for all read and write opera- tions. This is a one-page, 4096-byte buffer. Stream mode operation allows use of the following file system functions: CloseFile() ReadBytes() WriteBytesO SetFileLFA() GetFileLFA() GetFileSize() SetFileSize() DeleteFile() Errors are returned from any function not compatible with the file-access type you specified when the file was opened. Logical File Address All files are logically stored as -n bytes. The Logical File Address (LFA) is an unsigned dword (dLFA). This is the byte offset in the file to read or write from. LFA 0 is the beginning of the file. The file size minus 1 is the last logical byte in the file. Block access file system functions require to you specify a Logical File Address (LFA). Block access files have no internal buffers and do not maintain a current LFA or file pointer. Stream access files have internal buffers and maintain your current LFA. This is called a file pointer in some systems. For stream files, you do not specify an LFA to read or write from. The current LFA for stream files is updated with each ReadBytesO and WriteBytesO function. Additional functions are provided to allow you to find and set the current LFA. When a file is initially opened for Stream access, the file pointer is set to 0, no matter what mode the file was opened in File System Requests The file system is a message-based system service. This means it can be accessed directly with the Request primitive. The procedural interface for Request has 1 2 parameters. The file system is an ideal candidate for a message-based service. It meets all the requirements. The small amount of time for message routing will not make any measurable difference in the speed of its opera- tion because most of its time is spent accessing hardware. It also provides the shared access required for a true multitasking system. The file system actually runs as a separate task. Listing 14.1 is an example of a File System request in the C programming language.

Chapter 14 ■ File System Service Listing 14.1. OpenFile request in C. dError= Request ( “FILESYS “, /* ptr to name 1, MyExch, &MyRqhandle, 1 , /* wSvcCode /* dRespExch /* pRqHndlRet /* nSendPtrs &“AnyFile.doc” , /* pDatal 11, /* cbDatal &FileHandle /* pData2 4, /* cbData2 1 , /* dData0 0, /* dDatal 0); /* dData2 of service */

  • 1 for OpenFile */
  • respond here */
  • may be needed */
  • 1 Send ptr */
  • ptr to name */
  • size of name */
  • returned handle *, Size of a handle */ ModeRead */ Block Type Access *i not used */ Unused request parameters must be set to 0. All message-based services use the same request-based interface. Using the request interface allows for asynchronous program operation. You can make a request, then go do something else be- fore you come back to wait or check the function to see if it's completed (true multitasking). Each of the functions is identified by its Service Code number. Table 14.1 shows the service codes the file system supports. Table 14.1. File system service codes. Function Service Code OpenFile CloseFile ReadBlock WriteBlock ReadBytes WriteBytes GetFileLFA SetFileLFA GetFileSize SetFileSize CreateFile RenameFile DeleteFile CreateDirectory DeleteDirectory GetDirectorySector 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

Part III M MMURTL-Specific Details Procedural Interfaces If you don't have a need for asynchronous disk access, you can use a blocking procedural inter- face which is included in the file system itself. The procedural interface actually makes the re- quest for you by using your TSS Exchange. The request is transparent to the caller. It is easier to use because it has fewer parameters. This means there is a simple procedural interface call for each file system function. The blocking procedural interface is described with each of the call descriptions that follow later in this chapter. Device Access Through the File System Teletype fashion stream access to the NUL, VID, and KBD devices may be accessed through the file system, but only through the procedural interfaces. The Request interface will not al- low device access. High-level language libraries that implement device access (such as putchar( ) in C) must use the procedural interfaces for file access. All system device names are reserved and should not be used as filenames on the system. Table 14.2 lists the device names that are reserved and also the mode of stream access supported. Table 14.2. Device stream access. Device Description Access NUL NULL device Write-only KBD Keyboard Read-only VID Video Write-only LPT1 Printer 1 None LPT2 Printer 2 None COM1 RS-232 1 None COM2 RS-232 2 None COM3 RS-232 3 None COM4 RS-232 4 None FDO Floppy disk None FD1 Floppy disk None HDO Hard disk None HD1 Hard disk None Device access is currently implemented for NUL, KBD, and VID devices only.

Chapter 14 ■ File System Service File System Functions in Detail The following pages detail each of the file system functions that are available. OpenFile Procedural interface: OpenFile (pName, dcbname, dOpenMode, dAccessType, pdHandleRet) : dError OpenFile ( ) opens an existing file in the current path for block or stream operations. A full file specification may be provided to override the current job path. Opening in ModeModif y excludes all others from opening the file. Multiple users can open a file in ModeRead. If a file is open in ModeRead, it cannot be opened in ModeModif y by any other users. Procedural parameters: pName — Pointer to the filename or full file specification dcbName — Dword with length of the filename dOpenMode— READ= 0, MODIFY= 1 dAccessType — Block= 0, Stream= 1. pdHandleRet — Pointer to a dword where the handle to the file will be returned to you Request Parameters for OpenFile: wSvcCode = 1 nSend = 1 pDatal = pName cbDatal = dcbName pData2 = pdHandleRet cbData2 = 4 (Size of a file handle) dDataO = dOpenMode dDatal = dAccessType dData2 = Not used (0) CloseFile Procedural interface: CloseFile (dHandle): dError CloseFile () closes a file that was previously opened. If stream access type was specified, all buffers are flushed and deallocated.

208 Part III M MMURTL-Specific Details Procedural parameters: dHandle — A dword that was returned from OpenFile( ) Request Parameters for CloseFile: wSvcCode = 2 nSend = 0 pDatal = 0 cbDatal = 0 pData2 = 0 cbData2 = 0 dDataO = dHandle dDatal = 0 dData2 -0 ReadBlock Procedural interface: ReadBlock(dHandle, pDataRet, nBytes, dLFA, pdnBytesRet) : dError This reads one or more blocks from a file. The file must be opened for Block access or an error occurs. Procedural parameters: dHandle — Dword with a valid file handle (as returned from 0penFile( ) pDataRet — Pointer to a buffer large enough to hold the count of blocks you specify to read nBytes — Dword with number of bytes to read. This mustbe a multiple of the block size for the 5 1 2-byte disk. dLFA — Logical File Address to read from. This mustbe a multiple of the block size. pdnBlkRet — Pointer to a dword where the count of bytes successfully read will be returned. This will always be a multiple of the block size («X 512). Request parameters for ReadBlock: wSvcCode = 3 nSend = 0 pDatal = pDataRet cbDatal = nBytes (multiple of 512) pData2 = pdnBytesRet cbData2 = 4 (size of dnBytesRet) dData0 = dHandle dDatal = 0 dData2 = 0

Chapter 14 ■ File System Service ^nq WriteBlock Procedural interface: WriteBlock(dHandle, pData, nBytes, dLFA, pdnBytesRet) : dError This writes one or more blocks to a file. The file must be opened for Block access in Modify mode or an error occurs. Writing beyond the current file length is not allowed. SetFileSize( ) must be used to extend the file length if you intend to write beyond the current file size. See the SetFileSize() section. Procedural parameters: dHandle — Dword with a valid file handle as returned from OpenFile( ). pData — Pointer to the data to write nBytes — Dword with number of bytes to write. This must always be a multiple of 512. One block -512 bytes. dLFA — Logical File Address to write to. This mustbe a multiple of the block size. pdnBytesRet — Pointer to a dword where the number of bytes successfully written will be returned. This will always return a multiple of 512. Request parameters for ReadBlock: wSvcCode = 4 nSend = 1 pDatal = pData cbDatal = nBytes (512= 1 Block) pData2 = pdnBytesRet cbData2 = 4 (size of dnBytesRet) dDataO = dHandle dDatal = 0 dData2 = 0 ReadBytes Procedural interface: ReadBytes (dHandle, pDataRet, nBytes, pdnBytesRet): dError This reads one or more bytes from a file. The file must be opened for Stream access or an error occurs. The bytes are read from the current LFA. The LFA is updated to the next byte address following the data you read. Use SetFileLFA( ) to move the stream file pointer if you want to read from an LFA other than the current LFA. Get File LFA may be used to find the current LFA.

210 Part III ■ MMURTL-Specific Details Parameters: dHandle — Dword with a valid file handle, as returned from OpenFile( ) pDataRet — Pointer to a buffer large enough to hold the count of bytes you specify to read nBytes — Dword with number of bytes to read pdnBytesRet — Pointer to a dword where the number of bytes successfully read will be returned Request Parameters for ReadBytes: wSvcCode = 5 nSend = 0 pDatal = pDataRet cbDatal = nBytes pData2 = pdnBytesRet cbData2 = 4 (size of dnBytesRet) dDataO = dHandle dDatal = 0 dData2 = 0 WriteBytes Procedural interface: WriteBytes (dHandle, pData, nBytes, pdnBytesRet): dError This writes one or more bytes to a file. The file must be opened for stream access in Modify mode or an error occurs. The bytes are written beginning at the current LFA. The LFA is up- dated to the next byte address following the data you wrote. The file length is extended auto- matically if you write past the current End Of File. Use SetFileLFA( ) to move the stream file pointer if you want to read from an LFA other than the current LFA. GetFileLFA( ) may be used to find the current LFA. Procedural parameters: dHandle — Dword with a valid file handle, as returned from OpenFile pData — Pointer to the data to write nBytes — Dword with number of bytes to write pdnBytesRet — Pointer to a dword where the number of bytes successfully written will be returned

Chapter 14 ■ File System Service H Request parameters for ReadBytes: wSvcCode = 6 nSend = 1 pDatal = pData cbDatal = nBytes pData2 = pdnBytesRet cbData2 = 4 (size of dnBytesRet) dData0 = dHandle dDatal = 0 dData2 = 0 GetFikLFA Procedural Interface: GetFilel_FA(dHandle, pdLFARet): dError This gets the current LFA for files with stream mode access. An error occurs if the file is opened for Block access. Procedural parameters: dHandle — Dword with a valid file handle, as returned from OpenFile pdLFARet — Pointer to a dword where the current LFA will be returned Request parameters for GetFileLFA: wSvcCode = 7 nSend = 0 pDatal = pdLFARet cbDatal = 4 pData2 = 0 cbData2 = 0 dData0 = dHandle dDatal = 0 dData2 = 0 SetFileLFA Procedural interface: SetFileLFA(dHandle, dLFA) : dError This sets the current LFA (file pointer) for Stream Access files. An error occurs if the file is opened for Block access. The file LFA can not be set past the End Of File (EOF). The file will be set to EOF if you specify OFFFFFFFF hex (-1 for a signed long value in C).

I
212 Part III ■ MMURTL-Specific Details Procedural parameters: dHandle — Dword with a valid file handle, as returned from OpenFile( ). dLFA — Dword with the LFA you want to set. OFFFFFFFF hex will set the current LFA to End O fFile. est parameters for SetFileLFA wSvcCode = 8 nSend = 0 pDatal = 0 cbDatal = 0 pData2 = 0 cbData2 = 0 dData0 = dHandle dDatal = dLFA dData2 = 0 GetFileSize Procedural interface: GetFileSize(dHandle, pdSizeRet): dError This gets the current file size for files opened in any access mode. Procedural parameters: dhandle — Dword with a valid file handle, as returned from 0penFile( ) pdSizeRet — Pointer to a dword where the current size of the file will be returned Request parameters for GetFileLFA: wSvcCode = 9 nSend = 0 pDatal = pdSizeRet cbDatal = 4 pData2 = 0 cbData2 = 0 dDataO = dHandle dDatal = 0 dData2 = 0

Chapter 14 ■ File System Service SetFileSize Procedural interface: SetFileSize (dHandle, dSize): dError This sets the current file size for Stream and Block Access files. The file length, and allocated space on the disk, will be extended or truncated as necessary to accommodate the size you specify. The current LFA is not affected for Stream files unless it is now past the new EOF, in which case it is set to EOF automatically. Procedural parameters: dHandle — Dword with a valid file handle as returned from OpenFile( ) dSize — Dword with the new size of the file Request Parameters for SetFileSize: wSvcCode = 10 nSend = 0 pDatal = 0 cbDatal = 0 pData2 = 0 cbData2 = 0 dDataO = dHandle dDatal = dSize dData2 = 0 CreateFile Procedural interface: CreateFile (pName, dcbName, dAttributes) : dError This creates a new, empty file in the path specified. The file is closed after creation, and the file is ready to be opened and accessed. Procedural parameters: pName — Pointer to the filename or full file specification to create dcbName — Dword with length of the filename dAttributes — Dword with one of the following values: 0 = Normal File 2 = Hidden File 4 = System File 6 = Hidden System file

214 | Part III M MMURTI-Specific Details Request parameters for CreateFile: wSvcCode = 11 nSend = 1 pDatal = pName cbDatal = dcbName pData2 = 0 cbData2 = 0 dDatae = dAttributes dDatal = 0 dData2 = 0 RenameFile Procedural interface: RenameFile (pName, dcbname, pNewName dcbNewName) : dError This renames a file. The file must not be opened by anyone in any mode. Procedural parameters: pName — Pointer to the current filename or full file specification dcbName — Dword with length of the current filename pNewName — Pointer to the new filename or full file specification dcbNewName — Dword with length of the new filename Request parameters for RenameFile: wSvcCode nSend pDatal cbDatal pData2 cbData2 dDataO dDatal dData2 = 12 = 1 = pName = dcbName = pNewname = dcbNewname = 0 = 0 = 0 DeleteFile Procedural interface: DeleteFile (dHandle): dError This deletes a file from the system. No further access is possible, and the filename is available for re-use.

Chapter 14 ■ File System Service The file must be opened in Modify mode, which grants exclusive access. Procedural parameters: dHandle — Dword that was returned from OpenFile Request parameters for DeleteFile: wSvcCode = 13 nSend = 0 pDatal = 0 cbDatal = 0 pData2 = 0 cbData2 = 0 dDataO = dHandle dDatal = 0 dData2 = 0 CreateDirectory Procedural interface: CreateDirectory (pPath, dcbPath): dError This creates a new, empty directory for the path specified. The path must contain the new directory name as the last element. This means all subdirectories above the last directory speci- fied must already exist. If only the new directory name is specified, as opposed to a full path, the directory is created in your current path, specified in the Job Control Block. Procedural parameters: pPath — Pointer to the path (directory name) to create dcbPath — Dword with length of the path Request parameters for CreateDirectory: wSvcCode = 14 nSend = 1 pDatal = pPath cbDatal = dcbPath pData2 = 0 cbData2 = 0 dDataO = 0 dDatal = 0 dData2 = 0

I
216 Part III ■ MMURTL-Specific Details DeleteDirectory Procedural interface: DeleteDirectory (pPath, dcbPath, fAHFiles): dError This deletes a directory for the path specified. The path must contain the directory name as the last element. If only the existing directory name is specified, as opposed to a full path, the name is appended to the path from your job control block. All files and subdirectories will be deleted if fAHFiles is non-zero. Procedural parameters: pPath — Pointer to the path, or directory name, to delete dcbPath — Dword with length of the path fAHFiles — If set to non-zero, all files in this directory, all subdirectories, and files in subdirectories will be deleted. Request parameter > for DeleteDirec wSvcCode 15 nSend 1 pDatal pPath cbDatal dcbPath pData2 0 cbData2 0 dDataO 0 dDatal 0 dData2 0 GetDirSector Procedural Interface: GetDirSector (pPath, dcbPath, pSectRet, dSectNum): dError Directories on the disk are one or more sectors in size. Each sector contains 16 directory en- tries. This call returns one sector from a directory. You specify which logical directory sector you want to read (from 0 to nTotalSectors - 1 ). The directory must exist in the path specified. If no path is specified, the path in your JCB will be used. A single directory entry looks like this with 16 per sector: Name 8 Bytes Ext 3 Bytes

Chapter 14 ■ File System Service Attribute 1 Byte Reserved 10 Bytes Time 2 Bytes Date 2 Bytes StartClstr 2 Bytes FileSize 4 Bytes The fields are read and used exactly as MS-DOS uses them. Procedural parameters: pPath — Pointer to the path, or directory name, to read the sector from dcbPath — Dword with length of the path pSectRet — Pointer to a 512-byte block where the directory sector will be returned dSectNum — Dword with the logical sector number to return Request parameters for GetDirSector: wSvcCode = 16 nSend = 1 pDatal = pPath cbDatal = dcbPath pData2 = pSectRet cbData2 =512 dDataO = dSectNum dDatal = 0 dData2 = 0 ra File System Theory Understanding a bit more about how the file system is managed may help you make better use of it. Internal File System Structures The file system has several internal structures it uses to manage the logical disks and open files. Some structures are dynamically allocated, while others are part of the operating system data segment. File Control Blocks All file system implementations have some structure that is used to manage an open file. Quite a few of them use this same name, FCB.

21g Part III M MMURTL-Specific Details The file system allocates file system structures dynamically when it is initialized. The maxi- mum number of open files is currently limited to 128 files by this initial allocation. The file system starts with an initial 4K (one memory page) of FCBs. Each FCB is 128 bytes. Each open file is allocated an FCB. If the file is opened in Stream mode, you allocate a one- page buffer (4K) for reading and writing. The FCB actually contains a copy of the 32-byte directory entry from the disk. This is read into the FCB when the file is opened. File User Blocks Because this is a multitasking operating system, the FCB is not direcdy associated with the job that opened the file. Another structure, called the file user block (FUB), is what links the user of a file to the FCB. There is one FUB for each instance of a user with an open file. The FUBs contain the file pointer, the open mode, buffer pointers, and other things that are required to manage the user's link to the file. The file handle is actually a pointer to the FUB. Because it is a pointer, extra checking is done to ensure it is valid in every call. A bad pointer could do some real damage here if you let it. The FCB keeps track of the number of FUBs for the file. When it reaches 0, the FCB is deallocated for re-use. FAT Buffers In the FAT file system, the location of every cluster of one or more sectors of a file is managed in a linked list of sorts. This linked list is contained in a table called the File Allocation Table. A more accurate name would be cluster allocation table because it's actually allocating clusters of disk space to the files, it's not allocating files. The disk is allocated in clusters, with each cluster having an associated entry in the FAT. On most hard disks, they use what is called a FAT 16. This means each FAT entry is a 16-bit word. The beginning of the FAT represents the beginning of the usable data area on the logical disk. Let's look at an example of how you use the FAT to locate all parts of file on the disk. In this example, you'll assume that each FAT entry is worth 4K on disk, which is cluster size, and you'll assume the file size is 12K, or three entries. Assume the directory entry you read says the first FAT entry is number 4. X= not your file. L= Last entry in your file. FAT Position 123456789 10 Entry in FAT X X X 5 6 L

Chapter 14 ■ File System Service This means your file occupies the fourth, fifth, and sixth clusters in the data area on the disk. The fourth entry points to the fifth, the fifth points to the sixth, and the sixth is marked as the last. Have you ever gotten lost clusters when you ran a Chkdsk in MS-DOS? Who hasn't? It usually means it found some clusters pointing to other clusters that don't end, or it found a beginning cluster with no corresponding directory entry pointing to it. From this example, you can see that every file you access will require a minimum of two disk accesses to read the file, unless the piece of the FAT you need is already in memory. This means it's important to attempt to keep as much FAT information in memory as you can and manage it wisely. If your disk isn't too badly fragmented and if you are sequentially read- ing all of a file into memory (such as when loading an executable file), you can usually do it quite rapidly. Just IK of FAT space represents 2MB of data space on the disk if clusters are 4K. A badly fragmented disk can force as many as four or five accesses to different parts of the FAT just to read one file. The disk controller (IDE/MFM) can read 256 contiguous sectors in one read operation. That's 128K. That's a lot of FAT (or file). However, because of the design of the FAT file system, the actual contiguous read will usually be limited to the size of a cluster. A great number of files are read and written sequentially. These include, run files being ex- ecuted, source files for compilers, the initial filling of buffers for a word processor (and the final save usually), vector image files, and raster image files. The list could go on and on. Large database files are the major random users, and only a good level-4 mindreader knows where, inside of a 400MB file, the user will strike next. MMURTL's DOS FAT file system allocates a IK FAT buffer, based on file access patterns. A simple LRU (least recently used) algorithm ensures the most accessed FAT sectors will remain in memory. File Operations Reading a file is a multipart process. Look at what the file system goes through to open, read, and close a file:

  1. Look through the FCBs to see if someone already has it open in ModeRead. If so, allocate an FUB and attach it. If it's open in ModeWrite, return an error ErcFilelnUse.
  2. Locate the directory entry and read it into the FCB. Directories are stored as files. This means that you have to go to the FAT to find where the directory is stored so you can look through it. This is in itself time-consuming.
  3. Load FAT buffer if required. The first cluster of the file is listed in the directory entry. From this, you calculate which disk sector in the FAT has this entry, and you read it into the FAT buffer if it is not already in one. The file is open.

220 | Part III ■ MMURTL-Specific Details Read What actually happens on a read depends on whether the file is opened in Block or Stream mode. If opened in Block mode, you simply issue the read to the device driver to read the sec- tors into the caller's buffer (locating them using the FAT). The hardware is limited to 128K reads in one shot, and can only do this if 1 28K of the file is located in contiguous sectors. Usually, the commands to the device driver will be broken into several smaller reads as the file system finds each contiguous section listed in the FAT. Write Writing to a file is a little more complicated, and depends on how the file was opened. If the file is opened in Block mode, you issue the write command to the device driver to write out the sectors as indicated by the user. It sounds simple, but much overhead is involved. If the sectors have already been allocated in the FAT, you simply write over the existing data while you fol- low the cluster chain. If the file is being extended, you must find unallocated clusters, attach them to the chain, then write the data. On many disks there are two copies of the FAT for integrity purposes. Both copies must be updated. Close This is the easy part. You flush buffers to disk if necessary for Write mode. Then you deallocate the FUB and FCB.

Powered by TurnKey Linux.