1.\" $NetBSD: fstrans.9,v 1.29 2018/10/05 16:21:22 uwe 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 October 4, 2018 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_start_lazy , 40.Nm fstrans_done , 41.Nm fstrans_is_owner , 42.Nm fscow_establish , 43.Nm fscow_disestablish , 44.Nm fscow_run 45.Nd file system suspension helper subsystem 46.Sh SYNOPSIS 47.In sys/mount.h 48.In sys/fstrans.h 49.Ft void 50.Fn fstrans_start "struct mount *mp" 51.Ft int 52.Fn fstrans_start_nowait "struct mount *mp" 53.Ft void 54.Fn fstrans_start_lazy "struct mount *mp" 55.Ft void 56.Fn fstrans_done "struct mount *mp" 57.Ft int 58.Fn fstrans_setstate "struct mount *mp" "enum fstrans_state new_state" 59.Ft "enum fstrans_state" 60.Fn fstrans_getstate "struct mount *mp" 61.Ft int 62.Fn fstrans_is_owner "struct mount *mp" 63.Ft int 64.Fn fscow_establish "struct mount *mp" \ 65"int (*func)(void *, struct buf *, bool)" "void *cookie" 66.Ft int 67.Fn fscow_disestablish "struct mount *mp" \ 68"int (*func)(void *, struct buf *, bool)" "void *cookie" 69.Ft int 70.Fn fscow_run "struct buf *bp" "bool data_valid" 71.Sh DESCRIPTION 72The 73.Nm 74subsystem assists file system suspension and copy-on-write snapshots. 75.Pp 76The file system's normal operations, such as its 77.Xr vnodeops 9 , 78must be bracketed by 79.Fn fstrans_start 80and 81.Fn fstrans_done 82in a 83.Em shared 84transaction, which is blocked by suspending the file system and while 85it is suspended. 86.Pp 87Operations needed while suspending the file system must be bracketed by 88.Fn fstrans_start_lazy 89and 90.Fn fstrans_done 91in a 92.Em lazy 93transaction, which is allowed while suspending the file system, but 94blocked while the file system is suspended. 95.Pp 96Transactions are per-thread and nestable: if a thread is already in a 97transaction, it can enter another transaction without blocking. 98Each 99.Fn fstrans_start 100must be paired with 101.Fn fstrans_done . 102Transactions for multiple distinct mount points may not be nested. 103.Pp 104The file system's 105.Xr VFS_SUSPENDCTL 9 106method can use 107.Fn fstrans_setstate 108to: 109.Bl -dash 110.It 111enter the 112.Dv FSTRANS_SUSPENDING 113state to suspend all normal operations but allow lazy transactions, 114.It 115enter the 116.Dv FSTRANS_SUSPENDED 117state to suspend all operations, and 118.It 119restore to the 120.Dv FSTRANS_NORMAL 121state to resume all operations. 122.El 123.Pp 124A file system supporting 125.Nm 126may establish a copy-on-write callback with 127.Fn fscow_establish . 128The copy-on-write callback will be called every time a buffer is 129written to a block device with 130.Fn VOP_STRATEGY 131and every time a buffer is read into the 132.Xr buffercache 9 133with 134.Dv B_MODIFY 135set indicating the caller's intent to modify it. 136Anyone modifying a buffer may additionally use 137.Fn fscow_run 138to explicitly invoke the established callback. 139The copy-on-write callback must be disestablished with 140.Fn fscow_disestablish 141when the file system is done with it. 142.Sh FUNCTIONS 143.Bl -tag -width abcd 144.It Fn fstrans_start "mp" 145Enter a transaction on the file system 146.Fa mp 147in the current thread. 148If the file system is in a state that blocks such transactions, wait 149until it changes state to one that does not. 150.Pp 151If the file system is suspended, wait until it is resumed. 152.Pp 153However, if the current thread is already in a transaction on 154.Fa mp , 155.Fn fstrans_start 156will enter a nested transaction and return immediately without 157waiting. 158.Pp 159May sleep. 160.It Fn fstrans_start_nowait "mp" 161Like 162.Fn fstrans_start , 163but return 164.Er EBUSY 165immediately if transactions are blocked in its current state. 166.Pp 167May sleep nevertheless on internal locks. 168.It Fn fstrans_start_lazy "mp" 169Like 170.Fn fstrans_start , 171but will not block while suspending. 172.Pp 173May sleep. 174.It Fn fstrans_done "mp" 175End the current transaction on 176.Fa mp . 177.It Fn fstrans_getstate "mp" 178Return the current state of the file system 179.Fa mp . 180.Pp 181Must be called within a transaction for the answer to be stable. 182.It Fn fstrans_setstate "mp" "new_state" 183Change the state of the file system 184.Fa mp 185to 186.Fa new_state , 187and wait for all transactions not allowed in 188.Fa new_state 189to complete. 190.Bl -tag -width "Dv FSTRANS_SUSPENDING" 191.It Dv FSTRANS_NORMAL 192Allow all transactions. 193.It Dv FSTRANS_SUSPENDING 194Block 195.Dv FSTRANS_SHARED 196transactions but allow 197.Dv FSTRANS_LAZY 198transactions. 199.It Dv FSTRANS_SUSPENDED 200Block all transactions. 201.El 202.Pp 203A thread that changes a file system to a state other than 204.Dv FSTRANS_NORMAL 205enters a transaction for the purposes of 206.Fn fstrans_getstate 207until it changes state back to 208.Dv FSTRANS_NORMAL . 209.Pp 210Additionally, a thread that changes a file system to a state other than 211.Dv FSTRANS_NORMAL 212acquires an exclusive lock on the file system state, so that 213.Fn fstrans_is_owner 214will return true in that thread, and no other thread can change the 215file system's state until the owner restores it to 216.Dv FSTRANS_NORMAL . 217.Pp 218May sleep, and may be interrupted by a signal. 219On success, return zero. 220On failure, restore the file system to the 221.Dv FSTRANS_NORMAL 222state and return an error code. 223.Fn fstrans_setstate 224never fails if 225.Fa new_state 226is 227.Dv FSTRANS_NORMAL . 228.It Fn fstrans_is_owner "mp" 229Return 230.Dv true 231if the current thread is currently suspending the file system 232.Fa mp . 233.It Fn fscow_establish "mp" "func" "cookie" 234Establish a copy-on-write callback for the file system 235.Fa mp . 236The function 237.Fa func 238will be called for every buffer 239.Fa bp 240written through this file system as 241.Dl Fa func Ns ( Fa cookie , Fa bp , Fa data_valid ) 242where 243.Fa data_valid 244is true if and only if the buffer 245.Fa bp 246has not yet been modified. 247.Pp 248May sleep. 249.It Fn fscow_disestablish "mp" "func" "cookie" 250Disestablish a copy-on-write callback established with 251.Fn fscow_establish . 252.Pp 253May sleep. 254.It Fn fscow_run "bp" "data_valid" 255Run all copy-on-write callbacks established for the file system this buffer 256belongs to, if they have not already been run for this buffer. 257If 258.Fa data_valid 259is 260.Dv true 261the buffer data has not yet been modified. 262.Pp 263May sleep. 264.El 265.Sh EXAMPLES 266The following is an example of a file system suspend operation. 267.Bd -literal 268int 269xxx_suspendctl(struct mount *mp, int cmd) 270{ 271 int error; 272 273 switch (cmd) { 274 case SUSPEND_SUSPEND: 275 error = fstrans_setstate(mp, FSTRANS_SUSPENDING); 276 if (error) 277 return error; 278 return fstrans_setstate(mp, FSTRANS_SUSPENDED); 279 280 case SUSPEND_RESUME: 281 return fstrans_setstate(mp, FSTRANS_NORMAL); 282 283 default: 284 return EINVAL; 285 } 286} 287.Ed 288.Pp 289This is an example of a file system operation. 290.Bd -literal 291int 292xxx_create(void *v) 293{ 294 struct vop_create_args *ap = v; 295 struct mount *mp = ap->a_dvp->v_mount; 296 int error; 297 298 fstrans_start(mp); 299 300 /* Actually create the node. */ 301 302 fstrans_done(mp); 303 304 return 0; 305} 306.Ed 307.Sh CODE REFERENCES 308The 309.Nm 310subsystem is implemented in the file 311.Pa sys/kern/vfs_trans.c . 312.Sh SEE ALSO 313.Xr vfs_resume 9 , 314.Xr vfs_suspend 9 315.Sh HISTORY 316The 317.Nm 318subsystem appeared in 319.Nx 5.0 . 320.Sh AUTHORS 321The 322.Nm 323subsystem was written by 324.An J\(:urgen Hannken-Illjes 325.Aq hannken@NetBSD.org . 326.Sh BUGS 327.Nm 328is useful only for temporary suspension \(em it does not help to 329permanently block file system operations for unmounting, because 330.Fn fstrans_start 331cannot fail. 332