From patchwork Fri Jun 28 13:27:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 13716144 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2369C1BE25F for ; Fri, 28 Jun 2024 13:27:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.133 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719581266; cv=none; b=RpxOa3j9pY+3pYk8LmLSyUeHD2s4rgnTyJAwfsbGoOhoPMqRk8LSmu7+vml3r7jkoZ/KTV4EW20hTgfRGxLCyobW0JiY6/amdShkvqx3D+3wsnjvPj1/GD5yeisI63sSw+4hyE4KG33miKGupuNQREND1YnUq6375tOOF3dODnQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719581266; c=relaxed/simple; bh=I+P8N4lSbGisWXVdKRQBq4uU/8kd0b/6H8O4Wb+82Vk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=b5kDBkrs5lL7jqqa9qdH/R19FisrRrOsYNG+l8D+ooX4BFkyVVAAWicEPJM9QsvFH8FuU/YWDK/uqqMbhfIJmVAcpNQDy3+fWyTP7qu0pvQ+URMdNizK3HYZc37yNltWtnmI7DObC8Td4ClyYEuQYenlr2biRGdnQQxKwPhcTro= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=lst.de; spf=none smtp.mailfrom=bombadil.srs.infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=lf+A0ThJ; arc=none smtp.client-ip=198.137.202.133 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=lst.de Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=bombadil.srs.infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="lf+A0ThJ" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=9NRyytadyKUrTMT24uTseB2dZoo3P4Ngrlp0FpS3GDs=; b=lf+A0ThJ6iD4GxhAetSvHTbwp1 D7wKAq2ZpG6c2zyViwycQ2X4edrLFXCMaWWgxaYlLr27yL5l3q47B5omiAdzbNxdYT7U3RtKycJ36 e00CGdffDOOnaJVF5gmVsUP1W06i09h7OcnsBwANKG5+QbgPXzIuAVKT4nhEjEnocMUchX5DyhX8G +z/K/4nBcxGzA9nnj10PiVeXlDnkn+lxtAnoGB2oOPUmpKOJ6fWVQwwZfI+XspRipnW1JPifCU1Wd /c2phfqKsRDkADj0+qvPEhxM6SbHnMAKCViN6BGpf36w/mjbwl459CXAAgPwbDHCL+Ya8y5kQr+RM wmpiNfxA==; Received: from [2001:4bb8:2af:2acb:3b26:86b1:bdec:6790] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.97.1 #2 (Red Hat Linux)) id 1sNBdf-0000000DoiK-0DK1; Fri, 28 Jun 2024 13:27:43 +0000 From: Christoph Hellwig To: Jens Axboe Cc: "Martin K . Petersen" , Anuj Gupta , Kanchan Joshi , linux-block@vger.kernel.org Subject: [PATCH 1/3] block: split integrity support out of bio.h Date: Fri, 28 Jun 2024 15:27:17 +0200 Message-ID: <20240628132736.668184-2-hch@lst.de> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240628132736.668184-1-hch@lst.de> References: <20240628132736.668184-1-hch@lst.de> Precedence: bulk X-Mailing-List: linux-block@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Split struct bio_integrity_payload and the related prototypes out of bio.h into a separate bio-integrity.h header so that it is only pulled in by the few places that need it. Signed-off-by: Christoph Hellwig --- block/bio.c | 2 +- block/blk.h | 1 + block/bounce.c | 2 +- drivers/md/dm.c | 1 + drivers/nvme/host/ioctl.c | 1 + drivers/scsi/sd.c | 3 +- include/linux/bio-integrity.h | 149 +++++++++++++++++++++++++++++++++ include/linux/bio.h | 152 ---------------------------------- include/linux/blk-integrity.h | 1 + 9 files changed, 157 insertions(+), 155 deletions(-) create mode 100644 include/linux/bio-integrity.h diff --git a/block/bio.c b/block/bio.c index e9e809a63c5975..4ca3f31ce45fb5 100644 --- a/block/bio.c +++ b/block/bio.c @@ -4,7 +4,7 @@ */ #include #include -#include +#include #include #include #include diff --git a/block/blk.h b/block/blk.h index 47dadd2439b1ca..401e604f35d2cf 100644 --- a/block/blk.h +++ b/block/blk.h @@ -2,6 +2,7 @@ #ifndef BLK_INTERNAL_H #define BLK_INTERNAL_H +#include #include #include /* for max_pfn/max_low_pfn */ #include diff --git a/block/bounce.c b/block/bounce.c index d6a5219f29dd53..0d898cd5ec497f 100644 --- a/block/bounce.c +++ b/block/bounce.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 7d107ae06e1ae1..92d6eeb0a59327 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -11,6 +11,7 @@ #include "dm-uevent.h" #include "dm-ima.h" +#include #include #include #include diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c index 9d9d2a127c4ec2..f1d58e70933f54 100644 --- a/drivers/nvme/host/ioctl.c +++ b/drivers/nvme/host/ioctl.c @@ -3,6 +3,7 @@ * Copyright (c) 2011-2014, Intel Corporation. * Copyright (c) 2017-2021 Christoph Hellwig. */ +#include #include /* for force_successful_syscall_return */ #include #include diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 525f48c97f5e15..977f761714d575 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -33,11 +33,12 @@ * than the level indicated above to trigger output. */ +#include #include #include #include #include -#include +#include #include #include #include diff --git a/include/linux/bio-integrity.h b/include/linux/bio-integrity.h new file mode 100644 index 00000000000000..0912f47f1d1eea --- /dev/null +++ b/include/linux/bio-integrity.h @@ -0,0 +1,149 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_BIO_INTEGRITY_H +#define _LINUX_BIO_INTEGRITY_H + +#include + +enum bip_flags { + BIP_BLOCK_INTEGRITY = 1 << 0, /* block layer owns integrity data */ + BIP_MAPPED_INTEGRITY = 1 << 1, /* ref tag has been remapped */ + BIP_CTRL_NOCHECK = 1 << 2, /* disable HBA integrity checking */ + BIP_DISK_NOCHECK = 1 << 3, /* disable disk integrity checking */ + BIP_IP_CHECKSUM = 1 << 4, /* IP checksum */ + BIP_INTEGRITY_USER = 1 << 5, /* Integrity payload is user address */ + BIP_COPY_USER = 1 << 6, /* Kernel bounce buffer in use */ +}; + +struct bio_integrity_payload { + struct bio *bip_bio; /* parent bio */ + + struct bvec_iter bip_iter; + + unsigned short bip_vcnt; /* # of integrity bio_vecs */ + unsigned short bip_max_vcnt; /* integrity bio_vec slots */ + unsigned short bip_flags; /* control flags */ + + struct bvec_iter bio_iter; /* for rewinding parent bio */ + + struct work_struct bip_work; /* I/O completion */ + + struct bio_vec *bip_vec; + struct bio_vec bip_inline_vecs[];/* embedded bvec array */ +}; + +#ifdef CONFIG_BLK_DEV_INTEGRITY + +#define bip_for_each_vec(bvl, bip, iter) \ + for_each_bvec(bvl, (bip)->bip_vec, iter, (bip)->bip_iter) + +#define bio_for_each_integrity_vec(_bvl, _bio, _iter) \ + for_each_bio(_bio) \ + bip_for_each_vec(_bvl, _bio->bi_integrity, _iter) + +static inline struct bio_integrity_payload *bio_integrity(struct bio *bio) +{ + if (bio->bi_opf & REQ_INTEGRITY) + return bio->bi_integrity; + + return NULL; +} + +static inline bool bio_integrity_flagged(struct bio *bio, enum bip_flags flag) +{ + struct bio_integrity_payload *bip = bio_integrity(bio); + + if (bip) + return bip->bip_flags & flag; + + return false; +} + +static inline sector_t bip_get_seed(struct bio_integrity_payload *bip) +{ + return bip->bip_iter.bi_sector; +} + +static inline void bip_set_seed(struct bio_integrity_payload *bip, + sector_t seed) +{ + bip->bip_iter.bi_sector = seed; +} + +struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio, gfp_t gfp, + unsigned int nr); +int bio_integrity_add_page(struct bio *bio, struct page *page, unsigned int len, + unsigned int offset); +int bio_integrity_map_user(struct bio *bio, void __user *ubuf, ssize_t len, u32 seed); +bool bio_integrity_prep(struct bio *bio); +void bio_integrity_advance(struct bio *bio, unsigned int bytes_done); +void bio_integrity_trim(struct bio *bio); +int bio_integrity_clone(struct bio *bio, struct bio *bio_src, gfp_t gfp_mask); +int bioset_integrity_create(struct bio_set *bs, int pool_size); +void bioset_integrity_free(struct bio_set *bs); +void bio_integrity_init(void); + +#else /* CONFIG_BLK_DEV_INTEGRITY */ + +static inline void *bio_integrity(struct bio *bio) +{ + return NULL; +} + +static inline int bioset_integrity_create(struct bio_set *bs, int pool_size) +{ + return 0; +} + +static inline void bioset_integrity_free (struct bio_set *bs) +{ + return; +} + +static inline int bio_integrity_map_user(struct bio *bio, void __user *ubuf, + ssize_t len, u32 seed) +{ + return -EINVAL; +} + +static inline bool bio_integrity_prep(struct bio *bio) +{ + return true; +} + +static inline int bio_integrity_clone(struct bio *bio, struct bio *bio_src, + gfp_t gfp_mask) +{ + return 0; +} + +static inline void bio_integrity_advance(struct bio *bio, + unsigned int bytes_done) +{ +} + +static inline void bio_integrity_trim(struct bio *bio) +{ +} + +static inline void bio_integrity_init(void) +{ +} + +static inline bool bio_integrity_flagged(struct bio *bio, enum bip_flags flag) +{ + return false; +} + +static inline void *bio_integrity_alloc(struct bio * bio, gfp_t gfp, + unsigned int nr) +{ + return ERR_PTR(-EINVAL); +} + +static inline int bio_integrity_add_page(struct bio *bio, struct page *page, + unsigned int len, unsigned int offset) +{ + return 0; +} +#endif /* CONFIG_BLK_DEV_INTEGRITY */ +#endif /* _LINUX_BIO_INTEGRITY_H */ diff --git a/include/linux/bio.h b/include/linux/bio.h index d5379548d684e1..a46e2047bea4d2 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -321,69 +321,6 @@ static inline void bio_next_folio(struct folio_iter *fi, struct bio *bio) #define bio_for_each_folio_all(fi, bio) \ for (bio_first_folio(&fi, bio, 0); fi.folio; bio_next_folio(&fi, bio)) -enum bip_flags { - BIP_BLOCK_INTEGRITY = 1 << 0, /* block layer owns integrity data */ - BIP_MAPPED_INTEGRITY = 1 << 1, /* ref tag has been remapped */ - BIP_CTRL_NOCHECK = 1 << 2, /* disable HBA integrity checking */ - BIP_DISK_NOCHECK = 1 << 3, /* disable disk integrity checking */ - BIP_IP_CHECKSUM = 1 << 4, /* IP checksum */ - BIP_INTEGRITY_USER = 1 << 5, /* Integrity payload is user address */ - BIP_COPY_USER = 1 << 6, /* Kernel bounce buffer in use */ -}; - -/* - * bio integrity payload - */ -struct bio_integrity_payload { - struct bio *bip_bio; /* parent bio */ - - struct bvec_iter bip_iter; - - unsigned short bip_vcnt; /* # of integrity bio_vecs */ - unsigned short bip_max_vcnt; /* integrity bio_vec slots */ - unsigned short bip_flags; /* control flags */ - - struct bvec_iter bio_iter; /* for rewinding parent bio */ - - struct work_struct bip_work; /* I/O completion */ - - struct bio_vec *bip_vec; - struct bio_vec bip_inline_vecs[];/* embedded bvec array */ -}; - -#if defined(CONFIG_BLK_DEV_INTEGRITY) - -static inline struct bio_integrity_payload *bio_integrity(struct bio *bio) -{ - if (bio->bi_opf & REQ_INTEGRITY) - return bio->bi_integrity; - - return NULL; -} - -static inline bool bio_integrity_flagged(struct bio *bio, enum bip_flags flag) -{ - struct bio_integrity_payload *bip = bio_integrity(bio); - - if (bip) - return bip->bip_flags & flag; - - return false; -} - -static inline sector_t bip_get_seed(struct bio_integrity_payload *bip) -{ - return bip->bip_iter.bi_sector; -} - -static inline void bip_set_seed(struct bio_integrity_payload *bip, - sector_t seed) -{ - bip->bip_iter.bi_sector = seed; -} - -#endif /* CONFIG_BLK_DEV_INTEGRITY */ - void bio_trim(struct bio *bio, sector_t offset, sector_t size); extern struct bio *bio_split(struct bio *bio, int sectors, gfp_t gfp, struct bio_set *bs); @@ -721,95 +658,6 @@ static inline bool bioset_initialized(struct bio_set *bs) return bs->bio_slab != NULL; } -#if defined(CONFIG_BLK_DEV_INTEGRITY) - -#define bip_for_each_vec(bvl, bip, iter) \ - for_each_bvec(bvl, (bip)->bip_vec, iter, (bip)->bip_iter) - -#define bio_for_each_integrity_vec(_bvl, _bio, _iter) \ - for_each_bio(_bio) \ - bip_for_each_vec(_bvl, _bio->bi_integrity, _iter) - -int bio_integrity_map_user(struct bio *bio, void __user *ubuf, ssize_t len, u32 seed); -extern struct bio_integrity_payload *bio_integrity_alloc(struct bio *, gfp_t, unsigned int); -extern int bio_integrity_add_page(struct bio *, struct page *, unsigned int, unsigned int); -extern bool bio_integrity_prep(struct bio *); -extern void bio_integrity_advance(struct bio *, unsigned int); -extern void bio_integrity_trim(struct bio *); -extern int bio_integrity_clone(struct bio *, struct bio *, gfp_t); -extern int bioset_integrity_create(struct bio_set *, int); -extern void bioset_integrity_free(struct bio_set *); -extern void bio_integrity_init(void); - -#else /* CONFIG_BLK_DEV_INTEGRITY */ - -static inline void *bio_integrity(struct bio *bio) -{ - return NULL; -} - -static inline int bioset_integrity_create(struct bio_set *bs, int pool_size) -{ - return 0; -} - -static inline void bioset_integrity_free (struct bio_set *bs) -{ - return; -} - -static inline bool bio_integrity_prep(struct bio *bio) -{ - return true; -} - -static inline int bio_integrity_clone(struct bio *bio, struct bio *bio_src, - gfp_t gfp_mask) -{ - return 0; -} - -static inline void bio_integrity_advance(struct bio *bio, - unsigned int bytes_done) -{ - return; -} - -static inline void bio_integrity_trim(struct bio *bio) -{ - return; -} - -static inline void bio_integrity_init(void) -{ - return; -} - -static inline bool bio_integrity_flagged(struct bio *bio, enum bip_flags flag) -{ - return false; -} - -static inline void *bio_integrity_alloc(struct bio * bio, gfp_t gfp, - unsigned int nr) -{ - return ERR_PTR(-EINVAL); -} - -static inline int bio_integrity_add_page(struct bio *bio, struct page *page, - unsigned int len, unsigned int offset) -{ - return 0; -} - -static inline int bio_integrity_map_user(struct bio *bio, void __user *ubuf, - ssize_t len, u32 seed) -{ - return -EINVAL; -} - -#endif /* CONFIG_BLK_DEV_INTEGRITY */ - /* * Mark a bio as polled. Note that for async polled IO, the caller must * expect -EWOULDBLOCK if we cannot allocate a request (or other resources). diff --git a/include/linux/blk-integrity.h b/include/linux/blk-integrity.h index 804f856ed3e571..de98049b7ded91 100644 --- a/include/linux/blk-integrity.h +++ b/include/linux/blk-integrity.h @@ -3,6 +3,7 @@ #define _LINUX_BLK_INTEGRITY_H #include +#include struct request; From patchwork Fri Jun 28 13:27:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 13716145 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 964931BE25F for ; Fri, 28 Jun 2024 13:27:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.133 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719581269; cv=none; b=hrl+gnrA6imtz1lSIzhHwsn0oF8CYOkH2TOxY8zuMQNSruWp+mObwIID1DboOabMLTsHW8XjhByxatfk/Iyj1XlXKo9Ai5EPzbSkixLprl8lBfX//U2AK1S34V2T/XvUuqwdW5Cdx48BUjgpjzqI81AzczKFEBm2J+voTUm0NNs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719581269; c=relaxed/simple; bh=HCTk/0KQ6pZlGAXPBjPkRwrBQhkHWiQDulIqyBoway8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SU0o8S5ZAkVXJh9/PSr+Z26iZ6CRf2WUoADn0XkoyZgDa6b5I63bT7uODA93ERipO16B5oTm2PeD4vdRa51U0flq1+xPZNmHKMhj/myO30KjiMqX1idy0Y1m0quuyI9N7PARkJOFYtQa8sir1MAoYJpqt1jhT1soM7ET10A4RKI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=lst.de; spf=none smtp.mailfrom=bombadil.srs.infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=aOJi+v60; arc=none smtp.client-ip=198.137.202.133 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=lst.de Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=bombadil.srs.infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="aOJi+v60" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=RE5ZyYC07wI3H/fMNTgg02U8vPFwzmICFxNb1zBI5Do=; b=aOJi+v60VuVJnfn4QIiiOeAuYv 3PFBr74vRl+O19g0tJzHpsRKDMTyvbJJ9kT7QRQdBHlT+N/DD4hQbh85v0H1JrD11zAPzJkW4mqhn z3bflOq0yNtDEzS/6ozm38+QR5kGZ1q5Zr2NTluenUmaGG5gW7s7S98n6uTbD0A+AV+FIIp1S/Kl5 S/CZIGAv4FN1ZkYNhRfzbRKRqnzymCrpP7AI/xWrYCzdxmDtxTttTNFSO90pwWTZomcfj6vg2mMZ+ V4AeT0PHMjrh/sQdlhg2K+TaSNRCbE6XoyNpU3oVql8P0bQ4ss4ZbxrNZT9WGwAe4W7YAQkhI7r2r pIgXgoTA==; Received: from [2001:4bb8:2af:2acb:3b26:86b1:bdec:6790] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.97.1 #2 (Red Hat Linux)) id 1sNBdi-0000000Doij-3Gzk; Fri, 28 Jun 2024 13:27:47 +0000 From: Christoph Hellwig To: Jens Axboe Cc: "Martin K . Petersen" , Anuj Gupta , Kanchan Joshi , linux-block@vger.kernel.org Subject: [PATCH 2/3] block: also return bio_integrity_payload * from stubs Date: Fri, 28 Jun 2024 15:27:18 +0200 Message-ID: <20240628132736.668184-3-hch@lst.de> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240628132736.668184-1-hch@lst.de> References: <20240628132736.668184-1-hch@lst.de> Precedence: bulk X-Mailing-List: linux-block@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html struct bio_integrity_payload is defined unconditionally. No need to return void * from bio_integrity() and bio_integrity_alloc(). Signed-off-by: Christoph Hellwig --- include/linux/bio-integrity.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/linux/bio-integrity.h b/include/linux/bio-integrity.h index 0912f47f1d1eea..7b6e687d436de2 100644 --- a/include/linux/bio-integrity.h +++ b/include/linux/bio-integrity.h @@ -84,7 +84,7 @@ void bio_integrity_init(void); #else /* CONFIG_BLK_DEV_INTEGRITY */ -static inline void *bio_integrity(struct bio *bio) +static inline struct bio_integrity_payload *bio_integrity(struct bio *bio) { return NULL; } @@ -134,8 +134,8 @@ static inline bool bio_integrity_flagged(struct bio *bio, enum bip_flags flag) return false; } -static inline void *bio_integrity_alloc(struct bio * bio, gfp_t gfp, - unsigned int nr) +static inline struct bio_integrity_payload * +bio_integrity_alloc(struct bio * bio, gfp_t gfp, unsigned int nr) { return ERR_PTR(-EINVAL); } From patchwork Fri Jun 28 13:27:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 13716146 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1FBE11BE25A for ; Fri, 28 Jun 2024 13:27:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.133 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719581272; cv=none; b=DwxWU10/LdGq96RnF9BVbq6+8F94UxX2k1nCdZ5K9ptdTrAX4Sfi6eLl+hX2vHjd26k3WdaZe/Yk/bvPGW7fHlBdtIoHKKJXDljqyO4uGnVZ/BlnmbpK8c7V+mcyXfTVETR1vG+2iRFkaZq2TOg/i88tE1t4sQQH4FLFx66Sstc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719581272; c=relaxed/simple; bh=PFRGOahJxB4foZOfdnuYn24o+VBK6Cx/Qp8fJhpphRg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dxUdi0weD8qZkPRCLOMN9ihB/YoG9lW3begXB+AES6yFqlqdPUF/f9yRk/s+Euaf3v7UzK8IOXYpMcRWrWHoTHApkHpeBUkKRnr4nH03Y5H2QZWOpSuGSLVHobIr1jYZ5CfTU7M+uDZNWj3Y4PrtAhn6Y8iu1HiKpml0vma5BGo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=lst.de; spf=none smtp.mailfrom=bombadil.srs.infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=IoW3S6RP; arc=none smtp.client-ip=198.137.202.133 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=lst.de Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=bombadil.srs.infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="IoW3S6RP" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=2GSea+Gjv9tkKdJ4/prJAIKSyMcLdr3thr+72zaTZKc=; b=IoW3S6RP5ZCYQJr5ccfzyaS73w xViehBHHcT0iMr6UO1omu7hJrRSsTuVUJGUVxj2lWbthiUlTTG7v2yxXF0W2yV2C/4SD9+7Q98qJ0 QxzTyQvo/8ElZk9KPCffYsLOpr4ONty7uhpUUtYlnwDxSbnkORsySdTrMnxBL5rHBOCxN2mCFOhPa VcqLZ1iVhmH6DkIBa/f/i8cRq1AdZVKe9X1INuKW/JU4ZAvXHA57iazgW3Aq84r1teIxiiArIg9V0 5rCWV4bBsLNe4QUusKPCGZfGqQV+GcxXEZk95YWGszgcbgjiDpZNBGw7a2Iv6c9K/hreyPZYonYfd RsYCUaZA==; Received: from [2001:4bb8:2af:2acb:3b26:86b1:bdec:6790] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.97.1 #2 (Red Hat Linux)) id 1sNBdm-0000000Doj3-1Lqi; Fri, 28 Jun 2024 13:27:50 +0000 From: Christoph Hellwig To: Jens Axboe Cc: "Martin K . Petersen" , Anuj Gupta , Kanchan Joshi , linux-block@vger.kernel.org Subject: [PATCH 3/3] block: don't free submitter owned integrity payload on I/O completion Date: Fri, 28 Jun 2024 15:27:19 +0200 Message-ID: <20240628132736.668184-4-hch@lst.de> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240628132736.668184-1-hch@lst.de> References: <20240628132736.668184-1-hch@lst.de> Precedence: bulk X-Mailing-List: linux-block@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Currently __bio_integrity_endio unconditionally frees the integrity payload. While this works really well for block-layer generated integrity payloads, it is a bad idea for those passed in by the submitter, as it can't access the integrity data from the I/O completion handler. Change bio_integrity_endio to only call __bio_integrity_endio for block layer generated integrity data, and leave freeing of submitter allocated integrity data to bio_uninit which also gets called from the final bio_put. This requires that unmapping user mapped or copied integrity data is done by the caller now. Signed-off-by: Christoph Hellwig --- block/bio-integrity.c | 56 ++++++++++++++++------------------- block/blk-map.c | 3 ++ block/blk.h | 4 ++- include/linux/bio-integrity.h | 8 +++-- 4 files changed, 37 insertions(+), 34 deletions(-) diff --git a/block/bio-integrity.c b/block/bio-integrity.c index ad296849aa2a9a..8c6447bcddede2 100644 --- a/block/bio-integrity.c +++ b/block/bio-integrity.c @@ -22,9 +22,17 @@ void blk_flush_integrity(void) flush_workqueue(kintegrityd_wq); } -static void __bio_integrity_free(struct bio_set *bs, - struct bio_integrity_payload *bip) +/** + * bio_integrity_free - Free bio integrity payload + * @bio: bio containing bip to be freed + * + * Description: Free the integrity portion of a bio. + */ +void bio_integrity_free(struct bio *bio) { + struct bio_integrity_payload *bip = bio_integrity(bio); + struct bio_set *bs = bio->bi_pool; + if (bs && mempool_initialized(&bs->bio_integrity_pool)) { if (bip->bip_vec) bvec_free(&bs->bvec_integrity_pool, bip->bip_vec, @@ -33,6 +41,8 @@ static void __bio_integrity_free(struct bio_set *bs, } else { kfree(bip); } + bio->bi_integrity = NULL; + bio->bi_opf &= ~REQ_INTEGRITY; } /** @@ -86,7 +96,10 @@ struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio, return bip; err: - __bio_integrity_free(bs, bip); + if (bs && mempool_initialized(&bs->bio_integrity_pool)) + mempool_free(bip, &bs->bio_integrity_pool); + else + kfree(bip); return ERR_PTR(-ENOMEM); } EXPORT_SYMBOL(bio_integrity_alloc); @@ -118,9 +131,10 @@ static void bio_integrity_uncopy_user(struct bio_integrity_payload *bip) bio_integrity_unpin_bvec(copy, nr_vecs, true); } -static void bio_integrity_unmap_user(struct bio_integrity_payload *bip) +void bio_integrity_unmap_user(struct bio *bio) { - bool dirty = bio_data_dir(bip->bip_bio) == READ; + struct bio_integrity_payload *bip = bio_integrity(bio); + bool dirty = bio_data_dir(bio) == READ; if (bip->bip_flags & BIP_COPY_USER) { if (dirty) @@ -131,28 +145,7 @@ static void bio_integrity_unmap_user(struct bio_integrity_payload *bip) bio_integrity_unpin_bvec(bip->bip_vec, bip->bip_max_vcnt, dirty); } - -/** - * bio_integrity_free - Free bio integrity payload - * @bio: bio containing bip to be freed - * - * Description: Used to free the integrity portion of a bio. Usually - * called from bio_free(). - */ -void bio_integrity_free(struct bio *bio) -{ - struct bio_integrity_payload *bip = bio_integrity(bio); - struct bio_set *bs = bio->bi_pool; - - if (bip->bip_flags & BIP_BLOCK_INTEGRITY) - kfree(bvec_virt(bip->bip_vec)); - else if (bip->bip_flags & BIP_INTEGRITY_USER) - bio_integrity_unmap_user(bip); - - __bio_integrity_free(bs, bip); - bio->bi_integrity = NULL; - bio->bi_opf &= ~REQ_INTEGRITY; -} +EXPORT_SYMBOL_GPL(bio_integrity_unmap_user); /** * bio_integrity_add_page - Attach integrity metadata @@ -252,7 +245,7 @@ static int bio_integrity_copy_user(struct bio *bio, struct bio_vec *bvec, goto free_bip; } - bip->bip_flags |= BIP_INTEGRITY_USER | BIP_COPY_USER; + bip->bip_flags |= BIP_COPY_USER; bip->bip_iter.bi_sector = seed; return 0; free_bip: @@ -272,7 +265,6 @@ static int bio_integrity_init_user(struct bio *bio, struct bio_vec *bvec, return PTR_ERR(bip); memcpy(bip->bip_vec, bvec, nr_vecs * sizeof(*bvec)); - bip->bip_flags |= BIP_INTEGRITY_USER; bip->bip_iter.bi_sector = seed; bip->bip_iter.bi_size = len; return 0; @@ -479,6 +471,8 @@ static void bio_integrity_verify_fn(struct work_struct *work) struct bio *bio = bip->bip_bio; blk_integrity_verify(bio); + + kfree(bvec_virt(bip->bip_vec)); bio_integrity_free(bio); bio_endio(bio); } @@ -499,13 +493,13 @@ bool __bio_integrity_endio(struct bio *bio) struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk); struct bio_integrity_payload *bip = bio_integrity(bio); - if (bio_op(bio) == REQ_OP_READ && !bio->bi_status && - (bip->bip_flags & BIP_BLOCK_INTEGRITY) && bi->csum_type) { + if (bio_op(bio) == REQ_OP_READ && !bio->bi_status && bi->csum_type) { INIT_WORK(&bip->bip_work, bio_integrity_verify_fn); queue_work(kintegrityd_wq, &bip->bip_work); return false; } + kfree(bvec_virt(bip->bip_vec)); bio_integrity_free(bio); return true; } diff --git a/block/blk-map.c b/block/blk-map.c index bce144091128f6..0e1167b239342f 100644 --- a/block/blk-map.c +++ b/block/blk-map.c @@ -757,6 +757,9 @@ int blk_rq_unmap_user(struct bio *bio) bio_release_pages(bio, bio_data_dir(bio) == READ); } + if (bio_integrity(bio)) + bio_integrity_unmap_user(bio); + next_bio = bio; bio = bio->bi_next; blk_mq_map_bio_put(next_bio); diff --git a/block/blk.h b/block/blk.h index 401e604f35d2cf..e8a6e7497c8d36 100644 --- a/block/blk.h +++ b/block/blk.h @@ -206,7 +206,9 @@ bool __bio_integrity_endio(struct bio *); void bio_integrity_free(struct bio *bio); static inline bool bio_integrity_endio(struct bio *bio) { - if (bio_integrity(bio)) + struct bio_integrity_payload *bip = bio_integrity(bio); + + if (bip && (bip->bip_flags & BIP_BLOCK_INTEGRITY)) return __bio_integrity_endio(bio); return true; } diff --git a/include/linux/bio-integrity.h b/include/linux/bio-integrity.h index 7b6e687d436de2..a5a8b44e9b118f 100644 --- a/include/linux/bio-integrity.h +++ b/include/linux/bio-integrity.h @@ -10,8 +10,7 @@ enum bip_flags { BIP_CTRL_NOCHECK = 1 << 2, /* disable HBA integrity checking */ BIP_DISK_NOCHECK = 1 << 3, /* disable disk integrity checking */ BIP_IP_CHECKSUM = 1 << 4, /* IP checksum */ - BIP_INTEGRITY_USER = 1 << 5, /* Integrity payload is user address */ - BIP_COPY_USER = 1 << 6, /* Kernel bounce buffer in use */ + BIP_COPY_USER = 1 << 5, /* Kernel bounce buffer in use */ }; struct bio_integrity_payload { @@ -74,6 +73,7 @@ struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio, gfp_t gfp, int bio_integrity_add_page(struct bio *bio, struct page *page, unsigned int len, unsigned int offset); int bio_integrity_map_user(struct bio *bio, void __user *ubuf, ssize_t len, u32 seed); +void bio_integrity_unmap_user(struct bio *bio); bool bio_integrity_prep(struct bio *bio); void bio_integrity_advance(struct bio *bio, unsigned int bytes_done); void bio_integrity_trim(struct bio *bio); @@ -105,6 +105,10 @@ static inline int bio_integrity_map_user(struct bio *bio, void __user *ubuf, return -EINVAL; } +static inline void bio_integrity_unmap_user(struct bio *bio) +{ +} + static inline bool bio_integrity_prep(struct bio *bio) { return true;