@@ -416,8 +416,10 @@ static void ublk_queue_deinit(struct ublk_queue *q)
416416 if (q -> io_cmd_buf )
417417 munmap (q -> io_cmd_buf , ublk_queue_cmd_buf_sz (q ));
418418
419- for (i = 0 ; i < nr_ios ; i ++ )
419+ for (i = 0 ; i < nr_ios ; i ++ ) {
420420 free (q -> ios [i ].buf_addr );
421+ free (q -> ios [i ].integrity_buf );
422+ }
421423}
422424
423425static void ublk_thread_deinit (struct ublk_thread * t )
@@ -433,19 +435,21 @@ static void ublk_thread_deinit(struct ublk_thread *t)
433435 }
434436}
435437
436- static int ublk_queue_init (struct ublk_queue * q , unsigned long long extra_flags )
438+ static int ublk_queue_init (struct ublk_queue * q , unsigned long long extra_flags ,
439+ __u8 metadata_size )
437440{
438441 struct ublk_dev * dev = q -> dev ;
439442 int depth = dev -> dev_info .queue_depth ;
440443 int i ;
441- int cmd_buf_size , io_buf_size ;
444+ int cmd_buf_size , io_buf_size , integrity_size ;
442445 unsigned long off ;
443446
444447 q -> tgt_ops = dev -> tgt .ops ;
445448 q -> flags = 0 ;
446449 q -> q_depth = depth ;
447450 q -> flags = dev -> dev_info .flags ;
448451 q -> flags |= extra_flags ;
452+ q -> metadata_size = metadata_size ;
449453
450454 /* Cache fd in queue for fast path access */
451455 q -> ublk_fd = dev -> fds [0 ];
@@ -461,11 +465,23 @@ static int ublk_queue_init(struct ublk_queue *q, unsigned long long extra_flags)
461465 }
462466
463467 io_buf_size = dev -> dev_info .max_io_buf_bytes ;
468+ integrity_size = ublk_integrity_len (q , io_buf_size );
464469 for (i = 0 ; i < q -> q_depth ; i ++ ) {
465470 q -> ios [i ].buf_addr = NULL ;
466471 q -> ios [i ].flags = UBLKS_IO_NEED_FETCH_RQ | UBLKS_IO_FREE ;
467472 q -> ios [i ].tag = i ;
468473
474+ if (integrity_size ) {
475+ q -> ios [i ].integrity_buf = malloc (integrity_size );
476+ if (!q -> ios [i ].integrity_buf ) {
477+ ublk_err ("ublk dev %d queue %d io %d malloc(%d) failed: %m\n" ,
478+ dev -> dev_info .dev_id , q -> q_id , i ,
479+ integrity_size );
480+ goto fail ;
481+ }
482+ }
483+
484+
469485 if (ublk_queue_no_buf (q ))
470486 continue ;
471487
@@ -608,13 +624,13 @@ static void ublk_user_copy(const struct ublk_io *io, __u8 match_ublk_op)
608624 __u8 ublk_op = ublksrv_get_op (iod );
609625 __u32 len = iod -> nr_sectors << 9 ;
610626 void * addr = io -> buf_addr ;
627+ ssize_t copied ;
611628
612629 if (ublk_op != match_ublk_op )
613630 return ;
614631
615632 while (len ) {
616633 __u32 copy_len = min (len , UBLK_USER_COPY_LEN );
617- ssize_t copied ;
618634
619635 if (ublk_op == UBLK_IO_OP_WRITE )
620636 copied = pread (q -> ublk_fd , addr , copy_len , off );
@@ -627,6 +643,20 @@ static void ublk_user_copy(const struct ublk_io *io, __u8 match_ublk_op)
627643 off += copy_len ;
628644 len -= copy_len ;
629645 }
646+
647+ if (!(iod -> op_flags & UBLK_IO_F_INTEGRITY ))
648+ return ;
649+
650+ len = ublk_integrity_len (q , iod -> nr_sectors << 9 );
651+ off = ublk_user_copy_offset (q -> q_id , io -> tag );
652+ off |= UBLKSRV_IO_INTEGRITY_FLAG ;
653+ if (ublk_op == UBLK_IO_OP_WRITE )
654+ copied = pread (q -> ublk_fd , io -> integrity_buf , len , off );
655+ else if (ublk_op == UBLK_IO_OP_READ )
656+ copied = pwrite (q -> ublk_fd , io -> integrity_buf , len , off );
657+ else
658+ assert (0 );
659+ assert (copied == (ssize_t )len );
630660}
631661
632662int ublk_queue_io_cmd (struct ublk_thread * t , struct ublk_io * io )
@@ -1013,7 +1043,8 @@ static int ublk_start_daemon(const struct dev_ctx *ctx, struct ublk_dev *dev)
10131043 dev -> q [i ].dev = dev ;
10141044 dev -> q [i ].q_id = i ;
10151045
1016- ret = ublk_queue_init (& dev -> q [i ], extra_flags );
1046+ ret = ublk_queue_init (& dev -> q [i ], extra_flags ,
1047+ ctx -> metadata_size );
10171048 if (ret ) {
10181049 ublk_err ("ublk dev %d queue %d init queue failed\n" ,
10191050 dinfo -> dev_id , i );
0 commit comments