1.\" $NetBSD: fstrans.9,v 1.20 2015/03/31 21:08:06 riastradh Exp $ 2.\" 3.\" Copyright (c) 2007 The NetBSD Foundation, Inc. 4.\" All rights reserved. 5.\" 6.\" This code is derived from software contributed to The NetBSD Foundation 7.\" by Juergen Hannken-Illjes. 8.\" 9.\" Redistribution and use in source and binary forms, with or without 10.\" modification, are permitted provided that the following conditions 11.\" are met: 12.\" 1. Redistributions of source code must retain the above copyright 13.\" notice, this list of conditions and the following disclaimer. 14.\" 2. Redistributions in binary form must reproduce the above copyright 15.\" notice, this list of conditions and the following disclaimer in the 16.\" documentation and/or other materials provided with the distribution. 17.\" 18.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28.\" POSSIBILITY OF SUCH DAMAGE. 29.\" 30.Dd March 31, 2015 31.Dt FSTRANS 9 32.Os 33.Sh NAME 34.Nm fstrans , 35.Nm fstrans_setstate , 36.Nm fstrans_getstate , 37.Nm fstrans_start , 38.Nm fstrans_start_nowait , 39.Nm fstrans_done , 40.Nm fstrans_is_owner , 41.Nm fscow_establish , 42.Nm fscow_disestablish , 43.Nm fscow_run 44.Nd file system suspension helper subsystem 45.Sh SYNOPSIS 46.In sys/mount.h 47.In sys/fstrans.h 48.Ft int 49.Fn fstrans_mount "struct mount *mp" 50.Ft void 51.Fn fstrans_unmount "struct mount *mp" 52.Ft void 53.Fn fstrans_start "struct mount *mp" "enum fstrans_lock_type lock_type" 54.Ft int 55.Fn fstrans_start_nowait "struct mount *mp" "enum fstrans_lock_type lock_type" 56.Ft void 57.Fn fstrans_done "struct mount *mp" 58.Ft int 59.Fn fstrans_setstate "struct mount *mp" "enum fstrans_state new_state" 60.Ft "enum fstrans_state" 61.Fn fstrans_getstate "struct mount *mp" 62.Ft int 63.Fn fstrans_is_owner "struct mount *mp" 64.Ft int 65.Fn fscow_establish "struct mount *mp" \ 66"int (*func)(void *, struct buf *, bool)" "void *cookie" 67.Ft int 68.Fn fscow_disestablish "struct mount *mp" \ 69"int (*func)(void *, struct buf *, bool)" "void *cookie" 70.Ft int 71.Fn fscow_run "struct buf *bp" "bool data_valid" 72.Sh DESCRIPTION 73The 74.Nm 75subsystem assists file system suspension and copy-on-write snapshots. 76.Pp 77For a file system to use 78.Nm , 79its 80.Xr VFS_MOUNT 9 81method must call 82.Fn fstrans_mount , 83and its 84.Xr VFS_UNMOUNT 9 85method must call 86.Fn fstrans_unmount . 87.Pp 88The file system's normal operations, such as its 89.Xr vnodeops 9 , 90must be bracketed by 91.Fn fstrans_start 92and 93.Fn fstrans_done 94in a 95.Em shared 96transaction, which is blocked by suspending the file system and while 97it is suspended. 98.Pp 99Operations needed to sync the file system to its backing store must be 100bracketed by 101.Fn fstrans_start 102and 103.Fn fstrans_done 104in a 105.Em lazy 106transaction, which is allowed while suspending the file system in order 107to sync it to its backing store, but blocked while the file system is 108suspended. 109.Pp 110Transactions are per-thread and nestable: if a thread is already in a 111transaction, it can enter another transaction without blocking. 112Each 113.Fn fstrans_start 114must be paired with 115.Fn fstrans_done . 116Transactions for multiple distinct mount points may not be nested. 117.Pp 118The file system's 119.Xr VFS_SUSPENDCTL 9 120method can use 121.Fn fstrans_setstate 122to: 123.Bl -dash 124.It 125enter the 126.Dv FSTRANS_SUSPENDING 127to suspend all normal operations but allow syncing, 128.It 129enter the 130.Dv FSTRANS_SUSPENDED 131state to suspend all operations once synced, and 132.It 133restore to the 134.Dv FSTRANS_NORMAL 135state to resume all operations. 136.El 137.Pp 138A file system supporting 139.Nm 140may establish a copy-on-write callback with 141.Fn fscow_establish . 142The copy-on-write callback will be called every time a buffer is 143written to a block device with 144.Fn VOP_STRATEGY 145and every time a buffer is read into the 146.Xr buffercache 9 147with 148.Dv B_MODIFY 149set indicating the caller's intent to modify it. 150Anyone modifying a buffer may additionally use 151.Fn fscow_run 152to explicitly invoke the established callback. 153The copy-on-write callback must be disestablished with 154.Fn fscow_disestablish 155when the file system is done with it. 156.Sh FUNCTIONS 157.Bl -tag -width abcd 158.It Fn fstrans_mount "mp" 159Initialize the 160.Nm 161subsystem for the file system mounted at 162.Fa mp . 163Sets 164.Dv IMNT_HAS_TRANS 165in 166.Fa mp Ns Li "->mnt_iflag" . 167Return zero on success, or error code if 168.Xr vfs_busy 9 169fails. 170.Pp 171May sleep. 172.It Fn fstrans_unmount "mp" 173Finalize the 174.Nm 175subsystem. 176Clears 177.Dv IMNT_HAS_TRANS 178in 179.Fa mp Ns Li "->mnt_iflag" . 180Caller is responsible for ensuring that no transactions are active. 181.Pp 182May sleep. 183.It Fn fstrans_start "mp" "lock_type" 184Enter a transaction of type 185.Fa lock_type 186on the file system 187.Fa mp 188in the current thread. 189If the file system is in a state that blocks such transactions, wait 190until it changes state to one that does not. 191.Bl -tag -width FSTRANS_SHARED 192.It Dv FSTRANS_SHARED 193If the file system is suspending or suspended, wait until it is 194resumed. 195Intended for normal file system operations. 196.It Dv FSTRANS_LAZY 197If the file system is suspended, wait until it is resumed. 198Intended for operations needed to sync the file system to its backing 199store in order to suspend it. 200.El 201.Pp 202However, if the current thread is already in a transaction on 203.Fa mp , 204.Fn fstrans_start 205will enter a nested transaction and return immediately without 206waiting. 207.Pp 208May sleep. 209.It Fn fstrans_start_nowait "mp" "lock_type" 210Like 211.Fn fstrans_start , 212but return 213.Dv EBUSY 214immediately if 215.Fa lock_type 216transactions are blocked in its current state. 217.Pp 218May sleep nevertheless on internal locks. 219.It Fn fstrans_done "mp" 220End the current transaction on 221.Fa mp . 222.It Fn fstrans_getstate "mp" 223Return the current state of the file system 224.Fa mp . 225.Pp 226Must be called within a transaction for the answer to be stable. 227.It Fn fstrans_setstate "mp" "new_state" 228Change the state of the file system 229.Fa mp 230to 231.Fa new_state , 232and wait for all transactions not allowed in 233.Fa new_state 234to complete. 235.Bl -tag -width FSTRANS_SUSPENDING 236.It Dv FSTRANS_NORMAL 237Allow all transactions. 238.It Dv FSTRANS_SUSPENDING 239Block 240.Dv FSTRANS_SHARED 241transactions but allow 242.Dv FSTRANS_LAZY 243transactions. 244.It Dv FSTRANS_SUSPENDED 245Block all transactions. 246.El 247.Pp 248A thread that changes a file system to a state other than 249.Dv FSTRANS_NORMAL 250enters a transaction for the purposes of 251.Fn fstrans_getstate 252until it changes state back to 253.Dv FSTRANS_NORMAL . 254.Pp 255Additionally, a thread that changes a file system to a state other than 256.Dv FSTRANS_NORMAL 257acquires an exclusive lock on the file system state, so that 258.Fn fstrans_is_owner 259will return true in that thread, and no other thread can change the 260file system's state until the owner restores it to 261.Dv FSTRANS_NORMAL . 262.Pp 263May sleep, and may be interrupted by a signal. 264On success, return zero. 265On failure, restore the file system to the 266.Dv FSTRANS_NORMAL 267state and return an error code. 268.Fn fstrans_setstate 269never fails if 270.Fa new_state 271is 272.Dv FSTRANS_NORMAL . 273.It Fn fstrans_is_owner "mp" 274Return 275.Dv true 276if the current thread is currently suspending the file system 277.Fa mp . 278.It Fn fscow_establish "mp" "func" "cookie" 279Establish a copy-on-write callback for the file system 280.Fa mp . 281The function 282.Fa func 283will be called for every buffer 284.Fa bp 285written through this file system as 286.Dl Fa func Ns Li "(" Ns Fa cookie Ns Li "," Fa bp Ns Li "," Fa data_valid Ns Li ")" 287where 288.Fa data_valid 289is true if and only if the buffer 290.Fa bp 291has not yet been modified. 292.Pp 293May sleep. 294.It Fn fscow_disestablish "mp" "func" "cookie" 295Disestablish a copy-on-write callback established with 296.Fn fscow_establish . 297.Pp 298May sleep. 299.It Fn fscow_run "bp" "data_valid" 300Run all copy-on-write callbacks established for the file system this buffer 301belongs to, if they have not already been run for this buffer. 302If 303.Fa data_valid 304is 305.Dv true 306the buffer data has not yet been modified. 307.Pp 308May sleep. 309.El 310.Sh EXAMPLES 311The following is an example of a file system suspend operation. 312.Bd -literal 313int 314xxx_suspendctl(struct mount *mp, int cmd) 315{ 316 int error; 317 318 switch (cmd) { 319 case SUSPEND_SUSPEND: 320 error = fstrans_setstate(mp, FSTRANS_SUSPENDING); 321 if (error) 322 return error; 323 324 /* Sync file system state to disk. */ 325 326 return fstrans_setstate(mp, FSTRANS_SUSPENDED); 327 328 case SUSPEND_RESUME: 329 return fstrans_setstate(mp, FSTRANS_NORMAL); 330 331 default: 332 return EINVAL; 333 } 334} 335.Ed 336.Pp 337This is an example of a file system operation. 338.Bd -literal 339int 340xxx_create(void *v) 341{ 342 struct vop_create_args *ap = v; 343 struct mount *mp = ap-\*[Gt]a_dvp-\*[Gt]v_mount; 344 int error; 345 346 fstrans_start(mp, FSTRANS_SHARED); 347 348 /* Actually create the node. */ 349 350 fstrans_done(mp); 351 352 return 0; 353} 354.Ed 355.Sh CODE REFERENCES 356The 357.Nm 358subsystem is implemented in the file 359.Pa sys/kern/vfs_trans.c . 360.Sh SEE ALSO 361.Xr vfs_resume 9 , 362.Xr vfs_suspend 9 363.Sh HISTORY 364The 365.Nm 366subsystem appeared in 367.Nx 5.0 . 368.Sh AUTHORS 369The 370.Nm 371subsystem was written by 372.An J\(:urgen Hannken-Illjes 373.Aq hannken@NetBSD.org . 374.Sh BUGS 375.Nm 376is useful only for temporary suspension -- it does not help to 377permanently block file system operations for unmounting, because 378.Fn fstrans_start 379cannot fail. 380