File Truncation Can Cause Lost Clusters

ID Number: Q67582

3.20 3.21 3.30 3.30a 4.00 4.01

MS-DOS

buglist3.20 buglist3.30 buglist4.00 buglist4.01

Summary:

If a file is opened, extended, truncated, extended again, and then

closed, the File Allocation Table (FAT) chain for the truncated

section of the file will not be deallocated. This produces lost chains

on the disk that artificially reduce the amount of free space

available on the disk.

You can make this lost space available again by executing the CHKDSK

command with the /F parameter. For more information on the use of the

CHKDSK command, see the "Microsoft MS-DOS User's Reference."

More Information:

When the following sequence of events occur, MS-DOS will not properly

clean up the File Allocation Table for the space allocated to the

file.

1. A file is opened.

2. The file is extended by a seek and a write operation such that

MS-DOS must add at least one additional cluster to the file's

allocation chain.

3. The file is truncated such that one or more clusters are removed

from the file.

4. The file is once again extended such that one or more clusters are

added to the file's allocation chain.

5. The file is closed.

The file must be extended by a combination of a seek beyond the end of

file followed by a write. Simple write operations that cause the file

to be extended will not cause this problem to occur.

The following code fragment duplicates this problem on a drive where

the allocation unit (cluster) size is less than or equal to 4096

bytes. After the code is executed, lost clusters will be reported by

the CHKDSK command.

void LostClusters(void)

{

int fh; /* file handle for open file */

char charbuff[2];

fh = open("test.fil", O_CREAT | O_RDWR, S_IWRITE | S_IREAD);

/* Move file pointer beyond next cluster boundary */

lseek( fh, 4100L, SEEK_SET );

/* Force allocation of the new clusters */

/* the clusters allocated here are the ones that will become lost */

write( fh, charbuff, 2);

/* truncate the file below a cluster boundary */

chsize( fh, 4090L );

/* Seek past the cluster boundary again */

lseek( fh, 4100L, SEEK_END );

/* Force allocation of new clusters for the file */

write( fh, charbuff, 2);

close(fh);

}

Workaround

----------

When a situation is encountered where the file needs to be truncated

(0 bytes written), close the file and reopen it immediately following

the truncation operation (for example, after the chsize() shown

above). This forces MS-DOS to perform cleanup operations that properly

update the FAT.

Microsoft has confirmed this to be a problem in MS-DOS versions 3.20,

3.21, 3.30, 4.00 and 4.01. We are researching this problem and will

post new information here as it becomes available.