On Tue, Mar 19, 2013 at 03:01:51PM +0000, Konstantin Belousov wrote:
> Author: kib
> Date: Tue Mar 19 15:01:50 2013
> New Revision: 248519
> URL: http://svnweb.freebsd.org/changeset/base/248519
> 
> Log:
>   Support unmapped i/o for the md(4).
>   
>   The vnode-backed md(4) has to map the unmapped bio because VOP_READ()
>   and VOP_WRITE() interfaces do not allow to pass unmapped requests to
>   the filesystem. Vnode-backed md(4) uses pbufs instead of relying on
>   the bio_transient_map, to avoid usual md deadlock.
>   
>   Sponsored by:       The FreeBSD Foundation
>   Tested by:  pho, scottl

This commit message belongs to r248518.

> Modified:
>   head/sys/cam/ata/ata_da.c
>   head/sys/cam/cam_ccb.h
>   head/sys/cam/scsi/scsi_all.c
>   head/sys/cam/scsi/scsi_all.h
>   head/sys/cam/scsi/scsi_cd.c
>   head/sys/cam/scsi/scsi_da.c
> 
> Modified: head/sys/cam/ata/ata_da.c
> ==============================================================================
> --- head/sys/cam/ata/ata_da.c Tue Mar 19 14:53:23 2013        (r248518)
> +++ head/sys/cam/ata/ata_da.c Tue Mar 19 15:01:50 2013        (r248519)
> @@ -1167,6 +1167,8 @@ adaregister(struct cam_periph *periph, v
>           ((softc->flags & ADA_FLAG_CAN_CFA) &&
>           !(softc->flags & ADA_FLAG_CAN_48BIT)))
>               softc->disk->d_flags |= DISKFLAG_CANDELETE;
> +     if ((cpi.hba_misc & PIM_UNMAPPED) != 0)
> +             softc->disk->d_flags |= DISKFLAG_UNMAPPED_BIO;
>       strlcpy(softc->disk->d_descr, cgd->ident_data.model,
>           MIN(sizeof(softc->disk->d_descr), sizeof(cgd->ident_data.model)));
>       strlcpy(softc->disk->d_ident, cgd->ident_data.serial,
> @@ -1431,13 +1433,19 @@ adastart(struct cam_periph *periph, unio
>                               return;
>                       }
>  #endif
> +                     KASSERT((bp->bio_flags & BIO_UNMAPPED) == 0 ||
> +                         round_page(bp->bio_bcount + bp->bio_ma_offset) /
> +                         PAGE_SIZE == bp->bio_ma_n,
> +                         ("Short bio %p", bp));
>                       cam_fill_ataio(ataio,
>                           ada_retry_count,
>                           adadone,
> -                         bp->bio_cmd == BIO_READ ?
> -                             CAM_DIR_IN : CAM_DIR_OUT,
> +                         (bp->bio_cmd == BIO_READ ? CAM_DIR_IN :
> +                             CAM_DIR_OUT) | ((bp->bio_flags & BIO_UNMAPPED)
> +                             != 0 ? CAM_DATA_BIO : 0),
>                           tag_code,
> -                         bp->bio_data,
> +                         ((bp->bio_flags & BIO_UNMAPPED) != 0) ? (void *)bp :
> +                             bp->bio_data,
>                           bp->bio_bcount,
>                           ada_default_timeout*1000);
>  
> 
> Modified: head/sys/cam/cam_ccb.h
> ==============================================================================
> --- head/sys/cam/cam_ccb.h    Tue Mar 19 14:53:23 2013        (r248518)
> +++ head/sys/cam/cam_ccb.h    Tue Mar 19 15:01:50 2013        (r248519)
> @@ -42,7 +42,6 @@
>  #include <cam/scsi/scsi_all.h>
>  #include <cam/ata/ata_all.h>
>  
> -
>  /* General allocation length definitions for CCB structures */
>  #define      IOCDBLEN        CAM_MAX_CDBLEN  /* Space for CDB bytes/pointer 
> */
>  #define      VUHBALEN        14              /* Vendor Unique HBA length */
> @@ -572,7 +571,8 @@ typedef enum {
>       PIM_NOINITIATOR = 0x20, /* Initiator role not supported. */
>       PIM_NOBUSRESET  = 0x10, /* User has disabled initial BUS RESET */
>       PIM_NO_6_BYTE   = 0x08, /* Do not send 6-byte commands */
> -     PIM_SEQSCAN     = 0x04  /* Do bus scans sequentially, not in parallel */
> +     PIM_SEQSCAN     = 0x04, /* Do bus scans sequentially, not in parallel */
> +     PIM_UNMAPPED    = 0x02,
>  } pi_miscflag;
>  
>  /* Path Inquiry CCB */
> 
> Modified: head/sys/cam/scsi/scsi_all.c
> ==============================================================================
> --- head/sys/cam/scsi/scsi_all.c      Tue Mar 19 14:53:23 2013        
> (r248518)
> +++ head/sys/cam/scsi/scsi_all.c      Tue Mar 19 15:01:50 2013        
> (r248519)
> @@ -5679,7 +5679,11 @@ scsi_read_write(struct ccb_scsiio *csio,
>               u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len,
>               u_int32_t timeout)
>  {
> +     int read;
>       u_int8_t cdb_len;
> +
> +     read = (readop & SCSI_RW_DIRMASK) == SCSI_RW_READ;
> +
>       /*
>        * Use the smallest possible command to perform the operation
>        * as some legacy hardware does not support the 10 byte commands.
> @@ -5696,7 +5700,7 @@ scsi_read_write(struct ccb_scsiio *csio,
>               struct scsi_rw_6 *scsi_cmd;
>  
>               scsi_cmd = (struct scsi_rw_6 *)&csio->cdb_io.cdb_bytes;
> -             scsi_cmd->opcode = readop ? READ_6 : WRITE_6;
> +             scsi_cmd->opcode = read ? READ_6 : WRITE_6;
>               scsi_ulto3b(lba, scsi_cmd->addr);
>               scsi_cmd->length = block_count & 0xff;
>               scsi_cmd->control = 0;
> @@ -5715,7 +5719,7 @@ scsi_read_write(struct ccb_scsiio *csio,
>               struct scsi_rw_10 *scsi_cmd;
>  
>               scsi_cmd = (struct scsi_rw_10 *)&csio->cdb_io.cdb_bytes;
> -             scsi_cmd->opcode = readop ? READ_10 : WRITE_10;
> +             scsi_cmd->opcode = read ? READ_10 : WRITE_10;
>               scsi_cmd->byte2 = byte2;
>               scsi_ulto4b(lba, scsi_cmd->addr);
>               scsi_cmd->reserved = 0;
> @@ -5738,7 +5742,7 @@ scsi_read_write(struct ccb_scsiio *csio,
>               struct scsi_rw_12 *scsi_cmd;
>  
>               scsi_cmd = (struct scsi_rw_12 *)&csio->cdb_io.cdb_bytes;
> -             scsi_cmd->opcode = readop ? READ_12 : WRITE_12;
> +             scsi_cmd->opcode = read ? READ_12 : WRITE_12;
>               scsi_cmd->byte2 = byte2;
>               scsi_ulto4b(lba, scsi_cmd->addr);
>               scsi_cmd->reserved = 0;
> @@ -5760,7 +5764,7 @@ scsi_read_write(struct ccb_scsiio *csio,
>               struct scsi_rw_16 *scsi_cmd;
>  
>               scsi_cmd = (struct scsi_rw_16 *)&csio->cdb_io.cdb_bytes;
> -             scsi_cmd->opcode = readop ? READ_16 : WRITE_16;
> +             scsi_cmd->opcode = read ? READ_16 : WRITE_16;
>               scsi_cmd->byte2 = byte2;
>               scsi_u64to8b(lba, scsi_cmd->addr);
>               scsi_cmd->reserved = 0;
> @@ -5771,7 +5775,8 @@ scsi_read_write(struct ccb_scsiio *csio,
>       cam_fill_csio(csio,
>                     retries,
>                     cbfcnp,
> -                   /*flags*/readop ? CAM_DIR_IN : CAM_DIR_OUT,
> +                   (read ? CAM_DIR_IN : CAM_DIR_OUT) |
> +                   ((readop & SCSI_RW_BIO) != 0 ? CAM_DATA_BIO : 0),
>                     tag_action,
>                     data_ptr,
>                     dxfer_len,
> 
> Modified: head/sys/cam/scsi/scsi_all.h
> ==============================================================================
> --- head/sys/cam/scsi/scsi_all.h      Tue Mar 19 14:53:23 2013        
> (r248518)
> +++ head/sys/cam/scsi/scsi_all.h      Tue Mar 19 15:01:50 2013        
> (r248519)
> @@ -2354,6 +2354,10 @@ void scsi_write_buffer(struct ccb_scsiio
>                       uint8_t *data_ptr, uint32_t param_list_length,
>                       uint8_t sense_len, uint32_t timeout);
>  
> +#define      SCSI_RW_READ    0x0001
> +#define      SCSI_RW_WRITE   0x0002
> +#define      SCSI_RW_DIRMASK 0x0003
> +#define      SCSI_RW_BIO     0x1000
>  void scsi_read_write(struct ccb_scsiio *csio, u_int32_t retries,
>                    void (*cbfcnp)(struct cam_periph *, union ccb *),
>                    u_int8_t tag_action, int readop, u_int8_t byte2, 
> 
> Modified: head/sys/cam/scsi/scsi_cd.c
> ==============================================================================
> --- head/sys/cam/scsi/scsi_cd.c       Tue Mar 19 14:53:23 2013        
> (r248518)
> +++ head/sys/cam/scsi/scsi_cd.c       Tue Mar 19 15:01:50 2013        
> (r248519)
> @@ -1575,7 +1575,8 @@ cdstart(struct cam_periph *periph, union
>                                       /*retries*/ cd_retry_count,
>                                       /* cbfcnp */ cddone,
>                                       MSG_SIMPLE_Q_TAG,
> -                                     /* read */bp->bio_cmd == BIO_READ,
> +                                     /* read */bp->bio_cmd == BIO_READ ?
> +                                     SCSI_RW_READ : SCSI_RW_WRITE,
>                                       /* byte2 */ 0,
>                                       /* minimum_cmd_size */ 10,
>                                       /* lba */ bp->bio_offset /
> 
> Modified: head/sys/cam/scsi/scsi_da.c
> ==============================================================================
> --- head/sys/cam/scsi/scsi_da.c       Tue Mar 19 14:53:23 2013        
> (r248518)
> +++ head/sys/cam/scsi/scsi_da.c       Tue Mar 19 15:01:50 2013        
> (r248519)
> @@ -1184,7 +1184,7 @@ dadump(void *arg, void *virtual, vm_offs
>                               /*retries*/0,
>                               dadone,
>                               MSG_ORDERED_Q_TAG,
> -                             /*read*/FALSE,
> +                             /*read*/SCSI_RW_WRITE,
>                               /*byte2*/0,
>                               /*minimum_cmd_size*/ softc->minimum_cmd_size,
>                               offset / secsize,
> @@ -1757,6 +1757,8 @@ daregister(struct cam_periph *periph, vo
>       softc->disk->d_flags = 0;
>       if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0)
>               softc->disk->d_flags |= DISKFLAG_CANFLUSHCACHE;
> +     if ((cpi.hba_misc & PIM_UNMAPPED) != 0)
> +             softc->disk->d_flags |= DISKFLAG_UNMAPPED_BIO;
>       cam_strvis(softc->disk->d_descr, cgd->inq_data.vendor,
>           sizeof(cgd->inq_data.vendor), sizeof(softc->disk->d_descr));
>       strlcat(softc->disk->d_descr, " ", sizeof(softc->disk->d_descr));
> @@ -1985,14 +1987,18 @@ dastart(struct cam_periph *periph, union
>                                       /*retries*/da_retry_count,
>                                       /*cbfcnp*/dadone,
>                                       /*tag_action*/tag_code,
> -                                     /*read_op*/bp->bio_cmd
> -                                             == BIO_READ,
> +                                     /*read_op*/(bp->bio_cmd == BIO_READ ?
> +                                     SCSI_RW_READ : SCSI_RW_WRITE) |
> +                                     ((bp->bio_flags & BIO_UNMAPPED) != 0 ?
> +                                     SCSI_RW_BIO : 0),
>                                       /*byte2*/0,
>                                       softc->minimum_cmd_size,
>                                       /*lba*/bp->bio_pblkno,
>                                       /*block_count*/bp->bio_bcount /
>                                       softc->params.secsize,
> -                                     /*data_ptr*/ bp->bio_data,
> +                                     /*data_ptr*/ (bp->bio_flags &
> +                                     BIO_UNMAPPED) != 0 ? (void *)bp :
> +                                     bp->bio_data,
>                                       /*dxfer_len*/ bp->bio_bcount,
>                                       /*sense_len*/SSD_FULL_SIZE,
>                                       da_default_timeout * 1000);

-- 
Pawel Jakub Dawidek                       http://www.wheelsystems.com
FreeBSD committer                         http://www.FreeBSD.org
Am I Evil? Yes, I Am!                     http://tupytaj.pl

Attachment: pgpGoEyXtPkv1.pgp
Description: PGP signature

Reply via email to