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

NAME
     fstrans, fstrans_setstate, fstrans_getstate, fstrans_start,
     fstrans_start_nowait, 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>

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

     enum fstrans_state
     fstrans_getstate(struct mount *mp);

     void
     fstrans_start(struct mount *mp, enum fstrans_lock_type lock_type);

     int
     fstrans_start_nowait(struct mount *mp, enum fstrans_lock_type lock_type);

     void
     fstrans_done(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 is a set of operations to assist file system sus-
     pension.  These operations must not be used outside of file systems.

     File systems supporting this subsystem must set the flag IMNT_HAS_TRANS
     in mnt_iflag.

     File systems are always in one of these states:
           FSTRANS_NORMAL      normal operations.
           FSTRANS_SUSPENDING  preparing a suspension.
           FSTRANS_SUSPENDED   suspended.
     This state is represented by enum fstrans_state.

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

     fstrans_setstate(mp, new_state)
              changes the state of the file system mp to new_state.

     All file system operations use a fstrans lock.  This lock is recursive.
     A thread already owning a lock will always get another lock.  The lock
     has two variants:
           FSTRANS_SHARED  this lock will be granted if the file system is in
                           state FSTRANS_NORMAL.
           FSTRANS_LAZY    this lock will be granted if the file system is in
                           state FSTRANS_NORMAL or FSTRANS_SUSPENDING.  It
                           needs special care because operations using this
                           variant will not block while the file system pre-
                           pares suspension.
     The lock variant is represented by enum fstrans_lock_type.

     fstrans_start(mp, lock_type)
              sets a lock of type lock_type on the file system mp.

     fstrans_start_nowait(mp, lock_type)
              will not wait for a state change of the file system when
              attempting to aquire the lock.  The thread may still sleep while
              attempting to aquire the lock.

     fstrans_done(mp)
              releases a lock on the file system mp.

     fstrans_is_owner(mp)
              returns true if this thread is currently suspending the file
              system mp.

     fscow_establish(mp, func, cookie)
              Establish a copy-on-write callback for the file system mp.  func
              will be called for every buffer written through this file sys-
              tem.

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

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

RETURN VALUES
     The functions fstrans_setstate() and fstrans_start_nowait() return zero
     on success and an error value on failure.

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 != 0)
                             return error;

                     /* Sync file system state to disk. */

                     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;

             if ((error = fstrans_start(mp, FSTRANS_SHARED)) != 0)
                     return error;

             /* Actually create the node. */

             fstrans_done(mp);

             return 0;
     }

SEE ALSO
     vfs_resume(9), vfs_suspend(9)

CODE REFERENCES
     The actual code implementing this subsystem can be found in the file
     sys/kern/vfs_trans.c.

HISTORY
     The fstrans subsystem appeared in NetBSD 5.0.

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

NetBSD 5.0_STABLE              December 2, 2007              NetBSD 5.0_STABLE
