#ifndef _SYS_VFS_H
#define _SYS_VFS_H
#include <sys/zone.h>
#include <sys/types.h>
#include <sys/t_lock.h>
#include <sys/cred.h>
#include <sys/vnode.h>
#include <sys/statvfs.h>
#include <sys/refstr.h>
#include <sys/avl.h>
#include <sys/time.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct vfsops vfsops_t;
typedef struct {
int val[2];
} fsid_t;
#define MAXFIDSZ 64
#define OLD_MAXFIDSZ 16
typedef struct fid {
union {
long fid_pad;
struct {
ushort_t len;
char data[MAXFIDSZ];
} _fid;
} un;
} fid_t;
#ifdef _SYSCALL32
typedef struct fid32 {
union {
int32_t fid_pad;
struct {
uint16_t len;
char data[MAXFIDSZ];
} _fid;
} un;
} fid32_t;
#else
#define fid32 fid
typedef fid_t fid32_t;
#endif
#define fid_len un._fid.len
#define fid_data un._fid.data
typedef struct mntopt {
char *mo_name;
char **mo_cancel;
char *mo_arg;
int mo_flags;
void *mo_data;
} mntopt_t;
#define MO_SET 0x01
#define MO_NODISPLAY 0x02
#define MO_HASVALUE 0x04
#define MO_IGNORE 0x08
#define MO_DEFAULT MO_SET
#define MO_TAG 0x10
#define MO_EMPTY 0x20
#define VFS_NOFORCEOPT 0x01
#define VFS_DISPLAY 0x02
#define VFS_NODISPLAY 0x04
#define VFS_CREATEOPT 0x08
typedef struct mntopts {
uint_t mo_count;
mntopt_t *mo_list;
} mntopts_t;
typedef struct vskstat_anchor {
avl_node_t vsk_node;
kstat_t *vsk_ksp;
ulong_t vsk_fsid;
} vsk_anchor_t;
extern avl_tree_t vskstat_tree;
extern kmutex_t vskstat_tree_lock;
struct zone;
struct fem_head;
typedef struct vfs {
struct vfs *vfs_next;
struct vfs *vfs_prev;
vfsops_t *vfs_op;
struct vnode *vfs_vnodecovered;
uint_t vfs_flag;
uint_t vfs_bsize;
int vfs_fstype;
fsid_t vfs_fsid;
void *vfs_data;
dev_t vfs_dev;
ulong_t vfs_bcount;
struct vfs *vfs_list;
struct vfs *vfs_hash;
ksema_t vfs_reflock;
uint_t vfs_count;
mntopts_t vfs_mntopts;
refstr_t *vfs_resource;
refstr_t *vfs_mntpt;
time_t vfs_mtime;
struct vfs_impl *vfs_implp;
struct zone *vfs_zone;
struct vfs *vfs_zone_next;
struct vfs *vfs_zone_prev;
struct fem_head *vfs_femhead;
uint32_t vfs_lofi_id;
} vfs_t;
#define vfs_featureset vfs_implp->vi_featureset
#define vfs_vskap vfs_implp->vi_vskap
#define vfs_fstypevsp vfs_implp->vi_fstypevsp
#define vfs_vopstats vfs_implp->vi_vopstats
#define vfs_hrctime vfs_implp->vi_hrctime
#define VFS_RDONLY 0x01
#define VFS_NOMNTTAB 0x02
#define VFS_NOSETUID 0x08
#define VFS_REMOUNT 0x10
#define VFS_NOTRUNC 0x20
#define VFS_UNLINKABLE 0x40
#define VFS_PXFS 0x80
#define VFS_UNMOUNTED 0x100
#define VFS_NBMAND 0x200
#define VFS_XATTR 0x400
#define VFS_NODEVICES 0x800
#define VFS_NOEXEC 0x1000
#define VFS_STATS 0x2000
#define VFS_XID 0x4000
#define VFS_NORESOURCE "unspecified_resource"
#define VFS_NOMNTPT "unspecified_mountpoint"
typedef uint64_t vfs_feature_t;
#define VFSFT_XVATTR 0x100000001
#define VFSFT_CASEINSENSITIVE 0x100000002
#define VFSFT_NOCASESENSITIVE 0x100000004
#define VFSFT_DIRENTFLAGS 0x100000008
#define VFSFT_ACLONCREATE 0x100000010
#define VFSFT_ACEMASKONACCESS 0x100000020
#define VFSFT_SYSATTR_VIEWS 0x100000040
#define VFSFT_ACCESS_FILTER 0x100000080
#define VFSFT_REPARSE 0x100000100
#define VFSFT_ZEROCOPY_SUPPORTED 0x100000200
struct mounta {
char *spec;
char *dir;
int flags;
char *fstype;
char *dataptr;
int datalen;
char *optptr;
int optlen;
};
enum whymountroot { ROOT_INIT, ROOT_REMOUNT, ROOT_UNMOUNT};
typedef enum whymountroot whymountroot_t;
enum vntrans {
VNTRANS_EXISTS,
VNTRANS_IDLED,
VNTRANS_RECLAIMED,
VNTRANS_DESTROYED
};
typedef enum vntrans vntrans_t;
#define VFS_OPS \
int (*vfs_mount)(vfs_t *, vnode_t *, struct mounta *, cred_t *); \
int (*vfs_unmount)(vfs_t *, int, cred_t *); \
int (*vfs_root)(vfs_t *, vnode_t **); \
int (*vfs_statvfs)(vfs_t *, statvfs64_t *); \
int (*vfs_sync)(vfs_t *, short, cred_t *); \
int (*vfs_vget)(vfs_t *, vnode_t **, fid_t *); \
int (*vfs_mountroot)(vfs_t *, enum whymountroot); \
void (*vfs_freevfs)(vfs_t *); \
int (*vfs_vnstate)(vfs_t *, vnode_t *, vntrans_t); \
int (*vfs_syncfs)(vfs_t *, uint64_t, cred_t *)
struct vfsops {
VFS_OPS;
};
extern int fsop_mount(vfs_t *, vnode_t *, struct mounta *, cred_t *);
extern int fsop_unmount(vfs_t *, int, cred_t *);
extern int fsop_root(vfs_t *, vnode_t **);
extern int fsop_statfs(vfs_t *, statvfs64_t *);
extern int fsop_sync(vfs_t *, short, cred_t *);
extern int fsop_vget(vfs_t *, vnode_t **, fid_t *);
extern int fsop_mountroot(vfs_t *, enum whymountroot);
extern void fsop_freefs(vfs_t *);
extern int fsop_sync_by_kind(int, short, cred_t *);
extern int fsop_vnstate(vfs_t *, vnode_t *, vntrans_t);
extern int fsop_syncfs(vfs_t *, uint64_t, cred_t *);
#define VFS_MOUNT(vfsp, mvp, uap, cr) fsop_mount(vfsp, mvp, uap, cr)
#define VFS_UNMOUNT(vfsp, flag, cr) fsop_unmount(vfsp, flag, cr)
#define VFS_ROOT(vfsp, vpp) fsop_root(vfsp, vpp)
#define VFS_STATVFS(vfsp, sp) fsop_statfs(vfsp, sp)
#define VFS_SYNC(vfsp, flag, cr) fsop_sync(vfsp, flag, cr)
#define VFS_VGET(vfsp, vpp, fidp) fsop_vget(vfsp, vpp, fidp)
#define VFS_MOUNTROOT(vfsp, init) fsop_mountroot(vfsp, init)
#define VFS_FREEVFS(vfsp) fsop_freefs(vfsp)
#define VFS_VNSTATE(vfsp, vn, ns) fsop_vnstate(vfsp, vn, ns)
#define VFS_SYNCFS(vfsp, flag, cr) fsop_syncfs(vfsp, flag, cr)
#define VFSNAME_MOUNT "mount"
#define VFSNAME_UNMOUNT "unmount"
#define VFSNAME_ROOT "root"
#define VFSNAME_STATVFS "statvfs"
#define VFSNAME_SYNC "sync"
#define VFSNAME_VGET "vget"
#define VFSNAME_MOUNTROOT "mountroot"
#define VFSNAME_FREEVFS "freevfs"
#define VFSNAME_VNSTATE "vnstate"
#define VFSNAME_SYNCFS "syncfs"
typedef struct vfssw {
char *vsw_name;
int (*vsw_init) (int, char *);
int vsw_flag;
mntopts_t vsw_optproto;
uint_t vsw_count;
kmutex_t vsw_lock;
vfsops_t vsw_vfsops;
} vfssw_t;
typedef struct vfsdef_v5 {
int def_version;
char *name;
int (*init) (int, char *);
int flags;
mntopts_t *optproto;
} vfsdef_v5;
typedef struct vfsdef_v5 vfsdef_t;
enum {
VFSDEF_VERSION = 5
};
#define VSW_HASPROTO 0x01
#define VSW_CANRWRO 0x02
#define VSW_CANREMOUNT 0x04
#define VSW_NOTZONESAFE 0x08
#define VSW_VOLATILEDEV 0x10
#define VSW_STATS 0x20
#define VSW_XID 0x40
#define VSW_CANLOFI 0x80
#define VSW_ZMOUNT 0x100
#define VSW_MOUNTDEV 0x200
#define VSW_INSTALLED 0x8000
#define VFSSP_VERBATIM 0x1
#if defined(_KERNEL) || defined(_FAKE_KERNEL)
#define VFS_FEATURE_MAXSZ 4
typedef struct vfs_impl {
uint32_t vi_featureset[VFS_FEATURE_MAXSZ];
vsk_anchor_t *vi_vskap;
vopstats_t *vi_fstypevsp;
vopstats_t vi_vopstats;
timespec_t vi_hrctime;
zone_ref_t vi_zone_ref;
} vfs_impl_t;
struct umounta;
struct statvfsa;
struct fstatvfsa;
void vfs_freevfsops(vfsops_t *);
int vfs_freevfsops_by_type(int);
void vfs_setops(vfs_t *, vfsops_t *);
vfsops_t *vfs_getops(vfs_t *vfsp);
int vfs_matchops(vfs_t *, vfsops_t *);
int vfs_can_sync(vfs_t *vfsp);
vfs_t *vfs_alloc(int);
void vfs_free(vfs_t *);
void vfs_init(vfs_t *vfsp, vfsops_t *, void *);
void vfsimpl_setup(vfs_t *vfsp);
void vfsimpl_teardown(vfs_t *vfsp);
void vn_exists(vnode_t *);
void vn_idle(vnode_t *);
void vn_reclaim(vnode_t *);
void vn_invalid(vnode_t *);
int rootconf(void);
int domount(char *, struct mounta *, vnode_t *, struct cred *,
struct vfs **);
int dounmount(struct vfs *, int, cred_t *);
int vfs_lock(struct vfs *);
int vfs_rlock(struct vfs *);
void vfs_lock_wait(struct vfs *);
void vfs_rlock_wait(struct vfs *);
void vfs_unlock(struct vfs *);
int vfs_lock_held(struct vfs *);
struct _kthread *vfs_lock_owner(struct vfs *);
void sync(void);
void vfs_sync(int);
void vfs_mountroot(void);
void vfs_add(vnode_t *, struct vfs *, int);
void vfs_remove(struct vfs *);
void vfs_set_feature(vfs_t *, vfs_feature_t);
void vfs_clear_feature(vfs_t *, vfs_feature_t);
int vfs_has_feature(vfs_t *, vfs_feature_t);
void vfs_propagate_features(vfs_t *, vfs_t *);
void vfs_createopttbl(mntopts_t *, const char *);
void vfs_copyopttbl(const mntopts_t *, mntopts_t *);
void vfs_mergeopttbl(const mntopts_t *, const mntopts_t *, mntopts_t *);
void vfs_freeopttbl(mntopts_t *);
void vfs_parsemntopts(mntopts_t *, char *, int);
int vfs_buildoptionstr(const mntopts_t *, char *, int);
struct mntopt *vfs_hasopt(const mntopts_t *, const char *);
void vfs_mnttab_modtimeupd(void);
void vfs_clearmntopt(struct vfs *, const char *);
void vfs_setmntopt(struct vfs *, const char *, const char *, int);
void vfs_setresource(struct vfs *, const char *, uint32_t);
void vfs_setmntpoint(struct vfs *, const char *, uint32_t);
refstr_t *vfs_getresource(const struct vfs *);
refstr_t *vfs_getmntpoint(const struct vfs *);
int vfs_optionisset(const struct vfs *, const char *, char **);
int vfs_settag(uint_t, uint_t, const char *, const char *, cred_t *);
int vfs_clrtag(uint_t, uint_t, const char *, const char *, cred_t *);
void vfs_syncall(void);
void vfsinit(void);
void vfs_unmountall(void);
void vfs_make_fsid(fsid_t *, dev_t, int);
void vfs_addmip(dev_t, struct vfs *);
void vfs_delmip(struct vfs *);
int vfs_devismounted(dev_t);
int vfs_devmounting(dev_t, struct vfs *);
int vfs_opsinuse(vfsops_t *);
struct vfs *getvfs(fsid_t *);
struct vfs *vfs_dev2vfsp(dev_t);
struct vfs *vfs_mntpoint2vfsp(const char *);
struct vfssw *allocate_vfssw(const char *);
struct vfssw *vfs_getvfssw(const char *);
struct vfssw *vfs_getvfsswbyname(const char *);
struct vfssw *vfs_getvfsswbyvfsops(vfsops_t *);
void vfs_refvfssw(struct vfssw *);
void vfs_unrefvfssw(struct vfssw *);
uint_t vf_to_stf(uint_t);
void vfs_mnttab_modtime(timespec_t *);
void vfs_mnttab_poll(timespec_t *, struct pollhead **);
void vfs_list_lock(void);
void vfs_list_read_lock(void);
void vfs_list_unlock(void);
void vfs_list_add(struct vfs *);
void vfs_list_remove(struct vfs *);
void vfs_hold(vfs_t *vfsp);
void vfs_rele(vfs_t *vfsp);
void fs_freevfs(vfs_t *);
void vfs_root_redev(vfs_t *vfsp, dev_t ndev, int fstype);
int vfs_zone_change_safe(vfs_t *);
int vfs_get_lofi(vfs_t *, vnode_t **);
#define VFSHASH(maj, min) (((int)((maj)+(min))) & (vfshsz - 1))
#define VFS_ON_LIST(vfsp) \
((vfsp)->vfs_next != (vfsp) && (vfsp)->vfs_next != NULL)
extern struct vfssw vfssw[];
extern krwlock_t vfssw_lock;
extern char rootfstype[];
extern const int nfstype;
extern vfsops_t *EIO_vfsops;
extern struct vfs *rootvfs;
typedef struct {
struct vfs *rvfs_head;
kmutex_t rvfs_lock;
uint32_t rvfs_len;
} rvfs_t;
extern rvfs_t *rvfs_list;
extern int vfshsz;
extern const mntopts_t vfs_mntopts;
#endif
#define VFS_HOLD(vfsp) { \
vfs_hold(vfsp); \
}
#define VFS_RELE(vfsp) { \
vfs_rele(vfsp); \
}
#define VFS_INIT(vfsp, op, data) { \
vfs_init((vfsp), (op), (data)); \
}
#define VFS_INSTALLED(vfsswp) (((vfsswp)->vsw_flag & VSW_INSTALLED) != 0)
#define ALLOCATED_VFSSW(vswp) ((vswp)->vsw_name[0] != '\0')
#define RLOCK_VFSSW() (rw_enter(&vfssw_lock, RW_READER))
#define RUNLOCK_VFSSW() (rw_exit(&vfssw_lock))
#define WLOCK_VFSSW() (rw_enter(&vfssw_lock, RW_WRITER))
#define WUNLOCK_VFSSW() (rw_exit(&vfssw_lock))
#define VFSSW_LOCKED() (RW_LOCK_HELD(&vfssw_lock))
#define VFSSW_WRITE_LOCKED() (RW_WRITE_HELD(&vfssw_lock))
#define SYNC_ATTR 0x01
#define SYNC_CLOSE 0x02
#define SYNC_ALL 0x04
#ifdef __cplusplus
}
#endif
#endif