Date: Thu, 25 Sep 2014 09:11:01 +0000 (UTC) From: Alexander Motin <mav@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r272100 - stable/10/sys/cam/ctl Message-ID: <201409250911.s8P9B1VA045692@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mav Date: Thu Sep 25 09:11:01 2014 New Revision: 272100 URL: http://svnweb.freebsd.org/changeset/base/272100 Log: MFC r271949: Fix UNMAP stuck if the last block descriptor in the list is empty. Approved by: re (glebius) Modified: stable/10/sys/cam/ctl/ctl.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cam/ctl/ctl.c ============================================================================== --- stable/10/sys/cam/ctl/ctl.c Thu Sep 25 08:36:11 2014 (r272099) +++ stable/10/sys/cam/ctl/ctl.c Thu Sep 25 09:11:01 2014 (r272100) @@ -6039,7 +6039,7 @@ ctl_unmap(struct ctl_scsiio *ctsio) struct scsi_unmap *cdb; struct ctl_ptr_len_flags *ptrlen; struct scsi_unmap_header *hdr; - struct scsi_unmap_desc *buf, *end; + struct scsi_unmap_desc *buf, *end, *endnz, *range; uint64_t lba; uint32_t num_blocks; int len, retval; @@ -6092,24 +6092,38 @@ ctl_unmap(struct ctl_scsiio *ctsio) buf = (struct scsi_unmap_desc *)(hdr + 1); end = buf + len / sizeof(*buf); - ptrlen = (struct ctl_ptr_len_flags *)&ctsio->io_hdr.ctl_private[CTL_PRIV_LBA_LEN]; - ptrlen->ptr = (void *)buf; - ptrlen->len = len; - ptrlen->flags = byte2; - - for (; buf < end; buf++) { - lba = scsi_8btou64(buf->lba); - num_blocks = scsi_4btoul(buf->length); + endnz = buf; + for (range = buf; range < end; range++) { + lba = scsi_8btou64(range->lba); + num_blocks = scsi_4btoul(range->length); if (((lba + num_blocks) > (lun->be_lun->maxlba + 1)) || ((lba + num_blocks) < lba)) { ctl_set_lba_out_of_range(ctsio); ctl_done((union ctl_io *)ctsio); return (CTL_RETVAL_COMPLETE); } + if (num_blocks != 0) + endnz = range + 1; } - retval = lun->backend->config_write((union ctl_io *)ctsio); + /* + * Block backend can not handle zero last range. + * Filter it out and return if there is nothing left. + */ + len = (uint8_t *)endnz - (uint8_t *)buf; + if (len == 0) { + ctl_set_success(ctsio); + ctl_done((union ctl_io *)ctsio); + return (CTL_RETVAL_COMPLETE); + } + + ptrlen = (struct ctl_ptr_len_flags *) + &ctsio->io_hdr.ctl_private[CTL_PRIV_LBA_LEN]; + ptrlen->ptr = (void *)buf; + ptrlen->len = len; + ptrlen->flags = byte2; + retval = lun->backend->config_write((union ctl_io *)ctsio); return (retval); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201409250911.s8P9B1VA045692>