mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
e34e71d189
commit
02b62690c1
|
@ -1059,7 +1059,7 @@ begin
|
|||
Exit(error);
|
||||
end;
|
||||
|
||||
function devfs_lookupx(ap:p_vop_lookup_args;dm_unlock:PInteger):Integer;
|
||||
function devfs_lookupx(ap:p_vop_lookup_args;dm_unlock:PBoolean):Integer;
|
||||
label
|
||||
_or;
|
||||
var
|
||||
|
@ -1111,12 +1111,14 @@ begin
|
|||
if ((flags and ISLASTCN)<>0) and (nameiop<>LOOKUP) then
|
||||
Exit(EINVAL);
|
||||
de:=devfs_parent_dirent(dd);
|
||||
if (de=nil) then
|
||||
Exit(ENOENT);
|
||||
if (de=nil) then Exit(ENOENT);
|
||||
|
||||
dvplocked:=VOP_ISLOCKED(dvp);
|
||||
VOP_UNLOCK(dvp, 0);
|
||||
|
||||
error:=devfs_allocv(de, dvp^.v_mount, cnp^.cn_lkflags and LK_TYPE_MASK, vpp);
|
||||
dm_unlock^:=0;
|
||||
dm_unlock^:=False;
|
||||
|
||||
vn_lock(dvp, dvplocked or LK_RETRY);
|
||||
Exit(error);
|
||||
end;
|
||||
|
@ -1126,16 +1128,14 @@ begin
|
|||
while (de=nil) do
|
||||
begin { While(...) so we can use break }
|
||||
|
||||
if (nameiop=DELETE) then
|
||||
Exit(ENOENT);
|
||||
if (nameiop=DELETE) then Exit(ENOENT);
|
||||
|
||||
{
|
||||
* OK, we didn't have an entry for the name we were asked for
|
||||
* so we try to see if anybody can create it on demand.
|
||||
}
|
||||
pname:=devfs_fqpn(specname, dmp, dd, cnp);
|
||||
if (pname=nil) then
|
||||
break;
|
||||
if (pname=nil) then break;
|
||||
|
||||
cdev:=nil;
|
||||
DEVFS_DMP_HOLD(dmp);
|
||||
|
@ -1150,24 +1150,28 @@ begin
|
|||
else
|
||||
if (devfs_populate_vp(dvp)<>0) then
|
||||
begin
|
||||
dm_unlock^:=0;
|
||||
dm_unlock^:=false;
|
||||
sx_xlock(@dmp^.dm_lock);
|
||||
|
||||
if (DEVFS_DMP_DROP(dmp)) then
|
||||
begin
|
||||
sx_xunlock(@dmp^.dm_lock);
|
||||
devfs_unmount_final(dmp);
|
||||
end else
|
||||
sx_xunlock(@dmp^.dm_lock);
|
||||
|
||||
dev_rel(cdev);
|
||||
Exit(ENOENT);
|
||||
end;
|
||||
if DEVFS_DMP_DROP(dmp) then
|
||||
begin
|
||||
dm_unlock^:=0;
|
||||
dm_unlock^:=false;
|
||||
sx_xunlock(@dmp^.dm_lock);
|
||||
devfs_unmount_final(dmp);
|
||||
|
||||
if (cdev<>nil) then
|
||||
dev_rel(cdev);
|
||||
|
||||
Exit(ENOENT);
|
||||
end;
|
||||
|
||||
|
@ -1218,15 +1222,17 @@ begin
|
|||
Exit(0);
|
||||
end;
|
||||
end;
|
||||
|
||||
error:=devfs_allocv(de, dvp^.v_mount, cnp^.cn_lkflags and LK_TYPE_MASK, vpp);
|
||||
dm_unlock^:=0;
|
||||
dm_unlock^:=false;
|
||||
|
||||
Exit(error);
|
||||
end;
|
||||
|
||||
function devfs_lookup(ap:p_vop_lookup_args):Integer;
|
||||
var
|
||||
dmp:p_devfs_mount;
|
||||
dm_unlock:Integer;
|
||||
dm_unlock:Boolean;
|
||||
begin
|
||||
if (devfs_populate_vp(ap^.a_dvp)<>0) then
|
||||
begin
|
||||
|
@ -1234,10 +1240,11 @@ begin
|
|||
end;
|
||||
|
||||
dmp:=VFSTODEVFS(ap^.a_dvp^.v_mount);
|
||||
dm_unlock:=1;
|
||||
dm_unlock:=True;
|
||||
|
||||
Result:=devfs_lookupx(ap, @dm_unlock);
|
||||
|
||||
if (dm_unlock=1) then
|
||||
if (dm_unlock) then
|
||||
begin
|
||||
sx_xunlock(@dmp^.dm_lock);
|
||||
end;
|
||||
|
@ -1315,19 +1322,18 @@ begin
|
|||
dev:=vp^.v_rdev;
|
||||
fp:=ap^.a_fp;
|
||||
|
||||
if (vp^.v_type=VBLK) then
|
||||
Exit(ENXIO);
|
||||
|
||||
if (dev=nil) then
|
||||
Exit(ENXIO);
|
||||
if (vp^.v_type=VBLK) then Exit(ENXIO);
|
||||
if (dev=nil) then Exit(ENXIO);
|
||||
|
||||
{ Make this field valid before any I/O in d_open. }
|
||||
if (dev^.si_iosize_max=0) then
|
||||
begin
|
||||
dev^.si_iosize_max:=DFLTPHYS;
|
||||
end;
|
||||
|
||||
dsw:=dev_refthread(dev, @ref);
|
||||
if (dsw=nil) then
|
||||
Exit(ENXIO);
|
||||
if (dsw=nil) then Exit(ENXIO);
|
||||
|
||||
if (fp=nil) and (dsw^.d_fdopen<>nil) then
|
||||
begin
|
||||
dev_relthread(dev, ref);
|
||||
|
@ -1351,14 +1357,14 @@ begin
|
|||
{ cleanup any cdevpriv upon error }
|
||||
if (error<>0) then
|
||||
devfs_clear_cdevpriv();
|
||||
|
||||
td^.td_fpop:=fpop;
|
||||
|
||||
vn_lock(vp, vlocked or LK_RETRY);
|
||||
dev_relthread(dev, ref);
|
||||
if (error<>0) then
|
||||
begin
|
||||
if (error=ERESTART) then
|
||||
error:=EINTR;
|
||||
if (error=ERESTART) then error:=EINTR;
|
||||
Exit(error);
|
||||
end;
|
||||
|
||||
|
@ -1366,7 +1372,10 @@ begin
|
|||
Exit(error);
|
||||
|
||||
if (fp^.f_ops=@badfileops) then
|
||||
begin
|
||||
finit(fp, fp^.f_flag, DTYPE_VNODE, dev, @devfs_ops_f);
|
||||
end;
|
||||
|
||||
mtxp:=mtx_pool_find(mtxpool_sleep, fp);
|
||||
|
||||
{
|
||||
|
|
|
@ -28,10 +28,13 @@ function md_mount(mp:p_ufs_mount):Integer;
|
|||
function md_unmount(mp:p_ufs_mount):Integer;
|
||||
function md_free_dirent(de:p_ufs_dirent):Integer;
|
||||
|
||||
function md_vmkdir(dmp:p_ufs_mount;name:PChar;namelen:Integer;dotdot:p_ufs_dirent;inode:DWORD):p_ufs_dirent;
|
||||
function md_vmkdir(dmp:p_ufs_mount;name:PChar;namelen:Integer;dotdot:p_ufs_dirent):p_ufs_dirent;
|
||||
|
||||
function md_lookup(ap:p_vop_lookup_args):Integer;
|
||||
function md_readdir(ap:p_vop_readdir_args):Integer;
|
||||
function md_inactive(ap:p_vop_inactive_args):Integer;
|
||||
function md_reclaim(ap:p_vop_reclaim_args):Integer;
|
||||
function md_getattr(ap:p_vop_getattr_args):Integer;
|
||||
|
||||
const
|
||||
md_vnodeops_host:vop_vector=(
|
||||
|
@ -43,11 +46,11 @@ const
|
|||
vop_create :nil;
|
||||
vop_whiteout :nil;
|
||||
vop_mknod :nil;
|
||||
vop_open :nil;
|
||||
vop_close :nil;
|
||||
vop_open :nil; //TODO
|
||||
vop_close :nil; //TODO
|
||||
vop_access :nil; //parent
|
||||
vop_accessx :nil;
|
||||
vop_getattr :@ufs_getattr;
|
||||
vop_getattr :@md_getattr;
|
||||
vop_setattr :@ufs_setattr;
|
||||
vop_markatime :nil;
|
||||
vop_read :nil; //parent
|
||||
|
@ -56,17 +59,17 @@ const
|
|||
vop_poll :nil;
|
||||
vop_kqfilter :nil;
|
||||
vop_revoke :nil;
|
||||
vop_fsync :nil;
|
||||
vop_remove :@ufs_remove;
|
||||
vop_link :nil;
|
||||
vop_rename :nil;
|
||||
vop_mkdir :@ufs_mkdir;
|
||||
vop_rmdir :@ufs_rmdir;
|
||||
vop_symlink :@ufs_symlink;
|
||||
vop_fsync :nil; //TODO
|
||||
vop_remove :nil; //TODO
|
||||
vop_link :nil; //TODO
|
||||
vop_rename :nil; //TODO
|
||||
vop_mkdir :nil; //TODO
|
||||
vop_rmdir :nil; //TODO
|
||||
vop_symlink :nil; //TODO
|
||||
vop_readdir :@md_readdir;
|
||||
vop_readlink :@ufs_readlink;
|
||||
vop_inactive :nil;
|
||||
vop_reclaim :@ufs_reclaim;
|
||||
vop_inactive :@md_inactive;
|
||||
vop_reclaim :@md_reclaim;
|
||||
vop_lock1 :nil;
|
||||
vop_unlock :nil;
|
||||
vop_bmap :nil;
|
||||
|
@ -123,17 +126,22 @@ begin
|
|||
Result:=mp^.mnt_data;
|
||||
end;
|
||||
|
||||
procedure INIT_OBJ(var OBJ:TOBJ_ATTR;fd:THandle;FileName:PWideChar);
|
||||
function INIT_UNICODE(FileName:PWideChar):UNICODE_STRING;
|
||||
begin
|
||||
Result.Length :=strlen(FileName)*SizeOf(WideChar);
|
||||
Result.MaximumLength:=Result.Length+1;
|
||||
Result.Buffer :=FileName;
|
||||
end;
|
||||
|
||||
procedure INIT_OBJ(var OBJ:TOBJ_ATTR;fd:THandle;attr:ULONG;FileName:PWideChar);
|
||||
begin
|
||||
OBJ.OATTR.Length:=SizeOf(OBJECT_ATTRIBUTES);
|
||||
|
||||
OBJ.OATTR.RootDirectory:=fd;
|
||||
OBJ.OATTR.ObjectName :=@OBJ.UPATH;
|
||||
OBJ.OATTR.Attributes :=OBJ_CASE_INSENSITIVE;
|
||||
OBJ.OATTR.Attributes :=attr;
|
||||
|
||||
OBJ.UPATH.Length :=strlen(FileName)*SizeOf(WideChar);
|
||||
OBJ.UPATH.MaximumLength:=OBJ.UPATH.Length+1;
|
||||
OBJ.UPATH.Buffer :=FileName;
|
||||
OBJ.UPATH:=INIT_UNICODE(FileName);
|
||||
end;
|
||||
|
||||
function ntf2px(n:Integer):Integer; inline;
|
||||
|
@ -189,6 +197,11 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function get_inode(i:LARGE_INTEGER):Integer; inline;
|
||||
begin
|
||||
Result:=(i.LowPart+i.HighPart); //simple hash
|
||||
end;
|
||||
|
||||
function md_mount(mp:p_ufs_mount):Integer;
|
||||
var
|
||||
w:WideString;
|
||||
|
@ -201,7 +214,7 @@ begin
|
|||
w:='\??\'+w;
|
||||
|
||||
OBJ:=Default(TOBJ_ATTR);
|
||||
INIT_OBJ(OBJ,0,PWideChar(w));
|
||||
INIT_OBJ(OBJ,0,OBJ_CASE_INSENSITIVE,PWideChar(w));
|
||||
BLK:=Default(IO_STATUS_BLOCK);
|
||||
|
||||
R:=NtOpenFile(@F,
|
||||
|
@ -220,31 +233,112 @@ end;
|
|||
|
||||
function md_unmount(mp:p_ufs_mount):Integer;
|
||||
begin
|
||||
NtClose(THandle(mp^.ufs_md_fp));
|
||||
if (mp^.ufs_md_fp<>nil) then
|
||||
begin
|
||||
NtClose(THandle(mp^.ufs_md_fp));
|
||||
end;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function md_free_dirent(de:p_ufs_dirent):Integer;
|
||||
begin
|
||||
NtClose(THandle(de^.ufs_md_fp));
|
||||
if (de^.ufs_md_fp<>nil) then
|
||||
begin
|
||||
NtClose(THandle(de^.ufs_md_fp));
|
||||
end;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function md_update_dirent(de:p_ufs_dirent):Integer;
|
||||
function md_open_dirent(de:p_ufs_dirent):Integer;
|
||||
var
|
||||
u:RawByteString;
|
||||
w:WideString;
|
||||
OBJ:TOBJ_ATTR;
|
||||
BLK:IO_STATUS_BLOCK;
|
||||
F:Thandle;
|
||||
R:DWORD;
|
||||
begin
|
||||
SetString(u,@de^.ufs_dirent^.d_name,de^.ufs_dirent^.d_namlen);
|
||||
w:=UTF8Decode(u);
|
||||
|
||||
OBJ:=Default(TOBJ_ATTR);
|
||||
INIT_OBJ(OBJ,THandle(de^.ufs_dir^.ufs_md_fp),0,PWideChar(w));
|
||||
BLK:=Default(IO_STATUS_BLOCK);
|
||||
|
||||
R:=NtOpenFile(@F,
|
||||
SYNCHRONIZE or FILE_LIST_DIRECTORY or FILE_READ_ATTRIBUTES or FILE_WRITE_ATTRIBUTES,
|
||||
@OBJ,
|
||||
@BLK,
|
||||
FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,
|
||||
FILE_OPEN_FOR_BACKUP_INTENT or FILE_SYNCHRONOUS_IO_NONALERT or FILE_DIRECTORY_FILE
|
||||
);
|
||||
|
||||
Result:=ntf2px(R);
|
||||
if (Result<>0) then Exit;
|
||||
|
||||
de^.ufs_md_fp:=Pointer(F);
|
||||
end;
|
||||
|
||||
function md_open_dirent_file(de:p_ufs_dirent;fdr:PHandle):Integer;
|
||||
var
|
||||
u:RawByteString;
|
||||
w:WideString;
|
||||
OBJ:TOBJ_ATTR;
|
||||
BLK:IO_STATUS_BLOCK;
|
||||
F:Thandle;
|
||||
R:DWORD;
|
||||
begin
|
||||
SetString(u,@de^.ufs_dirent^.d_name,de^.ufs_dirent^.d_namlen);
|
||||
w:=UTF8Decode(u);
|
||||
|
||||
OBJ:=Default(TOBJ_ATTR);
|
||||
INIT_OBJ(OBJ,THandle(de^.ufs_dir^.ufs_md_fp),0,PWideChar(w));
|
||||
BLK:=Default(IO_STATUS_BLOCK);
|
||||
|
||||
R:=NtOpenFile(@F,
|
||||
SYNCHRONIZE or FILE_READ_DATA or FILE_READ_ATTRIBUTES or FILE_WRITE_ATTRIBUTES,
|
||||
@OBJ,
|
||||
@BLK,
|
||||
FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,
|
||||
FILE_OPEN_FOR_BACKUP_INTENT or FILE_SYNCHRONOUS_IO_NONALERT
|
||||
);
|
||||
|
||||
Result:=ntf2px(R);
|
||||
if (Result<>0) then Exit;
|
||||
|
||||
fdr^:=F;
|
||||
end;
|
||||
|
||||
function md_update_dirent(de:p_ufs_dirent):Integer;
|
||||
label
|
||||
_exit;
|
||||
var
|
||||
FP,RL:THandle;
|
||||
|
||||
FBI:FILE_BASIC_INFORMATION;
|
||||
//FSI:FILE_STANDARD_INFORMATION;
|
||||
FSI:FILE_STANDARD_INFORMATION;
|
||||
FII:FILE_INTERNAL_INFORMATION;
|
||||
BLK:IO_STATUS_BLOCK;
|
||||
R:DWORD;
|
||||
begin
|
||||
//ufs_inode (4) = FileInternalInformation (8) ??? hash it?
|
||||
if (de=nil) then Exit(0);
|
||||
|
||||
if (de^.ufs_md_fp=nil) then
|
||||
begin
|
||||
Result:=md_open_dirent_file(de,@FP);
|
||||
if (Result<>0) then Exit;
|
||||
RL:=FP;
|
||||
end else
|
||||
begin
|
||||
FP:=THandle(de^.ufs_md_fp);
|
||||
RL:=0;
|
||||
end;
|
||||
|
||||
FBI:=Default(FILE_BASIC_INFORMATION);
|
||||
//FSI:=Default(FILE_STANDARD_INFORMATION);
|
||||
BLK:=Default(IO_STATUS_BLOCK);
|
||||
|
||||
R:=NtQueryInformationFile(
|
||||
THandle(de^.ufs_md_fp),
|
||||
FP,
|
||||
@BLK,
|
||||
@FBI,
|
||||
SizeOf(FBI),
|
||||
|
@ -252,18 +346,20 @@ begin
|
|||
);
|
||||
|
||||
Result:=ntf2px(R);
|
||||
if (Result<>0) then Exit;
|
||||
if (Result<>0) then goto _exit;
|
||||
|
||||
de^.ufs_atime:=get_unix_file_time(FBI.LastAccessTime);
|
||||
de^.ufs_mtime:=get_unix_file_time(FBI.LastWriteTime);
|
||||
de^.ufs_ctime:=get_unix_file_time(FBI.ChangeTime);
|
||||
de^.ufs_btime:=get_unix_file_time(FBI.CreationTime);
|
||||
|
||||
{
|
||||
////
|
||||
|
||||
FSI:=Default(FILE_STANDARD_INFORMATION);
|
||||
BLK:=Default(IO_STATUS_BLOCK);
|
||||
|
||||
R:=NtQueryInformationFile(
|
||||
THandle(de^.ufs_md_fp),
|
||||
FP,
|
||||
@BLK,
|
||||
@FSI,
|
||||
SizeOf(FSI),
|
||||
|
@ -271,10 +367,42 @@ begin
|
|||
);
|
||||
|
||||
Result:=ntf2px(R);
|
||||
if (Result<>0) then Exit;
|
||||
if (Result<>0) then goto _exit;
|
||||
|
||||
de^.ufs_links:=FSI.NumberOfLinks;
|
||||
}
|
||||
if (de^.ufs_dirent^.d_type<>DT_DIR) then
|
||||
begin
|
||||
de^.ufs_links:=FSI.NumberOfLinks;
|
||||
de^.ufs_size :=Int64(FSI.EndOfFile);
|
||||
de^.ufs_bytes:=Int64(FSI.AllocationSize);
|
||||
end;
|
||||
|
||||
////
|
||||
|
||||
if (de^.ufs_inode=0) then
|
||||
begin
|
||||
FII:=Default(FILE_INTERNAL_INFORMATION);
|
||||
BLK:=Default(IO_STATUS_BLOCK);
|
||||
|
||||
R:=NtQueryInformationFile(
|
||||
FP,
|
||||
@BLK,
|
||||
@FII,
|
||||
SizeOf(FII),
|
||||
FileInternalInformation
|
||||
);
|
||||
|
||||
Result:=ntf2px(R);
|
||||
if (Result<>0) then goto _exit;
|
||||
|
||||
de^.ufs_inode:=get_inode(FII.IndexNumber);
|
||||
de^.ufs_dirent^.d_fileno:=de^.ufs_inode;
|
||||
end;
|
||||
|
||||
_exit:
|
||||
if (RL<>0) then
|
||||
begin
|
||||
NtClose(RL);
|
||||
end;
|
||||
end;
|
||||
|
||||
function md_newdirent(name:PChar;namelen:Integer):p_ufs_dirent;
|
||||
|
@ -297,10 +425,13 @@ begin
|
|||
de^.ufs_links :=1;
|
||||
de^.ufs_ref :=1;
|
||||
|
||||
sx_init(@de^.ufs_md_lock, 'md_lock');
|
||||
TAILQ_INIT(@de^.ufs_dlist);
|
||||
|
||||
Exit(de);
|
||||
end;
|
||||
|
||||
function md_vmkdir(dmp:p_ufs_mount;name:PChar;namelen:Integer;dotdot:p_ufs_dirent;inode:DWORD):p_ufs_dirent;
|
||||
function md_vmkdir(dmp:p_ufs_mount;name:PChar;namelen:Integer;dotdot:p_ufs_dirent):p_ufs_dirent;
|
||||
var
|
||||
nd:p_ufs_dirent;
|
||||
error:Integer;
|
||||
|
@ -308,37 +439,261 @@ begin
|
|||
{ Create the new directory }
|
||||
nd:=md_newdirent(name, namelen);
|
||||
|
||||
TAILQ_INIT(@nd^.ufs_dlist);
|
||||
|
||||
nd^.ufs_dirent^.d_type:=DT_DIR;
|
||||
nd^.ufs_mode :=&0555;
|
||||
nd^.ufs_mode :=&0777;
|
||||
nd^.ufs_links:=2;
|
||||
nd^.ufs_dir :=nd;
|
||||
|
||||
if (inode<>0) then
|
||||
nd^.ufs_inode:=inode
|
||||
else
|
||||
nd^.ufs_inode:=ufs_alloc_cdp_inode;
|
||||
nd^.ufs_dir :=dotdot;
|
||||
|
||||
if (dotdot=nil) then
|
||||
begin
|
||||
//move root handle
|
||||
nd^.ufs_md_fp:=dmp^.ufs_md_fp;
|
||||
end else
|
||||
begin
|
||||
//nd^.ufs_md_fp:=???
|
||||
sx_assert(@dmp^.ufs_lock);
|
||||
error:=md_open_dirent(nd);
|
||||
if (error<>0) then
|
||||
begin
|
||||
ufs_de_drop(nd);
|
||||
Exit(nil);
|
||||
end;
|
||||
|
||||
sx_assert(@dotdot^.ufs_md_lock);
|
||||
TAILQ_INSERT_TAIL(@dotdot^.ufs_dlist,nd,@nd^.ufs_list);
|
||||
Inc(dotdot^.ufs_links);
|
||||
ufs_de_hold(dotdot);
|
||||
end;
|
||||
|
||||
error:=md_update_dirent(nd);
|
||||
Assert(error=0);
|
||||
if (error<>0) then
|
||||
begin
|
||||
ufs_de_drop(nd);
|
||||
Exit(nil);
|
||||
end;
|
||||
|
||||
Exit(nd);
|
||||
end;
|
||||
|
||||
function md_find_cache(dd:p_ufs_dirent;name:PChar;namelen:Integer;_type:Integer):p_ufs_dirent;
|
||||
var
|
||||
de:p_ufs_dirent;
|
||||
begin
|
||||
sx_assert(@dd^.ufs_md_lock);
|
||||
|
||||
function md_lookupx(dmp:p_ufs_mount;ap:p_vop_lookup_args):Integer;
|
||||
de:=TAILQ_FIRST(@dd^.ufs_dlist);
|
||||
while (de<>nil) do
|
||||
begin
|
||||
if (namelen<>de^.ufs_dirent^.d_namlen) then
|
||||
begin
|
||||
de:=TAILQ_NEXT(de,@de^.ufs_list);
|
||||
continue;
|
||||
end;
|
||||
if (_type<>0) and (_type<>de^.ufs_dirent^.d_type) then
|
||||
begin
|
||||
de:=TAILQ_NEXT(de,@de^.ufs_list);
|
||||
continue;
|
||||
end;
|
||||
|
||||
if (CompareByte(name^, de^.ufs_dirent^.d_name, namelen)<>0) then
|
||||
begin
|
||||
de:=TAILQ_NEXT(de,@de^.ufs_list);
|
||||
continue;
|
||||
end;
|
||||
break;
|
||||
end;
|
||||
|
||||
Exit(de);
|
||||
end;
|
||||
|
||||
function md_lookup_dirent(dd:p_ufs_dirent;name:PChar;namelen:Integer):p_ufs_dirent;
|
||||
var
|
||||
u:RawByteString;
|
||||
w:WideString;
|
||||
|
||||
nd:p_ufs_dirent;
|
||||
de:p_dirent;
|
||||
|
||||
UNAME:UNICODE_STRING;
|
||||
NT_DIRENT:TNT_DIRENT;
|
||||
BLK:IO_STATUS_BLOCK;
|
||||
R:DWORD;
|
||||
begin
|
||||
sx_assert(@dd^.ufs_md_lock);
|
||||
|
||||
Result:=nil;
|
||||
SetString(u,name,namelen);
|
||||
w:=UTF8Decode(u);
|
||||
|
||||
UNAME:=INIT_UNICODE(PWideChar(w));
|
||||
NT_DIRENT:=Default(TNT_DIRENT);
|
||||
BLK:=Default(IO_STATUS_BLOCK);
|
||||
|
||||
R:=NtQueryDirectoryFile(
|
||||
THandle(dd^.ufs_md_fp),
|
||||
0,
|
||||
nil,
|
||||
nil,
|
||||
@BLK,
|
||||
@NT_DIRENT,
|
||||
SizeOf(NT_DIRENT),
|
||||
FileIdFullDirectoryInformation,
|
||||
True,
|
||||
@UNAME,
|
||||
True
|
||||
);
|
||||
|
||||
if (R<>0) then Exit;
|
||||
|
||||
{ Create the new directory }
|
||||
nd:=md_newdirent(name, namelen);
|
||||
|
||||
nd^.ufs_mode :=&0777;
|
||||
nd^.ufs_links:=1; //read link???
|
||||
nd^.ufs_dir :=dd;
|
||||
|
||||
if ((NT_DIRENT.Info.FileAttributes and FILE_ATTRIBUTE_DIRECTORY)=0) then
|
||||
begin
|
||||
nd^.ufs_size :=Int64(NT_DIRENT.Info.EndOfFile);
|
||||
nd^.ufs_bytes:=Int64(NT_DIRENT.Info.AllocationSize);
|
||||
end;
|
||||
|
||||
nd^.ufs_inode:=get_inode(NT_DIRENT.Info.FileId);
|
||||
|
||||
nd^.ufs_atime:=get_unix_file_time(NT_DIRENT.Info.LastAccessTime);
|
||||
nd^.ufs_mtime:=get_unix_file_time(NT_DIRENT.Info.LastWriteTime);
|
||||
nd^.ufs_ctime:=get_unix_file_time(NT_DIRENT.Info.ChangeTime);
|
||||
nd^.ufs_btime:=get_unix_file_time(NT_DIRENT.Info.CreationTime);
|
||||
|
||||
de:=nd^.ufs_dirent;
|
||||
|
||||
de^.d_fileno:=nd^.ufs_inode;
|
||||
de^.d_type :=NT_FA_TO_DT(NT_DIRENT.Info.FileAttributes,NT_DIRENT.Info.EaSize);
|
||||
|
||||
if (de^.d_type=DT_DIR) then
|
||||
begin
|
||||
R:=md_open_dirent(nd);
|
||||
if (R<>0) then
|
||||
begin
|
||||
ufs_de_drop(nd);
|
||||
Exit(nil);
|
||||
end;
|
||||
end;
|
||||
|
||||
TAILQ_INSERT_TAIL(@dd^.ufs_dlist,nd,@nd^.ufs_list);
|
||||
Inc(dd^.ufs_links);
|
||||
ufs_de_hold(dd);
|
||||
|
||||
Exit(nd);
|
||||
end;
|
||||
|
||||
procedure md_delete_cache(de:p_ufs_dirent);
|
||||
var
|
||||
dd:p_ufs_dirent;
|
||||
vp:p_vnode;
|
||||
begin
|
||||
if (de=nil) then Exit;
|
||||
|
||||
Assert((de^.ufs_flags and UFS_DOOMED)=0,'ufs_delete doomed dirent');
|
||||
de^.ufs_flags:=de^.ufs_flags or UFS_DOOMED;
|
||||
|
||||
dd:=de^.ufs_dir; //parent
|
||||
if (dd<>nil) then
|
||||
begin
|
||||
ufs_de_hold(dd);
|
||||
sx_xlock(@dd^.ufs_md_lock);
|
||||
end;
|
||||
|
||||
mtx_lock(ufs_interlock);
|
||||
vp:=de^.ufs_vnode;
|
||||
if (vp<>nil) then
|
||||
begin
|
||||
VI_LOCK(vp);
|
||||
mtx_unlock(ufs_interlock);
|
||||
vholdl(vp);
|
||||
|
||||
if (dd<>nil) then
|
||||
begin
|
||||
sx_unlock(@dd^.ufs_md_lock);
|
||||
end;
|
||||
|
||||
vn_lock(vp, LK_EXCLUSIVE or LK_INTERLOCK or LK_RETRY);
|
||||
|
||||
vgone(vp);
|
||||
|
||||
VOP_UNLOCK(vp, 0);
|
||||
|
||||
vdrop(vp);
|
||||
|
||||
if (dd<>nil) then
|
||||
begin
|
||||
sx_xlock(@dd^.ufs_md_lock);
|
||||
end;
|
||||
end else
|
||||
mtx_unlock(ufs_interlock);
|
||||
|
||||
if (de^.ufs_symlink<>nil) then
|
||||
begin
|
||||
FreeMem(de^.ufs_symlink);
|
||||
de^.ufs_symlink:=nil;
|
||||
end;
|
||||
|
||||
if (dd<>nil) then
|
||||
begin
|
||||
TAILQ_REMOVE(@dd^.ufs_dlist,de,@de^.ufs_list);
|
||||
sx_unlock(@dd^.ufs_md_lock);
|
||||
ufs_de_drop(dd);
|
||||
ufs_de_drop(dd);
|
||||
end;
|
||||
|
||||
ufs_de_drop(de);
|
||||
end;
|
||||
|
||||
function md_inactive(ap:p_vop_inactive_args):Integer;
|
||||
var
|
||||
vp:p_vnode;
|
||||
de:p_ufs_dirent;
|
||||
begin
|
||||
vp:=ap^.a_vp;
|
||||
|
||||
mtx_lock(ufs_interlock);
|
||||
de:=vp^.v_data;
|
||||
if (de<>nil) then
|
||||
begin
|
||||
de^.ufs_vnode:=nil;
|
||||
vp^.v_data:=nil;
|
||||
end;
|
||||
mtx_unlock(ufs_interlock);
|
||||
|
||||
md_delete_cache(de);
|
||||
|
||||
Exit(0);
|
||||
end;
|
||||
|
||||
function md_reclaim(ap:p_vop_reclaim_args):Integer;
|
||||
var
|
||||
vp:p_vnode;
|
||||
de:p_ufs_dirent;
|
||||
begin
|
||||
vp:=ap^.a_vp;
|
||||
|
||||
mtx_lock(ufs_interlock);
|
||||
de:=vp^.v_data;
|
||||
if (de<>nil) then
|
||||
begin
|
||||
de^.ufs_vnode:=nil;
|
||||
vp^.v_data:=nil;
|
||||
end;
|
||||
mtx_unlock(ufs_interlock);
|
||||
|
||||
md_delete_cache(de);
|
||||
|
||||
//vnode_destroy_vobject(vp);
|
||||
|
||||
Exit(0);
|
||||
end;
|
||||
|
||||
function md_lookupx(ap:p_vop_lookup_args):Integer;
|
||||
label
|
||||
_error;
|
||||
var
|
||||
cnp:p_componentname;
|
||||
dvp:p_vnode;
|
||||
|
@ -347,6 +702,7 @@ var
|
|||
dde:p_ufs_dirent;
|
||||
error,flags,nameiop,dvplocked:Integer;
|
||||
pname:PChar;
|
||||
dmp:p_ufs_mount;
|
||||
begin
|
||||
cnp:=ap^.a_cnp;
|
||||
vpp:=ap^.a_vpp;
|
||||
|
@ -357,32 +713,102 @@ begin
|
|||
dd:=dvp^.v_data;
|
||||
vpp^:=nil;
|
||||
|
||||
////////
|
||||
if (dvp^.v_type<>VDIR) then
|
||||
Exit(ENOTDIR);
|
||||
|
||||
Exit(ENOENT);
|
||||
if (((flags and ISDOTDOT)<>0) and ((dvp^.v_vflag and VV_ROOT)<>0)) then
|
||||
Exit(EIO);
|
||||
|
||||
error:=VOP_ACCESS(dvp, VEXEC);
|
||||
if (error<>0) then
|
||||
Exit(error);
|
||||
|
||||
if (cnp^.cn_namelen=1) and (pname^='.') then
|
||||
begin
|
||||
if ((flags and ISLASTCN) and nameiop<>LOOKUP) then
|
||||
Exit(EINVAL);
|
||||
|
||||
vpp^:=dvp;
|
||||
VREF(dvp);
|
||||
|
||||
Exit(0);
|
||||
end;
|
||||
|
||||
de:=md_find_cache(dd, cnp^.cn_nameptr, cnp^.cn_namelen, 0);
|
||||
|
||||
if (de=nil) then
|
||||
begin
|
||||
de:=md_lookup_dirent(dd, cnp^.cn_nameptr, cnp^.cn_namelen);
|
||||
end;
|
||||
|
||||
if (de=nil) then
|
||||
begin
|
||||
Case nameiop of
|
||||
CREATE:
|
||||
begin
|
||||
//if not last
|
||||
if ((flags and ISLASTCN)=0) then Exit(ENOENT);
|
||||
end;
|
||||
|
||||
LOOKUP,
|
||||
DELETE,
|
||||
RENAME:Exit(ENOENT);
|
||||
else;
|
||||
end;
|
||||
goto _error;
|
||||
end;
|
||||
|
||||
if ((de^.ufs_flags and UFS_WHITEOUT)<>0) then
|
||||
begin
|
||||
_error:
|
||||
if ((nameiop=CREATE) or (nameiop=RENAME)) and
|
||||
((flags and (LOCKPARENT or WANTPARENT))<>0) and
|
||||
((flags and ISLASTCN)<>0) then
|
||||
begin
|
||||
cnp^.cn_flags:=cnp^.cn_flags or SAVENAME;
|
||||
Exit(EJUSTRETURN);
|
||||
end;
|
||||
Exit(ENOENT);
|
||||
end;
|
||||
|
||||
if (cnp^.cn_nameiop=DELETE) and ((flags and ISLASTCN)<>0) then
|
||||
begin
|
||||
error:=VOP_ACCESS(dvp, VWRITE);
|
||||
if (error<>0) then
|
||||
Exit(error);
|
||||
|
||||
if (vpp^=dvp) then
|
||||
begin
|
||||
VREF(dvp);
|
||||
vpp^:=dvp;
|
||||
Exit(0);
|
||||
end;
|
||||
end;
|
||||
|
||||
dmp:=VFSTOUFS(ap^.a_dvp^.v_mount);
|
||||
sx_xlock(@dmp^.ufs_lock);
|
||||
error:=ufs_allocv(de, dvp^.v_mount, cnp^.cn_lkflags and LK_TYPE_MASK, vpp);
|
||||
|
||||
Exit(error);
|
||||
end;
|
||||
|
||||
function md_lookup(ap:p_vop_lookup_args):Integer;
|
||||
var
|
||||
dmp:p_ufs_mount;
|
||||
dd:p_ufs_dirent;
|
||||
begin
|
||||
dmp:=VFSTOUFS(ap^.a_dvp^.v_mount);
|
||||
sx_xlock(@dmp^.ufs_lock);
|
||||
Result:=md_lookupx(dmp,ap);
|
||||
sx_xunlock(@dmp^.ufs_lock);
|
||||
dd:=ap^.a_dvp^.v_data;
|
||||
sx_xlock(@dd^.ufs_md_lock);
|
||||
|
||||
Result:=md_lookupx(ap);
|
||||
|
||||
sx_xunlock(@dd^.ufs_md_lock);
|
||||
end;
|
||||
|
||||
function md_readdir(ap:p_vop_readdir_args):Integer;
|
||||
var
|
||||
uio:p_uio;
|
||||
|
||||
//mp:p_mount;
|
||||
//dmp:p_ufs_mount;
|
||||
|
||||
dd:p_ufs_dirent;
|
||||
|
||||
dt:t_dirent;
|
||||
|
||||
off:Int64;
|
||||
|
||||
NT_DIRENT:TNT_DIRENT;
|
||||
|
@ -397,14 +823,12 @@ begin
|
|||
if (uio^.uio_offset < 0) then
|
||||
Exit(EINVAL);
|
||||
|
||||
//mp:=ap^.a_vp^.v_mount;
|
||||
//dmp:=VFSTOUFS(mp);
|
||||
|
||||
dd:=ap^.a_vp^.v_data;
|
||||
|
||||
off:=0;
|
||||
|
||||
restart:=True;
|
||||
|
||||
sx_xlock(@dd^.ufs_md_lock);
|
||||
|
||||
repeat
|
||||
NT_DIRENT:=Default(TNT_DIRENT);
|
||||
BLK:=Default(IO_STATUS_BLOCK);
|
||||
|
@ -427,7 +851,7 @@ begin
|
|||
if (R=STATUS_NO_MORE_FILES) then Break;
|
||||
|
||||
Result:=ntf2px(R);
|
||||
if (Result<>0) then Exit;
|
||||
if (Result<>0) then Break;
|
||||
|
||||
dt:=Default(t_dirent);
|
||||
dt.d_reclen:=SizeOf(t_dirent)-(t_dirent.MAXNAMLEN+1)+NT_DIRENT.Info.FileNameLength;
|
||||
|
@ -436,7 +860,7 @@ begin
|
|||
|
||||
if (off >= uio^.uio_offset) then
|
||||
begin
|
||||
dt.d_fileno:=NT_DIRENT.Info.FileIndex; // FileId ????
|
||||
dt.d_fileno:=get_inode(NT_DIRENT.Info.FileId);
|
||||
//dt.d_reclen
|
||||
dt.d_type :=NT_FA_TO_DT(NT_DIRENT.Info.FileAttributes,NT_DIRENT.Info.EaSize);
|
||||
dt.d_namlen:=NT_DIRENT.Info.FileNameLength-1;
|
||||
|
@ -449,10 +873,26 @@ begin
|
|||
Inc(off,dt.d_reclen);
|
||||
until false;
|
||||
|
||||
sx_xunlock(@dd^.ufs_md_lock);
|
||||
uio^.uio_offset:=off;
|
||||
|
||||
Exit(0);
|
||||
end;
|
||||
|
||||
function md_getattr(ap:p_vop_getattr_args):Integer;
|
||||
var
|
||||
vp:p_vnode;
|
||||
de:p_ufs_dirent;
|
||||
|
||||
begin
|
||||
vp:=ap^.a_vp;
|
||||
de:=vp^.v_data;
|
||||
|
||||
Result:=md_update_dirent(de);
|
||||
if (Result<>0) then Exit;
|
||||
|
||||
Result:=ufs_getattr(ap);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
@ -31,12 +31,15 @@ type
|
|||
ufs_mode :mode_t; //S_IFMT
|
||||
ufs_uid :uid_t;
|
||||
ufs_gid :gid_t;
|
||||
ufs_size :Int64; // file size in bytes
|
||||
ufs_bytes :Int64; // bytes of disk space held by file
|
||||
ufs_atime :timespec; // time of last access
|
||||
ufs_mtime :timespec; // time of last data modification
|
||||
ufs_ctime :timespec; // time of last file status change
|
||||
ufs_btime :timespec; // time of file creation
|
||||
ufs_vnode :p_vnode;
|
||||
ufs_symlink:PChar;
|
||||
ufs_md_lock:t_sx;
|
||||
ufs_md_fp :Pointer; //host data
|
||||
end;
|
||||
|
||||
|
@ -181,6 +184,7 @@ begin
|
|||
if (System.InterlockedDecrement(p^.ufs_ref)=0) then
|
||||
begin
|
||||
md_free_dirent(p);
|
||||
sx_destroy(@p^.ufs_md_lock);
|
||||
FreeMem(p);
|
||||
Result:=True;
|
||||
end;
|
||||
|
@ -348,6 +352,9 @@ begin
|
|||
end;
|
||||
|
||||
function ufs_mount(mp:p_mount):Integer;
|
||||
label
|
||||
_err,
|
||||
_mount_err;
|
||||
var
|
||||
error:Integer;
|
||||
fmp:p_ufs_mount;
|
||||
|
@ -425,25 +432,26 @@ begin
|
|||
fmp^.ufs_vnops:=@md_vnodeops_host;
|
||||
|
||||
error:=md_mount(fmp);
|
||||
if (error<>0) then
|
||||
begin
|
||||
sx_xlock(@fmp^.ufs_lock);
|
||||
ufs_purge(fmp,fmp^.ufs_rootdir);
|
||||
sx_xunlock(@fmp^.ufs_lock);
|
||||
sx_destroy(@fmp^.ufs_lock);
|
||||
//free_unr(ufs_unr, fmp^.ufs_idx);
|
||||
FreeMem(fmp);
|
||||
Exit(error);
|
||||
end;
|
||||
if (error<>0) then goto _mount_err;
|
||||
|
||||
fmp^.ufs_rootdir:=md_vmkdir(fmp, nil, 0, nil, UFS_ROOTINO);
|
||||
fmp^.ufs_rootdir:=md_vmkdir(fmp, nil, 0, nil);
|
||||
end;
|
||||
|
||||
if (fmp^.ufs_rootdir=nil) then
|
||||
begin
|
||||
error:=EINVAL; //??
|
||||
goto _err;
|
||||
end;
|
||||
|
||||
error:=ufs_root(mp, LK_EXCLUSIVE, @rvp);
|
||||
if (error<>0) then
|
||||
begin
|
||||
_err:
|
||||
md_unmount(fmp);
|
||||
_mount_err:
|
||||
sx_xlock(@fmp^.ufs_lock);
|
||||
ufs_purge(fmp,fmp^.ufs_rootdir);
|
||||
sx_xunlock(@fmp^.ufs_lock);
|
||||
sx_destroy(@fmp^.ufs_lock);
|
||||
//free_unr(ufs_unr, fmp^.ufs_idx);
|
||||
FreeMem(fmp);
|
||||
|
|
|
@ -128,10 +128,10 @@ begin
|
|||
Exit(nil);
|
||||
|
||||
de:=TAILQ_FIRST(@de^.ufs_dlist); { '.' }
|
||||
if (de=nil) then Exit(nil);
|
||||
if (de=nil) then Exit(de^.ufs_dir);
|
||||
|
||||
de:=TAILQ_NEXT(de,@de^.ufs_list); { '..' }
|
||||
if (de=nil) then Exit(nil);
|
||||
if (de=nil) then Exit(de^.ufs_dir);
|
||||
|
||||
Exit(de^.ufs_dir);
|
||||
end;
|
||||
|
@ -161,6 +161,8 @@ begin
|
|||
de^.ufs_links :=1;
|
||||
de^.ufs_ref :=1;
|
||||
|
||||
TAILQ_INIT(@de^.ufs_dlist);
|
||||
|
||||
Exit(de);
|
||||
end;
|
||||
|
||||
|
@ -200,6 +202,7 @@ begin
|
|||
VI_LOCK(vp);
|
||||
mtx_unlock(ufs_interlock);
|
||||
vholdl(vp);
|
||||
|
||||
sx_unlock(@dm^.ufs_lock);
|
||||
|
||||
if ((flags and UFS_DEL_VNLOCKED)=0) then
|
||||
|
@ -229,10 +232,9 @@ begin
|
|||
de^.ufs_inode:=0;
|
||||
end;
|
||||
|
||||
ufs_de_drop(de);
|
||||
|
||||
if (dd<>nil) then
|
||||
begin
|
||||
TAILQ_REMOVE(@dd^.ufs_dlist,de,@de^.ufs_list);
|
||||
if ufs_de_drop(dd) then
|
||||
begin
|
||||
//
|
||||
|
@ -243,6 +245,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
ufs_de_drop(de);
|
||||
end;
|
||||
|
||||
function _ufs_dir_status(dm:p_ufs_mount;de:p_ufs_dirent):Integer;
|
||||
|
@ -293,13 +296,13 @@ begin
|
|||
de_dot:=TAILQ_FIRST(@de^.ufs_dlist);
|
||||
if (de_dot=nil) then
|
||||
begin
|
||||
//goto
|
||||
goto next;
|
||||
end;
|
||||
|
||||
de_dotdot:=TAILQ_NEXT(de_dot,@de_dot^.ufs_list);
|
||||
if (de_dotdot=nil) then
|
||||
begin
|
||||
//goto
|
||||
goto next;
|
||||
end;
|
||||
|
||||
{ Exit if the directory is not empty. }
|
||||
|
@ -310,19 +313,6 @@ begin
|
|||
|
||||
next:
|
||||
|
||||
if (de_dot<>nil) then
|
||||
begin
|
||||
TAILQ_REMOVE(@de^.ufs_dlist,de_dot,@de_dot^.ufs_list);
|
||||
end;
|
||||
if (de_dotdot<>nil) then
|
||||
begin
|
||||
TAILQ_REMOVE(@de^.ufs_dlist,de_dotdot,@de_dotdot^.ufs_list);
|
||||
end;
|
||||
if (dd<>nil) then
|
||||
begin
|
||||
TAILQ_REMOVE(@dd^.ufs_dlist,de,@de^.ufs_list);
|
||||
end;
|
||||
|
||||
ufs_de_hold(dd);
|
||||
ufs_delete(dm, de ,UFS_DEL_NORECURSE);
|
||||
ufs_delete(dm, de_dot ,UFS_DEL_NORECURSE);
|
||||
|
@ -337,12 +327,11 @@ begin
|
|||
sx_assert(@dm^.ufs_lock);
|
||||
|
||||
ufs_de_hold(dd);
|
||||
|
||||
repeat
|
||||
de:=TAILQ_LAST(@dd^.ufs_dlist);
|
||||
if (de=nil) then break;
|
||||
|
||||
TAILQ_REMOVE(@dd^.ufs_dlist,de,@de^.ufs_list);
|
||||
|
||||
if ((de^.ufs_flags and (UFS_DOT or UFS_DOTDOT))<>0) then
|
||||
ufs_delete(dm, de, UFS_DEL_NORECURSE)
|
||||
else
|
||||
|
@ -353,10 +342,10 @@ begin
|
|||
|
||||
until false;
|
||||
|
||||
ufs_de_drop(dd);
|
||||
|
||||
if ((dd^.ufs_flags and UFS_DOOMED)=0) then
|
||||
ufs_delete(dm, dd, UFS_DEL_NORECURSE);
|
||||
|
||||
ufs_de_drop(dd);
|
||||
end;
|
||||
|
||||
function ufs_vmkdir(dmp:p_ufs_mount;name:PChar;namelen:Integer;dotdot:p_ufs_dirent;inode:DWORD):p_ufs_dirent;
|
||||
|
@ -367,10 +356,8 @@ begin
|
|||
{ Create the new directory }
|
||||
nd:=ufs_newdirent(name, namelen);
|
||||
|
||||
TAILQ_INIT(@nd^.ufs_dlist);
|
||||
|
||||
nd^.ufs_dirent^.d_type:=DT_DIR;
|
||||
nd^.ufs_mode :=&0555;
|
||||
nd^.ufs_mode :=&0777;
|
||||
nd^.ufs_links:=2;
|
||||
nd^.ufs_dir :=nd;
|
||||
|
||||
|
@ -448,16 +435,14 @@ begin
|
|||
Exit(de);
|
||||
end;
|
||||
|
||||
function ufs_lookupx(ap:p_vop_lookup_args;dm_unlock:PInteger):Integer;
|
||||
function ufs_lookupx(ap:p_vop_lookup_args;dm_unlock:PBoolean):Integer;
|
||||
label
|
||||
_or;
|
||||
_error;
|
||||
var
|
||||
cnp:p_componentname;
|
||||
dvp:p_vnode;
|
||||
vpp:pp_vnode;
|
||||
de,dd:p_ufs_dirent;
|
||||
dde:p_ufs_dirent;
|
||||
dmp:p_ufs_mount;
|
||||
error,flags,nameiop,dvplocked:Integer;
|
||||
pname:PChar;
|
||||
begin
|
||||
|
@ -467,14 +452,11 @@ begin
|
|||
pname:=cnp^.cn_nameptr;
|
||||
flags:=cnp^.cn_flags;
|
||||
nameiop:=cnp^.cn_nameiop;
|
||||
dmp:=VFSTOUFS(dvp^.v_mount);
|
||||
dd:=dvp^.v_data;
|
||||
vpp^:=nil;
|
||||
|
||||
dm_unlock^:=0;
|
||||
|
||||
//if ((flags and ISLASTCN)<>0) and (nameiop=RENAME) then
|
||||
// Exit(EOPNOTSUPP);
|
||||
if ((flags and ISLASTCN)<>0) and (nameiop=RENAME) then
|
||||
Exit(EOPNOTSUPP);
|
||||
|
||||
if (dvp^.v_type<>VDIR) then
|
||||
Exit(ENOTDIR);
|
||||
|
@ -497,9 +479,6 @@ begin
|
|||
Exit(0);
|
||||
end;
|
||||
|
||||
dm_unlock^:=1;
|
||||
sx_xlock(@dmp^.ufs_lock);
|
||||
|
||||
if ((flags and ISDOTDOT)<>0) then
|
||||
begin
|
||||
if ((flags and ISLASTCN)<>0) and (nameiop<>LOOKUP) then
|
||||
|
@ -512,19 +491,19 @@ begin
|
|||
|
||||
dvplocked:=VOP_ISLOCKED(dvp);
|
||||
VOP_UNLOCK(dvp, 0);
|
||||
|
||||
error:=ufs_allocv(de, dvp^.v_mount, cnp^.cn_lkflags and LK_TYPE_MASK, vpp);
|
||||
dm_unlock^:=false;
|
||||
|
||||
vn_lock(dvp, dvplocked or LK_RETRY);
|
||||
|
||||
dm_unlock^:=0;
|
||||
Exit(error);
|
||||
end;
|
||||
|
||||
dd:=dvp^.v_data;
|
||||
de:=ufs_find(dd, cnp^.cn_nameptr, cnp^.cn_namelen, 0);
|
||||
while (de=nil) do
|
||||
begin { While(...) so we can use break }
|
||||
|
||||
if (de=nil) then
|
||||
begin
|
||||
Case nameiop of
|
||||
CREATE:
|
||||
begin
|
||||
|
@ -537,23 +516,12 @@ begin
|
|||
RENAME:Exit(ENOENT);
|
||||
else;
|
||||
end;
|
||||
{
|
||||
* OK, we didn't have an entry for the name we were asked for
|
||||
* so we try to see if anybody can create it on demand.
|
||||
}
|
||||
pname:=cnp^.cn_nameptr;
|
||||
|
||||
if (pname=nil) then
|
||||
break;
|
||||
|
||||
break;
|
||||
goto _error;
|
||||
end;
|
||||
|
||||
if (de=nil) then goto _or;
|
||||
|
||||
if ((de^.ufs_flags and UFS_WHITEOUT)<>0) then
|
||||
begin
|
||||
_or:
|
||||
_error:
|
||||
if ((nameiop=CREATE) or (nameiop=RENAME)) and
|
||||
((flags and (LOCKPARENT or WANTPARENT))<>0) and
|
||||
((flags and ISLASTCN)<>0) then
|
||||
|
@ -579,22 +547,24 @@ begin
|
|||
end;
|
||||
|
||||
error:=ufs_allocv(de, dvp^.v_mount, cnp^.cn_lkflags and LK_TYPE_MASK, vpp);
|
||||
dm_unlock^:=false;
|
||||
|
||||
dm_unlock^:=0;
|
||||
Exit(error);
|
||||
end;
|
||||
|
||||
function ufs_lookup(ap:p_vop_lookup_args):Integer;
|
||||
var
|
||||
dmp:p_ufs_mount;
|
||||
dm_unlock:Integer;
|
||||
dm_unlock:Boolean;
|
||||
begin
|
||||
dmp:=VFSTOUFS(ap^.a_dvp^.v_mount);
|
||||
dm_unlock:=1;
|
||||
|
||||
dm_unlock:=True;
|
||||
sx_xlock(@dmp^.ufs_lock);
|
||||
|
||||
Result:=ufs_lookupx(ap, @dm_unlock);
|
||||
|
||||
if (dm_unlock=1) then
|
||||
if (dm_unlock) then
|
||||
begin
|
||||
sx_xunlock(@dmp^.ufs_lock);
|
||||
end;
|
||||
|
@ -629,16 +599,9 @@ var
|
|||
vap:p_vattr;
|
||||
de:p_ufs_dirent;
|
||||
|
||||
procedure fix(var src,dst:timespec); inline;
|
||||
begin
|
||||
dst:=src;
|
||||
end;
|
||||
|
||||
begin
|
||||
vp:=ap^.a_vp;
|
||||
|
||||
vap:=ap^.a_vap;
|
||||
|
||||
de:=vp^.v_data;
|
||||
|
||||
vap^.va_uid :=de^.ufs_uid;
|
||||
|
@ -658,8 +621,8 @@ begin
|
|||
end;
|
||||
else
|
||||
begin
|
||||
vap^.va_size :=0;
|
||||
vap^.va_bytes:=0;
|
||||
vap^.va_size :=de^.ufs_size;
|
||||
vap^.va_bytes:=de^.ufs_bytes;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -805,12 +768,12 @@ begin
|
|||
mp:=ap^.a_vp^.v_mount;
|
||||
dmp:=VFSTOUFS(mp);
|
||||
|
||||
sx_xlock(@dmp^.ufs_lock);
|
||||
|
||||
error:=0;
|
||||
de:=ap^.a_vp^.v_data;
|
||||
off:=0;
|
||||
|
||||
sx_xlock(@dmp^.ufs_lock);
|
||||
|
||||
dd:=TAILQ_FIRST(@de^.ufs_dlist);
|
||||
while (dd<>nil) do
|
||||
begin
|
||||
|
@ -895,7 +858,7 @@ begin
|
|||
de^.ufs_flags:=UFS_USER;
|
||||
de^.ufs_uid :=0;
|
||||
de^.ufs_gid :=0;
|
||||
de^.ufs_mode :=&0755;
|
||||
de^.ufs_mode :=&0777;
|
||||
de^.ufs_inode:=ufs_alloc_cdp_inode;
|
||||
de^.ufs_dir :=dd;
|
||||
de^.ufs_dirent^.d_type:=DT_LNK;
|
||||
|
@ -906,7 +869,7 @@ begin
|
|||
|
||||
TAILQ_INSERT_TAIL(@dd^.ufs_dlist,de,@de^.ufs_list);
|
||||
|
||||
Exit(ufs_allocv(de, ap^.a_dvp^.v_mount, LK_EXCLUSIVE, ap^.a_vpp));
|
||||
Exit(ufs_allocv(de, ap^.a_dvp^.v_mount, LK_EXCLUSIVE, ap^.a_vpp)); //sx_xunlock
|
||||
end;
|
||||
|
||||
function ufs_remove(ap:p_vop_remove_args):Integer;
|
||||
|
@ -937,8 +900,6 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
TAILQ_REMOVE(@dd^.ufs_dlist,de,@de^.ufs_list);
|
||||
|
||||
if (de^.ufs_dirent^.d_type=DT_LNK) then
|
||||
begin
|
||||
de_cov:=ufs_find(dd, de^.ufs_dirent^.d_name, de^.ufs_dirent^.d_namlen, 0);
|
||||
|
@ -994,8 +955,6 @@ begin
|
|||
Exit;
|
||||
end;
|
||||
|
||||
TAILQ_REMOVE(@dd^.ufs_dlist,de,@de^.ufs_list);
|
||||
|
||||
VOP_UNLOCK(vp, 0);
|
||||
|
||||
if (dvp<>vp) then
|
||||
|
@ -1046,7 +1005,7 @@ begin
|
|||
|
||||
de^.ufs_mode :=vap^.va_mode;
|
||||
|
||||
Exit(ufs_allocv(de, ap^.a_dvp^.v_mount, LK_EXCLUSIVE, ap^.a_vpp));
|
||||
Exit(ufs_allocv(de, ap^.a_dvp^.v_mount, LK_EXCLUSIVE, ap^.a_vpp)); //sx_xunlock
|
||||
end;
|
||||
|
||||
function ufs_reclaim(ap:p_vop_reclaim_args):Integer;
|
||||
|
|
|
@ -281,7 +281,7 @@ begin
|
|||
'.',
|
||||
'..':
|
||||
begin
|
||||
Writeln(Space(s),namep,' |');
|
||||
Writeln(Space(s),namep:20,' |');
|
||||
Exit;
|
||||
end;
|
||||
else;
|
||||
|
@ -289,19 +289,12 @@ begin
|
|||
|
||||
err:=sys_lstat(PChar(dirp+namep),@sb);
|
||||
|
||||
//if (err=45) then
|
||||
//begin
|
||||
// sb.st_size:=512;
|
||||
// sb.st_mode:=S_IFMT;
|
||||
// goto _next;
|
||||
//end;
|
||||
|
||||
if (err<>0) then
|
||||
begin
|
||||
Writeln(Space(s),namep,' | (',err,')');
|
||||
Writeln(Space(s),namep:20,' | (',err,')');
|
||||
end else
|
||||
begin
|
||||
Write(Space(s),namep,' | ',ts_to_str(sb.st_birthtim {st_mtim}),' |');
|
||||
Write(Space(s),namep:20,' | ',ts_to_str(sb.st_birthtim {st_mtim}):19,' |');
|
||||
_next:
|
||||
|
||||
if ((sb.st_mode and S_IFDIR)<>0) then
|
||||
|
|
|
@ -2413,11 +2413,13 @@ begin
|
|||
error:=getvnode(fd, CAP_FSYNC, @fp);
|
||||
if (error<>0) then
|
||||
Exit(error);
|
||||
|
||||
vp:=fp^.f_vnode;
|
||||
vfslocked:=VFS_LOCK_GIANT(vp^.v_mount);
|
||||
error:=vn_start_write(vp, @mp, V_WAIT or PCATCH);
|
||||
if (error<>0) then
|
||||
goto drop;
|
||||
|
||||
if MNT_SHARED_WRITES(mp) or
|
||||
((mp=nil) and MNT_SHARED_WRITES(vp^.v_mount)) then
|
||||
begin
|
||||
|
|
|
@ -277,26 +277,26 @@ type
|
|||
|
||||
p_vattr=^t_vattr;
|
||||
t_vattr=record
|
||||
va_type :vtype;
|
||||
va_mode :SmallInt;
|
||||
va_nlink :SmallInt;
|
||||
va_uid :Integer;
|
||||
va_gid :Integer;
|
||||
va_fsid :Int64;
|
||||
va_fileid :Integer;
|
||||
va_size :Int64;
|
||||
va_blocksize:Integer;
|
||||
va_atime :timespec;
|
||||
va_mtime :timespec;
|
||||
va_ctime :timespec;
|
||||
va_birthtime:timespec;
|
||||
va_gen :Integer;
|
||||
va_flags :Integer;
|
||||
va_rdev :Integer;
|
||||
va_bytes :Int64;
|
||||
va_filerev :Int64;
|
||||
va_vaflags :Integer;
|
||||
va_spare :Integer;
|
||||
va_type :vtype; // vnode type (for create)
|
||||
va_mode :SmallInt; // files access mode and type
|
||||
va_nlink :SmallInt; // number of references to file
|
||||
va_uid :Integer; // owner user id
|
||||
va_gid :Integer; // owner group id
|
||||
va_fsid :Int64; // filesystem id
|
||||
va_fileid :Integer; // file id
|
||||
va_size :Int64; // file size in bytes
|
||||
va_blocksize:Integer; // blocksize preferred for i/o
|
||||
va_atime :timespec; // time of last access
|
||||
va_mtime :timespec; // time of last modification
|
||||
va_ctime :timespec; // time file changed
|
||||
va_birthtime:timespec; // time file created
|
||||
va_gen :Integer; // generation number of file
|
||||
va_flags :Integer; // flags defined for file
|
||||
va_rdev :Integer; // device the special file represents
|
||||
va_bytes :Int64; // bytes of disk space held by file
|
||||
va_filerev :Int64; // file modification number
|
||||
va_vaflags :Integer; // operations flags, see below
|
||||
va_spare :Integer; // remain quad aligned
|
||||
end;
|
||||
|
||||
const
|
||||
|
|
Loading…
Reference in New Issue