Changeset View
Changeset View
Standalone View
Standalone View
sys/sys/filedesc.h
Show First 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | |||||
struct pwd { | struct pwd { | ||||
volatile u_int pwd_refcount; | volatile u_int pwd_refcount; | ||||
struct vnode *pwd_cdir; /* current directory */ | struct vnode *pwd_cdir; /* current directory */ | ||||
struct vnode *pwd_rdir; /* root directory */ | struct vnode *pwd_rdir; /* root directory */ | ||||
struct vnode *pwd_jdir; /* jail root directory */ | struct vnode *pwd_jdir; /* jail root directory */ | ||||
}; | }; | ||||
typedef SMR_POINTER(struct pwd *) smrpwd_t; | typedef SMR_POINTER(struct pwd *) smrpwd_t; | ||||
struct pathsdesc { | |||||
struct sx pd_sx; /* protects members of this struct */ | |||||
mjg: this should be a mutex if possible. shared locking does not buy much here | |||||
cemAuthorUnsubmitted Done Inline ActionsThis was the existing lock style from filedesc; I did not check if it can be restricted further yet. The macros help there. cem: This was the existing lock style from filedesc; I did not check if it can be restricted further… | |||||
smrpwd_t pd_pwd; /* directories */ | |||||
volatile u_int pd_refcount; | |||||
u_short pd_cmask; /* mask for file creation */ | |||||
}; | |||||
struct filedesc { | struct filedesc { | ||||
struct fdescenttbl *fd_files; /* open files table */ | struct fdescenttbl *fd_files; /* open files table */ | ||||
smrpwd_t fd_pwd; /* directories */ | |||||
NDSLOTTYPE *fd_map; /* bitmap of free fds */ | NDSLOTTYPE *fd_map; /* bitmap of free fds */ | ||||
int fd_freefile; /* approx. next free file */ | int fd_freefile; /* approx. next free file */ | ||||
u_short fd_cmask; /* mask for file creation */ | |||||
int fd_refcnt; /* thread reference count */ | int fd_refcnt; /* thread reference count */ | ||||
int fd_holdcnt; /* hold count on structure + mutex */ | int fd_holdcnt; /* hold count on structure + mutex */ | ||||
struct sx fd_sx; /* protects members of this struct */ | struct sx fd_sx; /* protects members of this struct */ | ||||
struct kqlist fd_kqlist; /* list of kqueues on this filedesc */ | struct kqlist fd_kqlist; /* list of kqueues on this filedesc */ | ||||
int fd_holdleaderscount; /* block fdfree() for shared close() */ | int fd_holdleaderscount; /* block fdfree() for shared close() */ | ||||
int fd_holdleaderswakeup; /* fdfree() needs wakeup */ | int fd_holdleaderswakeup; /* fdfree() needs wakeup */ | ||||
}; | }; | ||||
Show All 20 Lines | |||||
/* | /* | ||||
* Per-process open flags. | * Per-process open flags. | ||||
*/ | */ | ||||
#define UF_EXCLOSE 0x01 /* auto-close on exec */ | #define UF_EXCLOSE 0x01 /* auto-close on exec */ | ||||
#ifdef _KERNEL | #ifdef _KERNEL | ||||
/* Lock a paths descriptor table. */ | |||||
#define PATHSDESC_LOCK(pdp) (&(pdp)->pd_sx) | |||||
#define PATHSDESC_LOCK_INIT(pdp) sx_init(PATHSDESC_LOCK(pdp), "pathsdesc") | |||||
#define PATHSDESC_LOCK_DESTROY(pdp) sx_destroy(PATHSDESC_LOCK(pdp)) | |||||
#define PATHSDESC_XLOCK(pdp) sx_xlock(PATHSDESC_LOCK(pdp)) | |||||
#define PATHSDESC_XUNLOCK(pdp) sx_xunlock(PATHSDESC_LOCK(pdp)) | |||||
#define PATHSDESC_SLOCK(pdp) sx_slock(PATHSDESC_LOCK(pdp)) | |||||
#define PATHSDESC_SUNLOCK(pdp) sx_sunlock(PATHSDESC_LOCK(pdp)) | |||||
#define PATHSDESC_LOCK_ASSERT(pdp, what) \ | |||||
Done Inline ActionsNow there is no use for slock/xlock distiction, this all should be unified on lock. mjg: Now there is no use for slock/xlock distiction, this all should be unified on lock. | |||||
Done Inline ActionsSure, I will clean that up before committing. I wanted to make sure a mutex made sense here before discarding the distinction. cem: Sure, I will clean that up before committing. I wanted to make sure a mutex made sense here… | |||||
sx_assert(PATHSDESC_LOCK(pdp), (what)) | |||||
#define PATHSDESC_ASSERT_LOCKED(pdp) \ | |||||
PATHSDESC_LOCK_ASSERT((pdp), SX_LOCKED) | |||||
#define PATHSDESC_ASSERT_XLOCKED(pdp) \ | |||||
PATHSDESC_LOCK_ASSERT((pdp), SX_XLOCKED) | |||||
#define PATHSDESC_ASSERT_UNLOCKED(pdp) \ | |||||
PATHSDESC_LOCK_ASSERT((pdp), SX_UNLOCKED) | |||||
#define PATHSDESC_LOCKED_LOAD_PWD(pdp) ({ \ | |||||
struct pathsdesc *_pdp = (pdp); \ | |||||
struct pwd *_pwd; \ | |||||
_pwd = smr_serialized_load(&(_pdp)->pd_pwd, \ | |||||
(PATHSDESC_ASSERT_LOCKED(_pdp), true)); \ | |||||
_pwd; \ | |||||
}) | |||||
#define PATHSDESC_XLOCKED_LOAD_PWD(pdp) ({ \ | |||||
struct pathsdesc *_pdp = (pdp); \ | |||||
struct pwd *_pwd; \ | |||||
_pwd = smr_serialized_load(&(_pdp)->pd_pwd, \ | |||||
(PATHSDESC_ASSERT_XLOCKED(_pdp), true)); \ | |||||
_pwd; \ | |||||
}) | |||||
/* Lock a file descriptor table. */ | /* Lock a file descriptor table. */ | ||||
#define FILEDESC_LOCK_INIT(fdp) sx_init(&(fdp)->fd_sx, "filedesc structure") | #define FILEDESC_LOCK_INIT(fdp) sx_init(&(fdp)->fd_sx, "filedesc structure") | ||||
#define FILEDESC_LOCK_DESTROY(fdp) sx_destroy(&(fdp)->fd_sx) | #define FILEDESC_LOCK_DESTROY(fdp) sx_destroy(&(fdp)->fd_sx) | ||||
#define FILEDESC_LOCK(fdp) (&(fdp)->fd_sx) | #define FILEDESC_LOCK(fdp) (&(fdp)->fd_sx) | ||||
#define FILEDESC_XLOCK(fdp) sx_xlock(&(fdp)->fd_sx) | #define FILEDESC_XLOCK(fdp) sx_xlock(&(fdp)->fd_sx) | ||||
#define FILEDESC_XUNLOCK(fdp) sx_xunlock(&(fdp)->fd_sx) | #define FILEDESC_XUNLOCK(fdp) sx_xunlock(&(fdp)->fd_sx) | ||||
#define FILEDESC_SLOCK(fdp) sx_slock(&(fdp)->fd_sx) | #define FILEDESC_SLOCK(fdp) sx_slock(&(fdp)->fd_sx) | ||||
#define FILEDESC_SUNLOCK(fdp) sx_sunlock(&(fdp)->fd_sx) | #define FILEDESC_SUNLOCK(fdp) sx_sunlock(&(fdp)->fd_sx) | ||||
#define FILEDESC_LOCK_ASSERT(fdp) sx_assert(&(fdp)->fd_sx, SX_LOCKED | \ | #define FILEDESC_LOCK_ASSERT(fdp) sx_assert(&(fdp)->fd_sx, SX_LOCKED | \ | ||||
SX_NOTRECURSED) | SX_NOTRECURSED) | ||||
#define FILEDESC_XLOCK_ASSERT(fdp) sx_assert(&(fdp)->fd_sx, SX_XLOCKED | \ | #define FILEDESC_XLOCK_ASSERT(fdp) sx_assert(&(fdp)->fd_sx, SX_XLOCKED | \ | ||||
SX_NOTRECURSED) | SX_NOTRECURSED) | ||||
#define FILEDESC_UNLOCK_ASSERT(fdp) sx_assert(&(fdp)->fd_sx, SX_UNLOCKED) | #define FILEDESC_UNLOCK_ASSERT(fdp) sx_assert(&(fdp)->fd_sx, SX_UNLOCKED) | ||||
#define FILEDESC_LOCKED_LOAD_PWD(fdp) ({ \ | |||||
struct filedesc *_fdp = (fdp); \ | |||||
struct pwd *_pwd; \ | |||||
_pwd = smr_serialized_load(&(_fdp)->fd_pwd, \ | |||||
(FILEDESC_LOCK_ASSERT(_fdp), true)); \ | |||||
_pwd; \ | |||||
}) | |||||
#define FILEDESC_XLOCKED_LOAD_PWD(fdp) ({ \ | |||||
struct filedesc *_fdp = (fdp); \ | |||||
struct pwd *_pwd; \ | |||||
_pwd = smr_serialized_load(&(_fdp)->fd_pwd, \ | |||||
(FILEDESC_XLOCK_ASSERT(_fdp), true)); \ | |||||
_pwd; \ | |||||
}) | |||||
#else | #else | ||||
/* | /* | ||||
* Accessor for libkvm et al. | * Accessor for libkvm et al. | ||||
*/ | */ | ||||
#define FILEDESC_KVM_LOAD_PWD(fdp) ({ \ | #define PATHSDESC_KVM_LOAD_PWD(pdp) ({ \ | ||||
struct filedesc *_fdp = (fdp); \ | struct pathsdesc *_pdp = (pdp); \ | ||||
struct pwd *_pwd; \ | struct pwd *_pwd; \ | ||||
_pwd = smr_kvm_load(&(_fdp)->fd_pwd); \ | _pwd = smr_kvm_load(&(_pdp)->pd_pwd); \ | ||||
_pwd; \ | _pwd; \ | ||||
}) | }) | ||||
#endif | #endif | ||||
#ifdef _KERNEL | #ifdef _KERNEL | ||||
/* Operation types for kern_dup(). */ | /* Operation types for kern_dup(). */ | ||||
▲ Show 20 Lines • Show All 106 Lines • ▼ Show 20 Lines | |||||
fd_modified(struct filedesc *fdp, int fd, seqc_t seqc) | fd_modified(struct filedesc *fdp, int fd, seqc_t seqc) | ||||
{ | { | ||||
return (!seqc_consistent(fd_seqc(fdp->fd_files, fd), seqc)); | return (!seqc_consistent(fd_seqc(fdp->fd_files, fd), seqc)); | ||||
} | } | ||||
#endif | #endif | ||||
/* cdir/rdir/jdir manipulation functions. */ | /* cdir/rdir/jdir manipulation functions. */ | ||||
struct pathsdesc *pdcopy(struct pathsdesc *pdp); | |||||
void pdescfree(struct thread *td); | |||||
struct pathsdesc *pdinit(struct pathsdesc *pdp, bool keeplock); | |||||
struct pathsdesc *pdshare(struct pathsdesc *pdp); | |||||
void pdunshare(struct thread *td); | |||||
void pwd_chdir(struct thread *td, struct vnode *vp); | void pwd_chdir(struct thread *td, struct vnode *vp); | ||||
int pwd_chroot(struct thread *td, struct vnode *vp); | int pwd_chroot(struct thread *td, struct vnode *vp); | ||||
void pwd_ensure_dirs(void); | void pwd_ensure_dirs(void); | ||||
void pwd_set_rootvnode(void); | void pwd_set_rootvnode(void); | ||||
struct pwd *pwd_hold_filedesc(struct filedesc *fdp); | struct pwd *pwd_hold_pathsdesc(struct pathsdesc *pdp); | ||||
bool pwd_hold_smr(struct pwd *pwd); | bool pwd_hold_smr(struct pwd *pwd); | ||||
struct pwd *pwd_hold(struct thread *td); | struct pwd *pwd_hold(struct thread *td); | ||||
void pwd_drop(struct pwd *pwd); | void pwd_drop(struct pwd *pwd); | ||||
static inline void | static inline void | ||||
pwd_set(struct filedesc *fdp, struct pwd *newpwd) | pwd_set(struct pathsdesc *pdp, struct pwd *newpwd) | ||||
{ | { | ||||
smr_serialized_store(&pdp->pd_pwd, newpwd, | |||||
smr_serialized_store(&fdp->fd_pwd, newpwd, | (PATHSDESC_ASSERT_XLOCKED(pdp), true)); | ||||
(FILEDESC_XLOCK_ASSERT(fdp), true)); | |||||
} | } | ||||
struct pwd *pwd_get_smr(void); | struct pwd *pwd_get_smr(void); | ||||
#endif /* _KERNEL */ | #endif /* _KERNEL */ | ||||
#endif /* !_SYS_FILEDESC_H_ */ | #endif /* !_SYS_FILEDESC_H_ */ |
this should be a mutex if possible. shared locking does not buy much here