#ifndef _FS_SMBFS_NODE_H_
#define _FS_SMBFS_NODE_H_
#define SMBFS_ROOT_INO 2
#define NREFPARENT 0x00001
#define N_ISSTREAM 0x00002
#define N_ISRSRCFRK 0x00004
#define NISMAPPED 0x00008
#define NNEEDS_FLUSH 0x00010
#define NNEEDS_EOF_SET 0x00020
#define NATTRCHANGED 0x00040
#define NALLOC 0x00080
#define NWALLOC 0x00100
#define NTRANSIT 0x00200
#define NWTRANSIT 0x00400
#define NDELETEONCLOSE 0x00800
#define NMARKEDFORDLETE 0x01000
#define NNEGNCENTRIES 0x02000
#define NWINDOWSYMLNK 0x04000
#define N_POLLNOTIFY 0x08000
#define NO_EXTENDEDOPEN 0x10000
#define NHAS_POSIXMODES 0x20000
#define UNKNOWNUID ((uid_t)99)
#define UNKNOWNGID ((gid_t)99)
struct smbfs_fctx;
enum smbfslocktype {SMBFS_SHARED_LOCK = 1, SMBFS_EXCLUSIVE_LOCK = 2, SMBFS_RECLAIM_LOCK = 3};
#define kNeedRevoke 0x01
#define kNeedReopen 0x02
enum {
kAnyMatch = 1,
kCheckDenyOrLocks = 2,
kExactMatch = 3
};
enum {
kAccessRead = 0x01,
kAccessWrite = 0x02,
kDenyRead = 0x10,
kDenyWrite = 0x20,
kOpenMask = 0x03,
kDenyMask = 0x30,
kAccessMask = 0x33
};
struct ByteRangeLockEntry {
int64_t offset;
int64_t length;
uint32_t lck_pid;
struct ByteRangeLockEntry *next;
};
struct fileRefEntry {
uint32_t refcnt;
uint32_t mmapped;
pid_t p_pid;
uint16_t fid;
uint16_t accessMode;
uint32_t rights;
struct proc *proc;
struct ByteRangeLockEntry *lockList;
struct fileRefEntry *next;
};
struct smb_open_dir {
uint32_t refcnt;
uint32_t kq_refcnt;
uint16_t fid;
struct smbfs_fctx *fctx;
void *nextEntry;
int32_t nextEntryLen;
int32_t nextEntryFlags;
off_t offset;
uint32_t needReopen;
uint32_t needsUpdate;
};
struct smb_open_file {
uint32_t refcnt;
uint16_t fid;
uint32_t rights;
uint16_t accessMode;
uint32_t mmapMode;
int32_t needClose;
int32_t openRWCnt;
int32_t openRCnt;
int32_t openWCnt;
int32_t openTotalWriteCnt;
int32_t clusterCloseError;
uint32_t openState;
lck_mtx_t openStateLock;
lck_mtx_t clusterWriteLock;
lck_mtx_t openDenyListLock;
struct fileRefEntry *openDenyList;
struct smbfs_flock *smbflock;
};
struct smbnode {
lck_rw_t n_rwlock;
void * n_lastvop;
void * n_activation;
uint32_t n_lockState;
uint32_t n_flag;
struct smbnode *n_parent;
vnode_t n_vnode;
struct smbmount *n_mount;
time_t attribute_cache_timer;
struct timespec n_crtime;
struct timespec n_mtime;
struct timespec n_atime;
struct timespec n_chtime;
struct timespec n_sizetime;
u_quad_t n_size;
uint8_t waitOnClusterWrite;
u_quad_t n_data_alloc;
int n_dosattr;
uint32_t n_flags_mask;
uid_t n_uid;
gid_t n_gid;
mode_t n_mode;
mode_t create_va_mode;
uid_t n_nfs_uid;
gid_t n_nfs_gid;
int set_create_va_mode;
time_t finfo_cache;
uint8_t finfo[FINDERINFOSIZE];
time_t rfrk_cache_timer;
u_quad_t rfrk_size;
lck_mtx_t rfrkMetaLock;
uint64_t n_ino;
uint64_t n_nlinks;
SInt32 n_child_refcnt;
union {
struct smb_open_dir dir;
struct smb_open_file file;
}open_type;
void *acl_cache_data;
struct timespec acl_cache_timer;
int acl_error;
size_t acl_cache_len;
lck_mtx_t f_ACLCacheLock;
lck_rw_t n_name_rwlock;
char *n_name;
size_t n_nmlen;
size_t n_snmlen;
char *n_sname;
LIST_ENTRY(smbnode) n_hash;
uint32_t maxAccessRights;
struct timespec maxAccessRightChTime;
uint32_t n_reparse_tag;
uint16_t n_fstatus;
char *n_symlink_target;
size_t n_symlink_target_len;
time_t n_symlink_cache_timer;
};
#define d_refcnt open_type.dir.refcnt
#define d_kqrefcnt open_type.dir.kq_refcnt
#define d_fctx open_type.dir.fctx
#define d_nextEntry open_type.dir.nextEntry
#define d_nextEntryFlags open_type.dir.nextEntryFlags
#define d_nextEntryLen open_type.dir.nextEntryLen
#define d_offset open_type.dir.offset
#define d_needReopen open_type.dir.needReopen
#define d_fid open_type.dir.fid
#define d_needsUpdate open_type.dir.needsUpdate
#define f_refcnt open_type.file.refcnt
#define f_fid open_type.file.fid
#define f_rights open_type.file.rights
#define f_accessMode open_type.file.accessMode
#define f_mmapMode open_type.file.mmapMode
#define f_needClose open_type.file.needClose
#define f_openRWCnt open_type.file.openRWCnt
#define f_openRCnt open_type.file.openRCnt
#define f_openWCnt open_type.file.openWCnt
#define f_openTotalWCnt open_type.file.openTotalWriteCnt
#define f_openDenyList open_type.file.openDenyList
#define f_smbflock open_type.file.smbflock
#define f_openState open_type.file.openState
#define f_openStateLock open_type.file.openStateLock
#define f_clusterWriteLock open_type.file.clusterWriteLock
#define f_openDenyListLock open_type.file.openDenyListLock
#define f_clusterCloseError open_type.file.clusterCloseError
#define SMB_MINATTRTIMO 2
#define SMB_MAXATTRTIMO 30
#define SMB_CACHE_TIME(ts, np, attrtimeo) { \
nanotime(&ts); \
attrtimeo = (ts.tv_sec - np->n_mtime.tv_sec) / 10; \
if (attrtimeo < SMB_MINATTRTIMO) \
attrtimeo = SMB_MINATTRTIMO; \
else if (attrtimeo > SMB_MAXATTRTIMO) \
attrtimeo = SMB_MAXATTRTIMO; \
nanouptime(&ts); \
}
#define SMB_ACL_MINTIMO 1
#define SMB_ACL_MAXTIMO 30
#define SET_ACL_CACHE_TIME(np) { \
struct timespec waittime; \
\
nanouptime(&np->acl_cache_timer); \
if (np->acl_error) { \
waittime.tv_sec = SMB_ACL_MAXTIMO; \
waittime.tv_nsec = 0; \
} else { \
waittime.tv_sec = SMB_ACL_MINTIMO; \
waittime.tv_nsec = 0; \
}\
timespecadd(&np->acl_cache_timer, &waittime); \
}
#define VTOSMB(vp) ((struct smbnode *)vnode_fsnode(vp))
#define SMBTOV(np) ((vnode_t )(np)->n_vnode)
extern lck_attr_t *smbfs_lock_attr;
extern lck_grp_t *smbfs_mutex_group;
extern lck_grp_t *smbfs_rwlock_group;
struct smbfattr;
int smbnode_lock(struct smbnode *np, enum smbfslocktype);
int smbnode_lockpair(struct smbnode *np1, struct smbnode *np2, enum smbfslocktype);
void smbnode_unlock(struct smbnode *np);
void smbnode_unlockpair(struct smbnode *np1, struct smbnode *np2);
uint32_t smbfs_hash(const char *name, size_t nmlen);
void smb_vhashrem (struct smbnode *np);
void smb_vhashadd(struct smbnode *np, uint32_t hashval);
int smbfs_nget(struct smb_share *share, struct mount *mp, vnode_t dvp, const char *name,
size_t nmlen, struct smbfattr *fap, vnode_t *vpp, uint32_t cnflags,
vfs_context_t context);
vnode_t smbfs_find_vgetstrm(struct smbmount *smp, struct smbnode *np, const char *sname,
size_t maxfilenamelen);
int smbfs_vgetstrm(struct smb_share *share, struct smbmount *smp, vnode_t vp,
vnode_t *svpp, struct smbfattr *fap, const char *sname);
int smb_get_rsrcfrk_size(struct smb_share *share, vnode_t vp, vfs_context_t context);
vnode_t smb_update_rsrc_and_getparent(vnode_t vp, int setsize);
int smb_check_posix_access(vfs_context_t context, struct smbnode * np,
mode_t rq_mode);
Boolean node_isimmutable(struct smb_share *share, vnode_t vp);
void smbfs_attr_cacheenter(struct smb_share *share, vnode_t vp, struct smbfattr *fap,
int UpdateResourceParent, vfs_context_t context);
int smbfs_attr_cachelookup(struct smb_share *share, vnode_t vp, struct vnode_attr *va,
vfs_context_t context, int useCacheDataOnly);
void smbfs_attr_touchdir(struct smbnode *dnp, int fatShare);
int smbfsIsCacheable(vnode_t vp);
void smbfs_setsize(vnode_t vp, off_t size);
int smbfs_update_size(struct smbnode *np, struct timespec * reqtime, u_quad_t new_size);
int FindByteRangeLockEntry(struct fileRefEntry *fndEntry, int64_t offset,
int64_t length, uint32_t lck_pid);
void AddRemoveByteRangeLockEntry(struct fileRefEntry *fndEntry, int64_t offset,
int64_t length, int8_t unLock, uint32_t lck_pid);
void AddFileRef(vnode_t vp, struct proc *p, uint16_t accessMode,
uint32_t rights, uint16_t fid, struct fileRefEntry **fndEntry);
int32_t FindFileEntryByFID(vnode_t vp, uint16_t fid, struct fileRefEntry **fndEntry);
int32_t FindMappedFileRef(vnode_t vp, struct fileRefEntry **fndEntry, uint16_t *fid);
int32_t FindFileRef(vnode_t vp, proc_t p, uint16_t accessMode, int32_t flags,
int64_t offset, int64_t length,
struct fileRefEntry **fndEntry,
uint16_t *fid);
void RemoveFileRef(vnode_t vp, struct fileRefEntry *inEntry);
int smbfs_readvdir(vnode_t vp, uio_t uio, vfs_context_t context, int flags,
int32_t *numdirent);
int smbfs_0extend(struct smb_share *share, uint16_t fid, u_quad_t from,
u_quad_t to, int ioflag, vfs_context_t context);
int smbfs_doread(struct smb_share *share, off_t endOfFile, uio_t uiop,
uint16_t fid, vfs_context_t context);
int smbfs_dowrite(struct smb_share *share, off_t endOfFile, uio_t uiop,
uint16_t fid, int ioflag, vfs_context_t context);
void smbfs_reconnect(struct smbmount *smp);
int32_t smbfs_IObusy(struct smbmount *smp);
void smbfs_ClearChildren(struct smbmount *smp, struct smbnode * parent);
#define smb_ubc_getsize(v) (vnode_vtype(v) == VREG ? ubc_getsize(v) : (off_t)0)
#endif