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)
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_NORMALFSTRANS_SUSPENDINGFSTRANS_SUSPENDEDmp)mp.
mp, new_state)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_SHAREDFSTRANS_NORMAL.
FSTRANS_LAZYFSTRANS_NORMAL
or
FSTRANS_SUSPENDING.
It needs special care because operations using this variant will not block
while the file system prepares suspension.
mp, lock_type)lock_type
on the file system
mp.
mp, lock_type)mp)mp.
mp)true
if this thread is currently suspending the file system
mp.
mp, func, cookie)mp.
func
will be called for every buffer written through this file system.
mp, func, cookie)).
bp, data_valid)data_valid
is
true
the buffer data has not yet been modified.
)
and
fstrans_start_nowait()
return zero on success and an error value on failure.
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.
if ((error = fstrans_start(mp, FSTRANS_SHARED)) != 0)
return error;
/* Actually create the node. */
fstrans_done(mp);
return 0;
}
int
xxx_create(void *v)
{
struct vop_create_args *ap = v;
struct mount *mp = ap->a_dvp->v_mount;
int error;
sys/kern/vfs_trans.c.