mirror of https://github.com/red-prig/fpPS4.git
216 lines
4.2 KiB
Plaintext
216 lines
4.2 KiB
Plaintext
unit fdesc_vfsops;
|
|
|
|
{$mode ObjFPC}{$H+}
|
|
{$CALLING SysV_ABI_CDecl}
|
|
|
|
interface
|
|
|
|
uses
|
|
vmount,
|
|
kern_param,
|
|
vfs_mount,
|
|
vnode,
|
|
fdescfs;
|
|
|
|
{
|
|
* /dev/fd Filesystem
|
|
}
|
|
function fdesc_cmount(ma,data:Pointer;flags:QWORD):Integer;
|
|
function fdesc_mount(mp:p_mount):Integer;
|
|
function fdesc_unmount(mp:p_mount;mntflags:Integer):Integer;
|
|
function fdesc_root(mp:p_mount;flags:Integer;vpp:pp_vnode):Integer;
|
|
function fdesc_statfs(mp:p_mount;sbp:p_statfs):Integer;
|
|
|
|
const
|
|
_fdesc_vfsops:vfsops=(
|
|
vfs_mount :@fdesc_mount;
|
|
vfs_cmount :@fdesc_cmount;
|
|
vfs_unmount :@fdesc_unmount;
|
|
vfs_root :@fdesc_root;
|
|
vfs_quotactl :nil;
|
|
vfs_statfs :@fdesc_statfs;
|
|
vfs_sync :nil;
|
|
vfs_vget :nil;
|
|
vfs_fhtovp :nil;
|
|
vfs_checkexp :nil;
|
|
vfs_init :@fdesc_init;
|
|
vfs_uninit :@fdesc_uninit;
|
|
vfs_extattrctl :nil;
|
|
vfs_sysctl :nil;
|
|
vfs_susp_clean :nil;
|
|
);
|
|
|
|
//VFS_SET(fdesc_vfsops, fdescfs, VFCF_SYNTHETIC);
|
|
fdescfs_vfsconf:vfsconf=(
|
|
vfc_version :VFS_VERSION;
|
|
vfc_name :'fdescfs';
|
|
vfc_vfsops :@_fdesc_vfsops;
|
|
vfc_typenum :-1;
|
|
vfc_refcount:0;
|
|
vfc_flags :VFCF_SYNTHETIC;
|
|
vfc_opts :nil;
|
|
vfc_list :(tqe_next:nil;tqe_prev:nil)
|
|
);
|
|
|
|
implementation
|
|
|
|
uses
|
|
errno,
|
|
vfiledesc,
|
|
vfs_subr,
|
|
vnode_if,
|
|
kern_mtx,
|
|
kern_id,
|
|
fdesc_vnops;
|
|
|
|
function VFSTOFDESC(mp:p_mount):p_fdescmount; inline;
|
|
begin
|
|
Result:=mp^.mnt_data;
|
|
end;
|
|
|
|
function VTOFDESC(vp:p_vnode):p_fdescnode; inline;
|
|
begin
|
|
Result:=vp^.v_data;
|
|
end;
|
|
|
|
{
|
|
* Compatibility shim for old mount(2) system call.
|
|
}
|
|
function fdesc_cmount(ma,data:Pointer;flags:QWORD):Integer;
|
|
begin
|
|
Exit(kernel_nmount(ma, flags));
|
|
end;
|
|
|
|
{
|
|
* Mount the per-process file descriptors (/dev/fd)
|
|
}
|
|
function fdesc_mount(mp:p_mount):Integer;
|
|
var
|
|
error:Integer;
|
|
fmp:p_fdescmount;
|
|
rvp:p_vnode;
|
|
begin
|
|
error:=0;
|
|
rvp:=nil;
|
|
{
|
|
* Update is a no-op
|
|
}
|
|
if ((mp^.mnt_flag and (MNT_UPDATE or MNT_ROOTFS))<>0) then
|
|
Exit(EOPNOTSUPP);
|
|
|
|
fmp:=AllocMem(sizeof(t_fdescmount)); { XXX }
|
|
|
|
{
|
|
* We need to initialize a few bits of our local mount point struct to
|
|
* avoid confusion in allocvp.
|
|
}
|
|
mp^.mnt_data:=fmp;
|
|
fmp^.flags:=0;
|
|
|
|
error:=fdesc_allocvp(_Froot, -1, FD_ROOT, mp, @rvp);
|
|
|
|
if (error<>0) then
|
|
begin
|
|
FreeMem(fmp);
|
|
mp^.mnt_data:=nil;
|
|
Exit(error);
|
|
end;
|
|
|
|
rvp^.v_type:=VDIR;
|
|
rvp^.v_vflag:=rvp^.v_vflag or VV_ROOT;
|
|
fmp^.f_root:=rvp;
|
|
|
|
VOP_UNLOCK(rvp, 0);
|
|
{ XXX -- don't mark as local to work around fts() problems }
|
|
{mp^.mnt_flag:=mp^.mnt_flag or MNT_LOCAL;}
|
|
MNT_ILOCK(mp);
|
|
mp^.mnt_kern_flag:=mp^.mnt_kern_flag or MNTK_MPSAFE;
|
|
MNT_IUNLOCK(mp);
|
|
vfs_getnewfsid(mp);
|
|
|
|
vfs_mountedfrom(mp, 'fdescfs');
|
|
Exit(0);
|
|
end;
|
|
|
|
function fdesc_unmount(mp:p_mount;mntflags:Integer):Integer;
|
|
var
|
|
fmp:p_fdescmount;
|
|
data:Pointer;
|
|
error:Integer;
|
|
flags:Integer;
|
|
begin
|
|
flags:=0;
|
|
|
|
fmp:=p_fdescmount(mp^.mnt_data);
|
|
|
|
if ((mntflags and MNT_FORCE)<>0) then
|
|
begin
|
|
{ The hash mutex protects the private mount flags. }
|
|
mtx_lock(fdesc_hashmtx);
|
|
fmp^.flags:=fmp^.flags or FMNT_UNMOUNTF;
|
|
mtx_unlock(fdesc_hashmtx);
|
|
flags:=flags or FORCECLOSE;
|
|
end;
|
|
|
|
{
|
|
* Clear out buffer cache. I don't think we
|
|
* ever get anything cached at this level at the
|
|
* moment, but who knows...
|
|
*
|
|
* There is 1 extra root vnode reference corresponding
|
|
* to f_root.
|
|
}
|
|
error:=vflush(mp, 1, flags);
|
|
if (error<>0) then
|
|
Exit(error);
|
|
|
|
{
|
|
* Finally, throw away the fdescmount structure. Hold the hashmtx to
|
|
* protect the fdescmount structure.
|
|
}
|
|
mtx_lock(fdesc_hashmtx);
|
|
data:=mp^.mnt_data;
|
|
mp^.mnt_data:=nil;
|
|
mtx_unlock(fdesc_hashmtx);
|
|
FreeMem(data); { XXX }
|
|
|
|
Exit(0);
|
|
end;
|
|
|
|
function fdesc_root(mp:p_mount;flags:Integer;vpp:pp_vnode):Integer;
|
|
var
|
|
vp:p_vnode;
|
|
begin
|
|
{
|
|
* Exitlocked reference to root.
|
|
}
|
|
vp:=VFSTOFDESC(mp)^.f_root;
|
|
vget(vp, LK_EXCLUSIVE or LK_RETRY);
|
|
vpp^:=vp;
|
|
Exit(0);
|
|
end;
|
|
|
|
function fdesc_statfs(mp:p_mount;sbp:p_statfs):Integer;
|
|
var
|
|
lim:Integer;
|
|
freefd:Integer;
|
|
begin
|
|
lim :=fd_table.fd_nfiles;
|
|
freefd:=fd_table.fd_freefd;
|
|
|
|
sbp^.f_flags :=0;
|
|
sbp^.f_bsize :=DEV_BSIZE;
|
|
sbp^.f_iosize:=DEV_BSIZE;
|
|
sbp^.f_blocks:=2; { 1K to keep df happy }
|
|
sbp^.f_bfree :=0;
|
|
sbp^.f_bavail:=0;
|
|
sbp^.f_files :=lim + 1; { Allow for '.' }
|
|
sbp^.f_ffree :=freefd;
|
|
Exit(0);
|
|
end;
|
|
|
|
|
|
|
|
end.
|
|
|