Disable automatic fsck_exfat on dirty volume mount in Mac OSX

I've several large hard disks formatted in exFAT to keep clean compatibility between Win7/Bootcamp and Snow Leopard.

Here's the problem: fsck_exfat needs something like 6-8gb of RAM to complete on a large disk. (windows' chkdsk works fine, btw). If OSX detects a volume as dirty, it appears to automatically try to fsck the volume... but I am discovering that it doesn't actually fix any problems. During this automatic scan, OSX has to page nearly everything else to swap. I use several external drives when I am at my desk at home, and if an exFAT volume is dirty then it might be 10+ minutes before the laptop is usable per drive, and this is after Finder loads.

Before you suggest using an alternate file system:

  • FAT32 - 4gb file limit is a problem for me, and I have at least one 3tb drive. Considering formatting back to this for the smaller drives
  • NTFS - Every OSX NTFS driver I have tried sucks. ntfs3g is wildly inefficient with CPU time and for some reason frequently freezes the whole system for seconds at a time during heavy I/O. Tuxera NTFS is better, but still crappy for heavy use. Things like Finder generating thumbnails for a large folder of images, or basic usage of Songbird on a managed library of 300+gb, become extremely unpleasant (and rickety).
  • HFS+ - The HFS driver I use in Windows (Paragon bundled with a Seagate drive) has corrupted at least one important folder and I refuse to touch it again

Worse, I was trying to run this laptop without swap as I am getting pissed off with OSX' swap behavior (basically, it pages inactive stuff to disk regardless of available RAM). The performance increase from having the swap file disabled was very nice. BUT! Whenever fsck starts, automatically, the laptop would freeze soon thereafter due to running out of RAM.

This of course threw me into a loop: start laptop, OSX sees dirty exFAT, automatically fscks them, laptop freezes, drives marked dirty because of bad shutdown, lather, rinse, repeat... not pleasant. Booting into Win7 and running chkdsk (and shutting down cleanly) breaks out of this loop. Swap is re-enabled for now :-(

The best part is I still have to manually fix the dirty volumes, because for whatever reason they mount as read-only! I can only undo that after I fsck them myself!

This is most frustrating. So... how does one disable the automatic fsck_exfat that runs on a dirty exFAT mount? Or do you have any alternative solutions? I don't mind OSX mounting the drives RO if it means I keep control of my computer (and can fsck the drives later, at my leisure).


Solution 1:

Disclaimer: I have no way to test it properly, but the following might give you some success.

  • Disable SIP: https://stackoverflow.com/a/32910408/619961
  • sudo plutil -replace FSPersonalities.ExFAT.FSRepairExecutable -string "/usr/bin/true" /System/Library/Filesystems/exfat.fs/Contents/Info.plist
  • Enable SIP

Background idea: After searching the XNU kernel code for useful references of how Apple might have implemented this feature, and analyzing the exfat_mount binary in hopper, I projected that replacing either FSRepairExecutable or FSVerificationExecutable to simply always return successful could tackle your challenge.

Here is the relevant portion of the ExFAT relevant plist:

  "FSPersonalities" => {
    "ExFAT" => {
      "FSRepairArguments" => "-y"
      "FSVerificationArguments" => "-n"
      "FSFormatMinimumSize" => 1048576
      "FSFormatExecutable" => "newfs_exfat"
      "FSFormatContentMask" => "Windows_NTFS"
      "FSName" => "ExFAT"
      "FSRepairExecutable" => "fsck_exfat"
      "FSMountExecutable" => "mount_exfat"
      "FSMountArguments" => ""
      "FSVerificationExecutable" => "fsck_exfat"
      "FSXMLOutputArgument" => "-x"
      "FSFormatArguments" => ""
      "FSFormatMaximumSize" => 144115188075855872
    }
  }

Since this file resides under the the /System folder, newer OSX kernels protect it using SIP. Hence the tiny tedious workaround described above.

Alternatively, to allow for easier future edits of this plist file without compromising your security too much, you can also leave SIP enabled while disabling it for the filesystem part in recovery mode:

   csrutil enable --without fs

Given that you seem to have struggled to a certain degree with your issue, have you ever thought of moving towards a virtualization solution like Parallels or VMWare?

Solution 2:

Inspired by Moreaki's answer (which doesn't seem to work on Mojave) I came up with this ugly workaround:

  1. Disable SIP (see Moreaki's answer).
  2. Create a backup of the original fsck_exfat:
    sudo cp /System/Library/Filesystems/exfat.fs/Contents/Resources/fsck_exfat /System/Library/Filesystems/exfat.fs/Contents/Resources/fsck_exfat_ORIGINAL
  1. Replace the fsck_exfat binary with /usr/bin/true:
    sudo cp /usr/bin/true /System/Library/Filesystems/exfat.fs/Contents/Resources/fsck_exfat
  1. Enable SIP.

Note: which -a fsck_exfat will show the binary at /sbin/fsck_exfat which is a symlink to the real binary under /System/Library/.... While Mac is checking an ExFat disk you can see the actual path to fsck_exfat with ps aux | grep exfat.

WARNING: After this change your system won't do any automatic checking and fixing of exfat drives anymore! In order to check and fix errors on these drives it is preferred to use an OS with better exfat support, such as Windows or even Linux. And if you don't have another OS then you can still use the copy you created on step #2 (/System/Library/Filesystems/exfat.fs/Contents/Resources/fsck_exfat_ORIGINAL). This method does not remove the dirty bit, — it just forces an immediate return from fsck_exfat with a successful response code (0).