Re: svn commit: r361491 - in head/sys: geom kern sys ufs/ffs ufs/ufs

2020-05-28 Thread Peter Jeremy
On 2020-May-25 23:47:32 +, Chuck Silvers  wrote:
>Author: chs
>Date: Mon May 25 23:47:31 2020
>New Revision: 361491
>URL: https://svnweb.freebsd.org/changeset/base/361491
>
>Log:
>  This commit enables a UFS filesystem to do a forcible unmount when
>  the underlying media fails or becomes inaccessible. For example
>  when a USB flash memory card hosting a UFS filesystem is unplugged.

This breaks the build when FFS is not built into the kernel but GEOM
is (eg for a ZFS-only system).  Specifically, ffs_subr.c is marked
"optional ffs | geom_label" and this commit added a dependency on
M_UFSMNT (defined in sys/ufs/ufs/ufs_vfsops.c) to ffs_subr.c.

The geom_label dependency exists because sys/geom/label/g_label_ufs.c
relies on ffs_sbget() (defined in ffs_subr.c) to taste UFS partitions.

I'm not sure of the best fix here - ideally, the new functions this
commit adds to ffs_subr.c would be moved to a different file (though
it's not immediately clear which file that would be.

-- 
Peter Jeremy


signature.asc
Description: PGP signature


svn commit: r361491 - in head/sys: geom kern sys ufs/ffs ufs/ufs

2020-05-25 Thread Chuck Silvers
Author: chs
Date: Mon May 25 23:47:31 2020
New Revision: 361491
URL: https://svnweb.freebsd.org/changeset/base/361491

Log:
  This commit enables a UFS filesystem to do a forcible unmount when
  the underlying media fails or becomes inaccessible. For example
  when a USB flash memory card hosting a UFS filesystem is unplugged.
  
  The strategy for handling disk I/O errors when soft updates are
  enabled is to stop writing to the disk of the affected file system
  but continue to accept I/O requests and report that all future
  writes by the file system to that disk actually succeed. Then
  initiate an asynchronous forced unmount of the affected file system.
  
  There are two cases for disk I/O errors:
  
 - ENXIO, which means that this disk is gone and the lower layers
   of the storage stack already guarantee that no future I/O to
   this disk will succeed.
  
 - EIO (or most other errors), which means that this particular
   I/O request has failed but subsequent I/O requests to this
   disk might still succeed.
  
  For ENXIO, we can just clear the error and continue, because we
  know that the file system cannot affect the on-disk state after we
  see this error. For EIO or other errors, we arrange for the geom_vfs
  layer to reject all future I/O requests with ENXIO just like is
  done when the geom_vfs is orphaned. In both cases, the file system
  code can just clear the error and proceed with the forcible unmount.
  
  This new treatment of I/O errors is needed for writes of any buffer
  that is involved in a dependency. Most dependencies are described
  by a structure attached to the buffer's b_dep field. But some are
  created and processed as a result of the completion of the dependencies
  attached to the buffer.
  
  Clearing of some dependencies require a read. For example if there
  is a dependency that requires an inode to be written, the disk block
  containing that inode must be read, the updated inode copied into
  place in that buffer, and the buffer then written back to disk.
  
  Often the needed buffer is already in memory and can be used. But
  if it needs to be read from the disk, the read will fail, so we
  fabricate a buffer full of zeroes and pretend that the read succeeded.
  This zero'ed buffer can be updated and written back to disk.
  
  The only case where a buffer full of zeros causes the code to do
  the wrong thing is when reading an inode buffer containing an inode
  that still has an inode dependency in memory that will reinitialize
  the effective link count (i_effnlink) based on the actual link count
  (i_nlink) that we read. To handle this case we now store the i_nlink
  value that we wrote in the inode dependency so that it can be
  restored into the zero'ed buffer thus keeping the tracking of the
  inode link count consistent.
  
  Because applications depend on knowing when an attempt to write
  their data to stable storage has failed, the fsync(2) and msync(2)
  system calls need to return errors if data fails to be written to
  stable storage. So these operations return ENXIO for every call
  made on files in a file system where we have otherwise been ignoring
  I/O errors.
  
  Coauthered by: mckusick
  Reviewed by:   kib
  Tested by: Peter Holm
  Approved by:   mckusick (mentor)
  Sponsored by:  Netflix
  Differential Revision:  https://reviews.freebsd.org/D24088

Modified:
  head/sys/geom/geom_vfs.c
  head/sys/kern/vfs_bio.c
  head/sys/sys/buf.h
  head/sys/ufs/ffs/ffs_alloc.c
  head/sys/ufs/ffs/ffs_balloc.c
  head/sys/ufs/ffs/ffs_extern.h
  head/sys/ufs/ffs/ffs_inode.c
  head/sys/ufs/ffs/ffs_softdep.c
  head/sys/ufs/ffs/ffs_subr.c
  head/sys/ufs/ffs/ffs_vfsops.c
  head/sys/ufs/ffs/ffs_vnops.c
  head/sys/ufs/ffs/softdep.h
  head/sys/ufs/ufs/ufs_vnops.c
  head/sys/ufs/ufs/ufsmount.h

Modified: head/sys/geom/geom_vfs.c
==
--- head/sys/geom/geom_vfs.cMon May 25 23:20:33 2020(r361490)
+++ head/sys/geom/geom_vfs.cMon May 25 23:47:31 2020(r361491)
@@ -55,6 +55,7 @@ struct g_vfs_softc {
struct bufobj   *sc_bo;
int  sc_active;
int  sc_orphaned;
+   int  sc_enxio_active;
 };
 
 static struct buf_ops __g_vfs_bufops = {
@@ -139,9 +140,14 @@ g_vfs_done(struct bio *bip)
 
cp = bip->bio_from;
sc = cp->geom->softc;
-   if (bip->bio_error && bip->bio_error != EOPNOTSUPP)
+   if (bip->bio_error != 0 && bip->bio_error != EOPNOTSUPP) {
+   if ((bp->b_xflags & BX_CVTENXIO) != 0)
+   sc->sc_enxio_active = 1;
+   if (sc->sc_enxio_active)
+   bip->bio_error = ENXIO;
g_print_bio("g_vfs_done():", bip, "error = %d",
bip->bio_error);
+   }
bp->b_error = bip->bio_error;
bp->b_ioflags = bip->bio_flags;
if (bip->bio_error)
@@ -172,7 +178,7 @@ g_vfs_st