Updated: 2022/Sep/29

Please read Privacy Policy. It's for your privacy.


FSTRANS(9)                 Kernel Developer's Manual                FSTRANS(9)

NAME
     fstrans, fstrans_setstate, fstrans_getstate, fstrans_start,
     fstrans_start_nowait, fstrans_start_lazy, fstrans_done, fstrans_is_owner,
     fscow_establish, fscow_disestablish, fscow_run - file system suspension
     helper subsystem

SYNOPSIS
     #include <sys/mount.h>
     #include <sys/fstrans.h>

     void
     fstrans_start(struct mount *mp);

     int
     fstrans_start_nowait(struct mount *mp);

     void
     fstrans_start_lazy(struct mount *mp);

     void
     fstrans_done(struct mount *mp);

     int
     fstrans_setstate(struct mount *mp, enum fstrans_state new_state);

     enum fstrans_state
     fstrans_getstate(struct mount *mp);

     int
     fstrans_is_owner(struct mount *mp);

     int
     fscow_establish(struct mount *mp,
         int (*func)(void *, struct buf *, bool), void *cookie);

     int
     fscow_disestablish(struct mount *mp,
         int (*func)(void *, struct buf *, bool), void *cookie);

     int
     fscow_run(struct buf *bp, bool data_valid);

DESCRIPTION
     The fstrans subsystem assists file system suspension and copy-on-write
     snapshots.

     The file system's normal operations, such as its vnodeops(9), must be
     bracketed by fstrans_start() and fstrans_done() in a shared transaction,
     which is blocked by suspending the file system and while it is suspended.

     Operations needed while suspending the file system  must be bracketed by
     fstrans_start_lazy() and fstrans_done() in a lazy transaction, which is
     allowed while suspending the file system, but blocked while the file
     system is suspended.

     Transactions are per-thread and nestable: if a thread is already in a
     transaction, it can enter another transaction without blocking.  Each
     fstrans_start() must be paired with fstrans_done().  Transactions for
     multiple distinct mount points may not be nested.

     The file system's VFS_SUSPENDCTL(9) method can use fstrans_setstate() to:

     -   enter the FSTRANS_SUSPENDING state to suspend all normal operations
         but allow lazy transactions,

     -   enter the FSTRANS_SUSPENDED state to suspend all operations, and

     -   restore to the FSTRANS_NORMAL state to resume all operations.

     A file system supporting fstrans may establish a copy-on-write callback
     with fscow_establish().  The copy-on-write callback will be called every
     time a buffer is written to a block device with VOP_STRATEGY() and every
     time a buffer is read into the buffercache(9) with B_MODIFY set
     indicating the caller's intent to modify it.  Anyone modifying a buffer
     may additionally use fscow_run() to explicitly invoke the established
     callback.  The copy-on-write callback must be disestablished with
     fscow_disestablish() when the file system is done with it.

FUNCTIONS
     fstrans_start(mp)
           Enter a transaction on the file system mp in the current thread.
           If the file system is in a state that blocks such transactions,
           wait until it changes state to one that does not.

           If the file system is suspended, wait until it is resumed.

           However, if the current thread is already in a transaction on mp,
           fstrans_start() will enter a nested transaction and return
           immediately without waiting.

           May sleep.

     fstrans_start_nowait(mp)
           Like fstrans_start(), but return EBUSY immediately if transactions
           are blocked in its current state.

           May sleep nevertheless on internal locks.

     fstrans_start_lazy(mp)
           Like fstrans_start(), but will not block while suspending.

           May sleep.

     fstrans_done(mp)
           End the current transaction on mp.

     fstrans_getstate(mp)
           Return the current state of the file system mp.

           Must be called within a transaction for the answer to be stable.

     fstrans_setstate(mp, new_state)
           Change the state of the file system mp to new_state, and wait for
           all transactions not allowed in new_state to complete.

           FSTRANS_NORMAL         Allow all transactions.

           FSTRANS_SUSPENDING     Block FSTRANS_SHARED transactions but allow
                                  FSTRANS_LAZY transactions.

           FSTRANS_SUSPENDED      Block all transactions.

           A thread that changes a file system to a state other than
           FSTRANS_NORMAL enters a transaction for the purposes of
           fstrans_getstate() until it changes state back to FSTRANS_NORMAL.

           Additionally, a thread that changes a file system to a state other
           than FSTRANS_NORMAL acquires an exclusive lock on the file system
           state, so that fstrans_is_owner() will return true in that thread,
           and no other thread can change the file system's state until the
           owner restores it to FSTRANS_NORMAL.

           May sleep, and may be interrupted by a signal.  On success, return
           zero.  On failure, restore the file system to the FSTRANS_NORMAL
           state and return an error code.  fstrans_setstate() never fails if
           new_state is FSTRANS_NORMAL.

     fstrans_is_owner(mp)
           Return true if the current thread is currently suspending the file
           system mp.

     fscow_establish(mp, func, cookie)
           Establish a copy-on-write callback for the file system mp.  The
           function func will be called for every buffer bp written through
           this file system as
                 func(cookie, bp, data_valid)
           where data_valid is true if and only if the buffer bp has not yet
           been modified.

           May sleep.

     fscow_disestablish(mp, func, cookie)
           Disestablish a copy-on-write callback established with
           fscow_establish().

           May sleep.

     fscow_run(bp, data_valid)
           Run all copy-on-write callbacks established for the file system
           this buffer belongs to, if they have not already been run for this
           buffer.  If data_valid is true the buffer data has not yet been
           modified.

           May sleep.

EXAMPLES
     The following is an example of a file system suspend operation.

     int
     xxx_suspendctl(struct mount *mp, int cmd)
     {
             int error;

             switch (cmd) {
             case SUSPEND_SUSPEND:
                     error = fstrans_setstate(mp, FSTRANS_SUSPENDING);
                     if (error)
                             return error;
                     return fstrans_setstate(mp, FSTRANS_SUSPENDED);

             case SUSPEND_RESUME:
                     return fstrans_setstate(mp, FSTRANS_NORMAL);

             default:
                     return EINVAL;
             }
     }

     This is an example of a file system operation.

     int
     xxx_create(void *v)
     {
             struct vop_create_args *ap = v;
             struct mount *mp = ap->a_dvp->v_mount;
             int error;

             fstrans_start(mp);

             /* Actually create the node. */

             fstrans_done(mp);

             return 0;
     }

CODE REFERENCES
     The fstrans subsystem is implemented in the file sys/kern/vfs_trans.c.

SEE ALSO
     vfs_resume(9), vfs_suspend(9)

HISTORY
     The fstrans subsystem appeared in NetBSD 5.0.

AUTHORS
     The fstrans subsystem was written by J"urgen Hannken-Illjes
     <hannken@NetBSD.org>.

BUGS
     fstrans is useful only for temporary suspension -- it does not help to
     permanently block file system operations for unmounting, because
     fstrans_start() cannot fail.

NetBSD 10.99                    October 4, 2018                   NetBSD 10.99