Module Name: src Committed By: riastradh Date: Tue Mar 31 15:47:50 UTC 2015
Modified Files: src/share/man/man9: fstrans.9 Log Message: Revamp fstrans(9) man page. - Fix example: fstrans_start never fails and returns void. - Add fstrans_mount/fstrans_unmount. - Explain intent, not just mechanism. - Add internal cross-references and redundant information from different callers' perspectives. To generate a diff of this commit: cvs rdiff -u -r1.16 -r1.17 src/share/man/man9/fstrans.9 Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/share/man/man9/fstrans.9 diff -u src/share/man/man9/fstrans.9:1.16 src/share/man/man9/fstrans.9:1.17 --- src/share/man/man9/fstrans.9:1.16 Tue Sep 17 19:58:03 2013 +++ src/share/man/man9/fstrans.9 Tue Mar 31 15:47:50 2015 @@ -1,4 +1,4 @@ -.\" $NetBSD: fstrans.9,v 1.16 2013/09/17 19:58:03 wiz Exp $ +.\" $NetBSD: fstrans.9,v 1.17 2015/03/31 15:47:50 riastradh Exp $ .\" .\" Copyright (c) 2007 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -27,7 +27,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd April 13, 2010 +.Dd March 31, 2015 .Dt FSTRANS 9 .Os .Sh NAME @@ -46,9 +46,9 @@ .In sys/mount.h .In sys/fstrans.h .Ft int -.Fn fstrans_setstate "struct mount *mp" "enum fstrans_state new_state" -.Ft "enum fstrans_state" -.Fn fstrans_getstate "struct mount *mp" +.Fn fstrans_mount "struct mount *mp" +.Ft void +.Fn fstrans_unmount "struct mount *mp" .Ft void .Fn fstrans_start "struct mount *mp" "enum fstrans_lock_type lock_type" .Ft int @@ -56,6 +56,10 @@ .Ft void .Fn fstrans_done "struct mount *mp" .Ft int +.Fn fstrans_setstate "struct mount *mp" "enum fstrans_state new_state" +.Ft "enum fstrans_state" +.Fn fstrans_getstate "struct mount *mp" +.Ft int .Fn fstrans_is_owner "struct mount *mp" .Ft int .Fn fscow_establish "struct mount *mp" \ @@ -68,105 +72,224 @@ .Sh DESCRIPTION The .Nm -subsystem is a set of operations to assist file system suspension. -These operations must not be used outside of file systems. +subsystem assists file system suspension and copy-on-write snapshots. .Pp -File systems supporting this subsystem must set the flag -.Dv IMNT_HAS_TRANS -in -.Dv "mnt_iflag" . +For a file system to use +.Nm , +its +.Xr VFS_MOUNT 9 +method must call +.Fn fstrans_mount , +and its +.Xr VFS_UNMOUNT 9 +method must call +.Fn fstrans_unmount . .Pp -File systems are always in one of these states: +The file system's normal operations, such as its +.Xr vnodeops 9 , +must be bracketed by +.Fn fstrans_start +and +.Fn fstrans_done +in a +.Em shared +transaction, which is blocked by suspending the file system and while +it is suspended. .Pp -.Bl -tag -offset indent -width FSTRANS_SUSPENDING -compact -.It Dv FSTRANS_NORMAL -Normal operations. -.It Dv FSTRANS_SUSPENDING -Preparing a suspension. -.It Dv FSTRANS_SUSPENDED -Suspended. -.El +Operations needed to sync the file system to its backing store must be +bracketed by +.Fn fstrans_start +and +.Fn fstrans_done +in a +.Em lazy +transaction, which is allowed while suspending the file system in order +to sync it to its backing store, but blocked while the file system is +suspended. .Pp -This state is represented by -.Vt "enum fstrans_state" . +Transactions are per-thread and nestable: if a thread is already in a +transaction, it can enter another transaction. +Each +.Fn fstrans_start +must be paired with +.Fn fstrans_done . +Entering a shared transaction while in a lazy transaction is not +allowed and will lead to deadlock. .Pp -All file system operations use a -.Em "fstrans lock" . -This lock is recursive. -A thread already owning a lock will always get another lock. -The lock has two variants: -.Bl -tag -offset indent -width FSTRANS_SHARED -.It Dv FSTRANS_SHARED -A lock that will be granted if the file system is in state -.Dv FSTRANS_NORMAL . -.It Dv FSTRANS_LAZY -A lock that will be granted if the file system is in state +The file system's +.Xr VFS_SUSPENDCTL 9 +method can use +.Fn fstrans_setstate +to: +.Bl -dash +.It +enter the +.Dv FSTRANS_SUSPENDING +to suspend all normal operations but allow syncing, +.It +enter the +.Dv FSTRANS_SUSPENDED +state to suspend all operations once synced, and +.It +restore to the .Dv FSTRANS_NORMAL -or -.Dv FSTRANS_SUSPENDING . -It needs special care because operations using this variant will not block -while the file system prepares suspension. +state to resume all operations. .El .Pp -The lock variant is represented by -.Vt "enum fstrans_lock_type" . +A file system supporting +.Nm +may establish a copy-on-write callback with +.Fn fscow_establish . +The copy-on-write callback will be called every time a buffer is +written to a block device with +.Fn VOP_STRATEGY +and every time a buffer is read into the +.Xr buffercache 9 +with +.Dv B_MODIFY +set indicating the caller's intent to modify it. +Anyone modifying a buffer may additionally use +.Fn fscow_run +to explicitly invoke the established callback. +The copy-on-write callback must be disestablished with +.Fn fscow_disestablish +when the file system is done with it. .Sh FUNCTIONS -The following functions comprise the -.Tn API -provided by -.Nm . -.Bl -tag -width compact -.It Fn fstrans_getstate "mp" -Returns the current state of the file system +.Bl -tag -width abcd +.It Fn fstrans_mount "mp" +Initialize the +.Nm +subsystem for the file system mounted at .Fa mp . -.It Fn fstrans_setstate "mp" "new_state" -Changes the state of the file system -.Fa mp -to -.Fa new_state . +Sets +.Dv IMNT_HAS_TRANS +in +.Fa mp Ns Li "->mnt_iflag" . +Return zero on success, or error code if +.Xr vfs_busy 9 +fails. +.It Fn fstrans_unmount "mp" +Finalize the +.Nm +subsystem. +Clears +.Dv IMNT_HAS_TRANS +in +.Fa mp Ns Li "->mnt_iflag" . +Caller is responsible for ensuring that no transactions are active. .It Fn fstrans_start "mp" "lock_type" -Sets a lock of type +Begin a transaction of type .Fa lock_type on the file system -.Fa mp . +.Fa 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. +.Bl -tag -width FSTRANS_SHARED +.It Dv FSTRANS_SHARED +If the file system is suspending or suspended, wait until it is +resumed. +Intended for normal file system operations. +.It Dv FSTRANS_LAZY +If the file system is suspended, wait until it is resumed. +Intended for operations needed to sync the file system to its backing +store in order to suspend it. +.El .It Fn fstrans_start_nowait "mp" "lock_type" Like .Fn fstrans_start , -but will not wait for a state change of the file system when attempting to -acquire the lock. -The thread may still sleep while attempting to acquire the lock. +but return +.Dv EBUSY +immediately if +.Fa lock_type +transactions are blocked in its current state. +.Pp +May sleep nevertheless on internal locks. .It Fn fstrans_done "mp" -Releases a lock on the file system +End the current transaction on +.Fa mp . +.It Fn fstrans_getstate "mp" +Return the current state of the file system .Fa mp . +.Pp +Must be called within a transaction for the answer to be stable. +.It Fn fstrans_setstate "mp" "new_state" +Change the state of the file system +.Fa mp +to +.Fa new_state , +and wait for all transactions not allowed in +.Fa new_state +to complete. +.Bl -tag -width FSTRANS_SUSPENDING +.It Dv FSTRANS_NORMAL +Allow all transactions. +.It Dv FSTRANS_SUSPENDING +Block +.Dv FSTRANS_SHARED +transactions but allow +.Dv FSTRANS_LAZY +transactions. +.It Dv FSTRANS_SUSPENDED +Block all transactions. +.El +.Pp +A thread that changes a file system to a state other than +.Dv FSTRANS_NORMAL +enters a transaction for the purposes of +.Fn fstrans_getstate +until it changes state back to +.Dv FSTRANS_NORMAL . +.Pp +Additionally, a thread that changes a file system to a state other than +.Dv FSTRANS_NORMAL +acquires an exclusive lock on the file system state, so that +.Fn 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 +.Dv FSTRANS_NORMAL . +.Pp +May sleep, and may be interrupted by a signal. +On success, return zero. +On failure, restore the file system to the +.Dv FSTRANS_NORMAL +state and return an error code. +.Fn fstrans_setstate +never fails if +.Fa new_state +is +.Dv FSTRANS_NORMAL . .It Fn fstrans_is_owner "mp" -Returns +Return .Dv true -if this thread is currently suspending the file system +if the current thread is currently suspending the file system .Fa mp . .It Fn fscow_establish "mp" "func" "cookie" Establish a copy-on-write callback for the file system .Fa mp . The function .Fa func -will be called for every buffer written through this file system. +will be called for every buffer +.Fa bp +written through this file system as +.Dl Fa func Ns Li "(" Ns Fa cookie Ns Li "," Fa bp Ns Li "," Fa data_valid Ns Li ")" +where +.Fa data_valid +is true if and only if the buffer +.Fa bp +has not yet been modified. .It Fn fscow_disestablish "mp" "func" "cookie" -Disestablish a copy-on-write callback registered with +Disestablish a copy-on-write callback established with .Fn fscow_establish . .It Fn fscow_run "bp" "data_valid" Run all copy-on-write callbacks established for the file system this buffer -belongs to. +belongs to, if they have not already been run for this buffer. If .Fa data_valid is .Dv true the buffer data has not yet been modified. .El -.Sh RETURN VALUES -The functions -.Fn fstrans_setstate -and -.Fn fstrans_start_nowait -return zero on success and an error value on failure. .Sh EXAMPLES The following is an example of a file system suspend operation. .Bd -literal @@ -178,7 +301,7 @@ xxx_suspendctl(struct mount *mp, int cmd switch (cmd) { case SUSPEND_SUSPEND: error = fstrans_setstate(mp, FSTRANS_SUSPENDING); - if (error != 0) + if (error) return error; /* Sync file system state to disk. */ @@ -203,8 +326,7 @@ xxx_create(void *v) struct mount *mp = ap-\*[Gt]a_dvp-\*[Gt]v_mount; int error; - if ((error = fstrans_start(mp, FSTRANS_SHARED)) != 0) - return error; + fstrans_start(mp, FSTRANS_SHARED); /* Actually create the node. */ @@ -214,7 +336,9 @@ xxx_create(void *v) } .Ed .Sh CODE REFERENCES -The actual code implementing this subsystem can be found in the file +The +.Nm +subsystem is implemented in the file .Pa sys/kern/vfs_trans.c . .Sh SEE ALSO .Xr vfs_resume 9 , @@ -230,3 +354,9 @@ The subsystem was written by .An J\(:urgen Hannken-Illjes .Aq hann...@netbsd.org . +.Sh BUGS +.Nm +is useful only for temporary suspension -- it does not help to +permanently block file system operations for unmounting, because +.Fn fstrans_start +cannot fail.