mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
c7cc66e974
commit
114689e7f8
|
@ -575,14 +575,11 @@ var
|
|||
begin
|
||||
Result:=ESRCH;
|
||||
|
||||
evf:=p_evf(id_get(@evf_table,key));
|
||||
if (evf=nil) then Exit;
|
||||
if not id_del(@evf_table,key,@evf) then Exit;
|
||||
|
||||
evf_delete(evf);
|
||||
id_release(@evf^.desc);
|
||||
|
||||
if not id_del(@evf_table,key) then Exit;
|
||||
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
|
|
|
@ -36,9 +36,9 @@ procedure id_table_init(t:p_id_desc_table;min:Integer);
|
|||
procedure id_table_fini(t:p_id_desc_table);
|
||||
|
||||
function id_new(t:p_id_desc_table;d:p_id_desc;pKey:PInteger):Boolean;
|
||||
function id_set(t:p_id_desc_table;d:p_id_desc;Key:Integer):Boolean;
|
||||
function id_set(t:p_id_desc_table;d:p_id_desc;Key:Integer;old:PPointer):Boolean;
|
||||
function id_get(t:p_id_desc_table;Key:Integer):p_id_desc;
|
||||
function id_del(t:p_id_desc_table;Key:Integer):Boolean;
|
||||
function id_del(t:p_id_desc_table;Key:Integer;old:PPointer):Boolean;
|
||||
|
||||
implementation
|
||||
|
||||
|
@ -140,7 +140,7 @@ begin
|
|||
rw_wunlock(t^.FLock);
|
||||
end;
|
||||
|
||||
function id_set(t:p_id_desc_table;d:p_id_desc;Key:Integer):Boolean;
|
||||
function id_set(t:p_id_desc_table;d:p_id_desc;Key:Integer;old:PPointer):Boolean;
|
||||
Label
|
||||
_exit;
|
||||
Var
|
||||
|
@ -154,10 +154,23 @@ begin
|
|||
data:=HAMT_insert32(@t^.FHAMT,Key,Pointer(d));
|
||||
|
||||
if (data=nil) then goto _exit;
|
||||
if (data^<>Pointer(d)) then goto _exit;
|
||||
|
||||
Inc(t^.FCount);
|
||||
id_acqure(d);
|
||||
if (data^<>Pointer(d)) then
|
||||
begin
|
||||
if (old<>nil) then
|
||||
begin
|
||||
old^:=data^;
|
||||
data^:=Pointer(d);
|
||||
end else
|
||||
begin
|
||||
goto _exit;
|
||||
end;
|
||||
end else
|
||||
if (old<>nil) then
|
||||
begin
|
||||
old^:=nil;
|
||||
end;
|
||||
|
||||
id_acqure(d);
|
||||
|
||||
Result:=True;
|
||||
|
@ -190,7 +203,7 @@ begin
|
|||
rw_runlock(t^.FLock);
|
||||
end;
|
||||
|
||||
function id_del(t:p_id_desc_table;Key:Integer):Boolean;
|
||||
function id_del(t:p_id_desc_table;Key:Integer;old:PPointer):Boolean;
|
||||
Var
|
||||
d:p_id_desc;
|
||||
begin
|
||||
|
@ -203,9 +216,19 @@ begin
|
|||
|
||||
if (d<>nil) then
|
||||
begin
|
||||
id_release(d);
|
||||
if (old<>nil) then
|
||||
begin
|
||||
old^:=d;
|
||||
end else
|
||||
begin
|
||||
id_release(d);
|
||||
end;
|
||||
Dec(t^.FCount);
|
||||
Result:=True;
|
||||
end else
|
||||
if (old<>nil) then
|
||||
begin
|
||||
old^:=nil;
|
||||
end;
|
||||
|
||||
rw_wunlock(t^.FLock);
|
||||
|
|
|
@ -427,14 +427,11 @@ var
|
|||
begin
|
||||
Result:=ESRCH;
|
||||
|
||||
sem:=p_osem(id_get(@osem_table,key));
|
||||
if (sem=nil) then Exit;
|
||||
if not id_del(@osem_table,key,@sem) then Exit;
|
||||
|
||||
osem_delete(sem);
|
||||
id_release(@sem^.desc);
|
||||
|
||||
if not id_del(@osem_table,key) then Exit;
|
||||
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
|
|
|
@ -92,6 +92,9 @@ const
|
|||
|
||||
THR_SUSPENDED =$0001;
|
||||
|
||||
// These flags are kept in p_flag.
|
||||
P_ADVLOCK =$00001; // Process may hold a POSIX advisory lock.
|
||||
|
||||
type
|
||||
p_teb=^teb;
|
||||
teb=packed record
|
||||
|
@ -143,6 +146,7 @@ type
|
|||
td_sqqueue :Integer;
|
||||
td_intrval :Integer;
|
||||
td_inhibitors :Integer;
|
||||
td_dupfd :Integer;
|
||||
td_timeo :Int64;
|
||||
//
|
||||
td_map_def_user :Pointer;
|
||||
|
|
|
@ -8,6 +8,10 @@ interface
|
|||
uses
|
||||
ntapi;
|
||||
|
||||
const
|
||||
IOSIZE_MAX =High(Int64);
|
||||
DEVFS_IOSIZE_MAX=High(Int64);
|
||||
|
||||
function copyin(udaddr,kaddr:Pointer;len:ptruint):Integer; inline;
|
||||
function copyinstr(udaddr,kaddr:Pointer;len:ptruint;lencopied:pptruint):Integer;
|
||||
function copyout(kaddr,udaddr:Pointer;len:ptruint):Integer; inline;
|
||||
|
|
|
@ -337,6 +337,18 @@
|
|||
<Filename Value="..\sysent.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="..\vfs\vfs_syscalls.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="..\vfs\vfilio.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="..\vfs\vdisk.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
|
|
@ -43,7 +43,8 @@ uses
|
|||
vfs_subr,
|
||||
vfs_mount,
|
||||
vfs_default,
|
||||
sysent;
|
||||
sysent,
|
||||
vfs_syscalls;
|
||||
|
||||
var
|
||||
mtx:umutex;
|
||||
|
|
27
sys/time.pas
27
sys/time.pas
|
@ -54,6 +54,10 @@ type
|
|||
tz_dstsec :DWORD;
|
||||
end;
|
||||
|
||||
function timespeccmp_lt(tvp,uvp:ptimespec):Integer; inline;
|
||||
|
||||
procedure TIMEVAL_TO_TIMESPEC(tv:ptimeval;ts:ptimespec); inline;
|
||||
procedure TIMESPEC_TO_TIMEVAL(tv:ptimeval;ts:ptimespec); inline;
|
||||
function TIMESPEC_TO_UNIT(ts:ptimespec):Int64; inline; //Unit
|
||||
function tvtohz(time:Int64):Int64; inline;
|
||||
procedure usec2timespec(ts:ptimespec;timeo:DWORD);
|
||||
|
@ -71,6 +75,29 @@ uses
|
|||
thr_error,
|
||||
kern_time;
|
||||
|
||||
function timespeccmp_lt(tvp,uvp:ptimespec):Integer; inline;
|
||||
begin
|
||||
if (tvp^.tv_sec=uvp^.tv_sec) then
|
||||
begin
|
||||
Result:=ord(tvp^.tv_nsec < uvp^.tv_nsec);
|
||||
end else
|
||||
begin
|
||||
Result:=ord(tvp^.tv_sec < uvp^.tv_sec);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIMEVAL_TO_TIMESPEC(tv:ptimeval;ts:ptimespec); inline;
|
||||
begin
|
||||
ts^.tv_sec :=tv^.tv_sec;
|
||||
ts^.tv_nsec:=tv^.tv_usec * 1000;
|
||||
end;
|
||||
|
||||
procedure TIMESPEC_TO_TIMEVAL(tv:ptimeval;ts:ptimespec); inline;
|
||||
begin
|
||||
tv^.tv_sec :=ts^.tv_sec;
|
||||
tv^.tv_usec:=ts^.tv_nsec div 1000;
|
||||
end;
|
||||
|
||||
function TIMESPEC_TO_UNIT(ts:ptimespec):Int64; inline; //Unit
|
||||
begin
|
||||
Result:=(QWORD(ts^.tv_sec)*10000000)+(QWORD(ts^.tv_nsec) div 100);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -6,11 +6,17 @@ unit sys_capability;
|
|||
interface
|
||||
|
||||
uses
|
||||
errno,
|
||||
vcapability,
|
||||
vfile,
|
||||
vuio,
|
||||
vstat,
|
||||
vm;
|
||||
|
||||
function sys_cap_new():Integer;
|
||||
function sys_cap_getrights():Integer;
|
||||
function sys_cap_enter():Integer;
|
||||
function sys_cap_getmode():Integer;
|
||||
|
||||
{
|
||||
* struct capability describes a capability, and is hung off of its struct
|
||||
* file f_data field. cap_file and cap_rightss are static once hooked up, as
|
||||
|
@ -30,8 +36,78 @@ function cap_rights(fp_cap:p_file):cap_rights_t;
|
|||
function cap_funwrap(fp_cap:p_file;rights:cap_rights_t;fpp:pp_file):Integer;
|
||||
function cap_funwrap_mmap(fp_cap:p_file;rights:cap_rights_t;maxprotp:PByte;fpp:pp_file):Integer;
|
||||
|
||||
function kern_capwrap(fp:p_file;rights:cap_rights_t;capfdp:PInteger):Integer;
|
||||
|
||||
function capability_close(fp:p_file):Integer;
|
||||
function capability_read(fp:p_file;uio:p_uio;flags:Integer):Integer;
|
||||
function capability_write(fp:p_file;uio:p_uio;flags:Integer):Integer;
|
||||
function capability_truncate(fp:p_file;length:Int64):Integer;
|
||||
function capability_ioctl(fp:p_file;com:QWORD;data:Pointer):Integer;
|
||||
function capability_poll(fp:p_file;events:Integer):Integer;
|
||||
function capability_kqfilter(fp:p_file;kn:Pointer):Integer;
|
||||
function capability_stat(fp:p_file;sb:p_stat):Integer;
|
||||
function capability_chmod(fp:p_file;mode:mode_t):Integer;
|
||||
function capability_chown(fp:p_file;uid:uid_t;gid:gid_t):Integer;
|
||||
|
||||
const
|
||||
capability_ops:fileops=(
|
||||
fo_read :@capability_read;
|
||||
fo_write :@capability_write;
|
||||
fo_truncate:@capability_truncate;
|
||||
fo_ioctl :@capability_ioctl;
|
||||
fo_poll :@capability_poll;
|
||||
fo_kqfilter:@capability_kqfilter;
|
||||
fo_stat :@capability_stat;
|
||||
fo_close :@capability_close;
|
||||
fo_chmod :@capability_chmod;
|
||||
fo_chown :@capability_chown;
|
||||
fo_flags :DFLAG_PASSABLE
|
||||
);
|
||||
|
||||
capability_ops_unpassable:fileops=(
|
||||
fo_read :@capability_read;
|
||||
fo_write :@capability_write;
|
||||
fo_truncate:@capability_truncate;
|
||||
fo_ioctl :@capability_ioctl;
|
||||
fo_poll :@capability_poll;
|
||||
fo_kqfilter:@capability_kqfilter;
|
||||
fo_stat :@capability_stat;
|
||||
fo_close :@capability_close;
|
||||
fo_chmod :@capability_chmod;
|
||||
fo_chown :@capability_chown;
|
||||
fo_flags :0
|
||||
);
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
errno,
|
||||
kern_descrip;
|
||||
|
||||
{
|
||||
* Stub Capability functions for when options CAPABILITIES isn't compiled
|
||||
* into the kernel.
|
||||
}
|
||||
function sys_cap_new():Integer;
|
||||
begin
|
||||
Exit(ENOSYS);
|
||||
end;
|
||||
|
||||
function sys_cap_getrights():Integer;
|
||||
begin
|
||||
Exit(ENOSYS);
|
||||
end;
|
||||
|
||||
function sys_cap_enter():Integer;
|
||||
begin
|
||||
Exit(ENOSYS);
|
||||
end;
|
||||
|
||||
function sys_cap_getmode():Integer;
|
||||
begin
|
||||
Exit(ENOSYS);
|
||||
end;
|
||||
|
||||
function cap_check(c:p_capability;rights:cap_rights_t):Integer;
|
||||
begin
|
||||
if ((c^.cap_rights or rights)<>c^.cap_rights) then
|
||||
|
@ -105,5 +181,148 @@ begin
|
|||
Exit(0);
|
||||
end;
|
||||
|
||||
{
|
||||
* Create a capability to wrap around an existing file.
|
||||
}
|
||||
function kern_capwrap(fp:p_file;rights:cap_rights_t;capfdp:PInteger):Integer;
|
||||
var
|
||||
cp,cp_old:p_capability;
|
||||
fp_object,fcapp:p_file;
|
||||
error:Integer;
|
||||
begin
|
||||
if ((rights or CAP_MASK_VALID)<>CAP_MASK_VALID) then
|
||||
Exit(EINVAL);
|
||||
|
||||
{
|
||||
* If a new capability is being derived from an existing capability,
|
||||
* then the new capability rights must be a subset of the existing
|
||||
* rights.
|
||||
}
|
||||
if (fp^.f_type=DTYPE_CAPABILITY) then
|
||||
begin
|
||||
cp_old:=fp^.f_data;
|
||||
if ((cp_old^.cap_rights or rights)<>cp_old^.cap_rights) then
|
||||
Exit(ENOTCAPABLE);
|
||||
end;
|
||||
|
||||
{
|
||||
* Allocate a new file descriptor to hang the capability off of.
|
||||
}
|
||||
error:=falloc(@fcapp, capfdp, fp^.f_flag);
|
||||
if (error<>0) then
|
||||
Exit(error);
|
||||
|
||||
{
|
||||
* Rather than nesting capabilities, directly reference the object an
|
||||
* existing capability references. There's nothing else interesting
|
||||
* to preserve for future use, as we've incorporated the previous
|
||||
* rights mask into the new one. This prevents us from having to
|
||||
* deal with capability chains.
|
||||
}
|
||||
if (fp^.f_type=DTYPE_CAPABILITY) then
|
||||
fp_object:=p_capability(fp^.f_data)^.cap_object
|
||||
else
|
||||
fp_object:=fp;
|
||||
fhold(fp_object);
|
||||
cp:=AllocMem(SizeOf(t_capability));
|
||||
cp^.cap_rights:=rights;
|
||||
cp^.cap_object:=fp_object;
|
||||
cp^.cap_file:=fcapp;
|
||||
|
||||
if ((fp^.f_flag and DFLAG_PASSABLE)<>0) then
|
||||
finit(fcapp, fp^.f_flag, DTYPE_CAPABILITY, cp, @capability_ops)
|
||||
else
|
||||
finit(fcapp, fp^.f_flag, DTYPE_CAPABILITY, cp, @capability_ops_unpassable);
|
||||
|
||||
{
|
||||
* Release our private reference (the proc filedesc still has one).
|
||||
}
|
||||
fdrop(fcapp);
|
||||
Exit(0);
|
||||
end;
|
||||
|
||||
{
|
||||
* When a capability is closed, simply drop the reference on the underlying
|
||||
* object and free the capability. fdrop() will handle the case where the
|
||||
* underlying object also needs to close, and the caller will have already
|
||||
* performed any object-specific lock or mqueue handling.
|
||||
}
|
||||
function capability_close(fp:p_file):Integer;
|
||||
var
|
||||
c:p_capability;
|
||||
fp_object:p_file;
|
||||
begin
|
||||
Assert(fp^.f_type=DTYPE_CAPABILITY,('capability_close: !capability'));
|
||||
|
||||
c:=fp^.f_data;
|
||||
fp^.f_ops:=@badfileops;
|
||||
fp^.f_data:=nil;
|
||||
fp_object:=c^.cap_object;
|
||||
FreeMem(c);
|
||||
|
||||
Exit(fdrop(fp_object));
|
||||
end;
|
||||
|
||||
{
|
||||
* In general, file descriptor operations should never make it to the
|
||||
* capability, only the underlying file descriptor operation vector, so panic
|
||||
* if we do turn up here.
|
||||
}
|
||||
function capability_read(fp:p_file;uio:p_uio;flags:Integer):Integer;
|
||||
begin
|
||||
Assert(False,'capability_read');
|
||||
Exit(ENOSYS);
|
||||
end;
|
||||
|
||||
function capability_write(fp:p_file;uio:p_uio;flags:Integer):Integer;
|
||||
begin
|
||||
Assert(False,'capability_write');
|
||||
Exit(ENOSYS);
|
||||
end;
|
||||
|
||||
function capability_truncate(fp:p_file;length:Int64):Integer;
|
||||
begin
|
||||
Assert(False,'capability_truncate');
|
||||
Exit(ENOSYS);
|
||||
end;
|
||||
|
||||
function capability_ioctl(fp:p_file;com:QWORD;data:Pointer):Integer;
|
||||
begin
|
||||
Assert(False,'capability_ioctl');
|
||||
Exit(ENOSYS);
|
||||
end;
|
||||
|
||||
function capability_poll(fp:p_file;events:Integer):Integer;
|
||||
begin
|
||||
Assert(False,'capability_poll');
|
||||
Exit(ENOSYS);
|
||||
end;
|
||||
|
||||
function capability_kqfilter(fp:p_file;kn:Pointer):Integer;
|
||||
begin
|
||||
Assert(False,'capability_kqfilter');
|
||||
Exit(ENOSYS);
|
||||
end;
|
||||
|
||||
function capability_stat(fp:p_file;sb:p_stat):Integer;
|
||||
begin
|
||||
Assert(False,'capability_stat');
|
||||
Exit(ENOSYS);
|
||||
end;
|
||||
|
||||
function capability_chmod(fp:p_file;mode:mode_t):Integer;
|
||||
begin
|
||||
Assert(False,'capability_chmod');
|
||||
Exit(ENOSYS);
|
||||
end;
|
||||
|
||||
function capability_chown(fp:p_file;uid:uid_t;gid:gid_t):Integer;
|
||||
begin
|
||||
Assert(False,'capability_chown');
|
||||
Exit(ENOSYS);
|
||||
end;
|
||||
|
||||
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
unit vdisk;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
{$CALLING SysV_ABI_CDecl}
|
||||
|
||||
interface
|
||||
|
||||
const
|
||||
DIOCGSECTORSIZE =$40046480;
|
||||
DIOCGMEDIASIZE =$40046481;
|
||||
DIOCGFWSECTORS =$40046482;
|
||||
DIOCGFWHEADS =$40046483;
|
||||
DIOCSKERNELDUMP =$80046485;
|
||||
DIOCGFRONTSTUFF =$40046486;
|
||||
DIOCGFLUSH =$20006487;
|
||||
DIOCGDELETE =$80086488;
|
||||
DISK_IDENT_SIZE =256 ;
|
||||
DIOCGIDENT =$41006489;
|
||||
DIOCGPROVIDERNAME=$4400648A;
|
||||
DIOCGSTRIPESIZE =$4004648B;
|
||||
DIOCGSTRIPEOFFSET=$4004648C;
|
||||
DIOCGPHYSPATH =$4400648D;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
|
|
@ -100,13 +100,34 @@ const
|
|||
{
|
||||
* Constants used for fcntl(2)
|
||||
}
|
||||
|
||||
{ command values }
|
||||
F_GETFL = 3; { get file status flags }
|
||||
F_SETFL = 4; { set file status flags }
|
||||
F_GETLK =11; { get record locking information }
|
||||
F_SETLK =12; { set record locking information }
|
||||
F_SETLKW=13; { F_SETLK; wait if blocked }
|
||||
F_DUPFD = 0; { duplicate file descriptor }
|
||||
F_GETFD = 1; { get file descriptor flags }
|
||||
F_SETFD = 2; { set file descriptor flags }
|
||||
|
||||
F_GETFL = 3; { get file status flags }
|
||||
F_SETFL = 4; { set file status flags }
|
||||
|
||||
F_GETOWN = 5; { get SIGIO/SIGURG proc/pgrp }
|
||||
F_SETOWN = 6; { set SIGIO/SIGURG proc/pgrp }
|
||||
|
||||
F_OGETLK = 7; { get record locking information }
|
||||
F_OSETLK = 8; { set record locking information }
|
||||
F_OSETLKW= 9; { F_SETLK; wait if blocked }
|
||||
F_DUP2FD =10; { duplicate file descriptor to arg }
|
||||
|
||||
F_GETLK =11; { get record locking information }
|
||||
F_SETLK =12; { set record locking information }
|
||||
F_SETLKW =13; { F_SETLK; wait if blocked }
|
||||
|
||||
F_SETLK_REMOTE =14; { debugging support for remote locks }
|
||||
F_READAHEAD =15; { read ahead }
|
||||
F_RDAHEAD =16; { Darwin compatible read ahead }
|
||||
F_DUPFD_CLOEXEC =17; { Like F_DUPFD, but FD_CLOEXEC is set }
|
||||
F_DUP2FD_CLOEXEC=18; { Like F_DUP2FD, but FD_CLOEXEC is set }
|
||||
|
||||
{ file descriptor flags (F_GETFD, F_SETFD) }
|
||||
FD_CLOEXEC=1; { close-on-exec flag }
|
||||
|
||||
{ record locking flags (F_GETLK, F_SETLK, F_SETLKW) }
|
||||
F_RDLCK =1; { shared or read lock }
|
||||
|
@ -121,6 +142,12 @@ const
|
|||
F_REMOTE=$080; { Lock owner is remote NFS client }
|
||||
F_NOINTR=$100; { Ignore signals when waiting }
|
||||
|
||||
// lock operations for flock(2)
|
||||
LOCK_SH =$01; // shared file lock
|
||||
LOCK_EX =$02; // exclusive file lock
|
||||
LOCK_NB =$04; // don't block when locking
|
||||
LOCK_UN =$08; // unlock file
|
||||
|
||||
//Advice to posix_fadvise
|
||||
POSIX_FADV_NORMAL =0; // no special treatment
|
||||
POSIX_FADV_RANDOM =1; // expect random page references
|
||||
|
@ -136,14 +163,26 @@ const
|
|||
type
|
||||
p_flock=^t_flock;
|
||||
t_flock=packed record
|
||||
l_start :QWORD ; // starting offset
|
||||
l_len :QWORD ; // len = 0 means until end of file
|
||||
l_start :Int64 ; // starting offset
|
||||
l_len :Int64 ; // len = 0 means until end of file
|
||||
l_pid :DWORD ; // lock owner
|
||||
l_type :WORD ; // lock type: read/write, etc.
|
||||
l_whence:WORD ; // type of l_start
|
||||
l_sysid :Integer; // remote system id or zero for local
|
||||
end;
|
||||
|
||||
{
|
||||
* Old advisory file segment locking data type,
|
||||
* before adding l_sysid.
|
||||
}
|
||||
__oflock=packed record
|
||||
l_start :Int64; // starting offset
|
||||
l_len :Int64; // len = 0 means until end of file
|
||||
l_pid :DWORD; // lock owner
|
||||
l_type :WORD ; // lock type: read/write, etc.
|
||||
l_whence:WORD ; // type of l_start
|
||||
end;
|
||||
|
||||
{ convert from open() flags to/from fflags; convert O_RD/WR to FREAD/FWRITE }
|
||||
function FFLAGS(oflags:Integer):Integer; inline;
|
||||
function OFLAGS(fflags:Integer):Integer; inline;
|
||||
|
|
|
@ -27,6 +27,8 @@ const
|
|||
MAXPATHLEN =PATH_MAX;
|
||||
MAXSYMLINKS=32;
|
||||
|
||||
maxfilesperproc = 44236;
|
||||
|
||||
// configurable pathname variables
|
||||
_PC_LINK_MAX =1;
|
||||
_PC_MAX_CANON =2;
|
||||
|
@ -39,6 +41,25 @@ const
|
|||
_PC_VDISABLE =9;
|
||||
_POSIX_VDISABLE =$ff;
|
||||
|
||||
_PC_ASYNC_IO =53;
|
||||
_PC_PRIO_IO =54;
|
||||
_PC_SYNC_IO =55;
|
||||
|
||||
_PC_ALLOC_SIZE_MIN =10;
|
||||
_PC_FILESIZEBITS =12;
|
||||
_PC_REC_INCR_XFER_SIZE=14;
|
||||
_PC_REC_MAX_XFER_SIZE =15;
|
||||
_PC_REC_MIN_XFER_SIZE =16;
|
||||
_PC_REC_XFER_ALIGN =17;
|
||||
_PC_SYMLINK_MAX =18;
|
||||
|
||||
_PC_ACL_EXTENDED=59;
|
||||
_PC_ACL_PATH_MAX=60;
|
||||
_PC_CAP_PRESENT =61;
|
||||
_PC_INF_PRESENT =62;
|
||||
_PC_MAC_PRESENT =63;
|
||||
_PC_ACL_NFS4 =64;
|
||||
|
||||
// access function
|
||||
F_OK=0; // test for existence of file
|
||||
X_OK=$01; // test for execute or search permission
|
||||
|
@ -46,9 +67,16 @@ const
|
|||
R_OK=$04; // test for read permission
|
||||
|
||||
// whence values for lseek(2)
|
||||
SEEK_SET=0; // set file offset to offset
|
||||
SEEK_CUR=1; // set file offset to current plus offset
|
||||
SEEK_END=2; // set file offset to EOF plus offset
|
||||
SEEK_SET =0; // set file offset to offset
|
||||
SEEK_CUR =1; // set file offset to current plus offset
|
||||
SEEK_END =2; // set file offset to EOF plus offset
|
||||
SEEK_DATA=3; // set file offset to next data past offset
|
||||
SEEK_HOLE=4; // set file offset to next hole past offset
|
||||
|
||||
// whence values for lseek(2); renamed by POSIX 1003.1
|
||||
L_SET =SEEK_SET;
|
||||
L_INCR=SEEK_CUR;
|
||||
L_XTND=SEEK_END;
|
||||
|
||||
DTYPE_VNODE = 1; { file }
|
||||
DTYPE_SOCKET = 2; { communications endpoint }
|
||||
|
@ -131,6 +159,7 @@ type
|
|||
* DTYPE_VNODE specific fields.
|
||||
}
|
||||
f_seqcount:Integer; { Count of sequential accesses. }
|
||||
f_exclose :Integer;
|
||||
f_nextoff :Int64; { next expected read/write offset. }
|
||||
f_vnun :Pointer;
|
||||
{
|
||||
|
@ -157,6 +186,14 @@ const
|
|||
var
|
||||
openfiles:Integer=0; { actual number of open files }
|
||||
|
||||
{
|
||||
* The module initialization routine for POSIX asynchronous I/O will
|
||||
* set this to the version of AIO that it implements. (Zero means
|
||||
* that it is not implemented.) This value is used here by pathconf()
|
||||
* and in kern_descrip.c by fpathconf().
|
||||
}
|
||||
async_io_version:Integer=0;
|
||||
|
||||
function fo_read(fp:p_file;uio:p_uio;flags:Integer):Integer;
|
||||
function fo_write(fp:p_file;uio:p_uio;flags:Integer):Integer;
|
||||
function fo_truncate(fp:p_file;length:Int64):Integer;
|
||||
|
@ -170,11 +207,6 @@ function fo_chown(fp:p_file;uid:uid_t;gid:gid_t):Integer;
|
|||
|
||||
implementation
|
||||
|
||||
//function foffset_get(fp:p_file):Int64; inline;
|
||||
//begin
|
||||
// Result:=(foffset_lock(fp, FOF_NOLOCK));
|
||||
//end;
|
||||
|
||||
{
|
||||
fhold(fp) (refcount_acquire(&(fp)^.f_count))
|
||||
fdrop(fp, td) (refcount_release(&(fp)^.f_count) ? _fdrop((fp), (td)) : _fnoop())
|
||||
|
|
|
@ -20,7 +20,7 @@ type
|
|||
NDSLOTTYPE=QWORD;
|
||||
|
||||
p_filedesc=^t_filedesc;
|
||||
t_filedesc=packed record
|
||||
t_filedesc=packed object
|
||||
fd_ofiles:t_id_desc_table;
|
||||
//fd_ofiles :pp_file ; { file structures for open files }
|
||||
//fd_ofileflags :PChar ; { per-process open file flags }
|
||||
|
@ -38,6 +38,8 @@ type
|
|||
//fd_kqlist :kqlist ; { list of kqueues on this filedesc }
|
||||
fd_holdleaderscount :Integer ; { block fdfree() for shared close() }
|
||||
fd_holdleaderswakeup:Integer ; { fdfree() needs wakeup }
|
||||
//
|
||||
property fd_nfiles:Integer read fd_ofiles.FCount;
|
||||
end;
|
||||
|
||||
{
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
unit vfilio;
|
||||
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
{$CALLING SysV_ABI_CDecl}
|
||||
|
||||
interface
|
||||
|
||||
const
|
||||
FIOCLEX =$20006601;
|
||||
FIONCLEX =$20006602;
|
||||
FIONREAD =$4004667F;
|
||||
FIONBIO =$8004667E;
|
||||
FIOASYNC =$8004667D;
|
||||
FIOSETOWN =$8004667C;
|
||||
FIOGETOWN =$4004667B;
|
||||
FIODTYPE =$4004667A;
|
||||
FIOGETLBA =$40046679;
|
||||
FIODGNAME =$80106678;
|
||||
FIONWRITE =$40046677;
|
||||
FIONSPACE =$40046676;
|
||||
FIOSEEKDATA=$C0046661;
|
||||
FIOSEEKHOLE=$C0046662;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
|
|
@ -219,6 +219,7 @@ end;
|
|||
function vop_panic(ap:Pointer):Integer;
|
||||
begin
|
||||
Assert(false,'filesystem goof: vop_panic[%s]');
|
||||
Exit(ENOENT);
|
||||
end;
|
||||
|
||||
{
|
||||
|
@ -1036,16 +1037,14 @@ begin
|
|||
Exit(error);
|
||||
end;
|
||||
//vinvalbuf(vp, V_CLEANONLY, 0, 0);
|
||||
{
|
||||
if (vp^.v_object<>nil) then
|
||||
begin
|
||||
start:=trunc_page(ap^.a_start);
|
||||
__end:=round_page(ap^.a_end);
|
||||
VM_OBJECT_LOCK(vp^.v_object);
|
||||
vm_object_page_cache(vp^.v_object, OFF_TO_IDX(start), OFF_TO_IDX(__end));
|
||||
VM_OBJECT_UNLOCK(vp^.v_object);
|
||||
end;
|
||||
}
|
||||
//if (vp^.v_object<>nil) then
|
||||
//begin
|
||||
// start:=trunc_page(ap^.a_start);
|
||||
// __end:=round_page(ap^.a_end);
|
||||
// VM_OBJECT_LOCK(vp^.v_object);
|
||||
// vm_object_page_cache(vp^.v_object, OFF_TO_IDX(start), OFF_TO_IDX(__end));
|
||||
// VM_OBJECT_UNLOCK(vp^.v_object);
|
||||
//end;
|
||||
VOP_UNLOCK(vp, 0);
|
||||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
end;
|
||||
|
|
|
@ -425,7 +425,7 @@ begin
|
|||
error:=_namei(@nd);
|
||||
if (error<>0) then
|
||||
Exit (error);
|
||||
if (not NDHASGIANT(@nd)) then
|
||||
if (NDHASGIANT(@nd)=0) then
|
||||
mtx_lock(VFS_Giant);
|
||||
NDFREE(@nd, NDF_ONLY_PNBUF);
|
||||
vp:=nd.ni_vp;
|
||||
|
|
|
@ -36,6 +36,8 @@ procedure vput(vp:p_vnode);
|
|||
|
||||
procedure vinactive(vp:p_vnode);
|
||||
|
||||
procedure vfs_notify_upper(vp:p_vnode;event:Integer);
|
||||
|
||||
procedure assert_vi_locked (vp:p_vnode;str:PChar);
|
||||
procedure assert_vi_unlocked (vp:p_vnode;str:PChar);
|
||||
procedure assert_vop_locked (vp:p_vnode;str:PChar);
|
||||
|
@ -49,6 +51,11 @@ function vfs_read_dirent(ap:p_vop_readdir_args;dp:p_dirent;off:QWORD):Integer;
|
|||
procedure vfs_mark_atime(vp:p_vnode);
|
||||
function vfs_unixify_accmode(accmode:p_accmode_t):Integer;
|
||||
|
||||
function vcount(vp:p_vnode):Integer;
|
||||
function count_dev(dev:Pointer):Integer; //cdev
|
||||
|
||||
procedure vfs_msync(mp:p_mount;flags:Integer);
|
||||
|
||||
function __mnt_vnode_next_all(mvp:pp_vnode;mp:p_mount):p_vnode;
|
||||
function __mnt_vnode_first_all(mvp:pp_vnode;mp:p_mount):p_vnode;
|
||||
procedure __mnt_vnode_markerfree_all(mvp:pp_vnode;mp:p_mount);
|
||||
|
@ -58,7 +65,8 @@ implementation
|
|||
uses
|
||||
errno,
|
||||
vfs_vnops,
|
||||
subr_uio;
|
||||
subr_uio,
|
||||
vm_object;
|
||||
|
||||
{
|
||||
* List of vnodes that are ready for recycling.
|
||||
|
@ -282,7 +290,6 @@ end;
|
|||
}
|
||||
procedure vattr_null(vap:p_vattr);
|
||||
begin
|
||||
|
||||
vap^.va_type:=VNON;
|
||||
vap^.va_size:=VNOVAL;
|
||||
vap^.va_bytes:=VNOVAL;
|
||||
|
@ -2152,9 +2159,9 @@ end;
|
|||
* failed lock upgrade.
|
||||
}
|
||||
procedure vinactive(vp:p_vnode);
|
||||
var
|
||||
obj:vm_object_t;
|
||||
begin
|
||||
//struct vm_object *obj;
|
||||
|
||||
ASSERT_VOP_ELOCKED(vp,'vinactive');
|
||||
ASSERT_VI_LOCKED(vp,'vinactive');
|
||||
Assert((vp^.v_iflag and VI_DOINGINACT)=0,'vinactive: recursed on VI_DOINGINACT');
|
||||
|
@ -2170,13 +2177,14 @@ begin
|
|||
* if there is at least one resident non-cached page, the vnode
|
||||
* cannot leave the active list without the page cleanup done.
|
||||
}
|
||||
obj:=nil;
|
||||
//obj:=vp^.v_object;
|
||||
//if (obj<>nil) and (obj^.flags and OBJ_MIGHTBEDIRTY)<>0) then
|
||||
//begin
|
||||
// VM_OBJECT_LOCK(obj);
|
||||
// vm_object_page_clean(obj, 0, 0, OBJPC_NOSYNC);
|
||||
// VM_OBJECT_UNLOCK(obj);
|
||||
//end;
|
||||
if (obj<>nil) and ((obj^.flags and OBJ_MIGHTBEDIRTY)<>0) then
|
||||
begin
|
||||
VM_OBJECT_LOCK(obj);
|
||||
//vm_object_page_clean(obj, 0, 0, OBJPC_NOSYNC);
|
||||
VM_OBJECT_UNLOCK(obj);
|
||||
end;
|
||||
VOP_INACTIVE(vp);
|
||||
VI_LOCK(vp);
|
||||
Assert((vp^.v_iflag and VI_DOINGINACT)<>0,'vinactive: lost VI_DOINGINACT');
|
||||
|
@ -2350,70 +2358,90 @@ begin
|
|||
vgonel(vp);
|
||||
VI_UNLOCK(vp);
|
||||
end;
|
||||
}
|
||||
|
||||
static void
|
||||
notify_lowervp_vfs_dummy(mp:p_mount __unused,
|
||||
struct vnode *lowervp __unused)
|
||||
procedure notify_lowervp_vfs_dummy(mp:p_mount;lowervp:p_vnode);
|
||||
begin
|
||||
end;
|
||||
|
||||
const
|
||||
vgonel_vfsops:vfsops=(
|
||||
vfs_mount :nil;
|
||||
vfs_cmount :nil;
|
||||
vfs_unmount :nil;
|
||||
vfs_root :nil;
|
||||
vfs_quotactl :nil;
|
||||
vfs_statfs :nil;
|
||||
vfs_sync :nil;
|
||||
vfs_vget :nil;
|
||||
vfs_fhtovp :nil;
|
||||
vfs_checkexp :nil;
|
||||
vfs_init :nil;
|
||||
vfs_uninit :nil;
|
||||
vfs_extattrctl :nil;
|
||||
vfs_sysctl :nil;
|
||||
vfs_susp_clean :nil;
|
||||
vfs_reclaim_lowervp:@notify_lowervp_vfs_dummy;
|
||||
vfs_unlink_lowervp :@notify_lowervp_vfs_dummy
|
||||
);
|
||||
|
||||
{
|
||||
* Notify upper mounts about reclaimed or unlinked vnode.
|
||||
}
|
||||
void
|
||||
vfs_notify_upper(vp:p_vnode, int event)
|
||||
procedure vfs_notify_upper(vp:p_vnode;event:Integer);
|
||||
label
|
||||
unlock;
|
||||
var
|
||||
mp,ump,mmp:p_mount;
|
||||
begin
|
||||
static struct vfsops vgonel_vfsops:=begin
|
||||
.vfs_reclaim_lowervp:=notify_lowervp_vfs_dummy,
|
||||
.vfs_unlink_lowervp:=notify_lowervp_vfs_dummy,
|
||||
end;;
|
||||
mp:p_mount, *ump, *mmp;
|
||||
|
||||
mp:=vp^.v_mount;
|
||||
if (mp=nil)
|
||||
if (mp=nil) then
|
||||
Exit;
|
||||
|
||||
MNT_ILOCK(mp);
|
||||
if (TAILQ_EMPTY(@mp^.mnt_uppers))
|
||||
if TAILQ_EMPTY(@mp^.mnt_uppers) then
|
||||
goto unlock;
|
||||
MNT_IUNLOCK(mp);
|
||||
mmp:=malloc(sizeof(struct mount), M_TEMP, M_WAITOK or M_ZERO);
|
||||
mmp:=AllocMem(SizeOf(mount));
|
||||
mmp^.mnt_op:=@vgonel_vfsops;
|
||||
mmp^.mnt_kern_flag:= or MNTK_MARKER;
|
||||
mmp^.mnt_kern_flag:=mmp^.mnt_kern_flag or MNTK_MARKER;
|
||||
MNT_ILOCK(mp);
|
||||
mp^.mnt_kern_flag:= or MNTK_VGONE_UPPER;
|
||||
for (ump:=TAILQ_FIRST(@mp^.mnt_uppers); ump<>nil;) begin
|
||||
if ((ump^.mnt_kern_flag and MNTK_MARKER)<>0) begin
|
||||
ump:=TAILQ_NEXT(ump, mnt_upper_link);
|
||||
mp^.mnt_kern_flag:=mmp^.mnt_kern_flag or MNTK_VGONE_UPPER;
|
||||
|
||||
ump:=TAILQ_FIRST(@mp^.mnt_uppers);
|
||||
while (ump<>nil) do
|
||||
begin
|
||||
if ((ump^.mnt_kern_flag and MNTK_MARKER)<>0) then
|
||||
begin
|
||||
ump:=TAILQ_NEXT(ump,@ump^.mnt_upper_link);
|
||||
continue;
|
||||
end;
|
||||
TAILQ_INSERT_AFTER(@mp^.mnt_uppers, ump, mmp, mnt_upper_link);
|
||||
TAILQ_INSERT_AFTER(@mp^.mnt_uppers, ump, mmp,@mmp^.mnt_upper_link);
|
||||
MNT_IUNLOCK(mp);
|
||||
switch (event) begin
|
||||
case VFS_NOTIFY_UPPER_RECLAIM:
|
||||
VFS_RECLAIM_LOWERVP(ump, vp);
|
||||
break;
|
||||
case VFS_NOTIFY_UPPER_UNLINK:
|
||||
VFS_UNLINK_LOWERVP(ump, vp);
|
||||
break;
|
||||
default:
|
||||
Assert(0, 'invalid event %d", event));
|
||||
break;
|
||||
case event of
|
||||
VFS_NOTIFY_UPPER_RECLAIM:
|
||||
VFS_RECLAIM_LOWERVP(ump, vp);
|
||||
VFS_NOTIFY_UPPER_UNLINK:
|
||||
VFS_UNLINK_LOWERVP(ump, vp);
|
||||
else
|
||||
Assert(false, 'invalid event');
|
||||
end;
|
||||
MNT_ILOCK(mp);
|
||||
ump:=TAILQ_NEXT(mmp, mnt_upper_link);
|
||||
TAILQ_REMOVE(@mp^.mnt_uppers, mmp, mnt_upper_link);
|
||||
ump:=TAILQ_NEXT(mmp,@mmp^.mnt_upper_link);
|
||||
TAILQ_REMOVE(@mp^.mnt_uppers, mmp,@mmp^.mnt_upper_link);
|
||||
end;
|
||||
free(mmp, M_TEMP);
|
||||
mp^.mnt_kern_flag:= and ~MNTK_VGONE_UPPER;
|
||||
if ((mp^.mnt_kern_flag and MNTK_VGONE_WAITER)<>0) begin
|
||||
mp^.mnt_kern_flag:= and ~MNTK_VGONE_WAITER;
|
||||
FreeMem(mmp);
|
||||
mp^.mnt_kern_flag:=mp^.mnt_kern_flag and (not MNTK_VGONE_UPPER);
|
||||
if ((mp^.mnt_kern_flag and MNTK_VGONE_WAITER)<>0) then
|
||||
begin
|
||||
mp^.mnt_kern_flag:=mp^.mnt_kern_flag and (not MNTK_VGONE_WAITER);
|
||||
wakeup(@mp^.mnt_uppers);
|
||||
end;
|
||||
unlock:
|
||||
MNT_IUNLOCK(mp);
|
||||
end;
|
||||
|
||||
{
|
||||
{
|
||||
* vgone, with the vp interlock held.
|
||||
}
|
||||
|
@ -2508,6 +2536,7 @@ end;
|
|||
}
|
||||
function vcount(vp:p_vnode):Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
//dev_lock();
|
||||
//count:=vp^.v_rdev^.si_usecount;
|
||||
//dev_unlock();
|
||||
|
@ -2519,6 +2548,7 @@ end;
|
|||
}
|
||||
function count_dev(dev:Pointer):Integer; //cdev
|
||||
begin
|
||||
Result:=0;
|
||||
//dev_lock();
|
||||
//count:=dev^.si_usecount;
|
||||
//dev_unlock();
|
||||
|
@ -2529,15 +2559,14 @@ end;
|
|||
* perform msync on all vnodes under a mount point
|
||||
* the mount point must be locked.
|
||||
}
|
||||
|
||||
{
|
||||
void
|
||||
vfs_msync(mp:p_mount, int flags)
|
||||
procedure vfs_msync(mp:p_mount;flags:Integer);
|
||||
var
|
||||
vp,mvp:p_vnode;
|
||||
obj:Pointer; //vm_object
|
||||
begin
|
||||
vp:p_vnode, *mvp;
|
||||
struct vm_object *obj;
|
||||
|
||||
MNT_VNODE_FOREACH_ACTIVE(vp, mp, mvp) begin
|
||||
{
|
||||
MNT_VNODE_FOREACH_ACTIVE(vp, mp, mvp)
|
||||
begin
|
||||
obj:=vp^.v_object;
|
||||
if (obj<>nil and (obj^.flags and OBJ_MIGHTBEDIRTY)<>0 and
|
||||
(flags=MNT_WAIT or VOP_ISLOCKED(vp)=0)) begin
|
||||
|
@ -2562,8 +2591,8 @@ begin
|
|||
end; else
|
||||
VI_UNLOCK(vp);
|
||||
end;
|
||||
end;
|
||||
}
|
||||
end;
|
||||
|
||||
{
|
||||
static void
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -10,7 +10,6 @@ uses
|
|||
kern_thr,
|
||||
kern_mtx,
|
||||
time,
|
||||
vuio,
|
||||
vmparam;
|
||||
|
||||
const
|
||||
|
@ -210,7 +209,7 @@ type
|
|||
va_nlink :Word;
|
||||
va_uid :Integer;
|
||||
va_gid :Integer;
|
||||
va_fsid :DWORD;
|
||||
va_fsid :Integer;
|
||||
va_fileid :QWORD;
|
||||
va_size :QWORD;
|
||||
va_blocksize:QWORD;
|
||||
|
@ -220,7 +219,7 @@ type
|
|||
va_birthtime:timespec;
|
||||
va_gen :QWORD;
|
||||
va_flags :QWORD;
|
||||
va_rdev :DWORD;
|
||||
va_rdev :Integer;
|
||||
va_bytes :QWORD;
|
||||
va_filerev :QWORD;
|
||||
va_vaflags :DWORD;
|
||||
|
@ -233,22 +232,16 @@ 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
|
||||
|
||||
uses
|
||||
errno,
|
||||
vnode_if,
|
||||
vnamei,
|
||||
vfile,
|
||||
vmount,
|
||||
vfcntl,
|
||||
vfs_lookup,
|
||||
vfs_subr,
|
||||
kern_synch;
|
||||
|
||||
procedure VI_LOCK(vp:p_vnode);
|
||||
begin
|
||||
mtx_lock(vp^.v_interlock);
|
||||
|
@ -274,6 +267,27 @@ 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.
|
||||
|
||||
|
|
|
@ -9,11 +9,18 @@ uses
|
|||
vmount,
|
||||
vnamei,
|
||||
vfile,
|
||||
vstat,
|
||||
vmparam,
|
||||
vfs_vnode,
|
||||
kern_mtx;
|
||||
|
||||
function vn_lock(vp:p_vnode;flags:Integer):Integer;
|
||||
|
||||
function vn_open(ndp:p_nameidata;
|
||||
flagp:PInteger;
|
||||
cmode:Integer;
|
||||
fp:p_file):Integer;
|
||||
|
||||
function vn_open_cred(ndp:p_nameidata;
|
||||
flagp:PInteger;
|
||||
cmode:Integer;
|
||||
|
@ -23,8 +30,28 @@ function vn_open_cred(ndp:p_nameidata;
|
|||
function vn_writechk(vp:p_vnode):Integer;
|
||||
function vn_start_write(vp:p_vnode;mpp:pp_mount;flags:Integer):Integer;
|
||||
procedure vn_finished_write(mp:p_mount);
|
||||
|
||||
function vn_close(vp:p_vnode;flags:Integer):Integer;
|
||||
function vn_stat(vp:p_vnode;sb:p_stat):Integer;
|
||||
|
||||
const
|
||||
vnops:fileops=(
|
||||
fo_read :nil;//@vn_io_fault;
|
||||
fo_write :nil;//@vn_io_fault;
|
||||
fo_truncate:nil;//@vn_truncate;
|
||||
fo_ioctl :nil;//@vn_ioctl;
|
||||
fo_poll :nil;//@vn_poll;
|
||||
fo_kqfilter:nil;//@vn_kqfilter;
|
||||
fo_stat :nil;//@vn_statfile;
|
||||
fo_close :nil;//@vn_closefile;
|
||||
fo_chmod :nil;//@vn_chmod;
|
||||
fo_chown :nil;//@vn_chown;
|
||||
fo_flags :DFLAG_PASSABLE or DFLAG_SEEKABLE
|
||||
);
|
||||
|
||||
function foffset_get(fp:p_file):Int64; inline;
|
||||
function foffset_lock(fp:p_file;flags:Integer):Int64;
|
||||
procedure foffset_lock(fp:p_file;val:Int64;flags:Integer);
|
||||
procedure foffset_unlock(fp:p_file;val:Int64;flags:Integer);
|
||||
|
||||
implementation
|
||||
|
||||
|
@ -58,6 +85,14 @@ begin
|
|||
until ((flags and LK_RETRY)=0) or (Result=0);
|
||||
end;
|
||||
|
||||
function vn_open(ndp:p_nameidata;
|
||||
flagp:PInteger;
|
||||
cmode:Integer;
|
||||
fp:p_file):Integer;
|
||||
begin
|
||||
Result:=vn_open_cred(ndp, flagp, cmode, 0, fp);
|
||||
end;
|
||||
|
||||
{
|
||||
* Common code for vnode open operations.
|
||||
* Check permissions, and call the VOP_OPEN or VOP_CREATE routine.
|
||||
|
@ -65,7 +100,6 @@ end;
|
|||
* Note that this does NOT free nameidata for the successful case,
|
||||
* due to the NDINIT being done elsewhere.
|
||||
}
|
||||
|
||||
function vn_open_cred(ndp:p_nameidata;
|
||||
flagp:PInteger;
|
||||
cmode:Integer;
|
||||
|
@ -82,14 +116,14 @@ var
|
|||
fmode,error:Integer;
|
||||
accmode:accmode_t;
|
||||
mps:Integer;
|
||||
vfslocked:Boolean;
|
||||
vfslocked:Integer;
|
||||
begin
|
||||
vap:=@vat;
|
||||
|
||||
mps:=ndp^.ni_cnd.cn_flags and MPSAFE;
|
||||
|
||||
restart:
|
||||
vfslocked:=False;
|
||||
vfslocked:=0;
|
||||
fmode:=flagp^;
|
||||
if ((fmode and O_CREAT)<>0) then
|
||||
begin
|
||||
|
@ -383,5 +417,143 @@ begin
|
|||
Exit(error);
|
||||
end;
|
||||
|
||||
function vn_stat(vp:p_vnode;sb:p_stat):Integer;
|
||||
var
|
||||
vattr:t_vattr;
|
||||
vap:p_vattr;
|
||||
error:Integer;
|
||||
mode:WORD;
|
||||
begin
|
||||
//error:=mac_vnode_check_stat(active_cred, file_cred, vp);
|
||||
//if (error<>0) then
|
||||
// Exit(error);
|
||||
|
||||
vap:=@vattr;
|
||||
|
||||
{
|
||||
* Initialize defaults for new and unusual fields, so that file
|
||||
* systems which don't support these fields don't need to know
|
||||
* about them.
|
||||
}
|
||||
vap^.va_birthtime.tv_sec:=-1;
|
||||
vap^.va_birthtime.tv_nsec:=0;
|
||||
vap^.va_fsid:=VNOVAL;
|
||||
vap^.va_rdev:=NODEV;
|
||||
|
||||
error:=VOP_GETATTR(vp, vap);
|
||||
if (error<>0) then
|
||||
Exit(error);
|
||||
|
||||
{
|
||||
* Zero the spare stat fields
|
||||
}
|
||||
FillChar(sb^,SizeOf(t_stat),0);
|
||||
|
||||
{
|
||||
* Copy from vattr table
|
||||
}
|
||||
if (vap^.va_fsid<>VNOVAL) then
|
||||
sb^.st_dev:=vap^.va_fsid
|
||||
else
|
||||
sb^.st_dev:=p_mount(vp^.v_mount)^.mnt_stat.f_fsid.val[0];
|
||||
sb^.st_ino:=vap^.va_fileid;
|
||||
mode:=vap^.va_mode;
|
||||
case vap^.va_type of
|
||||
VREG:
|
||||
mode:=mode or S_IFREG;
|
||||
VDIR:
|
||||
mode:=mode or S_IFDIR;
|
||||
VBLK:
|
||||
mode:=mode or S_IFBLK;
|
||||
VCHR:
|
||||
mode:=mode or S_IFCHR;
|
||||
VLNK:
|
||||
mode:=mode or S_IFLNK;
|
||||
VSOCK:
|
||||
mode:=mode or S_IFSOCK;
|
||||
VFIFO:
|
||||
mode:=mode or S_IFIFO;
|
||||
else
|
||||
Exit(EBADF);
|
||||
end;;
|
||||
sb^.st_mode:=mode;
|
||||
sb^.st_nlink:=vap^.va_nlink;
|
||||
sb^.st_uid:=vap^.va_uid;
|
||||
sb^.st_gid:=vap^.va_gid;
|
||||
sb^.st_rdev:=vap^.va_rdev;
|
||||
if (vap^.va_size > High(Int64)) then
|
||||
Exit(EOVERFLOW);
|
||||
sb^.st_size:=vap^.va_size;
|
||||
sb^.st_atim:=vap^.va_atime;
|
||||
sb^.st_mtim:=vap^.va_mtime;
|
||||
sb^.st_ctim:=vap^.va_ctime;
|
||||
sb^.st_birthtim:=vap^.va_birthtime;
|
||||
|
||||
{
|
||||
* According to www.opengroup.org, the meaning of st_blksize is
|
||||
* "a filesystem-specific preferred I/O block size for this
|
||||
* object. In some filesystem types, this may vary from file
|
||||
* to file"
|
||||
* Use miminum/default of PAGE_SIZE (e.g. for VCHR).
|
||||
}
|
||||
|
||||
if (PAGE_SIZE>vap^.va_blocksize) then
|
||||
begin
|
||||
sb^.st_blksize:=PAGE_SIZE;
|
||||
end else
|
||||
begin
|
||||
sb^.st_blksize:=vap^.va_blocksize;
|
||||
end;
|
||||
|
||||
sb^.st_flags:=vap^.va_flags;
|
||||
//if (priv_check(td, PRIV_VFS_GENERATION)) then
|
||||
// sb^.st_gen:=0;
|
||||
//else
|
||||
sb^.st_gen:=vap^.va_gen;
|
||||
|
||||
sb^.st_blocks:=vap^.va_bytes div S_BLKSIZE;
|
||||
Exit(0);
|
||||
end;
|
||||
|
||||
|
||||
function foffset_get(fp:p_file):Int64; inline;
|
||||
begin
|
||||
Result:=(foffset_lock(fp, FOF_NOLOCK));
|
||||
end;
|
||||
|
||||
function foffset_lock(fp:p_file;flags:Integer):Int64;
|
||||
begin
|
||||
Assert((flags and FOF_OFFSET)=0, 'FOF_OFFSET passed');
|
||||
|
||||
if ((flags and FOF_NOLOCK)<>0) then
|
||||
Exit(fp^.f_offset);
|
||||
end;
|
||||
|
||||
procedure foffset_lock(fp:p_file;val:Int64;flags:Integer);
|
||||
begin
|
||||
Assert((flags and FOF_OFFSET)=0, ('FOF_OFFSET passed'));
|
||||
|
||||
if ((flags and FOF_NOLOCK)<>0) then
|
||||
begin
|
||||
if ((flags and FOF_NOUPDATE)=0) then
|
||||
fp^.f_offset:=val;
|
||||
if ((flags and FOF_NEXTOFF)<>0) then
|
||||
fp^.f_nextoff:=val;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure foffset_unlock(fp:p_file;val:Int64;flags:Integer);
|
||||
begin
|
||||
Assert((flags and FOF_OFFSET)=0, ('FOF_OFFSET passed'));
|
||||
|
||||
if ((flags and FOF_NOLOCK)<>0) then
|
||||
begin
|
||||
if ((flags and FOF_NOUPDATE)=0) then
|
||||
fp^.f_offset:=val;
|
||||
if ((flags and FOF_NEXTOFF)<>0) then
|
||||
fp^.f_nextoff:=val;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@ const
|
|||
MFSNAMELEN=16; // length of type name including null
|
||||
MNAMELEN =88; // size of on/from name bufs
|
||||
|
||||
STATFS_VERSION=$20030518; // current version number
|
||||
|
||||
//User specifiable flags, stored in mnt_flag.
|
||||
MNT_RDONLY =$0000000000000001; // read only filesystem
|
||||
MNT_SYNCHRONOUS=$0000000000000002; // fs written synchronously
|
||||
|
@ -40,6 +42,14 @@ const
|
|||
MNT_NOCLUSTERW =$0000000080000000; // disable cluster write
|
||||
MNT_SUJ =$0000000100000000; // using journaled soft updates
|
||||
|
||||
//NFS export related mount flags.
|
||||
MNT_EXRDONLY =$0000000000000080; // exported read only
|
||||
MNT_EXPORTED =$0000000000000100; // filesystem is exported
|
||||
MNT_DEFEXPORTED=$0000000000000200; // exported to the world
|
||||
MNT_EXPORTANON =$0000000000000400; // anon uid mapping for all
|
||||
MNT_EXKERB =$0000000000000800; // exported with Kerberos
|
||||
MNT_EXPUBLIC =$0000000020000000; // public export (WebNFS)
|
||||
|
||||
{
|
||||
* Flags set by internal operations,
|
||||
* but visible to the user.
|
||||
|
@ -65,6 +75,17 @@ const
|
|||
MNT_SNAPSHOT =$0000000001000000; // snapshot the filesystem
|
||||
MNT_BYFSID =$0000000008000000; // specify filesystem by ID.
|
||||
|
||||
MNT_VISFLAGMASK=(MNT_RDONLY or MNT_SYNCHRONOUS or MNT_NOEXEC or
|
||||
MNT_NOSUID or MNT_UNION or MNT_SUJ or
|
||||
MNT_ASYNC or MNT_EXRDONLY or MNT_EXPORTED or
|
||||
MNT_DEFEXPORTED or MNT_EXPORTANON or MNT_EXKERB or
|
||||
MNT_LOCAL or MNT_USER or MNT_QUOTA or
|
||||
MNT_ROOTFS or MNT_NOATIME or MNT_NOCLUSTERR or
|
||||
MNT_NOCLUSTERW or MNT_SUIDDIR or MNT_SOFTDEP or
|
||||
MNT_IGNORE or MNT_EXPUBLIC or MNT_NOSYMFOLLOW or
|
||||
MNT_GJOURNAL or MNT_MULTILABEL or MNT_ACLS or
|
||||
MNT_NFS4ACLS);
|
||||
|
||||
MNT_UPDATEMASK=(MNT_NOSUID or MNT_NOEXEC or
|
||||
MNT_SYNCHRONOUS or MNT_UNION or MNT_ASYNC or
|
||||
MNT_NOATIME or
|
||||
|
@ -202,7 +223,8 @@ type
|
|||
pp_mount=^p_mount;
|
||||
p_mount=^mount;
|
||||
|
||||
p_statfs=^statfs;
|
||||
pp_statfs=^p_statfs;
|
||||
p_statfs=^t_statfs;
|
||||
p_vfsconf=^vfsconf;
|
||||
|
||||
vfs_cmount_t =function (ma,data:Pointer;flags:QWORD):Integer;
|
||||
|
@ -263,7 +285,7 @@ type
|
|||
vfc_list :TAILQ_ENTRY ; // list of vfscons
|
||||
end;
|
||||
|
||||
statfs=packed record
|
||||
t_statfs=packed record
|
||||
f_version :DWORD; // structure version number
|
||||
f_type :DWORD; // type of filesystem
|
||||
f_flags :QWORD; // copy of mount exported flags
|
||||
|
@ -321,7 +343,7 @@ type
|
|||
mnt_opt :p_vfsoptlist;// current mount options
|
||||
mnt_optnew :p_vfsoptlist;// new options passed to fs
|
||||
mnt_maxsymlinklen :Integer ;// max size of short symlink
|
||||
mnt_stat :statfs ;// cache of filesystem stats
|
||||
mnt_stat :t_statfs ;// cache of filesystem stats
|
||||
mnt_data :Pointer ;// private data
|
||||
mnt_time :time_t ;// last time written
|
||||
mnt_iosize_max :Integer ;// max size for clusters, etc
|
||||
|
@ -344,6 +366,9 @@ type
|
|||
end;
|
||||
|
||||
const
|
||||
VFS_NOTIFY_UPPER_RECLAIM=1;
|
||||
VFS_NOTIFY_UPPER_UNLINK =2;
|
||||
|
||||
VFS_VERSION=$19660120;
|
||||
|
||||
var
|
||||
|
@ -352,6 +377,8 @@ var
|
|||
|
||||
VFS_Giant:mtx;
|
||||
|
||||
function MNT_SHARED_WRITES(mp:p_mount):Boolean; inline;
|
||||
|
||||
procedure MNT_ILOCK(mp:p_mount); inline;
|
||||
function MNT_ITRYLOCK(mp:p_mount):Boolean; inline;
|
||||
procedure MNT_IUNLOCK(mp:p_mount); inline;
|
||||
|
@ -370,10 +397,26 @@ function VFS_MOUNT(mp:p_mount):Integer;
|
|||
function VFS_UNMOUNT(mp:p_mount;FORCE:Integer):Integer;
|
||||
function VFS_ROOT(mp:p_mount;flags:Integer;vpp:pp_vnode):Integer;
|
||||
function VFS_STATFS(mp:p_mount;sbp:p_statfs):Integer;
|
||||
function VFS_SYNC(mp:p_mount;WAIT:Integer):Integer;
|
||||
function VFS_VGET(mp:p_mount;ino:QWORD;flags:Integer;vpp:pp_vnode):Integer;
|
||||
procedure VFS_RECLAIM_LOWERVP(mp:p_mount;vp:p_vnode);
|
||||
procedure VFS_UNLINK_LOWERVP(mp:p_mount;vp:p_vnode);
|
||||
procedure VFS_KNOTE_LOCKED(vp:p_vnode;hint:Integer);
|
||||
procedure VFS_KNOTE_UNLOCKED(vp:p_vnode;hint:Integer);
|
||||
|
||||
implementation
|
||||
|
||||
function MNT_SHARED_WRITES(mp:p_mount):Boolean; inline;
|
||||
begin
|
||||
if (mp<>nil) then
|
||||
begin
|
||||
Result:=((mp^.mnt_kern_flag and MNTK_SHARED_WRITES)<>0);
|
||||
end else
|
||||
begin
|
||||
Result:=False;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure MNT_ILOCK(mp:p_mount); inline;
|
||||
begin
|
||||
mtx_lock(mp^.mnt_mtx);
|
||||
|
@ -484,6 +527,15 @@ begin
|
|||
VFS_EPILOGUE(_enable_stops);
|
||||
end;
|
||||
|
||||
function VFS_SYNC(mp:p_mount;WAIT:Integer):Integer;
|
||||
var
|
||||
_enable_stops:Boolean;
|
||||
begin
|
||||
_enable_stops:=VFS_PROLOGUE(MP);
|
||||
Result:=mp^.mnt_op^.vfs_sync(mp,WAIT);
|
||||
VFS_EPILOGUE(_enable_stops);
|
||||
end;
|
||||
|
||||
function VFS_VGET(mp:p_mount;ino:QWORD;flags:Integer;vpp:pp_vnode):Integer;
|
||||
var
|
||||
_enable_stops:Boolean;
|
||||
|
@ -493,6 +545,41 @@ begin
|
|||
VFS_EPILOGUE(_enable_stops);
|
||||
end;
|
||||
|
||||
procedure VFS_RECLAIM_LOWERVP(mp:p_mount;vp:p_vnode);
|
||||
var
|
||||
_enable_stops:Boolean;
|
||||
begin
|
||||
if (mp^.mnt_op^.vfs_reclaim_lowervp<>nil) then
|
||||
begin
|
||||
_enable_stops:=VFS_PROLOGUE(MP);
|
||||
mp^.mnt_op^.vfs_reclaim_lowervp(mp,vp);
|
||||
VFS_EPILOGUE(_enable_stops);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure VFS_UNLINK_LOWERVP(mp:p_mount;vp:p_vnode);
|
||||
var
|
||||
_enable_stops:Boolean;
|
||||
begin
|
||||
if (mp^.mnt_op^.vfs_unlink_lowervp<>nil) then
|
||||
begin
|
||||
_enable_stops:=VFS_PROLOGUE(MP);
|
||||
mp^.mnt_op^.vfs_unlink_lowervp(mp,vp);
|
||||
VFS_EPILOGUE(_enable_stops);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure VFS_KNOTE_LOCKED(vp:p_vnode;hint:Integer);
|
||||
begin
|
||||
//if ((vp^.v_vflag and VV_NOKNOTE)=0) then
|
||||
// VN_KNOTE(vp, hint, KNF_LISTLOCKED);
|
||||
end;
|
||||
|
||||
procedure VFS_KNOTE_UNLOCKED(vp:p_vnode;hint:Integer);
|
||||
begin
|
||||
//if ((vp^.v_vflag and VV_NOKNOTE)=0) then
|
||||
// VN_KNOTE(vp, hint, 0);
|
||||
end;
|
||||
|
||||
initialization
|
||||
mtx_init(mountlist_mtx);
|
||||
|
|
|
@ -140,7 +140,7 @@ type
|
|||
ni_cnd:componentname;
|
||||
end;
|
||||
|
||||
function NDHASGIANT(ndp:p_nameidata):Boolean; inline;
|
||||
function NDHASGIANT(ndp:p_nameidata):Integer; inline;
|
||||
|
||||
procedure NDINIT_ALL(
|
||||
ndp:p_nameidata;
|
||||
|
@ -191,9 +191,9 @@ procedure NDINIT_ATVP(
|
|||
|
||||
implementation
|
||||
|
||||
function NDHASGIANT(ndp:p_nameidata):Boolean; inline;
|
||||
function NDHASGIANT(ndp:p_nameidata):Integer; inline;
|
||||
begin
|
||||
Result:=(ndp^.ni_cnd.cn_flags and GIANTHELD)<>0;
|
||||
Result:=ord((ndp^.ni_cnd.cn_flags and GIANTHELD)<>0);
|
||||
end;
|
||||
|
||||
procedure NDINIT_ALL(
|
||||
|
@ -216,7 +216,7 @@ begin
|
|||
ndp^.ni_strictrelative:=0;
|
||||
ndp^.ni_rightsneeded :=rights;
|
||||
ndp^.ni_baserights :=0;
|
||||
ndp^.ni_cnd.cn_thread:=td;
|
||||
ndp^.ni_cnd.cn_thread :=td;
|
||||
end;
|
||||
|
||||
procedure NDINIT(
|
||||
|
|
|
@ -68,8 +68,20 @@ const
|
|||
S_IFSOCK =&0140000; // socket
|
||||
S_ISVTX =&0001000; // save swapped text even after use
|
||||
|
||||
S_ISUID =&0004000; // set user id on execution
|
||||
S_ISGID =&0002000; // set group id on execution
|
||||
S_ISTXT =&0001000; // sticky bit
|
||||
|
||||
S_IFWHT =&0160000; // whiteout
|
||||
|
||||
ACCESSPERMS=(S_IRWXU or S_IRWXG or S_IRWXO); // 0777
|
||||
ALLPERMS =(S_ISUID or S_ISGID or S_ISTXT or S_IRWXU or S_IRWXG or S_IRWXO); // 7777
|
||||
DEFFILEMODE=(S_IRUSR or S_IWUSR or S_IRGRP or S_IWGRP or S_IROTH or S_IWOTH); // 0666
|
||||
|
||||
S_BLKSIZE=512; // block size used in the stat struct
|
||||
|
||||
NODEV=-1; // non-existent device
|
||||
|
||||
{
|
||||
* Definitions of flags stored in file flags word.
|
||||
*
|
||||
|
|
|
@ -6,7 +6,8 @@ unit kern_resource;
|
|||
interface
|
||||
|
||||
uses
|
||||
vmparam;
|
||||
vmparam,
|
||||
vfile;
|
||||
|
||||
const
|
||||
RLIMIT_CPU = 0; // maximum cpu time in seconds
|
||||
|
@ -37,6 +38,7 @@ begin
|
|||
RLIMIT_STACK :Result:=MAXSSIZ;
|
||||
RLIMIT_MEMLOCK:Result:=pageablemem;
|
||||
RLIMIT_VMEM :Result:=pageablemem;
|
||||
RLIMIT_NOFILE :Result:=maxfilesperproc;
|
||||
else;
|
||||
end;
|
||||
end;
|
||||
|
@ -49,6 +51,7 @@ begin
|
|||
RLIMIT_STACK :Result:=MAXSSIZ;
|
||||
RLIMIT_MEMLOCK:Result:=pageablemem;
|
||||
RLIMIT_VMEM :Result:=pageablemem;
|
||||
RLIMIT_NOFILE :Result:=maxfilesperproc;
|
||||
else;
|
||||
end;
|
||||
end;
|
||||
|
|
Loading…
Reference in New Issue