This commit is contained in:
Pavel 2023-05-05 17:57:44 +03:00
parent 26e2ae4e23
commit 917b19ce77
16 changed files with 868 additions and 201 deletions

View File

@ -388,13 +388,18 @@ var
td:p_kthread;
begin
td:=curkthread;
if (td=nil) then Exit;
Result:=(not flags) or (td^.td_pflags and flags);
td^.td_pflags:=td^.td_pflags or flags;
end;
procedure curthread_pflags_restore(save:Integer);
var
td:p_kthread;
begin
curkthread^.td_pflags:=curkthread^.td_pflags and save;
td:=curkthread;
if (td=nil) then Exit;
td^.td_pflags:=td^.td_pflags and save;
end;
//

View File

@ -10,10 +10,6 @@ uses
ntapi,
time;
procedure timevalfix(t1:ptimeval);
procedure timevaladd(t1,t2:ptimeval);
procedure timevalsub(t1,t2:ptimeval);
function cputick2usec(time:QWORD):QWORD; inline;
function get_unit_uptime:Int64;
procedure getmicrouptime(tvp:ptimeval);
@ -40,34 +36,6 @@ Const
POW10_7 =10000000;
POW10_9 =1000000000;
procedure timevalfix(t1:ptimeval);
begin
if (t1^.tv_usec < 0) then
begin
Dec(t1^.tv_sec);
Inc(t1^.tv_usec,1000000);
end;
if (t1^.tv_usec >= 1000000) then
begin
Inc(t1^.tv_sec);
Dec(t1^.tv_usec,1000000);
end;
end;
procedure timevaladd(t1,t2:ptimeval);
begin
Inc(t1^.tv_sec ,t2^.tv_sec);
Inc(t1^.tv_usec,t2^.tv_usec);
timevalfix(t1);
end;
procedure timevalsub(t1,t2:ptimeval);
begin
Dec(t1^.tv_sec ,t2^.tv_sec);
Dec(t1^.tv_usec,t2^.tv_usec);
timevalfix(t1);
end;
function cputick2usec(time:QWORD):QWORD; inline;
begin
Result:=time div 10;

View File

@ -12,6 +12,7 @@ const
IOSIZE_MAX =High(Int64);
DEVFS_IOSIZE_MAX=High(Int64);
function copystr(from,_to:Pointer;maxlen:ptruint;lencopied:pptruint):Integer;
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;
@ -26,8 +27,19 @@ function suword64(var base:QWORD;word:QWORD):DWORD; inline;
implementation
uses
sysutils,
errno;
function copystr(from,_to:Pointer;maxlen:ptruint;lencopied:pptruint):Integer;
begin
strlcopy(_to,from,maxlen);
if (lencopied<>nil) then
begin
lencopied^:=strlen(_to);
end;
Result:=0;
end;
function copyin(udaddr,kaddr:Pointer;len:ptruint):Integer; inline;
begin
if (NtReadVirtualMemory(NtCurrentProcess,udaddr,kaddr,len,nil)=0) then

View File

@ -30,7 +30,8 @@ uses
devfs,
devfs_devs,
devfs_vfsops,
kern_descrip;
kern_descrip,
vfs_mountroot;
//Daemon for a separate thread
procedure sys_update;
@ -41,6 +42,7 @@ end;
procedure module_init;
begin
vfs_register(@devfs_vfsconf);
vfs_mountroot.vfs_mountroot();
end;
//Manual order of lazy initialization

View File

@ -441,6 +441,10 @@
<Filename Value="..\vfs\vttycom.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="..\vfs\vfs_mountroot.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>

View File

@ -1,6 +1,7 @@
uses
windows,
dateutils,
atomic,
ntapi,
mqueue,
@ -53,7 +54,11 @@ uses
sys_fnmatch,
devfs,
devfs_vfsops,
devfs_vnops;
devfs_vnops,
vfs_mountroot,
vstat,
vfcntl,
vdirent;
var
mtx:umutex;
@ -223,6 +228,96 @@ var
ymm0:array[0..31] of Byte=(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
ymm0_ptr:Pointer=@ymm0;
function ts_to_str(ts:timespec):RawByteString;
var
D:TDateTime;
begin
D:=UnixToDateTime(ts.tv_sec);
D:=UniversalTimeToLocal(D);
Result:=DateTimeToStr(D);
end;
function IncludeUnixTrailing(Const Path:RawByteString):RawByteString;
Var
L:Integer;
begin
Result:=Path;
L:=Length(Result);
If (L=0) or (Path[L]<>'/') then
begin
SetLength(Result,L+1);
Result[L+1]:='/';
end;
end;
procedure test_dirs(const p:RawByteString;s:Byte);
var
td:p_kthread;
sb:t_stat;
buf:array[0..511] of Byte;
dir:p_dirent;
fd:Integer;
err:Integer;
c:Integer;
begin
td:=curkthread;
err:=sys_stat(PChar(p),@sb);
if (err<>0) then
begin
Writeln(Space(s),p,' | (',err,')');
end else
begin
Write(Space(s),p,' | ',ts_to_str(sb.st_mtim),' |');
if ((sb.st_mode and S_IFDIR)<>0) then
begin
Write(' DIR');
Assert(sb.st_size=512);
fd:=sys_open(PChar(p),O_RDONLY or O_DIRECTORY,0);
if (fd<0) then
begin
Write(' | (',fd,')');
Exit;
end else
begin
Writeln;
end;
Writeln(Space(s),'->');
repeat
FillChar(buf,512,0);
dir:=@buf;
err:=sys_getdents(fd,dir,512);
if (err<0) then Break;
c:=td^.td_retval[0];
if (c=0) then Break;
while (dir<(@buf+c)) do
begin
case RawByteString(dir^.d_name) of
'.':;
'..':;
else
//Writeln(dir^.d_name);
test_dirs(IncludeUnixTrailing(p)+RawByteString(dir^.d_name),s+1);
end;
PByte(dir):=PByte(dir)+dir^.d_reclen;
end;
until false;
Writeln(Space(s),'<-');
end else
begin
Writeln(' ',sb.st_size);
end;
end;
end;
procedure test_thread; sysv_abi_default;
var
rax:qword;
@ -236,6 +331,10 @@ begin
if (tid<>curkthread^.td_tid) then
begin
Writeln('[--test_dirs--]');
test_dirs('/',1);
Writeln('[--test_dirs--]');
tid2:=curkthread^.td_tid;
evf:=evf_create('evf test',EVF_ATTR_TH_PRIO,0);

View File

@ -65,6 +65,10 @@ function _nsec2usec(nsec:QWORD):QWORD; //Nanosecond to Microsecond
function _msec2nsec(msec:QWORD):QWORD; //Milisecond to Nanosecond
function _nsec2msec(nsec:QWORD):QWORD; //Nanosecond to Milisecond
procedure timevalfix(t1:ptimeval);
procedure timevaladd(t1,t2:ptimeval);
procedure timevalsub(t1,t2:ptimeval);
function timespeccmp_lt(tvp,uvp:ptimespec):Integer; inline;
procedure TIMEVAL_TO_TIMESPEC(tv:ptimeval;ts:ptimespec); inline;
@ -126,6 +130,34 @@ begin
Result:=(nsec+999999) div 1000000;
end;
procedure timevalfix(t1:ptimeval);
begin
if (t1^.tv_usec < 0) then
begin
Dec(t1^.tv_sec);
Inc(t1^.tv_usec,1000000);
end;
if (t1^.tv_usec >= 1000000) then
begin
Inc(t1^.tv_sec);
Dec(t1^.tv_usec,1000000);
end;
end;
procedure timevaladd(t1,t2:ptimeval);
begin
Inc(t1^.tv_sec ,t2^.tv_sec);
Inc(t1^.tv_usec,t2^.tv_usec);
timevalfix(t1);
end;
procedure timevalsub(t1,t2:ptimeval);
begin
Dec(t1^.tv_sec ,t2^.tv_sec);
Dec(t1^.tv_usec,t2^.tv_usec);
timevalfix(t1);
end;
function timespeccmp_lt(tvp,uvp:ptimespec):Integer; inline;
begin
if (tvp^.tv_sec=uvp^.tv_sec) then

View File

@ -58,7 +58,7 @@ begin
end;
save:=curthread_pflags_set(newflags);
while (n > 0 and uio^.uio_resid) do
while (n > 0) and (uio^.uio_resid<>0) do
begin
iov:=uio^.uio_iov;
cnt:=iov^.iov_len;
@ -88,17 +88,16 @@ begin
Move(cp^, iov^.iov_base^, cnt)
else
Move(iov^.iov_base^, cp^, cnt);
break;
end;
UIO_NOCOPY:;
else;
end;
iov^.iov_base:=iov^.iov_base + cnt;
Dec(iov^.iov_len,cnt);
Dec(uio^.uio_resid,cnt);
Inc(iov^.iov_base ,cnt);
Dec(iov^.iov_len ,cnt);
Dec(uio^.uio_resid ,cnt);
Inc(uio^.uio_offset,cnt);
cp:=cp + cnt;
Inc(cp,cnt);
Dec(n,cnt);
end;

View File

@ -528,6 +528,42 @@ begin
{ NOTREACHED }
end;
function lockmgr(lk:p_mtx;flags:Integer;ilk:p_mtx):Integer;
var
op:Integer;
begin
op:=(flags and LK_TYPE_MASK);
case op of
LK_SHARED,
LK_EXCLUSIVE:
begin
mtx_lock(lk^);
end;
LK_RELEASE:
begin
mtx_unlock(lk^);
end;
LK_UPGRADE:
begin
if not mtx_owned(lk^) then
begin
mtx_lock(lk^);
end;
end;
LK_DOWNGRADE:;//
else
Assert(false);
end;
if ((flags and LK_INTERLOCK)<>0) then
begin
mtx_unlock(ilk^);
end;
Result:=0;
end;
{
* Standard lock, unlock and islocked functions.
}
@ -537,14 +573,7 @@ var
begin
vp:=ap^.a_vp;
if (ap^.a_flags and LK_INTERLOCK)<>0 then
begin
mtx_unlock(VI_MTX(vp)^);
Exit(0);
end;
mtx_lock(vp^.v_vnlock^);
Exit(0);
Result:=lockmgr(vp^.v_vnlock,ap^.a_flags,VI_MTX(vp));
//Exit(_lockmgr_args(vp^.v_vnlock, ap^.a_flags, VI_MTX(vp),
// LK_WMESG_DEFAULT, LK_PRIO_DEFAULT, LK_TIMO_DEFAULT, ap^.a_file,
@ -558,14 +587,7 @@ var
begin
vp:=ap^.a_vp;
if (ap^.a_flags and LK_INTERLOCK)<>0 then
begin
mtx_unlock(VI_MTX(vp)^);
Exit(0);
end;
mtx_unlock(vp^.v_vnlock^);
Exit(0);
Result:=lockmgr(vp^.v_vnlock,ap^.a_flags or LK_RELEASE,VI_MTX(vp));
//Exit(lockmgr(vp^.v_vnlock, ap^.a_flags or LK_RELEASE, VI_MTX(vp)));
end;
@ -778,7 +800,7 @@ var
off:QWORD;
fileno:DWORD;
va:t_vattr;
nd:nameidata;
nd:t_nameidata;
td:p_kthread;
dp:p_dirent;
mvp:p_vnode;

View File

@ -67,7 +67,7 @@ end;
* if symbolic link, massage name in buffer and continue
* end;
}
procedure namei_cleanup_cnp(cnp:p_componentname);
procedure namei_cleanup_cnp(cnp:p_componentname); inline;
begin
FreeMem(cnp^.cn_pnbuf);
end;
@ -92,10 +92,10 @@ begin
cnp:=@ndp^.ni_cnd;
td:=cnp^.cn_thread;
Assert(((cnp^.cn_flags and MPSAFE)<>0) or mtx_owned(VFS_Giant),('NOT MPSAFE and Giant not held'));
Assert(((cnp^.cn_flags and MPSAFE)<>0) or mtx_owned(VFS_Giant),'NOT MPSAFE and Giant not held');
Assert((cnp^.cn_nameiop and (not OPMASK))=0,'namei: nameiop contaminated with flags');
Assert((cnp^.cn_flags and OPMASK)=0,('namei: flags contaminated with nameiops'));
Assert((cnp^.cn_flags and OPMASK)=0,'namei: flags contaminated with nameiops');
if (lookup_shared=0) then
cnp^.cn_flags:=cnp^.cn_flags and (not LOCKSHARED);
@ -113,8 +113,7 @@ begin
if (ndp^.ni_segflg=UIO_SYSSPACE) then
begin
ndp^.ni_pathlen:=strlcopy(ndp^.ni_dirp,cnp^.cn_pnbuf,MAXPATHLEN)-ndp^.ni_dirp;
error:=0;
error:=copystr(ndp^.ni_dirp, cnp^.cn_pnbuf, MAXPATHLEN, @ndp^.ni_pathlen);
end else
begin
error:=copyinstr(ndp^.ni_dirp, cnp^.cn_pnbuf, MAXPATHLEN, @ndp^.ni_pathlen);
@ -141,14 +140,6 @@ begin
ndp^.ni_rootdir:=fdp^.fd_rdir;
ndp^.ni_topdir:=fdp^.fd_jdir;
{
* If we are auditing the kernel pathname, save the user pathname.
}
//if ((cnp^.cn_flags and AUDITVNODE1)<>0) then
// AUDIT_ARG_UPATH1(td, ndp^.ni_dirfd, cnp^.cn_pnbuf);
//if ((cnp^.cn_flags and AUDITVNODE2)<>0) then
// AUDIT_ARG_UPATH2(td, ndp^.ni_dirfd, cnp^.cn_pnbuf);
dp:=nil;
if (cnp^.cn_pnbuf[0]<>'/') then
begin
@ -159,13 +150,10 @@ begin
end else
if (ndp^.ni_dirfd<>AT_FDCWD) then
begin
//if (cnp^.cn_flags and AUDITVNODE1)
// AUDIT_ARG_ATFD1(ndp^.ni_dirfd);
//if (cnp^.cn_flags and AUDITVNODE2)
// AUDIT_ARG_ATFD2(ndp^.ni_dirfd);
error:=fgetvp_rights(ndp^.ni_dirfd,
ndp^.ni_rightsneeded or CAP_LOOKUP,
@ndp^.ni_baserights, @dp);
ndp^.ni_rightsneeded or CAP_LOOKUP,
@ndp^.ni_baserights,
@dp);
end;
if (error<>0) or (dp<>nil) then
@ -276,15 +264,16 @@ begin
else
cp:=cnp^.cn_pnbuf;
aiov.iov_base:=cp;
aiov.iov_len:=MAXPATHLEN;
auio.uio_iov:=@aiov;
aiov.iov_base :=cp;
aiov.iov_len :=MAXPATHLEN;
auio.uio_iov :=@aiov;
auio.uio_iovcnt:=1;
auio.uio_offset:=0;
auio.uio_rw:=UIO_READ;
auio.uio_rw :=UIO_READ;
auio.uio_segflg:=UIO_SYSSPACE;
auio.uio_td:=td;
auio.uio_resid:=MAXPATHLEN;
auio.uio_td :=td;
auio.uio_resid :=MAXPATHLEN;
error:=VOP_READLINK(ndp^.ni_vp, @auio);
if (error<>0) then
begin
@ -313,8 +302,8 @@ begin
FreeMem(cnp^.cn_pnbuf);
cnp^.cn_pnbuf:=cp;
end else
cnp^.cn_pnbuf[linklen]:='0';
ndp^.ni_pathlen += linklen;
cnp^.cn_pnbuf[linklen]:=#0;
Inc(ndp^.ni_pathlen,linklen);
vput(ndp^.ni_vp);
dp:=ndp^.ni_dvp;
end;
@ -459,7 +448,7 @@ begin
(cnp^.cn_nameiop<>LOOKUP)) then
docache:=0;
_rdonly:=cnp^.cn_flags and RDONLY;
cnp^.cn_flags:= cnp^.cn_flags and (not ISSYMLINK);
cnp^.cn_flags:=cnp^.cn_flags and (not ISSYMLINK);
ndp^.ni_dvp:=nil;
{
* We use shared locks until we hit the parent of the last cn then
@ -567,12 +556,6 @@ dirloop:
end;
ndp^.ni_vp:=dp;
//if (cnp^.cn_flags and AUDITVNODE1) then
// AUDIT_ARG_VNODE1(dp);
//else
//if (cnp^.cn_flags and AUDITVNODE2) then
// AUDIT_ARG_VNODE2(dp);
if ((cnp^.cn_flags and (LOCKPARENT or LOCKLEAF))=0) then
VOP_UNLOCK(dp, 0);
{ XXX This should probably move to the top of function. }
@ -669,6 +652,7 @@ unionlookup:
(VOP_ISLOCKED(dp)=LK_SHARED) and
((cnp^.cn_flags and ISLASTCN)<>0) and ((cnp^.cn_flags and LOCKPARENT)<>0) then
vn_lock(dp, LK_UPGRADE or LK_RETRY);
if ((dp^.v_iflag and VI_DOOMED)<>0) then
begin
error:=ENOENT;
@ -893,13 +877,9 @@ nextname:
ni_dvp_unlocked:=1;
end;
//if (cnp^.cn_flags and AUDITVNODE1) then
// AUDIT_ARG_VNODE1(dp);
//else if (cnp^.cn_flags and AUDITVNODE2) then
// AUDIT_ARG_VNODE2(dp);
if ((cnp^.cn_flags and LOCKLEAF)=0) then
VOP_UNLOCK(dp, 0);
success:
{
* Because of lookup_shared we may have the vnode shared locked, but

View File

@ -33,6 +33,22 @@ const
nil
);
type
{ A memory allocation which must be freed when we are done }
p_mntaarg=^t_mntaarg;
t_mntaarg=packed record
next:SLIST_ENTRY; //mntaarg
end;
{ The header for the mount arguments }
p_mntarg=^t_mntarg;
t_mntarg=packed record
v:p_iovec;
len:Integer;
error:Integer;
list:SLIST_HEAD; //mntaarg
end;
procedure vfs_freeopt(opts:p_vfsoptlist;opt:p_vfsopt);
procedure vfs_freeopts(opts:p_vfsoptlist);
procedure vfs_deleteopt(opts:p_vfsoptlist;name:PChar);
@ -77,6 +93,13 @@ function vfs_donmount(fsflags:QWORD;fsoptions:p_uio):Integer;
function dounmount(mp:p_mount;flags:Integer):Integer;
function mount_argb(ma:p_mntarg;flag:Integer;name:PChar):p_mntarg;
function mount_argf(ma:p_mntarg;name,fmt:PChar;const Args:Array of const):p_mntarg; register;
function mount_argsu(ma:p_mntarg;name:PChar;val:Pointer;len:Integer):p_mntarg;
function mount_arg(ma:p_mntarg;name:PChar;val:Pointer;len:Integer):p_mntarg;
procedure free_mntarg(ma:p_mntarg);
function kernel_mount(ma:p_mntarg;flags:QWORD):Integer;
implementation
uses
@ -211,12 +234,12 @@ begin
begin
if (vfs_equalopts(opt^.name, opt2^.name)<>0) then
begin
tmp:=TAILQ_PREV(opt2,@opt^.link);
tmp:=TAILQ_PREV(opt2,@opt2^.link);
vfs_freeopt(opts, opt2);
opt2:=tmp;
end else
begin
opt2:=TAILQ_PREV(opt2,@opt^.link);
opt2:=TAILQ_PREV(opt2,@opt2^.link);
end;
end;
//
@ -643,7 +666,8 @@ end;
function strlcpy(dst,src:PChar;size:ptrint):ptrint; inline;
begin
Result:=strlcopy(dst,src,size)-dst;
strlcopy(dst,src,size);
Result:=strlen(dst);
end;
function vfs_setopts(opts:p_vfsoptlist;name,value:PChar):Integer;
@ -720,11 +744,11 @@ begin
mp^.mnt_stat.f_type:=vfsp^.vfc_typenum;
Inc(mp^.mnt_gen);
strlcopy(mp^.mnt_stat.f_fstypename, vfsp^.vfc_name, MFSNAMELEN);
strlcopy(@mp^.mnt_stat.f_fstypename, @vfsp^.vfc_name, MFSNAMELEN);
mp^.mnt_vnodecovered:=vp;
strlcopy(mp^.mnt_stat.f_mntonname, fspath, MNAMELEN);
strlcopy(@mp^.mnt_stat.f_mntonname, fspath, MNAMELEN);
mp^.mnt_iosize_max:=DFLTPHYS;
@ -941,7 +965,7 @@ begin
VI_UNLOCK(vp);
vfs_unbusy(mp);
vput(vp);
Exit (EBUSY);
Exit(EBUSY);
end;
vp^.v_iflag:=vp^.v_iflag or VI_MOUNT;
VI_UNLOCK(vp);
@ -951,6 +975,7 @@ begin
mp^.mnt_flag:=mp^.mnt_flag and (not MNT_UPDATEMASK);
mp^.mnt_flag:=(mp^.mnt_flag or fsflags) and (MNT_RELOAD or MNT_FORCE or MNT_UPDATE or
MNT_SNAPSHOT or MNT_ROOTFS or MNT_UPDATEMASK or MNT_RDONLY);
if ((mp^.mnt_flag and MNT_ASYNC)=0) then
mp^.mnt_kern_flag:=mp^.mnt_kern_flag and (not MNTK_ASYNC);
MNT_IUNLOCK(mp);
@ -1050,7 +1075,7 @@ function vfs_domount(fstype:PChar; { Filesystem type. }
):Integer;
var
vfsp:p_vfsconf;
nd:nameidata;
nd:t_nameidata;
vp:p_vnode;
pathbuf:PChar;
error:Integer;
@ -1462,6 +1487,153 @@ begin
Exit(0);
end;
{
* Add a boolean argument.
*
* flag is the boolean value.
* name must start with 'no'.
}
function mount_argb(ma:p_mntarg;flag:Integer;name:PChar):p_mntarg;
begin
Assert((name[0]='n') and (name[1]='o'),'mount_argb(...,%s): name must start with no');
Exit(mount_arg(ma, name + (ord(flag<>0)*2), nil, 0));
end;
{
* Add an argument printf style
}
function mount_argf(ma:p_mntarg;name,fmt:PChar;const Args:Array of const):p_mntarg; register;
var
maa:p_mntaarg;
len:Integer;
sb:RawByteString;
begin
if (ma=nil) then
begin
ma:=AllocMem(sizeof(t_mntarg));
SLIST_INIT(@ma^.list);
end;
if (ma^.error<>0) then
Exit(ma);
ma^.v:=ReAllocMem(ma^.v, sizeof(iovec) * (ma^.len + 2));
ma^.v[ma^.len].iov_base:=name;
ma^.v[ma^.len].iov_len :=strlen(name) + 1;
Inc(ma^.len);
sb:=Format(fmt,Args);
len:=Length(sb) + 1;
maa:=AllocMem(sizeof(t_mntaarg) + len);
SLIST_INSERT_HEAD(@ma^.list,maa,@maa^.next);
Move(PChar(sb)^, (maa + 1)^, len);
ma^.v[ma^.len].iov_base:=maa + 1;
ma^.v[ma^.len].iov_len :=len;
Inc(ma^.len);
Exit(ma);
end;
{
* Add an argument which is a userland string.
}
function mount_argsu(ma:p_mntarg;name:PChar;val:Pointer;len:Integer):p_mntarg;
var
maa:p_mntaarg;
tbuf:Pointer;
begin
if (val=nil) then
Exit(ma);
if (ma=nil) then
begin
ma:=AllocMem(sizeof(t_mntarg));
SLIST_INIT(@ma^.list);
end;
if (ma^.error<>0) then
Exit(ma);
maa:=AllocMem(sizeof(t_mntaarg) + len);
SLIST_INSERT_HEAD(@ma^.list,maa,@maa^.next);
tbuf:=Pointer(maa + 1);
ma^.error:=copyinstr(val, tbuf, len, nil);
Exit(mount_arg(ma, name, tbuf, -1));
end;
{
* Plain argument.
*
* If length is -1, treat value as a C string.
}
function mount_arg(ma:p_mntarg;name:PChar;val:Pointer;len:Integer):p_mntarg;
begin
if (ma=nil) then
begin
ma:=AllocMem(sizeof(t_mntarg));
SLIST_INIT(@ma^.list);
end;
if (ma^.error<>0) then
Exit(ma);
ma^.v:=ReAllocMem(ma^.v, sizeof(iovec) * (ma^.len + 2));
ma^.v[ma^.len].iov_base:=name;
ma^.v[ma^.len].iov_len :=strlen(name) + 1;
Inc(ma^.len);
ma^.v[ma^.len].iov_base:=val;
if (len < 0) then
ma^.v[ma^.len].iov_len:=strlen(val) + 1
else
ma^.v[ma^.len].iov_len:=len;
Inc(ma^.len);
Exit(ma);
end;
{
* Free a mntarg structure
}
procedure free_mntarg(ma:p_mntarg);
var
maa:p_mntaarg;
begin
while (not SLIST_EMPTY(@ma^.list)) do
begin
maa:=SLIST_FIRST(@ma^.list);
SLIST_REMOVE_HEAD(@ma^.list,@p_mntaarg(nil)^.next);
FreeMem(maa);
end;
FreeMem(ma^.v);
FreeMem(ma);
end;
{
* Mount a filesystem
}
function kernel_mount(ma:p_mntarg;flags:QWORD):Integer;
var
auio:t_uio;
error:Integer;
begin
Assert(ma<>nil, 'kernel_mount nil ma');
Assert(ma^.v<>nil, 'kernel_mount nil ma^.v');
Assert((ma^.len and 1)=0, 'kernel_mount odd ma^.len (%d)');
auio.uio_iov:=ma^.v;
auio.uio_iovcnt:=ma^.len;
auio.uio_segflg:=UIO_SYSSPACE;
error:=ma^.error;
if (error=0) then
error:=vfs_donmount(flags, @auio);
free_mntarg(ma);
Exit(error);
end;
end.

349
sys/vfs/vfs_mountroot.pas Normal file
View File

@ -0,0 +1,349 @@
unit vfs_mountroot;
{$mode ObjFPC}{$H+}
{$CALLING SysV_ABI_CDecl}
interface
uses
mqueue,
vmount;
procedure vfs_mountroot();
function vfs_mountroot_simple(fstype,fspath,from,opts:PChar):Integer;
implementation
uses
sysutils,
errno,
vuio,
vnamei,
vfs_vnode,
vnode_if,
vfiledesc,
vfs_subr,
vfs_init,
vfs_mount,
vfs_syscalls,
vfs_lookup,
kern_thr,
kern_mtx;
function strdup(src:PChar):PChar; inline;
var
i:ptrint;
begin
i:=strlen(src);
Result:=AllocMem(i+1);
Move(src^,Result^,i);
end;
function strsep(stringp:PPChar;delim:PChar):PChar;
var
b,e:PChar;
begin
b:=stringp^;
if (b=nil) then Exit(nil);
e:=strpos(b,delim)+strlen(delim);
if (e^<>#0) then
begin
e^:=#0;
Inc(e);
stringp^:=e;
end else
begin
stringp^:=nil;
end;
Result:=b;
end;
function parse_mountroot_options(ma:p_mntarg;options:PChar):p_mntarg;
var
p:PChar;
name,name_arg:PChar;
val,val_arg:PChar;
opts:PChar;
begin
if (options=nil) or (options[0]=#0) then
Exit(ma);
p:=strdup(options);
opts:=p;
if (opts=nil) then
begin
Exit(ma);
end;
name:=strsep(@p, ',');
while (name<>nil) do
begin
if (name[0]=#0) then
break;
val:=strscan(name, '=');
if (val<>nil) then
begin
val^:=#0;
Inc(val);
end;
name_arg:=strdup(name);
val_arg:=nil;
if (val<>nil) then
val_arg:=strdup(val);
ma:=mount_arg(ma, name_arg, val_arg, (ord(val_arg<>nil)*(-1)));
name:=strsep(@p, ',');
end;
FreeMem(opts);
Exit(ma);
end;
procedure set_rootvnode();
begin
if (VFS_ROOT(TAILQ_FIRST(@mountlist), LK_EXCLUSIVE, @rootvnode)<>0) then
Assert(False,'Cannot find root vnode');
VOP_UNLOCK(rootvnode, 0);
FILEDESC_XLOCK(@fd_table);
if (fd_table.fd_cdir<>nil) then
vrele(fd_table.fd_cdir);
fd_table.fd_cdir:=rootvnode;
VREF(rootvnode);
if (fd_table.fd_rdir<>nil) then
vrele(fd_table.fd_rdir);
fd_table.fd_rdir:=rootvnode;
VREF(rootvnode);
FILEDESC_XUNLOCK(@fd_table);
end;
function vfs_mountroot_devfs(mpp:pp_mount):Integer;
var
opts:p_vfsoptlist;
vfsp:p_vfsconf;
mp:p_mount;
error:Integer;
begin
mpp^:=nil;
vfsp:=vfs_byname('devfs');
Assert(vfsp<>nil,'Could not find devfs by name');
if (vfsp=nil) then
Exit(ENOENT);
mp:=vfs_mount_alloc(nil, vfsp, '/dev');
error:=vmount.VFS_MOUNT(mp);
Assert(error=0,'VFS_MOUNT(devfs) failed');
if (error<>0) then
Exit(error);
opts:=AllocMem(sizeof(vfsoptlist));
TAILQ_INIT(opts);
mp^.mnt_opt:=opts;
mtx_lock(mountlist_mtx);
TAILQ_INSERT_HEAD(@mountlist,mp,@mp^.mnt_list);
mtx_unlock(mountlist_mtx);
mpp^:=mp;
set_rootvnode();
error:=kern_symlink('/', 'dev', UIO_SYSSPACE);
if (error<>0) then
begin
Writeln('kern_symlink /dev / returns ',error);
end;
Exit(error);
end;
function vfs_mountroot_shuffle(mpdevfs:p_mount):Integer;
var
nd:t_nameidata;
mporoot,mpnroot:p_mount;
vp,vporoot,vpdevfs:p_vnode;
fspath:PChar;
error:Integer;
begin
mpnroot:=TAILQ_NEXT(mpdevfs,@mpdevfs^.mnt_list);
{ Shuffle the mountlist. }
mtx_lock(mountlist_mtx);
mporoot:=TAILQ_FIRST(@mountlist);
TAILQ_REMOVE(@mountlist,mpdevfs,@mpdevfs^.mnt_list);
if (mporoot<>mpdevfs) then
begin
TAILQ_REMOVE(@mountlist,mpnroot,@mpnroot^.mnt_list);
TAILQ_INSERT_HEAD(@mountlist,mpnroot,@mpnroot^.mnt_list);
end;
TAILQ_INSERT_TAIL(@mountlist,mpdevfs,@mpdevfs^.mnt_list);
mtx_unlock(mountlist_mtx);
//cache_purgevfs(mporoot);
//if (mporoot<>mpdevfs) then
// cache_purgevfs(mpdevfs);
VFS_ROOT(mporoot, LK_EXCLUSIVE, @vporoot);
VI_LOCK(vporoot);
vporoot^.v_iflag:=vporoot^.v_iflag and (not VI_MOUNT);
VI_UNLOCK(vporoot);
vporoot^.v_mountedhere:=nil;
mporoot^.mnt_flag:=mporoot^.mnt_flag and (not MNT_ROOTFS);
mporoot^.mnt_vnodecovered:=nil;
vput(vporoot);
{ Set up the new rootvnode, and purge the cache }
mpnroot^.mnt_vnodecovered:=nil;
set_rootvnode();
//cache_purgevfs(rootvnode^.v_mount);
if (mporoot<>mpdevfs) then
begin
{ Remount old root under /.mount or /mnt }
fspath:='/.mount';
NDINIT(@nd, LOOKUP, FOLLOW or LOCKLEAF, UIO_SYSSPACE, fspath, curkthread);
error:=_namei(@nd);
if (error<>0) then
begin
NDFREE(@nd, NDF_ONLY_PNBUF);
fspath:='/mnt';
NDINIT(@nd, LOOKUP, FOLLOW or LOCKLEAF, UIO_SYSSPACE, fspath, curkthread);
error:=_namei(@nd);
end;
if (error=0) then
begin
vp:=nd.ni_vp;
if (vp^.v_type=VDIR) then
error:=0
else
error:=ENOTDIR;
//if (error=0) then
// error:=vinvalbuf(vp, V_SAVE, 0, 0);
if (error=0) then
begin
//cache_purge(vp);
mporoot^.mnt_vnodecovered:=vp;
vp^.v_mountedhere:=mporoot;
strlcopy(@mporoot^.mnt_stat.f_mntonname, fspath, MNAMELEN);
VOP_UNLOCK(vp, 0);
end else
vput(vp);
end;
NDFREE(@nd, NDF_ONLY_PNBUF);
if (error<>0) then
Writeln('mountroot: unable to remount previous root under /.mount or /mnt ', error);
end;
{ Remount devfs under /dev }
NDINIT(@nd, LOOKUP, FOLLOW or LOCKLEAF, UIO_SYSSPACE, '/dev', curkthread);
error:=_namei(@nd);
if (error=0) then
begin
vp:=nd.ni_vp;
if (vp^.v_type=VDIR) then
error:=0
else
error:=ENOTDIR;
//if (error=0) then
// error:=vinvalbuf(vp, V_SAVE, 0, 0);
if (error=0) then
begin
vpdevfs:=mpdevfs^.mnt_vnodecovered;
if (vpdevfs<>nil) then
begin
//cache_purge(vpdevfs);
vpdevfs^.v_mountedhere:=nil;
vrele(vpdevfs);
end;
mpdevfs^.mnt_vnodecovered:=vp;
vp^.v_mountedhere:=mpdevfs;
VOP_UNLOCK(vp, 0);
end else
vput(vp);
end;
if (error<>0) then
Writeln('mountroot: unable to remount devfs under /dev ', error);
NDFREE(@nd, NDF_ONLY_PNBUF);
if (mporoot=mpdevfs) then
begin
vfs_unbusy(mpdevfs);
{ Unlink the no longer needed /dev/dev ^. / symlink }
error:=kern_unlink('/dev/dev', UIO_SYSSPACE);
if (error<>0) then
Writeln('mountroot: unable to unlink /dev/dev ', error);
end;
Exit(0);
end;
function vfs_mountroot_simple(fstype,fspath,from,opts:PChar):Integer;
const
ERRMSGL=255;
var
ma:p_mntarg;
errmsg:RawByteString;
begin
errmsg:='';
SetLength(errmsg,ERRMSGL);
FillChar(PChar(errmsg)^,ERRMSGL,0);
if (vfs_byname(fstype)=nil) then
begin
strlcopy(PChar(errmsg),'unknown file system',ERRMSGL);
Exit(ENOENT);
end;
ma:=nil;
ma:=mount_arg(ma, 'fstype', fstype, -1);
ma:=mount_arg(ma, 'fspath', fspath, -1);
ma:=mount_arg(ma, 'from' , from , -1);
ma:=mount_arg(ma, 'errmsg', PChar(errmsg), ERRMSGL);
ma:=parse_mountroot_options(ma, opts);
Result:=kernel_mount(ma, MNT_ROOTFS);
end;
procedure vfs_mountroot();
var
mp:p_mount;
error:Integer;
begin
error:=vfs_mountroot_devfs(@mp);
if (error<>0) then
begin
error:=vfs_mountroot_shuffle(mp);
end;
end;
end.

View File

@ -79,11 +79,14 @@ function sys_renameat(oldfd:Integer;old:PChar;newfd:Integer;new:PChar):Integer;
function sys_mkdir(path:PChar;mode:Integer):Integer;
function sys_mkdirat(fd:Integer;path:PChar;mode:Integer):Integer;
function sys_rmdir(path:PChar):Integer;
function sys_getdirentries(fd:Integer;buf:PChar;count:DWORD;basep:PInt64):Integer;
function sys_getdents(fd:Integer;buf:PChar;count:DWORD):Integer;
function sys_getdirentries(fd:Integer;buf:Pointer;count:DWORD;basep:PInt64):Integer;
function sys_getdents(fd:Integer;buf:Pointer;count:DWORD):Integer;
function sys_umask(newmask:Integer):Integer;
function sys_revoke(path:PChar):Integer;
function kern_symlink(path,link:PChar;segflg:uio_seg):Integer;
function kern_unlink(path:PChar;pathseg:uio_seg):Integer;
implementation
uses
@ -146,7 +149,7 @@ var
sb:t_statfs;
vfslocked:Integer;
error:Integer;
nd:nameidata;
nd:t_nameidata;
begin
NDINIT(@nd, LOOKUP, FOLLOW or LOCKSHARED or LOCKLEAF or MPSAFE or AUDITVNODE1, pathseg, path, curkthread);
error:=_namei(@nd);
@ -496,7 +499,7 @@ end;
function kern_chdir(path:PChar;pathseg:uio_seg):Integer;
var
error:Integer;
nd:nameidata;
nd:t_nameidata;
vp:p_vnode;
vfslocked:Integer;
begin
@ -582,7 +585,7 @@ label
e_vunlock;
var
error:Integer;
nd:nameidata;
nd:t_nameidata;
vfslocked:Integer;
begin
error:=EPERM;
@ -728,7 +731,7 @@ var
nfp:p_file;
_type,indx,error,error_open:Integer;
lf:t_flock;
nd:nameidata;
nd:t_nameidata;
vfslocked:Integer;
rights_needed:cap_rights_t;
begin
@ -925,7 +928,7 @@ var
mp:p_mount;
vattr:t_vattr;
error:Integer;
nd:nameidata;
nd:t_nameidata;
vfslocked:Integer;
begin
restart:
@ -985,7 +988,7 @@ var
vattr:t_vattr;
error:Integer;
whiteout:Integer;
nd:nameidata;
nd:t_nameidata;
vfslocked:Integer;
begin
whiteout:=0;
@ -1134,7 +1137,7 @@ function kern_linkat(fd1,fd2:Integer;path1,path2:PChar;segflg:uio_seg;follow:Int
var
vp:p_vnode;
mp:p_mount;
nd:nameidata;
nd:t_nameidata;
vfslocked:Integer;
lvfslocked:Integer;
error:Integer;
@ -1236,7 +1239,7 @@ var
vattr:t_vattr;
syspath:PChar;
error:Integer;
nd:nameidata;
nd:t_nameidata;
vfslocked:Integer;
begin
if (segflg=UIO_SYSSPACE) then
@ -1326,7 +1329,7 @@ var
mp:p_mount;
vp:p_vnode;
error:Integer;
nd:nameidata;
nd:t_nameidata;
sb:t_stat;
vfslocked:Integer;
@ -1575,7 +1578,7 @@ label
out1;
var
vp:p_vnode;
nd:nameidata;
nd:t_nameidata;
vfslocked:Integer;
error:Integer;
begin
@ -1616,7 +1619,7 @@ function kern_statat_vnhook(flag,fd:Integer;
sbp:p_stat;
hook:t_statat_hook_cb):Integer;
var
nd:nameidata;
nd:t_nameidata;
sb:t_stat;
error, vfslocked:Integer;
begin
@ -1656,7 +1659,6 @@ end;
function kern_statat(flag,fd:Integer;path:PChar;
pathseg:uio_seg;sbp:p_stat):Integer;
begin
Exit(kern_statat_vnhook(flag, fd, path, pathseg, sbp, nil));
end;
@ -1712,7 +1714,7 @@ end;
function kern_pathconf(path:PChar;pathseg:uio_seg;name:Integer;flags:QWORD):Integer;
var
td:p_kthread;
nd:nameidata;
nd:t_nameidata;
error,vfslocked:Integer;
begin
td:=curkthread;
@ -1750,7 +1752,7 @@ var
aiov:iovec;
auio:t_uio;
error:Integer;
nd:nameidata;
nd:t_nameidata;
vfslocked:Integer;
begin
if (count > IOSIZE_MAX) then
@ -1859,7 +1861,7 @@ end;
function sys_chflags(path:PChar;flags:Integer):Integer;
var
error:Integer;
nd:nameidata;
nd:t_nameidata;
vfslocked:Integer;
begin
NDINIT(@nd, LOOKUP, FOLLOW or MPSAFE or AUDITVNODE1, UIO_USERSPACE, path, curkthread);
@ -1880,7 +1882,7 @@ end;
function sys_lchflags(path:PChar;flags:Integer):Integer;
var
error:Integer;
nd:nameidata;
nd:t_nameidata;
vfslocked:Integer;
begin
NDINIT(@nd, LOOKUP, NOFOLLOW or MPSAFE or AUDITVNODE1, UIO_USERSPACE, path, curkthread);
@ -1944,7 +1946,7 @@ end;
function kern_fchmodat(fd:Integer;path:PChar;pathseg:uio_seg;mode,flag:Integer):Integer;
var
error:Integer;
nd:nameidata;
nd:t_nameidata;
vfslocked:Integer;
follow:Integer;
begin
@ -2043,7 +2045,7 @@ end;
function kern_fchownat(fd:Integer;path:PChar;pathseg:uio_seg;uid,gid,flag:Integer):Integer;
var
nd:nameidata;
nd:t_nameidata;
error,vfslocked,follow:Integer;
begin
if (flag and AT_SYMLINK_NOFOLLOW)<>0 then
@ -2194,7 +2196,7 @@ end;
function kern_utimesat(fd:Integer;path:PChar;pathseg:uio_seg;
tptr:ptimeval;tptrseg:uio_seg):Integer;
var
nd:nameidata;
nd:t_nameidata;
ts:array[0..1] of timespec;
error,vfslocked:Integer;
begin
@ -2238,7 +2240,7 @@ function kern_lutimes(path:PChar;pathseg:uio_seg;
var
ts:array[0..1] of timespec;
error:Integer;
nd:nameidata;
nd:t_nameidata;
vfslocked:Integer;
begin
error:=getutimes(tptr, tptrseg, ts);
@ -2300,7 +2302,7 @@ var
vp:p_vnode;
rl_cookie:Pointer;
vattr:t_vattr;
nd:nameidata;
nd:t_nameidata;
error,vfslocked:Integer;
begin
if (length < 0) then
@ -2413,7 +2415,7 @@ label
var
mp:p_mount;
tvp,fvp,tdvp:p_vnode;
fromnd,tond:nameidata;
fromnd,tond:t_nameidata;
tvfslocked:Integer;
fvfslocked:Integer;
error:Integer;
@ -2556,7 +2558,7 @@ var
vp:p_vnode;
vattr:t_vattr;
error:Integer;
nd:nameidata;
nd:t_nameidata;
vfslocked:Integer;
begin
restart:
@ -2641,7 +2643,7 @@ var
mp:p_mount;
vp:p_vnode;
error:Integer;
nd:nameidata;
nd:t_nameidata;
vfslocked:Integer;
begin
restart:
@ -2720,7 +2722,7 @@ begin
Exit(kern_rmdir(path, UIO_USERSPACE));
end;
function kern_getdirentries(fd:Integer;buf:PChar;count:DWORD;basep:PInt64):Integer;
function kern_getdirentries(fd:Integer;buf:Pointer;count:DWORD;basep:PInt64):Integer;
label
unionread,
fail;
@ -2781,9 +2783,9 @@ unionread:
VFS_UNLOCK_GIANT(vfslocked);
goto fail;
end;
if (count=auio.uio_resid and
(vp^.v_vflag and VV_ROOT) and
(p_mount(vp^.v_mount)^.mnt_flag and MNT_UNION)) then
if (count=auio.uio_resid) and
((vp^.v_vflag and VV_ROOT)<>0) and
((p_mount(vp^.v_mount)^.mnt_flag and MNT_UNION)<>0) then
begin
tvp:=vp;
vp:=p_mount(vp^.v_mount)^.mnt_vnodecovered;
@ -2808,7 +2810,7 @@ end;
{
* Read a block of directory entries in a filesystem independent format.
}
function sys_getdirentries(fd:Integer;buf:PChar;count:DWORD;basep:PInt64):Integer;
function sys_getdirentries(fd:Integer;buf:Pointer;count:DWORD;basep:PInt64):Integer;
var
base:Int64;
error:Integer;
@ -2821,7 +2823,7 @@ begin
Exit(error);
end;
function sys_getdents(fd:Integer;buf:PChar;count:DWORD):Integer;
function sys_getdents(fd:Integer;buf:Pointer;count:DWORD):Integer;
begin
Exit(sys_getdirentries(fd,buf,count,nil));
end;
@ -2849,7 +2851,7 @@ var
vp:p_vnode;
vattr:t_vattr;
error:Integer;
nd:nameidata;
nd:t_nameidata;
vfslocked:Integer;
begin
NDINIT(@nd, LOOKUP, FOLLOW or LOCKLEAF or MPSAFE or AUDITVNODE1,

View File

@ -275,7 +275,7 @@ 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;
rootvnode:p_vnode=nil;
implementation

View File

@ -61,7 +61,6 @@ const
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);
procedure foffset_lock_uio(fp:p_file;uio:p_uio;flags:Integer);
procedure foffset_unlock_uio(fp:p_file;uio:p_uio;flags:Integer);
@ -319,16 +318,19 @@ function vn_start_write_locked(mp:p_mount;flags:Integer):Integer;
label
unlock;
var
td:p_kthread;
error:Integer;
begin
mtx_assert(MNT_MTX(mp)^);
error:=0;
td:=curkthread;
{
* Check on status of suspension.
}
if ((curkthread^.td_pflags and TDP_IGNSUSP)=0) or
(mp^.mnt_susp_owner<>curkthread) then
if (td<>nil) then
if ((td^.td_pflags and TDP_IGNSUSP)=0) or
(mp^.mnt_susp_owner<>td) then
begin
while ((mp^.mnt_kern_flag and MNTK_SUSPEND)<>0) do
begin
@ -342,6 +344,7 @@ begin
goto unlock;
end;
end;
if ((flags and V_XSLEEP)<>0) then
goto unlock;
Inc(mp^.mnt_writeopcount);
@ -495,9 +498,9 @@ begin
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;
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;
@ -539,37 +542,55 @@ begin
end;
function foffset_lock(fp:p_file;flags:Integer):Int64;
var
mtxp:p_mtx;
begin
Result:=0;
Assert((flags and FOF_OFFSET)=0, 'FOF_OFFSET passed');
if ((flags and FOF_NOLOCK)<>0) then
Exit(fp^.f_offset);
end;
mtxp:=mtx_pool_find(mtxpool_sleep, fp);
mtx_lock(mtxp^);
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
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;
while ((fp^.f_vnread_flags and FOFFSET_LOCKED)<>0) do
begin
fp^.f_vnread_flags:=fp^.f_vnread_flags or FOFFSET_LOCK_WAITING;
msleep(@fp^.f_vnread_flags, mtxp, PUSER, 'vofflock', 0);
end;
fp^.f_vnread_flags:=fp^.f_vnread_flags or FOFFSET_LOCKED;
end;
Result:=fp^.f_offset;
mtx_unlock(mtxp^);
end;
procedure foffset_unlock(fp:p_file;val:Int64;flags:Integer);
var
mtxp:p_mtx;
begin
Assert((flags and FOF_OFFSET)=0, ('FOF_OFFSET passed'));
Assert((flags and FOF_OFFSET)=0,'FOF_OFFSET passed');
if ((flags and FOF_NOLOCK)<>0) then
mtxp:=mtx_pool_find(mtxpool_sleep, fp);
mtx_lock(mtxp^);
if ((flags and FOF_NOUPDATE)=0) then
fp^.f_offset:=val;
if ((flags and FOF_NEXTOFF)<>0) then
fp^.f_nextoff:=val;
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;
Assert((fp^.f_vnread_flags and FOFFSET_LOCKED)<>0,'Lost FOFFSET_LOCKED');
if ((fp^.f_vnread_flags and FOFFSET_LOCK_WAITING)<>0) then
wakeup(@fp^.f_vnread_flags);
fp^.f_vnread_flags:=0;
end;
mtx_unlock(mtxp^);
end;
procedure foffset_lock_uio(fp:p_file;uio:p_uio;flags:Integer);

View File

@ -100,45 +100,45 @@ type
{
* Encapsulation of namei parameters.
}
p_nameidata=^nameidata;
nameidata=packed record
{
* Arguments to namei/lookup.
}
ni_dirp:PChar; { pathname pointer }
ni_segflg:uio_seg; { location of pathname }
_align1 :Integer;
ni_rightsneeded:cap_rights_t; { rights required to look up vnode }
{
* Arguments to lookup.
}
ni_startdir:p_vnode; { starting directory }
ni_rootdir :p_vnode; { logical root directory }
ni_topdir :p_vnode; { logical top directory }
ni_dirfd :Integer; { starting directory for *at functions }
ni_strictrelative:Integer; { relative lookup only; no '..' }
{
* Results: returned from namei
}
ni_baserights:cap_rights_t; { rights the *at base has (or -1) }
{
* Results: returned from/manipulated by lookup
}
ni_vp :p_vnode; { vnode of result }
ni_dvp:p_vnode; { vnode of intermediate directory }
{
* Shared between namei and lookup/commit routines.
}
ni_pathlen:QWORD; { remaining chars in path }
ni_next :PChar; { next location in pathname }
ni_loopcnt:QWORD; { count of symlinks encountered }
{
* Lookup parameters: this structure describes the subset of
* information from the nameidata structure that is passed
* through the VOP interface.
}
ni_cnd:componentname;
end;
p_nameidata=^t_nameidata;
t_nameidata=packed record
{
* Arguments to namei/lookup.
}
ni_dirp:PChar; { pathname pointer }
ni_segflg:uio_seg; { location of pathname }
_align1 :Integer;
ni_rightsneeded:cap_rights_t; { rights required to look up vnode }
{
* Arguments to lookup.
}
ni_startdir:p_vnode; { starting directory }
ni_rootdir :p_vnode; { logical root directory }
ni_topdir :p_vnode; { logical top directory }
ni_dirfd :Integer; { starting directory for *at functions }
ni_strictrelative:Integer; { relative lookup only; no '..' }
{
* Results: returned from namei
}
ni_baserights:cap_rights_t; { rights the *at base has (or -1) }
{
* Results: returned from/manipulated by lookup
}
ni_vp :p_vnode; { vnode of result }
ni_dvp:p_vnode; { vnode of intermediate directory }
{
* Shared between namei and lookup/commit routines.
}
ni_pathlen:QWORD; { remaining chars in path }
ni_next :PChar; { next location in pathname }
ni_loopcnt:QWORD; { count of symlinks encountered }
{
* Lookup parameters: this structure describes the subset of
* information from the nameidata structure that is passed
* through the VOP interface.
}
ni_cnd:componentname;
end;
function NDHASGIANT(ndp:p_nameidata):Integer; inline;