@@ -3,7 +3,7 @@ use crate::Test;
3
3
use io_uring:: { cqueue, opcode, squeue, types, IoUring } ;
4
4
use std:: ffi:: CString ;
5
5
use std:: fs;
6
- use std:: io:: Write ;
6
+ use std:: io:: { Read , Write } ;
7
7
use std:: os:: unix:: ffi:: OsStrExt ;
8
8
use std:: os:: unix:: io:: { AsRawFd , FromRawFd , IntoRawFd } ;
9
9
@@ -810,3 +810,130 @@ pub fn test_file_splice<S: squeue::EntryMarker, C: cqueue::EntryMarker>(
810
810
811
811
Ok ( ( ) )
812
812
}
813
+
814
+ pub fn test_ftruncate < S : squeue:: EntryMarker , C : cqueue:: EntryMarker > (
815
+ ring : & mut IoUring < S , C > ,
816
+ test : & Test ,
817
+ ) -> anyhow:: Result < ( ) > {
818
+ require ! (
819
+ test;
820
+ test. probe. is_supported( opcode:: Ftruncate :: CODE ) ;
821
+ ) ;
822
+
823
+ println ! ( "test ftruncate" ) ;
824
+
825
+ let dir = tempfile:: TempDir :: new_in ( "." ) ?;
826
+ let dir = dir. path ( ) ;
827
+ let file = dir. join ( "io-uring-test-file-input" ) ;
828
+
829
+ let input = & [ 0x9f ; 1024 ] ;
830
+
831
+ fs:: write ( & file, input) ?;
832
+ let fd = fs:: OpenOptions :: new ( ) . write ( true ) . open ( & file) ?;
833
+ let fd = types:: Fd ( fd. as_raw_fd ( ) ) ;
834
+ let ftruncate_e = opcode:: Ftruncate :: new ( fd, 512 ) ;
835
+
836
+ unsafe {
837
+ ring. submission ( )
838
+ . push ( & ftruncate_e. build ( ) . user_data ( 0x33 ) . into ( ) )
839
+ . expect ( "queue is full" ) ;
840
+ }
841
+
842
+ ring. submit_and_wait ( 1 ) ?;
843
+
844
+ let cqes: Vec < cqueue:: Entry > = ring. completion ( ) . map ( Into :: into) . collect ( ) ;
845
+
846
+ assert_eq ! ( cqes. len( ) , 1 ) ;
847
+ assert_eq ! ( cqes[ 0 ] . user_data( ) , 0x33 ) ;
848
+ assert_eq ! ( cqes[ 0 ] . result( ) , 0 ) ;
849
+ assert_eq ! (
850
+ fs:: read( & file) . expect( "could not read truncated file" ) ,
851
+ & input[ ..512 ]
852
+ ) ;
853
+
854
+ let ftruncate_e = opcode:: Ftruncate :: new ( fd, 0 ) ;
855
+
856
+ unsafe {
857
+ ring. submission ( )
858
+ . push ( & ftruncate_e. build ( ) . user_data ( 0x34 ) . into ( ) )
859
+ . expect ( "queue is full" ) ;
860
+ }
861
+
862
+ ring. submit_and_wait ( 1 ) ?;
863
+
864
+ let cqes: Vec < cqueue:: Entry > = ring. completion ( ) . map ( Into :: into) . collect ( ) ;
865
+
866
+ assert_eq ! ( cqes. len( ) , 1 ) ;
867
+ assert_eq ! ( cqes[ 0 ] . user_data( ) , 0x34 ) ;
868
+ assert_eq ! ( cqes[ 0 ] . result( ) , 0 ) ;
869
+ assert_eq ! (
870
+ fs:: metadata( & file)
871
+ . expect( "could not read truncated file" )
872
+ . len( ) ,
873
+ 0
874
+ ) ;
875
+
876
+ Ok ( ( ) )
877
+ }
878
+
879
+ pub fn test_fixed_fd_install < S : squeue:: EntryMarker , C : cqueue:: EntryMarker > (
880
+ ring : & mut IoUring < S , C > ,
881
+ test : & Test ,
882
+ ) -> anyhow:: Result < ( ) > {
883
+ require ! (
884
+ test;
885
+ test. probe. is_supported( opcode:: Read :: CODE ) ;
886
+ test. probe. is_supported( opcode:: FixedFdInstall :: CODE ) ;
887
+ ) ;
888
+
889
+ println ! ( "test fixed_fd_install" ) ;
890
+
891
+ let dir = tempfile:: TempDir :: new_in ( "." ) ?;
892
+ let dir = dir. path ( ) ;
893
+ let file = dir. join ( "io-uring-test-file-input" ) ;
894
+
895
+ let input = & [ 0x9f ; 1024 ] ;
896
+ let mut output = vec ! [ 0 ; 1024 ] ;
897
+
898
+ fs:: write ( & file, input) ?;
899
+ let fd = fs:: OpenOptions :: new ( ) . read ( true ) . open ( & file) ?;
900
+ let fd = types:: Fd ( fd. as_raw_fd ( ) ) ;
901
+ ring. submitter ( ) . register_files ( & [ fd. 0 ] ) ?;
902
+ let fd = types:: Fixed ( 0 ) ;
903
+
904
+ let read_e = opcode:: Read :: new ( fd, output. as_mut_ptr ( ) , output. len ( ) as _ ) ;
905
+ unsafe {
906
+ ring. submission ( )
907
+ . push ( & read_e. build ( ) . user_data ( 0x01 ) . into ( ) )
908
+ . expect ( "queue is full" ) ;
909
+ }
910
+
911
+ assert_eq ! ( ring. submit_and_wait( 1 ) ?, 1 ) ;
912
+ let cqes: Vec < cqueue:: Entry > = ring. completion ( ) . map ( Into :: into) . collect ( ) ;
913
+ assert_eq ! ( cqes. len( ) , 1 ) ;
914
+ assert_eq ! ( cqes[ 0 ] . user_data( ) , 0x01 ) ;
915
+ assert_eq ! ( cqes[ 0 ] . result( ) , 1024 ) ;
916
+ assert_eq ! ( output, input) ;
917
+
918
+ let fixed_fd_install_e = opcode:: FixedFdInstall :: new ( fd, 0 ) ;
919
+
920
+ unsafe {
921
+ ring. submission ( )
922
+ . push ( & fixed_fd_install_e. build ( ) . user_data ( 0x02 ) . into ( ) )
923
+ . expect ( "queue is full" ) ;
924
+ }
925
+
926
+ ring. submit_and_wait ( 1 ) ?;
927
+
928
+ let cqes: Vec < cqueue:: Entry > = ring. completion ( ) . map ( Into :: into) . collect ( ) ;
929
+
930
+ assert_eq ! ( cqes. len( ) , 1 ) ;
931
+ assert_eq ! ( cqes[ 0 ] . user_data( ) , 0x02 ) ;
932
+ let fd = cqes[ 0 ] . result ( ) ;
933
+ assert ! ( fd > 0 ) ;
934
+ let mut file = unsafe { fs:: File :: from_raw_fd ( fd) } ;
935
+ file. read_exact ( & mut output) ?;
936
+ assert_eq ! ( output, input) ;
937
+
938
+ Ok ( ( ) )
939
+ }
0 commit comments