mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
0b73576b10
commit
d1c2fb94be
|
@ -50,6 +50,8 @@ function md_rename(ap:p_vop_rename_args):Integer;
|
|||
function md_create(ap:p_vop_create_args):Integer;
|
||||
function md_open(ap:p_vop_open_args):Integer;
|
||||
function md_close(ap:p_vop_close_args):Integer;
|
||||
function md_fsync(ap:p_vop_fsync_args):Integer;
|
||||
function md_setattr(ap:p_vop_setattr_args):Integer;
|
||||
|
||||
const
|
||||
md_vnodeops_host:vop_vector=(
|
||||
|
@ -66,7 +68,7 @@ const
|
|||
vop_access :nil; //parent
|
||||
vop_accessx :nil;
|
||||
vop_getattr :@md_getattr;
|
||||
vop_setattr :@ufs_setattr;
|
||||
vop_setattr :@md_setattr;
|
||||
vop_markatime :nil;
|
||||
vop_read :nil; //parent
|
||||
vop_write :nil;
|
||||
|
@ -74,7 +76,7 @@ const
|
|||
vop_poll :nil;
|
||||
vop_kqfilter :nil;
|
||||
vop_revoke :nil;
|
||||
vop_fsync :nil; //TODO
|
||||
vop_fsync :@md_fsync;
|
||||
vop_remove :@md_remove;
|
||||
vop_link :@md_link;
|
||||
vop_rename :@md_rename;
|
||||
|
@ -210,13 +212,19 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function get_unix_file_time(time:LARGE_INTEGER):timespec;
|
||||
function get_unix_file_time(time:LARGE_INTEGER):timespec; inline;
|
||||
begin
|
||||
Int64(time):=Int64(time)-DELTA_EPOCH_IN_UNIT;
|
||||
Result.tv_sec :=(Int64(time) div UNIT_PER_SEC);
|
||||
Result.tv_nsec:=(Int64(time) mod UNIT_PER_SEC)*100;
|
||||
end;
|
||||
|
||||
function get_win_file_time(time:timespec):LARGE_INTEGER; inline;
|
||||
begin
|
||||
Int64(Result):=(time.tv_sec*UNIT_PER_SEC)+(time.tv_nsec div 100);
|
||||
Int64(Result):=Int64(Result)+DELTA_EPOCH_IN_UNIT;
|
||||
end;
|
||||
|
||||
function NT_FA_TO_DT(a,e:ULONG):Byte;
|
||||
begin
|
||||
if ((a and FILE_ATTRIBUTE_REPARSE_POINT)<>0) and
|
||||
|
@ -1767,7 +1775,7 @@ begin
|
|||
end else
|
||||
if ((flags and O_TRUNC)<>0) then
|
||||
begin
|
||||
Result:=FILE_OVERWRITE;
|
||||
Result:=FILE_OVERWRITE_IF;
|
||||
end else
|
||||
begin
|
||||
Result:=FILE_OPEN_IF;
|
||||
|
@ -1775,7 +1783,7 @@ begin
|
|||
end else
|
||||
if ((flags and O_TRUNC)<>0) then
|
||||
begin
|
||||
Result:=FILE_OVERWRITE_IF;
|
||||
Result:=FILE_OVERWRITE;
|
||||
end else
|
||||
begin
|
||||
Result:=FILE_OPEN;
|
||||
|
@ -1886,7 +1894,6 @@ begin
|
|||
begin
|
||||
md_unlink_cache(de);
|
||||
sx_xunlock(@dd^.ufs_md_lock);
|
||||
NtClose(FD);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
|
@ -1935,6 +1942,245 @@ begin
|
|||
Result:=0;
|
||||
end;
|
||||
|
||||
function md_fsync(ap:p_vop_fsync_args):Integer;
|
||||
var
|
||||
vp:p_vnode;
|
||||
FD:THandle;
|
||||
fullsync:Boolean;
|
||||
|
||||
BLK:IO_STATUS_BLOCK;
|
||||
begin
|
||||
vp:=ap^.a_vp;
|
||||
FD:=THandle(vp^.v_un);
|
||||
fullsync:=((ap^.a_waitfor and 2)<>0);
|
||||
|
||||
if (FD=0) then Exit(EINVAL);
|
||||
|
||||
BLK:=Default(IO_STATUS_BLOCK);
|
||||
|
||||
//result doesn't matter
|
||||
NtFlushBuffersFile(FD,@BLK);
|
||||
|
||||
if fullsync then
|
||||
begin
|
||||
//atime
|
||||
//mtime
|
||||
end;
|
||||
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function md_setattr(ap:p_vop_setattr_args):Integer;
|
||||
label
|
||||
_err;
|
||||
var
|
||||
de:p_ufs_dirent;
|
||||
vap:p_vattr;
|
||||
vp:p_vnode;
|
||||
error:Integer;
|
||||
uid:uid_t;
|
||||
gid:gid_t;
|
||||
|
||||
change_time,change_size:Boolean;
|
||||
|
||||
FD,RL:THandle;
|
||||
|
||||
FBI:FILE_BASIC_INFORMATION;
|
||||
BLK:IO_STATUS_BLOCK;
|
||||
SIZE:Int64;
|
||||
R:DWORD;
|
||||
|
||||
procedure _settime(var dst:LARGE_INTEGER;var src:timespec); inline;
|
||||
begin
|
||||
if (src.tv_sec<>-1) and (src.tv_nsec<>-1) then
|
||||
begin
|
||||
dst:=get_win_file_time(src);
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
vap:=ap^.a_vap;
|
||||
vp:=ap^.a_vp;
|
||||
|
||||
if (vap^.va_type <>VNON) or
|
||||
(vap^.va_nlink <>VNOVAL) or
|
||||
(vap^.va_fsid <>VNOVAL) or
|
||||
(vap^.va_fileid <>VNOVAL) or
|
||||
(vap^.va_blocksize<>VNOVAL) or
|
||||
((vap^.va_flags <>VNOVAL) and (vap^.va_flags<>0)) or
|
||||
(vap^.va_rdev <>VNOVAL) or
|
||||
(vap^.va_bytes <>VNOVAL) or
|
||||
(vap^.va_gen <>VNOVAL) then
|
||||
begin
|
||||
Exit(EINVAL);
|
||||
end;
|
||||
|
||||
de:=vp^.v_data;
|
||||
|
||||
error:=0;
|
||||
change_time:=False;
|
||||
change_size:=False;
|
||||
|
||||
if (vap^.va_uid=VNOVAL) then
|
||||
uid:=de^.ufs_uid
|
||||
else
|
||||
uid:=vap^.va_uid;
|
||||
|
||||
if (vap^.va_gid=VNOVAL) then
|
||||
gid:=de^.ufs_gid
|
||||
else
|
||||
gid:=vap^.va_gid;
|
||||
|
||||
if (uid<>de^.ufs_uid) or (gid<>de^.ufs_gid) then
|
||||
begin
|
||||
//if ((ap^.a_cred^.cr_uid<>de^.de_uid) or uid<>de^.de_uid or
|
||||
// (gid<>de^.de_gid and !groupmember(gid, ap^.a_cred))) then
|
||||
//begin
|
||||
// error:=priv_check(td, PRIV_VFS_CHOWN);
|
||||
// if (error<>) then
|
||||
// Exit(error);
|
||||
//end;
|
||||
de^.ufs_uid:=uid;
|
||||
de^.ufs_gid:=gid;
|
||||
end;
|
||||
|
||||
if (vap^.va_mode<>VNOVAL) then
|
||||
begin
|
||||
//if (ap^.a_cred^.cr_uid<>de^.de_uid) then
|
||||
//begin
|
||||
// error:=priv_check(td, PRIV_VFS_ADMIN);
|
||||
// if (error<>0) then
|
||||
// Exit(error);
|
||||
//end;
|
||||
de^.ufs_mode:=vap^.va_mode;
|
||||
end;
|
||||
|
||||
if (vap^.va_atime.tv_sec<>VNOVAL) or
|
||||
(vap^.va_mtime.tv_sec<>VNOVAL) or
|
||||
(vap^.va_birthtime.tv_sec<>VNOVAL) then
|
||||
begin
|
||||
{ See the comment in ufs_vnops::ufs_setattr(). }
|
||||
|
||||
error:=VOP_ACCESS(vp, VADMIN);
|
||||
if (error<>0) then
|
||||
begin
|
||||
if ((vap^.va_vaflags and VA_UTIMES_NULL)=0) then Exit(error);
|
||||
error:=VOP_ACCESS(vp, VWRITE);
|
||||
if (error<>0) then Exit(error);
|
||||
end;
|
||||
|
||||
if (vap^.va_atime.tv_sec<>VNOVAL) then
|
||||
begin
|
||||
de^.ufs_atime:=vap^.va_atime;
|
||||
end;
|
||||
if (vap^.va_mtime.tv_sec<>VNOVAL) then
|
||||
begin
|
||||
de^.ufs_mtime:=vap^.va_mtime;
|
||||
end;
|
||||
if (vap^.va_birthtime.tv_sec<>VNOVAL) then
|
||||
begin
|
||||
de^.ufs_btime:=vap^.va_birthtime;
|
||||
end;
|
||||
|
||||
change_time:=True;
|
||||
end;
|
||||
|
||||
if (vap^.va_size<>VNOVAL) then
|
||||
begin
|
||||
change_size:=True;
|
||||
end;
|
||||
|
||||
if change_time or change_size then
|
||||
begin
|
||||
|
||||
if (vp^.v_un<>nil) then
|
||||
begin
|
||||
FD:=THandle(vp^.v_un);
|
||||
RL:=0;
|
||||
end else
|
||||
if (de^.ufs_md_fp<>nil) then
|
||||
begin
|
||||
FD:=THandle(de^.ufs_md_fp);
|
||||
RL:=0;
|
||||
end else
|
||||
begin
|
||||
Result:=md_open_dirent_file(de,True,@FD);
|
||||
if (Result<>0) then Exit;
|
||||
RL:=FD;
|
||||
end;
|
||||
|
||||
if change_time then
|
||||
begin
|
||||
BLK:=Default(IO_STATUS_BLOCK);
|
||||
|
||||
R:=NtQueryInformationFile(
|
||||
FD,
|
||||
@BLK,
|
||||
@FBI,
|
||||
SizeOf(FBI),
|
||||
FileBasicInformation);
|
||||
|
||||
Result:=ntf2px(R);
|
||||
if (Result<>0) then goto _err;
|
||||
|
||||
//update
|
||||
de^.ufs_ctime:=get_unix_file_time(FBI.ChangeTime);
|
||||
|
||||
_settime(FBI.LastAccessTime,de^.ufs_atime);
|
||||
_settime(FBI.LastWriteTime ,de^.ufs_mtime);
|
||||
_settime(FBI.CreationTime ,de^.ufs_btime);
|
||||
|
||||
BLK:=Default(IO_STATUS_BLOCK);
|
||||
|
||||
R:=NtSetInformationFile(
|
||||
FD,
|
||||
@BLK,
|
||||
@FBI,
|
||||
SizeOf(FBI),
|
||||
FileBasicInformation);
|
||||
|
||||
Result:=ntf2px(R);
|
||||
if (Result<>0) then goto _err;
|
||||
end;
|
||||
|
||||
if change_size then
|
||||
begin
|
||||
SIZE:=vap^.va_size;
|
||||
|
||||
R:=NtSetInformationFile(
|
||||
FD,
|
||||
@BLK,
|
||||
@SIZE,
|
||||
SizeOf(Int64),
|
||||
FileEndOfFileInformation);
|
||||
|
||||
if (R<>0) then
|
||||
begin
|
||||
R:=NtSetInformationFile(
|
||||
FD,
|
||||
@BLK,
|
||||
@SIZE,
|
||||
SizeOf(Int64),
|
||||
FileAllocationInformation);
|
||||
end;
|
||||
|
||||
Result:=ntf2px(R);
|
||||
if (Result<>0) then goto _err;
|
||||
|
||||
de^.ufs_size:=SIZE;
|
||||
end;
|
||||
|
||||
_err:
|
||||
if (RL<>0) then
|
||||
begin
|
||||
NtClose(RL);
|
||||
end;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
@ -682,6 +682,7 @@ begin
|
|||
(vap^.va_birthtime.tv_sec<>VNOVAL) then
|
||||
begin
|
||||
{ See the comment in ufs_vnops::ufs_setattr(). }
|
||||
|
||||
error:=VOP_ACCESS(vp, VADMIN);
|
||||
if (error<>0) then
|
||||
begin
|
||||
|
@ -689,6 +690,7 @@ begin
|
|||
error:=VOP_ACCESS(vp, VWRITE);
|
||||
if (error<>0) then Exit(error);
|
||||
end;
|
||||
|
||||
if (vap^.va_atime.tv_sec<>VNOVAL) then
|
||||
begin
|
||||
de^.ufs_atime:=vap^.va_atime;
|
||||
|
|
|
@ -273,11 +273,14 @@ var
|
|||
begin
|
||||
td:=curkthread;
|
||||
|
||||
Writeln('sys_open=',sys_open('/app0/test.txt',O_RDWR or O_CREAT,&777));
|
||||
Writeln('sys_open=',sys_open('/app0/test.txt',O_RDWR or O_CREAT or O_TRUNC,&777));
|
||||
fd_1:=td^.td_retval[0];
|
||||
|
||||
Writeln('sys_fstatfs=',sys_fstatfs(fd_1,@fs));
|
||||
|
||||
Writeln('sys_fsync=',sys_fsync(fd_1));
|
||||
Writeln('sys_fdatasync=',sys_fdatasync(fd_1));
|
||||
|
||||
Writeln('sys_open=',sys_open('/app0/test.txt',O_RDWR or O_CREAT,&777));
|
||||
fd_2:=td^.td_retval[0];
|
||||
|
||||
|
|
|
@ -2422,15 +2422,12 @@ function kern_fsync(fd:Integer;fullsync:Boolean):Integer;
|
|||
label
|
||||
drop;
|
||||
var
|
||||
td:p_kthread;
|
||||
vp:p_vnode;
|
||||
mp:p_mount;
|
||||
fp:p_file;
|
||||
vfslocked:Integer;
|
||||
error,lock_flags:Integer;
|
||||
begin
|
||||
td:=curkthread;
|
||||
|
||||
error:=getvnode(fd, CAP_FSYNC, @fp);
|
||||
if (error<>0) then Exit(error);
|
||||
|
||||
|
@ -2449,17 +2446,13 @@ begin
|
|||
end;
|
||||
vn_lock(vp, lock_flags or LK_RETRY);
|
||||
|
||||
td^.td_fpop:=fp;
|
||||
|
||||
//if (vp^.v_object<>nil) then
|
||||
//begin
|
||||
// VM_OBJECT_LOCK(vp^.v_object);
|
||||
// vm_object_page_clean(vp^.v_object, 0, 0, 0);
|
||||
// VM_OBJECT_UNLOCK(vp^.v_object);
|
||||
//end;
|
||||
error:=VOP_FSYNC(vp, MNT_WAIT);
|
||||
|
||||
td^.td_fpop:=nil;
|
||||
error:=VOP_FSYNC(vp, MNT_WAIT or ((ord(fullsync) and 1) shl 1));
|
||||
|
||||
VOP_UNLOCK(vp, 0);
|
||||
vn_finished_write(mp);
|
||||
|
|
Loading…
Reference in New Issue