Changeset View
Standalone View
sys/sys/mount.h
Show First 20 Lines • Show All 185 Lines • ▼ Show 20 Lines | struct mount_pcpu { | ||||
int mntp_lockref; | int mntp_lockref; | ||||
int mntp_writeopcount; | int mntp_writeopcount; | ||||
}; | }; | ||||
_Static_assert(sizeof(struct mount_pcpu) == 16, | _Static_assert(sizeof(struct mount_pcpu) == 16, | ||||
"the struct is allocated from pcpu 16 zone"); | "the struct is allocated from pcpu 16 zone"); | ||||
/* | /* | ||||
* Structure for tracking a stacked filesystem mounted above another | |||||
* filesystem. This is expected to be stored in the upper FS' per-mount data. | |||||
* | |||||
* Lock reference: | |||||
* i - lower mount interlock | |||||
* c - constant from node initialization | |||||
*/ | |||||
struct mount_upper_node { | |||||
struct mount *mp; /* (c) mount object for upper FS */ | |||||
TAILQ_ENTRY(mount_upper_node) mnt_upper_link; /* (i) position in uppers list */ | |||||
}; | |||||
/* | |||||
* Structure per mounted filesystem. Each mounted filesystem has an | * Structure per mounted filesystem. Each mounted filesystem has an | ||||
* array of operations and an instance record. The filesystems are | * array of operations and an instance record. The filesystems are | ||||
* put on a doubly linked list. | * put on a doubly linked list. | ||||
* | * | ||||
* Lock reference: | * Lock reference: | ||||
* l - mnt_listmtx | * l - mnt_listmtx | ||||
* m - mountlist_mtx | * m - mountlist_mtx | ||||
* i - interlock | * i - interlock | ||||
* i* - interlock of uppers' list head | |||||
* v - vnode freelist mutex | * v - vnode freelist mutex | ||||
* d - deferred unmount list mutex | |||||
* | * | ||||
* Unmarked fields are considered stable as long as a ref is held. | * Unmarked fields are considered stable as long as a ref is held. | ||||
* | * | ||||
*/ | */ | ||||
struct mount { | struct mount { | ||||
int mnt_vfs_ops; /* (i) pending vfs ops */ | int mnt_vfs_ops; /* (i) pending vfs ops */ | ||||
int mnt_kern_flag; /* (i) kernel only flags */ | int mnt_kern_flag; /* (i) kernel only flags */ | ||||
uint64_t mnt_flag; /* (i) flags shared with user */ | uint64_t mnt_flag; /* (i) flags shared with user */ | ||||
Show All 25 Lines | #define mnt_startzero mnt_list | ||||
int mnt_secondary_writes; /* (i) # of secondary writes */ | int mnt_secondary_writes; /* (i) # of secondary writes */ | ||||
int mnt_secondary_accwrites;/* (i) secondary wr. starts */ | int mnt_secondary_accwrites;/* (i) secondary wr. starts */ | ||||
struct thread *mnt_susp_owner; /* (i) thread owning suspension */ | struct thread *mnt_susp_owner; /* (i) thread owning suspension */ | ||||
#define mnt_endzero mnt_gjprovider | #define mnt_endzero mnt_gjprovider | ||||
char *mnt_gjprovider; /* gjournal provider name */ | char *mnt_gjprovider; /* gjournal provider name */ | ||||
struct mtx mnt_listmtx; | struct mtx mnt_listmtx; | ||||
struct vnodelst mnt_lazyvnodelist; /* (l) list of lazy vnodes */ | struct vnodelst mnt_lazyvnodelist; /* (l) list of lazy vnodes */ | ||||
int mnt_lazyvnodelistsize; /* (l) # of lazy vnodes */ | int mnt_lazyvnodelistsize; /* (l) # of lazy vnodes */ | ||||
int mnt_pinned_count; /* (i) unmount prevented */ | int mnt_upper_pending; /* (i) # of pending ops on mnt_uppers */ | ||||
struct lock mnt_explock; /* vfs_export walkers lock */ | struct lock mnt_explock; /* vfs_export walkers lock */ | ||||
TAILQ_ENTRY(mount) mnt_upper_link; /* (i*) we in the all uppers */ | TAILQ_HEAD(, mount_upper_node) mnt_uppers; /* (i) upper mounts over us */ | ||||
TAILQ_HEAD(, mount) mnt_uppers; /* (i) upper mounts over us */ | TAILQ_HEAD(, mount_upper_node) mnt_notify; /* (i) upper mounts for notification */ | ||||
STAILQ_ENTRY(mount) taskqueue_link; /* (d) our place in deferred unmount list */ | |||||
chs: All the other struct mount fields have a "mnt_" prefix, these new ones ought to have that… | |||||
jahAuthorUnsubmitted Done Inline ActionsDone. jah: Done. | |||||
uint64_t taskqueue_flags; /* (d) unmount flags passed from taskqueue */ | |||||
}; | }; | ||||
#endif /* _WANT_MOUNT || _KERNEL */ | #endif /* _WANT_MOUNT || _KERNEL */ | ||||
#ifdef _KERNEL | #ifdef _KERNEL | ||||
/* | /* | ||||
* Definitions for MNT_VNODE_FOREACH_ALL. | * Definitions for MNT_VNODE_FOREACH_ALL. | ||||
*/ | */ | ||||
struct vnode *__mnt_vnode_next_all(struct vnode **mvp, struct mount *mp); | struct vnode *__mnt_vnode_next_all(struct vnode **mvp, struct mount *mp); | ||||
▲ Show 20 Lines • Show All 160 Lines • ▼ Show 20 Lines | #define MNT_UPDATEMASK (MNT_NOSUID | MNT_NOEXEC | \ | ||||
MNT_NOATIME | \ | MNT_NOATIME | \ | ||||
MNT_NOSYMFOLLOW | MNT_IGNORE | \ | MNT_NOSYMFOLLOW | MNT_IGNORE | \ | ||||
MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR | \ | MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR | \ | ||||
MNT_ACLS | MNT_USER | MNT_NFS4ACLS | \ | MNT_ACLS | MNT_USER | MNT_NFS4ACLS | \ | ||||
MNT_AUTOMOUNTED | MNT_UNTRUSTED) | MNT_AUTOMOUNTED | MNT_UNTRUSTED) | ||||
/* | /* | ||||
* External filesystem command modifier flags. | * External filesystem command modifier flags. | ||||
* Unmount can use the MNT_FORCE flag. | * Unmount can use the MNT_FORCE flag. | ||||
chsUnsubmitted Not Done Inline ActionsYou should update this comment with the names of any new flags that are now valid to use with unmount(). It looks like MNT_BYFSID can already be used with unmount, so that flag should be listed here too. chs: You should update this comment with the names of any new flags that are now valid to use with… | |||||
* XXX: These are not STATES and really should be somewhere else. | * XXX: These are not STATES and really should be somewhere else. | ||||
* XXX: MNT_BYFSID and MNT_NONBUSY collide with MNT_ACLS and MNT_MULTILABEL, | * XXX: MNT_BYFSID and MNT_NONBUSY collide with MNT_ACLS and MNT_MULTILABEL, | ||||
* but because MNT_ACLS and MNT_MULTILABEL are only used for mount(2), | * but because MNT_ACLS and MNT_MULTILABEL are only used for mount(2), | ||||
* and MNT_BYFSID and MNT_NONBUSY are only used for unmount(2), | * and MNT_BYFSID and MNT_NONBUSY are only used for unmount(2), | ||||
* it's harmless. | * it's harmless. | ||||
*/ | */ | ||||
#define MNT_UPDATE 0x0000000000010000ULL /* not real mount, just update */ | #define MNT_UPDATE 0x0000000000010000ULL /* not real mount, just update */ | ||||
#define MNT_DELEXPORT 0x0000000000020000ULL /* delete export host lists */ | #define MNT_DELEXPORT 0x0000000000020000ULL /* delete export host lists */ | ||||
#define MNT_RELOAD 0x0000000000040000ULL /* reload filesystem data */ | #define MNT_RELOAD 0x0000000000040000ULL /* reload filesystem data */ | ||||
#define MNT_FORCE 0x0000000000080000ULL /* force unmount or readonly */ | #define MNT_FORCE 0x0000000000080000ULL /* force unmount or readonly */ | ||||
#define MNT_SNAPSHOT 0x0000000001000000ULL /* snapshot the filesystem */ | #define MNT_SNAPSHOT 0x0000000001000000ULL /* snapshot the filesystem */ | ||||
#define MNT_NONBUSY 0x0000000004000000ULL /* check vnode use counts. */ | #define MNT_NONBUSY 0x0000000004000000ULL /* check vnode use counts. */ | ||||
#define MNT_BYFSID 0x0000000008000000ULL /* specify filesystem by ID. */ | #define MNT_BYFSID 0x0000000008000000ULL /* specify filesystem by ID. */ | ||||
#define MNT_NOCOVER 0x0000001000000000ULL /* Do not cover a mount point */ | #define MNT_NOCOVER 0x0000001000000000ULL /* Do not cover a mount point */ | ||||
#define MNT_EMPTYDIR 0x0000002000000000ULL /* Only mount on empty dir */ | #define MNT_EMPTYDIR 0x0000002000000000ULL /* Only mount on empty dir */ | ||||
#define MNT_RECURSE 0x0000100000000000ULL /* recursively unmount uppers */ | |||||
#define MNT_TASKQUEUE 0x0000200000000000ULL /* unmount in taskqueue context */ | |||||
chsUnsubmitted Not Done Inline ActionsThe MNT_* flags are part of the syscall interface, and the name of an interface flag ought to describe what it does rather than how it does it. This is really about making the unmount asynchronous, and the fact that a taskqueue is the kernel abstraction that is used to make the operation asynchronous is just an internal detail. I would suggest "MNT_ASYNC" as the name, but I see there's already a flag with that name. However, MNT_ASYNC is currently only used for mount and not for unmount, so there would be no ambiguity to use the existing MNT_ASYNC flag in this new context. Or are these new flags not intended to be part of the syscall interface? I don't see any change here to add support in the umount command for using these new flags. chs: The MNT_* flags are part of the syscall interface, and the name of an interface flag ought to… | |||||
jahAuthorUnsubmitted Done Inline ActionsGood point, I've renamed MNT_TASKQUEUE to MNT_DEFERRED. That said, these new flags aren't intended to be exposed through the sysctl interface. I wouldn't object to exposing MNT_RECURSE through something like a '-r' option to umount(8), but I see no reason to ever expose MNT_DEFERRED to userspace. This reminds me of something that occurred to me while I was writing the code though: these flags are effectively prevented from being exposed to userspace because they're outside the 32-bit range of unmount_args->flags. jah: Good point, I've renamed MNT_TASKQUEUE to MNT_DEFERRED. That said, these new flags aren't… | |||||
#define MNT_CMDFLAGS (MNT_UPDATE | MNT_DELEXPORT | MNT_RELOAD | \ | #define MNT_CMDFLAGS (MNT_UPDATE | MNT_DELEXPORT | MNT_RELOAD | \ | ||||
MNT_FORCE | MNT_SNAPSHOT | MNT_NONBUSY | \ | MNT_FORCE | MNT_SNAPSHOT | MNT_NONBUSY | \ | ||||
MNT_BYFSID | MNT_NOCOVER | MNT_EMPTYDIR) | MNT_BYFSID | MNT_NOCOVER | MNT_EMPTYDIR | \ | ||||
MNT_RECURSE | MNT_TASKQUEUE) | |||||
/* | /* | ||||
* Internal filesystem control flags stored in mnt_kern_flag. | * Internal filesystem control flags stored in mnt_kern_flag. | ||||
* | * | ||||
* MNTK_UNMOUNT locks the mount entry so that name lookup cannot | * MNTK_UNMOUNT locks the mount entry so that name lookup cannot | ||||
* proceed past the mount point. This keeps the subtree stable during | * proceed past the mount point. This keeps the subtree stable during | ||||
* mounts and unmounts. When non-forced unmount flushes all vnodes | * mounts and unmounts. When non-forced unmount flushes all vnodes | ||||
* from the mp queue, the MNTK_UNMOUNT flag prevents insmntque() from | * from the mp queue, the MNTK_UNMOUNT flag prevents insmntque() from | ||||
* queueing new vnodes. | * queueing new vnodes. | ||||
Show All 9 Lines | |||||
#define MNTK_NOMSYNC 0x00000008 /* don't do msync */ | #define MNTK_NOMSYNC 0x00000008 /* don't do msync */ | ||||
#define MNTK_DRAINING 0x00000010 /* lock draining is happening */ | #define MNTK_DRAINING 0x00000010 /* lock draining is happening */ | ||||
#define MNTK_REFEXPIRE 0x00000020 /* refcount expiring is happening */ | #define MNTK_REFEXPIRE 0x00000020 /* refcount expiring is happening */ | ||||
#define MNTK_EXTENDED_SHARED 0x00000040 /* Allow shared locking for more ops */ | #define MNTK_EXTENDED_SHARED 0x00000040 /* Allow shared locking for more ops */ | ||||
#define MNTK_SHARED_WRITES 0x00000080 /* Allow shared locking for writes */ | #define MNTK_SHARED_WRITES 0x00000080 /* Allow shared locking for writes */ | ||||
#define MNTK_NO_IOPF 0x00000100 /* Disallow page faults during reads | #define MNTK_NO_IOPF 0x00000100 /* Disallow page faults during reads | ||||
and writes. Filesystem shall properly | and writes. Filesystem shall properly | ||||
handle i/o state on EFAULT. */ | handle i/o state on EFAULT. */ | ||||
#define MNTK_VGONE_UPPER 0x00000200 | #define MNTK_RECURSE 0x00000200 /* pending recursive unmount */ | ||||
#define MNTK_VGONE_WAITER 0x00000400 | #define MNTK_UPPER_WAITER 0x00000400 /* waiting to drain MNTK_UPPER_PENDING */ | ||||
#define MNTK_LOOKUP_EXCL_DOTDOT 0x00000800 | #define MNTK_LOOKUP_EXCL_DOTDOT 0x00000800 | ||||
#define MNTK_MARKER 0x00001000 | |||||
#define MNTK_UNMAPPED_BUFS 0x00002000 | #define MNTK_UNMAPPED_BUFS 0x00002000 | ||||
#define MNTK_USES_BCACHE 0x00004000 /* FS uses the buffer cache. */ | #define MNTK_USES_BCACHE 0x00004000 /* FS uses the buffer cache. */ | ||||
#define MNTK_TEXT_REFS 0x00008000 /* Keep use ref for text */ | #define MNTK_TEXT_REFS 0x00008000 /* Keep use ref for text */ | ||||
#define MNTK_VMSETSIZE_BUG 0x00010000 | #define MNTK_VMSETSIZE_BUG 0x00010000 | ||||
#define MNTK_UNIONFS 0x00020000 /* A hack for F_ISUNIONSTACK */ | #define MNTK_UNIONFS 0x00020000 /* A hack for F_ISUNIONSTACK */ | ||||
#define MNTK_FPLOOKUP 0x00040000 /* fast path lookup is supported */ | #define MNTK_FPLOOKUP 0x00040000 /* fast path lookup is supported */ | ||||
#define MNTK_SUSPEND_ALL 0x00080000 /* Suspended by all-fs suspension */ | #define MNTK_SUSPEND_ALL 0x00080000 /* Suspended by all-fs suspension */ | ||||
#define MNTK_TASKQUEUE_WAITER 0x00100000 /* Waiting on unmount taskqueue */ | |||||
#define MNTK_NOASYNC 0x00800000 /* disable async */ | #define MNTK_NOASYNC 0x00800000 /* disable async */ | ||||
#define MNTK_UNMOUNT 0x01000000 /* unmount in progress */ | #define MNTK_UNMOUNT 0x01000000 /* unmount in progress */ | ||||
#define MNTK_MWAIT 0x02000000 /* waiting for unmount to finish */ | #define MNTK_MWAIT 0x02000000 /* waiting for unmount to finish */ | ||||
#define MNTK_SUSPEND 0x08000000 /* request write suspension */ | #define MNTK_SUSPEND 0x08000000 /* request write suspension */ | ||||
#define MNTK_SUSPEND2 0x04000000 /* block secondary writes */ | #define MNTK_SUSPEND2 0x04000000 /* block secondary writes */ | ||||
#define MNTK_SUSPENDED 0x10000000 /* write operations are suspended */ | #define MNTK_SUSPENDED 0x10000000 /* write operations are suspended */ | ||||
#define MNTK_NULL_NOCACHE 0x20000000 /* auto disable cache for nullfs | #define MNTK_NULL_NOCACHE 0x20000000 /* auto disable cache for nullfs | ||||
mounts over this fs */ | mounts over this fs */ | ||||
#define MNTK_LOOKUP_SHARED 0x40000000 /* FS supports shared lock lookups */ | #define MNTK_LOOKUP_SHARED 0x40000000 /* FS supports shared lock lookups */ | ||||
#define MNTK_NOKNOTE 0x80000000 /* Don't send KNOTEs from VOP hooks */ | #define MNTK_NOKNOTE 0x80000000 /* Don't send KNOTEs from VOP hooks */ | ||||
▲ Show 20 Lines • Show All 457 Lines • ▼ Show 20 Lines | static moduledata_t fsname ## _mod = { \ | ||||
& fsname ## _vfsconf \ | & fsname ## _vfsconf \ | ||||
}; \ | }; \ | ||||
DECLARE_MODULE(fsname, fsname ## _mod, SI_SUB_VFS, SI_ORDER_MIDDLE) | DECLARE_MODULE(fsname, fsname ## _mod, SI_SUB_VFS, SI_ORDER_MIDDLE) | ||||
/* | /* | ||||
* exported vnode operations | * exported vnode operations | ||||
*/ | */ | ||||
int dounmount(struct mount *, int, struct thread *); | int dounmount(struct mount *, uint64_t, struct thread *); | ||||
int kernel_mount(struct mntarg *ma, uint64_t flags); | int kernel_mount(struct mntarg *ma, uint64_t flags); | ||||
int kernel_vmount(int flags, ...); | int kernel_vmount(int flags, ...); | ||||
struct mntarg *mount_arg(struct mntarg *ma, const char *name, const void *val, int len); | struct mntarg *mount_arg(struct mntarg *ma, const char *name, const void *val, int len); | ||||
struct mntarg *mount_argb(struct mntarg *ma, int flag, const char *name); | struct mntarg *mount_argb(struct mntarg *ma, int flag, const char *name); | ||||
struct mntarg *mount_argf(struct mntarg *ma, const char *name, const char *fmt, ...); | struct mntarg *mount_argf(struct mntarg *ma, const char *name, const char *fmt, ...); | ||||
struct mntarg *mount_argsu(struct mntarg *ma, const char *name, const void *val, int len); | struct mntarg *mount_argsu(struct mntarg *ma, const char *name, const void *val, int len); | ||||
void statfs_scale_blocks(struct statfs *sf, long max_size); | void statfs_scale_blocks(struct statfs *sf, long max_size); | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | |||||
struct mount *vfs_ref_from_vp(struct vnode *); | struct mount *vfs_ref_from_vp(struct vnode *); | ||||
void vfs_ref(struct mount *); | void vfs_ref(struct mount *); | ||||
void vfs_rel(struct mount *); | void vfs_rel(struct mount *); | ||||
struct mount *vfs_mount_alloc(struct vnode *, struct vfsconf *, const char *, | struct mount *vfs_mount_alloc(struct vnode *, struct vfsconf *, const char *, | ||||
struct ucred *); | struct ucred *); | ||||
int vfs_suser(struct mount *, struct thread *); | int vfs_suser(struct mount *, struct thread *); | ||||
void vfs_unbusy(struct mount *); | void vfs_unbusy(struct mount *); | ||||
void vfs_unmountall(void); | void vfs_unmountall(void); | ||||
struct mount *vfs_pin_from_vp(struct vnode *); | struct mount *vfs_register_upper_from_vp(struct vnode *, | ||||
void vfs_unpin(struct mount *); | struct mount *ump, struct mount_upper_node *); | ||||
void vfs_register_for_notification(struct mount *, struct mount *, | |||||
struct mount_upper_node *); | |||||
void vfs_unregister_for_notification(struct mount *, | |||||
struct mount_upper_node *); | |||||
void vfs_unregister_upper(struct mount *, struct mount_upper_node *); | |||||
extern TAILQ_HEAD(mntlist, mount) mountlist; /* mounted filesystem list */ | extern TAILQ_HEAD(mntlist, mount) mountlist; /* mounted filesystem list */ | ||||
extern struct mtx_padalign mountlist_mtx; | extern struct mtx_padalign mountlist_mtx; | ||||
extern struct nfs_public nfs_pub; | extern struct nfs_public nfs_pub; | ||||
extern struct sx vfsconf_sx; | extern struct sx vfsconf_sx; | ||||
#define vfsconf_lock() sx_xlock(&vfsconf_sx) | #define vfsconf_lock() sx_xlock(&vfsconf_sx) | ||||
#define vfsconf_unlock() sx_xunlock(&vfsconf_sx) | #define vfsconf_unlock() sx_xunlock(&vfsconf_sx) | ||||
#define vfsconf_slock() sx_slock(&vfsconf_sx) | #define vfsconf_slock() sx_slock(&vfsconf_sx) | ||||
#define vfsconf_sunlock() sx_sunlock(&vfsconf_sx) | #define vfsconf_sunlock() sx_sunlock(&vfsconf_sx) | ||||
▲ Show 20 Lines • Show All 144 Lines • Show Last 20 Lines |
All the other struct mount fields have a "mnt_" prefix, these new ones ought to have that prefix as well.