unit vfs_vnode; {$mode ObjFPC}{$H+} {$CALLING SysV_ABI_CDecl} interface uses mqueue, kern_thr, kern_mtx, vselinfo, time, vmparam; const VI_MOUNT =$0020; // Mount in progress VI_AGE =$0040; // Insert vnode at head of free list VI_DOOMED =$0080; // This vnode is being recycled VI_FREE =$0100; // This vnode is on the freelist VI_ACTIVE =$0200; // This vnode is on the active list VI_DOINGINACT =$0800; // VOP_INACTIVE is in progress VI_OWEINACT =$1000; // Need to call inactive VV_ROOT =$0001; // root of its filesystem VV_ISTTY =$0002; // vnode represents a tty VV_NOSYNC =$0004; // unlinked, stop syncing VV_ETERNALDEV =$0008; // device that is never destroyed VV_CACHEDLABEL=$0010; // Vnode has valid cached MAC label VV_TEXT =$0020; // vnode is a pure text prototype VV_COPYONWRITE=$0040; // vnode is doing copy-on-write VV_SYSTEM =$0080; // vnode being used by kernel VV_PROCDEP =$0100; // vnode is process dependent VV_NOKNOTE =$0200; // don't activate knotes on this vnode VV_DELETED =$0400; // should be removed VV_MD =$0800; // vnode backs the md device VV_FORCEINSMQ =$1000; // force the insmntque to succeed //Flags for va_vaflags. VA_UTIMES_NULL=$01; // utimes argument was NULL VA_EXCLUSIVE =$02; // exclusive create request { * Flags for ioflag. (high 16 bits used to ask for read-ahead and * help with write clustering) * NB: IO_NDELAY and IO_DIRECT are linked to fcntl.h } IO_UNIT =$0001; { do I/O as atomic unit } IO_APPEND =$0002; { append write to end } IO_NDELAY =$0004; { FNDELAY flag set in file table } IO_NODELOCKED=$0008; { underlying node already locked } IO_ASYNC =$0010; { bawrite rather then bdwrite } IO_VMIO =$0020; { data already in VMIO space } IO_INVAL =$0040; { invalidate after I/O } IO_SYNC =$0080; { do I/O synchronously } IO_DIRECT =$0100; { attempt to bypass buffer cache } IO_EXT =$0400; { operate on external attributes } IO_NORMAL =$0800; { operate on regular data } IO_NOMACCHECK=$1000; { MAC checks unnecessary } IO_BUFLOCKED =$2000; { ffs flag; indir buf is locked } IO_SEQMAX =$7F; { seq heuristic max value } IO_SEQSHIFT =16; { seq heuristic in upper 16 bits } //Flags for accmode_t. VEXEC =&000000000100; // execute/search permission VWRITE =&000000000200; // write permission VREAD =&000000000400; // read permission VADMIN =&000000010000; // being the file owner VAPPEND=&000000040000; // permission to write/append VEXPLICIT_DENY =&000000100000; VDELETE_CHILD =&000001000000; VREAD_ATTRIBUTES =&000002000000; // permission to stat(2) VWRITE_ATTRIBUTES =&000004000000; // change {m,c,a}time VDELETE =&000010000000; VREAD_ACL =&000020000000; // read ACL and file mode VWRITE_ACL =&000040000000; // change ACL and/or file mode VWRITE_OWNER =&000100000000; // change file owner VSYNCHRONIZE =&000200000000; VADMIN_PERMS =VADMIN or VWRITE_ATTRIBUTES or VWRITE_ACL or VWRITE_OWNER; //Permissions that were traditionally granted to everyone. VSTAT_PERMS =VREAD_ATTRIBUTES or VREAD_ACL; //Permissions that allow to change the state of the file in any way. VMODIFY_PERMS =VWRITE or VAPPEND or VADMIN_PERMS or VDELETE_CHILD or VDELETE; // vn_open_flags VN_OPEN_NOAUDIT=$00000001; //Flags to various vnode functions. SKIPSYSTEM =$0001; // vflush: skip vnodes marked VSYSTEM FORCECLOSE =$0002; // vflush: force file closure WRITECLOSE =$0004; // vflush: only close writable files EARLYFLUSH =$0008; // vflush: early call for ffs_flushfiles V_SAVE =$0001; // vinvalbuf: sync file first V_ALT =$0002; // vinvalbuf: invalidate only alternate bufs V_NORMAL =$0004; // vinvalbuf: invalidate only regular bufs V_CLEANONLY=$0008; // vinvalbuf: invalidate only clean bufs REVOKEALL =$0001; // vop_revoke: revoke all aliases V_WAIT =$0001; // vn_start_write: sleep for suspend V_NOWAIT =$0002; // vn_start_write: don't sleep for suspend V_XSLEEP =$0004; // vn_start_write: just return after sleep VR_START_WRITE=$0001; // vfs_write_resume: start write atomically VR_NO_SUSPCLR =$0002; // vfs_write_resume: do not clear suspension VNOVAL=-1; DEV_BSHIFT=9; DEV_BSIZE =(1 shl DEV_BSHIFT); BLKDEV_IOSIZE=PAGE_SIZE; DFLTPHYS =(64 * 1024); MAXPHYS =(128 * 1024); type p_accmode_t=^accmode_t; accmode_t=Integer; pp_vnode=^p_vnode; p_vnode=^t_vnode; p_vop_vector=^vop_vector; vop_vector=packed record vop_default :p_vop_vector; vop_bypass :Pointer; vop_islocked :Pointer; vop_lookup :Pointer; vop_cachedlookup :Pointer; vop_create :Pointer; vop_whiteout :Pointer; vop_mknod :Pointer; vop_open :Pointer; vop_close :Pointer; vop_access :Pointer; vop_accessx :Pointer; vop_getattr :Pointer; vop_setattr :Pointer; vop_markatime :Pointer; vop_read :Pointer; vop_write :Pointer; vop_ioctl :Pointer; vop_poll :Pointer; vop_kqfilter :Pointer; vop_revoke :Pointer; vop_fsync :Pointer; vop_remove :Pointer; vop_link :Pointer; vop_rename :Pointer; vop_mkdir :Pointer; vop_rmdir :Pointer; vop_symlink :Pointer; vop_readdir :Pointer; vop_readlink :Pointer; vop_inactive :Pointer; vop_reclaim :Pointer; vop_lock1 :Pointer; vop_unlock :Pointer; vop_bmap :Pointer; vop_strategy :Pointer; vop_getwritemount :Pointer; vop_print :Pointer; vop_pathconf :Pointer; vop_advlock :Pointer; vop_advlockasync :Pointer; vop_advlockpurge :Pointer; vop_reallocblks :Pointer; vop_getpages :Pointer; vop_putpages :Pointer; vop_getacl :Pointer; vop_setacl :Pointer; vop_aclcheck :Pointer; vop_closeextattr :Pointer; vop_getextattr :Pointer; vop_listextattr :Pointer; vop_openextattr :Pointer; vop_deleteextattr :Pointer; vop_setextattr :Pointer; vop_setlabel :Pointer; vop_vptofh :Pointer; vop_vptocnp :Pointer; vop_allocate :Pointer; vop_advise :Pointer; vop_unp_bind :Pointer; vop_unp_connect :Pointer; vop_unp_detach :Pointer; vop_is_text :Pointer; vop_set_text :Pointer; vop_unset_text :Pointer; vop_get_writecount:Pointer; vop_add_writecount:Pointer; end; vtype=(VNON,VREG,VDIR,VBLK,VCHR,VLNK,VSOCK,VFIFO,VBAD,VMARKER); p_vpollinfo=^vpollinfo; vpollinfo=packed record vpi_lock :mtx; // lock to protect below vpi_selinfo:t_selinfo; // identity of poller(s) vpi_events :Word; // what they are looking for vpi_revents:Word; // what has happened end; t_vnode=packed object v_type:vtype; v_tag :PChar; v_op :p_vop_vector; v_data:Pointer; v_mount:Pointer; //mount v_nmntvnodes:TAILQ_ENTRY; //vnode v_un:Pointer; v_hash:DWORD; v_holdcnt :Integer; v_usecount:Integer; v_writecount:Integer; v_lock:mtx; v_interlock:mtx; v_iflag:QWORD; v_vflag:QWORD; v_actfreelist:TAILQ_ENTRY; v_pollinfo:p_vpollinfo; // i Poll events, p for *v_pi property v_mountedhere:Pointer read v_un{.vu_mount } write v_un; //mount property v_socket :Pointer read v_un{.vu_socket } write v_un; //socket property v_rdev :Pointer read v_un{.vu_cdev } write v_un; //cdev property v_fifoinfo :Pointer read v_un{.vu_fifoinfo} write v_un; //fifoinfo end; p_vattr=^t_vattr; t_vattr=packed record va_type :vtype; va_mode :Word; va_nlink :Word; va_uid :Integer; va_gid :Integer; va_fsid :Integer; va_fileid :QWORD; va_size :QWORD; va_blocksize:QWORD; va_atime :timespec; va_mtime :timespec; va_ctime :timespec; va_birthtime:timespec; va_gen :QWORD; va_flags :QWORD; va_rdev :Integer; va_bytes :QWORD; va_filerev :QWORD; va_vaflags :DWORD; end; procedure VI_LOCK(vp:p_vnode); function VI_TRYLOCK(vp:p_vnode):Boolean; procedure VI_UNLOCK(vp:p_vnode); function VI_MTX(vp:p_vnode):p_mtx; inline; function IGNORE_LOCK(vp:p_vnode):Boolean; inline; procedure vn_rangelock_unlock(vp:p_vnode;cookie:Pointer); procedure vn_rangelock_unlock_range(vp:p_vnode;cookie:Pointer;start,__end:Int64); function vn_rangelock_rlock(vp:p_vnode;start,__end:Int64):Pointer; function vn_rangelock_wlock(vp:p_vnode;start,__end:Int64):Pointer; var rootvnode:p_vnode; implementation procedure VI_LOCK(vp:p_vnode); begin mtx_lock(vp^.v_interlock); end; function VI_TRYLOCK(vp:p_vnode):Boolean; begin Result:=mtx_trylock(vp^.v_interlock); end; procedure VI_UNLOCK(vp:p_vnode); begin mtx_unlock(vp^.v_interlock); end; function VI_MTX(vp:p_vnode):p_mtx; inline; begin Result:=@vp^.v_interlock; end; function IGNORE_LOCK(vp:p_vnode):Boolean; inline; begin Result:=(vp=nil) or (vp^.v_type=VCHR) or (vp^.v_type=VBAD); end; procedure vn_rangelock_unlock(vp:p_vnode;cookie:Pointer); begin //rangelock_unlock(@vp^.v_rl, (cookie), VI_MTX(vp)) end; procedure vn_rangelock_unlock_range(vp:p_vnode;cookie:Pointer;start,__end:Int64); begin //rangelock_unlock_range(@vp^.v_rl, (cookie), start, __end, VI_MTX(vp)) end; function vn_rangelock_rlock(vp:p_vnode;start,__end:Int64):Pointer; begin Result:=nil; //Result:=rangelock_rlock(@vp^.v_rl, start, __end, VI_MTX(vp)) end; function vn_rangelock_wlock(vp:p_vnode;start,__end:Int64):Pointer; begin Result:=nil; //Result:=rangelock_wlock(@vp^.v_rl, start, __end, VI_MTX(vp)) end; end.