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);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to