FPPS4/sys/vfs/vnamei.pas

277 lines
7.3 KiB
Plaintext

unit vnamei;
{$mode ObjFPC}{$H+}
{$CALLING SysV_ABI_CDecl}
interface
uses
vcapability,
vfcntl,
vuio,
vnode,
kern_thr;
const
{
* namei operations
}
LOOKUP=0; { perform name lookup only }
CREATE=1; { setup for file creation }
DELETE=2; { setup for file deletion }
RENAME=3; { setup for file renaming }
OPMASK=3; { mask for operation }
{
* namei operational modifier flags,stored in ni_cnd.flags
}
LOCKLEAF =$0004; { lock inode on return }
LOCKPARENT=$0008; { want parent vnode returned locked }
WANTPARENT=$0010; { want parent vnode returned unlocked }
NOCACHE =$0020; { name must not be left in cache }
FOLLOW =$0040; { follow symbolic links }
LOCKSHARED=$0100; { Shared lock leaf }
NOFOLLOW =$0000; { do not follow symbolic links (pseudo) }
MODMASK =$01fc; { mask of operational modifiers }
{
* Namei parameter descriptors.
*
* SAVENAME may be set by either the callers of namei or by VOP_LOOKUP.
* If the caller of namei sets the flag (for example execve wants to
* know the name of the program that is being executed),then it must
* free the buffer. If VOP_LOOKUP sets the flag,then the buffer must
* be freed by either the commit routine or the VOP_ABORT routine.
* SAVESTART is set only by the callers of namei. It implies SAVENAME
* plus the addition of saving the parent directory that contains the
* name in ni_startdir. It allows repeated calls to lookup for the
* name being sought. The caller is responsible for releasing the
* buffer and for vrele'ing ni_startdir.
}
RDONLY =$00000200; { lookup with read-only semantics }
HASBUF =$00000400; { has allocated pathname buffer }
SAVENAME =$00000800; { save pathname buffer }
SAVESTART =$00001000; { save starting directory }
ISDOTDOT =$00002000; { current component name is .. }
MAKEENTRY =$00004000; { entry is to be added to name cache }
ISLASTCN =$00008000; { this is last component of pathname }
ISSYMLINK =$00010000; { symlink needs interpretation }
ISWHITEOUT =$00020000; { found whiteout }
DOWHITEOUT =$00040000; { do whiteouts }
WILLBEDIR =$00080000; { new files will be dirs; allow trailing / }
ISUNICODE =$00100000; { current component name is unicode}
ISOPEN =$00200000; { caller is opening; return a real vnode. }
NOCROSSMOUNT =$00400000; { do not cross mount points }
NOMACCHECK =$00800000; { do not perform MAC checks }
MPSAFE =$01000000; { namei() must acquire Giant if needed. }
GIANTHELD =$02000000; { namei() is holding giant. }
AUDITVNODE1 =$04000000; { audit the looked up vnode information }
AUDITVNODE2 =$08000000; { audit the looked up vnode information }
TRAILINGSLASH=$10000000; { path ended in a slash }
PARAMASK =$1ffffe00; { mask of parameter descriptors }
NDF_NO_DVP_RELE =$00000001;
NDF_NO_DVP_UNLOCK =$00000002;
NDF_NO_DVP_PUT =$00000003;
NDF_NO_VP_RELE =$00000004;
NDF_NO_VP_UNLOCK =$00000008;
NDF_NO_VP_PUT =$0000000c;
NDF_NO_STARTDIR_RELE=$00000010;
NDF_NO_FREE_PNBUF =$00000020;
NDF_ONLY_PNBUF =(not NDF_NO_FREE_PNBUF);
type
p_componentname=^componentname;
componentname=packed record
{
* Arguments to lookup.
}
cn_nameiop:Integer; { namei operation }
cn_lkflags:Integer; { Lock flags LK_EXCLUSIVE or LK_SHARED }
cn_flags :QWORD; { flags to namei }
cn_thread :p_kthread; { thread requesting lookup }
{
* Shared between lookup and commit routines.
}
cn_pnbuf :PChar; { pathname buffer }
cn_nameptr:PChar; { pointer to looked up name }
cn_namelen:Int64; { length of looked up component }
cn_consume:Int64; { chars to consume in lookup() }
end;
{
* Encapsulation of namei parameters.
}
p_nameidata=^t_nameidata;
t_nameidata=record
{
* Arguments to namei/lookup.
}
ni_dirp:PChar; { pathname pointer }
ni_segflg:uio_seg; { location of pathname }
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;
procedure NDINIT_ALL(
ndp:p_nameidata;
op:QWORD;
flags:QWORD;
segflg:uio_seg;
namep:PChar;
dirfd:Integer;
startdir:p_vnode;
rights:cap_rights_t;
td:p_kthread); inline;
procedure NDINIT(
ndp:p_nameidata;
op:QWORD;
flags:QWORD;
segflg:uio_seg;
namep:PChar;
td:p_kthread); inline;
procedure NDINIT_AT(
ndp:p_nameidata;
op:QWORD;
flags:QWORD;
segflg:uio_seg;
namep:PChar;
dirfd:Integer;
td:p_kthread); inline;
procedure NDINIT_ATRIGHTS(
ndp:p_nameidata;
op:QWORD;
flags:QWORD;
segflg:uio_seg;
namep:PChar;
dirfd:Integer;
rights:cap_rights_t;
td:p_kthread); inline;
procedure NDINIT_ATVP(
ndp:p_nameidata;
op:QWORD;
flags:QWORD;
segflg:uio_seg;
namep:PChar;
vp:p_vnode;
td:p_kthread); inline;
function nd_namei(ndp:p_nameidata):Integer; external;
function nd_lookup(ndp:p_nameidata):Integer; external;
procedure NDFREE(ndp:p_nameidata;flags:Integer); external;
implementation
function NDHASGIANT(ndp:p_nameidata):Integer; inline;
begin
Result:=ord((ndp^.ni_cnd.cn_flags and GIANTHELD)<>0);
end;
procedure NDINIT_ALL(
ndp:p_nameidata;
op:QWORD;
flags:QWORD;
segflg:uio_seg;
namep:PChar;
dirfd:Integer;
startdir:p_vnode;
rights:cap_rights_t;
td:p_kthread); inline;
begin
ndp^:=Default(t_nameidata);
ndp^.ni_cnd.cn_nameiop:=op;
ndp^.ni_cnd.cn_flags :=flags;
ndp^.ni_segflg :=segflg;
ndp^.ni_dirp :=namep;
ndp^.ni_dirfd :=dirfd;
ndp^.ni_startdir :=startdir;
ndp^.ni_strictrelative:=0;
ndp^.ni_rightsneeded :=rights;
ndp^.ni_baserights :=0;
ndp^.ni_cnd.cn_thread :=td;
end;
procedure NDINIT(
ndp:p_nameidata;
op:QWORD;
flags:QWORD;
segflg:uio_seg;
namep:PChar;
td:p_kthread); inline;
begin
NDINIT_ALL(ndp,op,flags,segflg,namep,AT_FDCWD,nil,0,td);
end;
procedure NDINIT_AT(
ndp:p_nameidata;
op:QWORD;
flags:QWORD;
segflg:uio_seg;
namep:PChar;
dirfd:Integer;
td:p_kthread); inline;
begin
NDINIT_ALL(ndp,op,flags,segflg,namep,dirfd,nil,0,td);
end;
procedure NDINIT_ATRIGHTS(
ndp:p_nameidata;
op:QWORD;
flags:QWORD;
segflg:uio_seg;
namep:PChar;
dirfd:Integer;
rights:cap_rights_t;
td:p_kthread); inline;
begin
NDINIT_ALL(ndp,op,flags,segflg,namep,dirfd,nil,rights,td);
end;
procedure NDINIT_ATVP(
ndp:p_nameidata;
op:QWORD;
flags:QWORD;
segflg:uio_seg;
namep:PChar;
vp:p_vnode;
td:p_kthread); inline;
begin
NDINIT_ALL(ndp,op,flags,segflg,namep,AT_FDCWD,vp,0,td);
end;
end.