mirror of https://github.com/red-prig/fpPS4.git
330 lines
9.5 KiB
Plaintext
330 lines
9.5 KiB
Plaintext
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.
|
|
|