From owner-dev-commits-src-all@freebsd.org Tue Sep 14 19:52:32 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id E614F66F9D1; Tue, 14 Sep 2021 19:52:32 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4H8DXJ65CZz4mXG; Tue, 14 Sep 2021 19:52:32 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id B162B20AB8; Tue, 14 Sep 2021 19:52:32 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 18EJqWmk076357; Tue, 14 Sep 2021 19:52:32 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 18EJqWa5076356; Tue, 14 Sep 2021 19:52:32 GMT (envelope-from git) Date: Tue, 14 Sep 2021 19:52:32 GMT Message-Id: <202109141952.18EJqWa5076356@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Ka Ho Ng Subject: git: 49050613ef1f - main - ctl(4): Do hole-punching for UNMAP to file-backed LUNs MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: khng X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 49050613ef1fac244c3cb9767cbdff3d10bee670 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 14 Sep 2021 19:52:33 -0000 The branch main has been updated by khng: URL: https://cgit.FreeBSD.org/src/commit/?id=49050613ef1fac244c3cb9767cbdff3d10bee670 commit 49050613ef1fac244c3cb9767cbdff3d10bee670 Author: Ka Ho Ng AuthorDate: 2021-09-14 19:51:58 +0000 Commit: Ka Ho Ng CommitDate: 2021-09-14 19:51:58 +0000 ctl(4): Do hole-punching for UNMAP to file-backed LUNs This adds support for SCSI UNMAP command to file-backed LUNs, if the underlying file system has a non-zerofilling VOP_DEALLOCATE implementation where some or all parts of the requested operation range may be deallocated. Sponsored by: The FreeBSD Foundation Reviewed by: mav Differential Revision: https://reviews.freebsd.org/D31922 --- sys/cam/ctl/ctl_backend_block.c | 99 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 2 deletions(-) diff --git a/sys/cam/ctl/ctl_backend_block.c b/sys/cam/ctl/ctl_backend_block.c index 83ea6b43dac3..8c126d8be229 100644 --- a/sys/cam/ctl/ctl_backend_block.c +++ b/sys/cam/ctl/ctl_backend_block.c @@ -3,13 +3,16 @@ * * Copyright (c) 2003 Silicon Graphics International Corp. * Copyright (c) 2009-2011 Spectra Logic Corporation - * Copyright (c) 2012 The FreeBSD Foundation + * Copyright (c) 2012,2021 The FreeBSD Foundation * Copyright (c) 2014-2015 Alexander Motin * All rights reserved. * * Portions of this software were developed by Edward Tomasz Napierala * under sponsorship from the FreeBSD Foundation. * + * Portions of this software were developed by Ka Ho Ng + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -81,6 +84,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include @@ -245,6 +249,8 @@ static void ctl_be_block_gls_file(struct ctl_be_block_lun *be_lun, struct ctl_be_block_io *beio); static uint64_t ctl_be_block_getattr_file(struct ctl_be_block_lun *be_lun, const char *attrname); +static void ctl_be_block_unmap_file(struct ctl_be_block_lun *be_lun, + struct ctl_be_block_io *beio); static void ctl_be_block_flush_dev(struct ctl_be_block_lun *be_lun, struct ctl_be_block_io *beio); static void ctl_be_block_unmap_dev(struct ctl_be_block_lun *be_lun, @@ -854,6 +860,84 @@ ctl_be_block_getattr_file(struct ctl_be_block_lun *be_lun, const char *attrname) return (val); } +static void +ctl_be_block_unmap_file(struct ctl_be_block_lun *be_lun, + struct ctl_be_block_io *beio) +{ + struct ctl_be_block_filedata *file_data; + union ctl_io *io; + struct ctl_ptr_len_flags *ptrlen; + struct scsi_unmap_desc *buf, *end; + struct mount *mp; + off_t off, len; + int error; + + io = beio->io; + file_data = &be_lun->backend.file; + mp = NULL; + error = 0; + + binuptime(&beio->ds_t0); + devstat_start_transaction(be_lun->disk_stats, &beio->ds_t0); + + (void)vn_start_write(be_lun->vn, &mp, V_WAIT); + vn_lock(be_lun->vn, vn_lktype_write(mp, be_lun->vn) | LK_RETRY); + if (beio->io_offset == -1) { + beio->io_len = 0; + ptrlen = (struct ctl_ptr_len_flags *) + &io->io_hdr.ctl_private[CTL_PRIV_LBA_LEN]; + buf = (struct scsi_unmap_desc *)ptrlen->ptr; + end = buf + ptrlen->len / sizeof(*buf); + for (; buf < end; buf++) { + off = (off_t)scsi_8btou64(buf->lba) * + be_lun->cbe_lun.blocksize; + len = (off_t)scsi_4btoul(buf->length) * + be_lun->cbe_lun.blocksize; + beio->io_len += len; + error = vn_deallocate(be_lun->vn, &off, &len, + 0, IO_NOMACCHECK | IO_NODELOCKED, file_data->cred, + NOCRED); + if (error != 0) + break; + } + } else { + /* WRITE_SAME */ + off = beio->io_offset; + len = beio->io_len; + error = vn_deallocate(be_lun->vn, &off, &len, 0, + IO_NOMACCHECK | IO_NODELOCKED, file_data->cred, NOCRED); + } + VOP_UNLOCK(be_lun->vn); + vn_finished_write(mp); + + mtx_lock(&be_lun->io_lock); + devstat_end_transaction(beio->lun->disk_stats, beio->io_len, + beio->ds_tag_type, beio->ds_trans_type, + /*now*/ NULL, /*then*/&beio->ds_t0); + mtx_unlock(&be_lun->io_lock); + + /* + * If we got an error, set the sense data to "MEDIUM ERROR" and + * return the I/O to the user. + */ + switch (error) { + case 0: + ctl_set_success(&io->scsiio); + break; + case ENOSPC: + case EDQUOT: + ctl_set_space_alloc_fail(&io->scsiio); + break; + case EROFS: + case EACCES: + ctl_set_hw_write_protected(&io->scsiio); + break; + default: + ctl_set_medium_error(&io->scsiio, false); + } + ctl_complete_beio(beio); +} + static void ctl_be_block_dispatch_zvol(struct ctl_be_block_lun *be_lun, struct ctl_be_block_io *beio) @@ -1804,6 +1888,7 @@ ctl_be_block_open_file(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req) struct vattr vattr; off_t ps, pss, po, pos, us, uss, uo, uos; int error; + long pconf; cbe_lun = &be_lun->cbe_lun; file_data = &be_lun->backend.file; @@ -1814,7 +1899,7 @@ ctl_be_block_open_file(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req) be_lun->lun_flush = ctl_be_block_flush_file; be_lun->get_lba_status = ctl_be_block_gls_file; be_lun->getattr = ctl_be_block_getattr_file; - be_lun->unmap = NULL; + be_lun->unmap = ctl_be_block_unmap_file; cbe_lun->flags &= ~CTL_LUN_FLAG_UNMAP; error = VOP_GETATTR(be_lun->vn, &vattr, curthread->td_ucred); @@ -1825,6 +1910,16 @@ ctl_be_block_open_file(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req) return (error); } + error = VOP_PATHCONF(be_lun->vn, _PC_DEALLOC_PRESENT, &pconf); + if (error != 0) { + snprintf(req->error_str, sizeof(req->error_str), + "error calling VOP_PATHCONF() for file %s", + be_lun->dev_path); + return (error); + } + if (pconf == 1) + cbe_lun->flags |= CTL_LUN_FLAG_UNMAP; + file_data->cred = crhold(curthread->td_ucred); if (params->lun_size_bytes != 0) be_lun->size_bytes = params->lun_size_bytes;