Fix a bug with dirty file system handling.
r356313 broke handling of dirty file system because we have restricted the correction of "odd" byte sequences to checkfat(), and as a result the dirty bit is never cleared. The old fsck_msdosfs code would write FAT twice to fix the dirty bit, which is also not ideal. Fix this by introducing a new rountine, cleardirty() which will perform the set of clean bit only, and use it in checkfilesys() if we thought the file system was dirty. Reviewed by: cem, emaste MFC after: 3 day Differential Revision: https://reviews.freebsd.org/D24581
This commit is contained in:
parent
258ba4c027
commit
401475f50c
@ -169,7 +169,7 @@ checkfilesys(const char *fname)
|
||||
|
||||
if (mod & FSDIRTY) {
|
||||
pwarn("MARKING FILE SYSTEM CLEAN\n");
|
||||
mod |= writefat(fat);
|
||||
mod |= cleardirty(fat);
|
||||
} else {
|
||||
pwarn("\n***** FILE SYSTEM IS LEFT MARKED AS DIRTY *****\n");
|
||||
mod |= FSERROR; /* file system not clean */
|
||||
|
@ -90,6 +90,8 @@ int writefsinfo(int, struct bootblock *);
|
||||
/* Opaque type */
|
||||
struct fat_descriptor;
|
||||
|
||||
int cleardirty(struct fat_descriptor *);
|
||||
|
||||
void fat_clear_cl_head(struct fat_descriptor *, cl_t);
|
||||
bool fat_is_cl_head(struct fat_descriptor *, cl_t);
|
||||
|
||||
|
@ -578,7 +578,6 @@ valid_cl(struct fat_descriptor *fat, cl_t cl)
|
||||
* h = hard error flag (1 = ok; 0 = I/O error)
|
||||
* x = any value ok
|
||||
*/
|
||||
|
||||
int
|
||||
checkdirty(int fs, struct bootblock *boot)
|
||||
{
|
||||
@ -642,6 +641,53 @@ checkdirty(int fs, struct bootblock *boot)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
cleardirty(struct fat_descriptor *fat)
|
||||
{
|
||||
int fd, ret = FSERROR;
|
||||
struct bootblock *boot;
|
||||
u_char *buffer;
|
||||
size_t len;
|
||||
off_t off;
|
||||
|
||||
boot = boot_of_(fat);
|
||||
fd = fd_of_(fat);
|
||||
|
||||
if (boot->ClustMask != CLUST16_MASK && boot->ClustMask != CLUST32_MASK)
|
||||
return 0;
|
||||
|
||||
off = boot->bpbResSectors;
|
||||
off *= boot->bpbBytesPerSec;
|
||||
|
||||
buffer = malloc(len = boot->bpbBytesPerSec);
|
||||
if (buffer == NULL) {
|
||||
perr("No memory for FAT sectors (%zu)", len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((size_t)pread(fd, buffer, len, off) != len) {
|
||||
perr("Unable to read FAT");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (boot->ClustMask == CLUST16_MASK) {
|
||||
buffer[3] |= 0x80;
|
||||
} else {
|
||||
buffer[7] |= 0x08;
|
||||
}
|
||||
|
||||
if ((size_t)pwrite(fd, buffer, len, off) != len) {
|
||||
perr("Unable to write FAT");
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = FSOK;
|
||||
|
||||
err:
|
||||
free(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a FAT from disk. Returns 1 if successful, 0 otherwise.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user