diff --git a/rtl/ntapi.pas b/rtl/ntapi.pas index 5cd1b8ed..51a66885 100644 --- a/rtl/ntapi.pas +++ b/rtl/ntapi.pas @@ -32,6 +32,7 @@ const STATUS_OBJECT_NAME_NOT_FOUND =$C0000034; //ENOENT STATUS_OBJECT_NAME_COLLISION =$C0000035; //EEXIST STATUS_OBJECT_PATH_NOT_FOUND =$C000003A; //ENOENT + STATUS_OBJECT_PATH_SYNTAX_BAD =$C000003B; //ENOTDIR STATUS_SHARING_VIOLATION =$C0000043; //EACCES STATUS_FILE_LOCK_CONFLICT =$C0000054; //EWOULDBLOCK STATUS_LOCK_NOT_GRANTED =$C0000055; //EWOULDBLOCK diff --git a/sys/fs/ufs/ufs.pas b/sys/fs/ufs/ufs.pas index 44265694..0af1ac27 100644 --- a/sys/fs/ufs/ufs.pas +++ b/sys/fs/ufs/ufs.pas @@ -219,7 +219,9 @@ var begin not_found:=0; if ((de^.ufs_flags and UFS_DOOMED)<>0) then + begin not_found:=1; + end; ufs_de_drop(de); @@ -230,7 +232,9 @@ begin end; if (not_found=1) or ((drop_lock<>0) and (not_found<>2)) then + begin sx_unlock(@dmp^.ufs_lock); + end; Exit(not_found); end; @@ -377,7 +381,9 @@ begin error:=ufs_allocv(dmp^.ufs_rootdir, mp, LK_EXCLUSIVE, @vp); if (error<>0) then + begin Exit(error); + end; vp^.v_vflag:=vp^.v_vflag or VV_ROOT; vpp^:=vp; @@ -515,7 +521,9 @@ begin error:=vflush(mp, 1, flags); if (error<>0) then + begin Exit(error); + end; sx_xlock(@fmp^.ufs_lock); diff --git a/sys/fs/ufs/ufs_vnops.pas b/sys/fs/ufs/ufs_vnops.pas index 8dfaabe2..3b1a00bb 100644 --- a/sys/fs/ufs/ufs_vnops.pas +++ b/sys/fs/ufs/ufs_vnops.pas @@ -248,7 +248,9 @@ begin if (de^.ufs_dirent^.d_type<>DT_DIR) then Exit(ENOTDIR); if ((de^.ufs_flags and UFS_DOOMED)<>0) or (de=dm^.ufs_rootdir) then + begin Exit(EBUSY); + end; de_dot:=TAILQ_FIRST(@de^.ufs_dlist); Assert(de_dot<>nil, 'ufs_rmdir: . missing'); @@ -258,7 +260,9 @@ begin { Exit if the directory is not empty. } if (TAILQ_NEXT(de_dotdot,@de_dotdot^.ufs_list)<>nil) then + begin Exit(ENOTEMPTY); + end; end; function _ufs_rmdir(dm:p_ufs_mount;de:p_ufs_dirent):Integer; @@ -275,7 +279,9 @@ begin Assert(de^.ufs_dirent^.d_type=DT_DIR,'ufs_rmdir: de is not a directory'); if ((de^.ufs_flags and UFS_DOOMED)<>0) or (de=dm^.ufs_rootdir) then + begin Exit(EBUSY); + end; dd :=nil; de_dot :=nil; @@ -295,7 +301,9 @@ begin { Exit if the directory is not empty. } if (TAILQ_NEXT(de_dotdot,@de_dotdot^.ufs_list)<>nil) then + begin Exit(ENOTEMPTY); + end; dd:=ufs_parent_dirent(de); @@ -439,22 +447,32 @@ begin vpp^:=nil; if ((flags and ISLASTCN)<>0) and (nameiop=RENAME) then + begin Exit(EOPNOTSUPP); + end; if (dvp^.v_type<>VDIR) then + begin Exit(ENOTDIR); + end; if (((flags and ISDOTDOT)<>0) and ((dvp^.v_vflag and VV_ROOT)<>0)) then + begin Exit(EIO); + end; error:=VOP_ACCESS(dvp, VEXEC); if (error<>0) then + begin Exit(error); + end; if (cnp^.cn_namelen=1) and (pname^='.') then begin if ((flags and ISLASTCN) and nameiop<>LOOKUP) then + begin Exit(EINVAL); + end; vpp^:=dvp; VREF(dvp); @@ -465,7 +483,9 @@ begin if ((flags and ISDOTDOT)<>0) then begin if ((flags and ISLASTCN)<>0) and (nameiop<>LOOKUP) then + begin Exit(EINVAL); + end; de:=ufs_parent_dirent(dd); @@ -506,7 +526,9 @@ begin begin error:=VOP_ACCESS(dvp, VWRITE); if (error<>0) then + begin Exit(error); + end; if (vpp^=dvp) then begin @@ -558,7 +580,9 @@ begin end; if (error<>EACCES) then + begin Exit(error); + end; if ((p_proc.p_flag and P_CONTROLT)=0) then begin @@ -735,11 +759,15 @@ begin tmp_ncookies:=nil; if (ap^.a_vp^.v_type<>VDIR) then + begin Exit(ENOTDIR); + end; uio:=ap^.a_uio; if (uio^.uio_offset < 0) then + begin Exit(EINVAL); + end; if (ap^.a_ncookies<>nil) then begin @@ -792,7 +820,9 @@ end; function ufs_rread(ap:p_vop_read_args):Integer; begin if (ap^.a_vp^.v_type<>VDIR) then + begin Exit(EINVAL); + end; Exit(VOP_READDIR(ap^.a_vp, ap^.a_uio, nil, nil, nil)); end; diff --git a/sys/kern/kern_dynlib.pas b/sys/kern/kern_dynlib.pas index d5778aba..042dde3e 100644 --- a/sys/kern/kern_dynlib.pas +++ b/sys/kern/kern_dynlib.pas @@ -212,6 +212,8 @@ begin Result:=copyinstr(moduleFileName,@fname,sizeof(fname),@len); if (Result<>0) then Exit; + Writeln('sys_dynlib_load_prx:',fname); + dynlibs_lock; obj:=nil; diff --git a/sys/md/md_vnops.pas b/sys/md/md_vnops.pas index cd8f6b8e..10729c90 100644 --- a/sys/md/md_vnops.pas +++ b/sys/md/md_vnops.pas @@ -203,6 +203,7 @@ begin STATUS_OBJECT_NAME_NOT_FOUND :Result:=ENOENT; STATUS_OBJECT_NAME_COLLISION :Result:=EEXIST; STATUS_OBJECT_PATH_NOT_FOUND :Result:=ENOENT; + STATUS_OBJECT_PATH_SYNTAX_BAD:Result:=ENOTDIR; STATUS_SHARING_VIOLATION :Result:=EACCES; STATUS_FILE_LOCK_CONFLICT :Result:=EWOULDBLOCK; STATUS_LOCK_NOT_GRANTED :Result:=EWOULDBLOCK; @@ -419,8 +420,15 @@ end; function md_free_dirent(de:p_ufs_dirent):Integer; var + s:Pointer; fd:THandle; begin + s:=System.InterlockedExchange(de^.ufs_symlink,nil); + if (s<>nil) then + begin + FreeMem(s); + end; + if ((de^.ufs_flags and UFS_DROOT)=0) then //if not root dir begin fd:=THandle(System.InterlockedExchange(de^.ufs_md_fp,nil)); @@ -442,6 +450,8 @@ var begin w:=_UTF8Decode(@de^.ufs_dirent^.d_name,de^.ufs_dirent^.d_namlen); + Assert(de^.ufs_dir^.ufs_md_fp<>nil); + OBJ:=Default(TOBJ_ATTR); INIT_OBJ(OBJ,THandle(de^.ufs_dir^.ufs_md_fp),0,PWideChar(w)); BLK:=Default(IO_STATUS_BLOCK); @@ -473,6 +483,8 @@ var begin w:=_UTF8Decode(@de^.ufs_dirent^.d_name,de^.ufs_dirent^.d_namlen); + Assert(de^.ufs_dir^.ufs_md_fp<>nil); + OBJ:=Default(TOBJ_ATTR); INIT_OBJ(OBJ,THandle(de^.ufs_dir^.ufs_md_fp),0,PWideChar(w)); BLK:=Default(IO_STATUS_BLOCK); @@ -509,18 +521,14 @@ begin fdr^:=F; end; -function md_find_rel_mount_path(var src:PWideChar;var len:SizeInt):Integer; +function md_find_rel_mount_path(first:p_mount;var src:PWideChar;var len:SizeInt):Integer; var mp:p_mount; W:WideString; -begin - Result:=ERESTART; - mtx_lock(mountlist_mtx); - mp:=TAILQ_FIRST(@mountlist); - while (mp<>nil) do + function compare(mp:p_mount):Boolean; begin - + Result:=False; if (mp^.mnt_vfc=@ufs_vfsconf) then //current fstype if ((mp^.mnt_flag and MNT_ROOTFS)=0) then //host mount begin @@ -542,11 +550,33 @@ begin Inc(src,Length(W)); Dec(len,Length(W)); - Result:=0; - Break; + Result:=True; end; //cmp end; //len end; + end; + +begin + Result:=ERESTART; + mtx_lock(mountlist_mtx); + + if (first<>nil) then + if compare(first) then + begin + mtx_unlock(mountlist_mtx); + Exit(0); + end; + + mp:=TAILQ_FIRST(@mountlist); + while (mp<>nil) do + begin + + if (first<>mp) then + if compare(mp) then + begin + Result:=0; + Break; + end; mp:=TAILQ_NEXT(mp,@mp^.mnt_list); end; @@ -566,6 +596,8 @@ var nt_abs:Boolean; R:DWORD; + + mp:p_mount; begin if (de^.ufs_dirent^.d_type<>DT_LNK) then Exit(EINVAL); @@ -628,8 +660,15 @@ begin if nt_abs then begin + mp:=nil; + + if (de^.ufs_vnode<>nil) then + begin + mp:=de^.ufs_vnode^.v_mount; + end; + //find by mount points - Result:=md_find_rel_mount_path(P,len); + Result:=md_find_rel_mount_path(mp,P,len); if (Result<>0) then Exit; end; @@ -961,14 +1000,16 @@ begin end; procedure md_unlink_cache(de:p_ufs_dirent); +label + _start; var dd:p_ufs_dirent; notlocked:Boolean; + fparent:Boolean; begin if (de=nil) then Exit; - //clear fd - md_free_dirent(de); + _start: dd:=System.InterlockedExchange(de^.ufs_dir,nil); //parent @@ -989,18 +1030,22 @@ begin sx_xlock(@dd^.ufs_md_lock); end; TAILQ_REMOVE(@dd^.ufs_dlist,de,@de^.ufs_list); + fparent:=TAILQ_EMPTY(@dd^.ufs_dlist) and (dd^.ufs_dir<>nil); if notlocked then begin sx_unlock(@dd^.ufs_md_lock); end; ufs_de_drop(dd); //prev hold ufs_de_drop(dd); //list hold + if fparent then + begin + de:=dd; + goto _start; + end; end; end; procedure md_delete_cache(de:p_ufs_dirent); -var - s:Pointer; begin if (de=nil) then Exit; @@ -1011,12 +1056,6 @@ begin md_unlink_cache(de); - s:=System.InterlockedExchange(de^.ufs_symlink,nil); - if (s<>nil) then - begin - FreeMem(s); - end; - ufs_de_drop(de); end; @@ -1036,6 +1075,7 @@ begin begin md_delete_cache(de); end; + vrecycle(vp); end; Exit(0); @@ -1079,19 +1119,27 @@ begin vpp^:=nil; if (dvp^.v_type<>VDIR) then + begin Exit(ENOTDIR); + end; if (((flags and ISDOTDOT)<>0) and ((dvp^.v_vflag and VV_ROOT)<>0)) then + begin Exit(EIO); + end; error:=VOP_ACCESS(dvp, VEXEC); if (error<>0) then + begin Exit(error); + end; if (cnp^.cn_namelen=1) and (pname^='.') then begin if ((flags and ISLASTCN) and nameiop<>LOOKUP) then + begin Exit(EINVAL); + end; vpp^:=dvp; VREF(dvp); @@ -1130,7 +1178,9 @@ begin begin error:=VOP_ACCESS(dvp, VWRITE); if (error<>0) then + begin Exit(error); + end; if (vpp^=dvp) then begin @@ -1173,11 +1223,15 @@ var restart:Boolean; begin if (ap^.a_vp^.v_type<>VDIR) then + begin Exit(ENOTDIR); + end; uio:=ap^.a_uio; if (uio^.uio_offset < 0) then + begin Exit(EINVAL); + end; dd:=ap^.a_vp^.v_data; off:=0; diff --git a/sys/test/kern_jit_dynamic.pas b/sys/test/kern_jit_dynamic.pas index 9f595e99..74dbdf12 100644 --- a/sys/test/kern_jit_dynamic.pas +++ b/sys/test/kern_jit_dynamic.pas @@ -208,8 +208,11 @@ var jctx:p_jctx; begin jctx:=td^.td_jctx; - jctx^.cblob^.dec_ref; - jctx^.cblob:=nil; + if (jctx^.cblob<>nil) then + begin + jctx^.cblob^.dec_ref; + jctx^.cblob:=nil; + end; end; procedure switch_to_jit(td:p_kthread); public;