[Bug 210316] panic after trying to r/w mount msdosfs on write protected media

Bruce Evans brde at optusnet.com.au
Thu May 17 07:15:10 UTC 2018


On Thu, 17 May 2018 a bug that doesn't want replies at freebsd.org wrote:

> https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=210316
>
> --- Comment #14 from Andriy Gapon <avg at FreeBSD.org> ---
> (In reply to Conrad Meyer from comment #13)
>
> Indeed, if we talk about the general behaviour.
>
> I see that I utterly failed to explain that I was thinking purely in a context
> of what msdos does in markvoldirty.
> Right now that code can leave behind a perpetually dirty buffer and I was
> thinking how that can be avoided.
>
> Maybe markvoldirty should do
>    bp = getblk(...)
>    bp->b_flags |= B_INVAL | B_RELBUF | B_NOCACHE;
>    bp->b_flags &= ~(B_ASYNC | B_CACHE);
>    brelse(bp);
> after a failed write?
> Looks clumsy, but should work.

I think this is the only way to clean up the buffer cache.

> Or maybe markvoldirty should not use buffer cache for its write?
> It could use g_write_data, for example.  But that sounds like layering
> violation.

Not a good way.

Markvoldirty() was obtained from apple and fixed a bit by me, but is still
very bad, without even this write protection bug.

Before it was implemented, you could use removable media with write
protection on, and have no writes occur even if you forgot to mount
with ro, and nothing bad happened if the media was removed without
unmounting provided it was never explicitly written to.  Now,
markvoldirty() ensures that bad things happen if the media is removed
without unmounting, even if the media is writeable initially so that
markvoldirty() doesn't fail.

I thought that failures were handled better.  markvoldirty() returns
bwrite().  There is a lot of error handling for this, but this ends
up as just markvoldirty() back to clean with the result voided for the
final call.  For unwriteable media, the buffer remains in the buffer
cache forever.

One idea for improving this is to delay markvoldirty() until the first
explicit write().  Also, don't clobber the disk to write atimes even if
the fs is mounted rw and without -noatime (it takes something like FAT32
before atimes even exist in msdosfs).  msdosfs has always had an internal
flag pm_fmod which was apparently intended for a similar optimization, but
it is useless since it is always set on successful rw mounts and not cleared
until unmount, and it is write-only except for a check in msdosfs_sync()
where it just causes a panic if it is not set.  The voldirty flag and
any internal dirty flags should also be set to clean if the file system
is not written to for some time after a successful complete sync, so that
the fs is usually clean if it is not written to often.  All versions of
Windows that I have tried seem to do this.

Bruce


More information about the freebsd-fs mailing list