Date: Mon, 27 Apr 2020 02:01:48 +0000 (UTC) From: Xin LI <delphij@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r360359 - head/sbin/fsck_msdosfs Message-ID: <202004270201.03R21mdA058857@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: delphij Date: Mon Apr 27 02:01:48 2020 New Revision: 360359 URL: https://svnweb.freebsd.org/changeset/base/360359 Log: 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 Modified: head/sbin/fsck_msdosfs/check.c head/sbin/fsck_msdosfs/ext.h head/sbin/fsck_msdosfs/fat.c Modified: head/sbin/fsck_msdosfs/check.c ============================================================================== --- head/sbin/fsck_msdosfs/check.c Sun Apr 26 22:08:47 2020 (r360358) +++ head/sbin/fsck_msdosfs/check.c Mon Apr 27 02:01:48 2020 (r360359) @@ -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 */ Modified: head/sbin/fsck_msdosfs/ext.h ============================================================================== --- head/sbin/fsck_msdosfs/ext.h Sun Apr 26 22:08:47 2020 (r360358) +++ head/sbin/fsck_msdosfs/ext.h Mon Apr 27 02:01:48 2020 (r360359) @@ -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); Modified: head/sbin/fsck_msdosfs/fat.c ============================================================================== --- head/sbin/fsck_msdosfs/fat.c Sun Apr 26 22:08:47 2020 (r360358) +++ head/sbin/fsck_msdosfs/fat.c Mon Apr 27 02:01:48 2020 (r360359) @@ -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) { @@ -636,6 +635,53 @@ checkdirty(int fs, struct bootblock *boot) if ((buffer[7] & 0x0c) == 0x0c) ret = 1; } + +err: + free(buffer); + 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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202004270201.03R21mdA058857>