* refs/heads/tmp-cab4399: Linux 4.19.47 NFS: Fix a double unlock from nfs_match,get_client drm/sun4i: dsi: Enforce boundaries on the start delay vfio-ccw: Prevent quiesce function going into an infinite loop drm/sun4i: dsi: Change the start delay calculation drm: Wake up next in drm_read() chain if we are forced to putback the event drm/drv: Hold ref on parent device during drm_device lifetime drm/v3d: Handle errors from IRQ setup. ASoC: davinci-mcasp: Fix clang warning without CONFIG_PM spi: Fix zero length xfer bug spi: imx: stop buffer overflow in RX FIFO flush spi: rspi: Fix sequencer reset during initialization drm/omap: dsi: Fix PM for display blank with paired dss_pll calls spi : spi-topcliff-pch: Fix to handle empty DMA buffers scsi: lpfc: Fix SLI3 commands being issued on SLI4 devices media: saa7146: avoid high stack usage with clang scsi: lpfc: Fix fc4type information for FDMI scsi: lpfc: Fix FDMI manufacturer attribute value media: vimc: zero the media_device on probe media: go7007: avoid clang frame overflow warning with KASAN media: gspca: do not resubmit URBs when streaming has stopped media: vimc: stream: fix thread state before sleep scsi: ufs: fix a missing check of devm_reset_control_get drm/amd/display: Set stream->mode_changed when connectors change drm/amd/display: Fix Divide by 0 in memory calculations media: staging: davinci_vpfe: disallow building with COMPILE_TEST media: m88ds3103: serialize reset messages in m88ds3103_set_frontend media: dvbsky: Avoid leaking dvb frontend media: si2165: fix a missing check of return value igb: Exclude device from suspend direct complete optimization tinydrm/mipi-dbi: Use dma-safe buffers for all SPI transfers e1000e: Disable runtime PM on CNP+ thunderbolt: property: Fix a NULL pointer dereference drm/amd/display: fix releasing planes when exiting odm thunderbolt: Fix to check for kmemdup failure thunderbolt: Fix to check return value of ida_simple_get hwrng: omap - Set default quality dmaengine: tegra210-adma: use devm_clk_*() helpers batman-adv: allow updating DAT entry timeouts on incoming ARP Replies selinux: avoid uninitialized variable warning scsi: lpfc: avoid uninitialized variable warning scsi: qla4xxx: avoid freeing unallocated dma memory usb: core: Add PM runtime calls to usb_hcd_platform_shutdown rcuperf: Fix cleanup path for invalid perf_type strings x86/mce: Handle varying MCA bank counts rcutorture: Fix cleanup path for invalid torture_type strings x86/mce: Fix machine_check_poll() tests for error types overflow: Fix -Wtype-limits compilation warnings tty: ipwireless: fix missing checks for ioremap virtio_console: initialize vtermno value for ports scsi: qedf: Add missing return in qedf_post_io_req() in the fcport offload check timekeeping: Force upper bound for setting CLOCK_REALTIME thunderbolt: Fix to check the return value of kmemdup thunderbolt: property: Fix a missing check of kzalloc efifb: Omit memory map check on legacy boot media: gspca: Kill URBs on USB device disconnect media: wl128x: prevent two potential buffer overflows media: video-mux: fix null pointer dereferences kobject: Don't trigger kobject_uevent(KOBJ_REMOVE) twice. spi: tegra114: reset controller on probe HID: logitech-hidpp: change low battery level threshold from 31 to 30 percent cxgb3/l2t: Fix undefined behaviour ASoC: fsl_utils: fix a leaked reference by adding missing of_node_put ASoC: eukrea-tlv320: fix a leaked reference by adding missing of_node_put HID: core: move Usage Page concatenation to Main item sh: sh7786: Add explicit I/O cast to sh7786_mm_sel() RDMA/hns: Fix bad endianess of port_pd variable chardev: add additional check for minor range overlap x86/uaccess: Fix up the fixup x86/ia32: Fix ia32_restore_sigcontext() AC leak x86/uaccess, signal: Fix AC=1 bloat x86/uaccess, ftrace: Fix ftrace_likely_update() vs. SMAP wil6210: fix return code of wmi_mgmt_tx and wmi_mgmt_tx_ext arm64: cpu_ops: fix a leaked reference by adding missing of_node_put drm/panel: otm8009a: Add delay at the end of initialization scsi: ufs: Avoid configuring regulator with undefined voltage range scsi: ufs: Fix regulator load and icc-level configuration rtlwifi: fix potential NULL pointer dereference rtc: xgene: fix possible race condition brcmfmac: fix Oops when bringing up interface during USB disconnect brcmfmac: fix race during disconnect when USB completion is in progress brcmfmac: fix WARNING during USB disconnect in case of unempty psq brcmfmac: convert dev_init_lock mutex to completion b43: shut up clang -Wuninitialized variable warning brcmfmac: fix missing checks for kmemdup mwifiex: Fix mem leak in mwifiex_tm_cmd rtlwifi: fix a potential NULL pointer dereference selftests/bpf: ksym_search won't check symbols exists iio: adc: ti-ads7950: Fix improper use of mlock iio: common: ssp_sensors: Initialize calculated_time in ssp_common_process_data iio: hmc5843: fix potential NULL pointer dereferences iio: ad_sigma_delta: Properly handle SPI bus locking vs CS assertion drm/pl111: fix possible object reference leak x86/build: Keep local relocations with ld.lld block: sed-opal: fix IOC_OPAL_ENABLE_DISABLE_MBR cpufreq: kirkwood: fix possible object reference leak cpufreq: pmac32: fix possible object reference leak cpufreq/pasemi: fix possible object reference leak cpufreq: ppc_cbe: fix possible object reference leak qmi_wwan: Add quirk for Quectel dynamic config selftests: cgroup: fix cleanup path in test_memcg_subtree_control() s390: cio: fix cio_irb declaration s390/mm: silence compiler warning when compiling without CONFIG_PGSTE x86/microcode: Fix the ancient deprecated microcode loading method s390: zcrypt: initialize variables before_use clk: rockchip: Make rkpwm a critical clock on rk3288 extcon: arizona: Disable mic detect if running when driver is removed clk: rockchip: Fix video codec clocks on rk3288 PM / core: Propagate dev->power.wakeup_path when no callbacks drm/amdgpu: fix old fence check in amdgpu_fence_emit mmc: sdhci-of-esdhc: add erratum eSDHC-A001 and A-008358 support mmc: sdhci-of-esdhc: add erratum A-009204 support mmc: sdhci-of-esdhc: add erratum eSDHC5 support mmc_spi: add a status check for spi_sync_locked mmc: core: make pwrseq_emmc (partially) support sleepy GPIO controllers scsi: libsas: Do discovery on empty PHY to update PHY info hwmon: (f71805f) Use request_muxed_region for Super-IO accesses hwmon: (pc87427) Use request_muxed_region for Super-IO accesses hwmon: (smsc47b397) Use request_muxed_region for Super-IO accesses hwmon: (smsc47m1) Use request_muxed_region for Super-IO accesses hwmon: (vt1211) Use request_muxed_region for Super-IO accesses perf/x86/intel/cstate: Add Icelake support perf/x86/intel/rapl: Add Icelake support perf/x86/msr: Add Icelake support RDMA/cxgb4: Fix null pointer dereference on alloc_skb failure arm64: vdso: Fix clock_getres() for CLOCK_REALTIME ACPI/IORT: Reject platform device creation on NUMA node mapping failure i40e: don't allow changes to HW VLAN stripping on active port VLANs i40e: Able to add up to 16 MAC filters on an untrusted VF phy: mapphone-mdm6600: add gpiolib dependency phy: sun4i-usb: Make sure to disable PHY0 passby for peripheral mode drm: etnaviv: avoid DMA API warning when importing buffers x86/irq/64: Limit IST stack overflow check to #DB stack USB: core: Don't unbind interfaces following device reset failure s390/qeth: handle error from qeth_update_from_chp_desc() thunderbolt: Take domain lock in switch sysfs attribute callbacks irq_work: Do not raise an IPI when queueing work on the local CPU drm/msm: a5xx: fix possible object reference leak staging: vc04_services: handle kzalloc failure sched/core: Handle overflow in cpu_shares_write_u64 sched/rt: Check integer overflow at usec to nsec conversion sched/core: Check quota and period overflow at usec to nsec conversion cgroup: protect cgroup->nr_(dying_)descendants by css_set_lock random: add a spinlock_t to struct batched_entropy random: fix CRNG initialization when random.trust_cpu=1 powerpc/64: Fix booting large kernels with STRICT_KERNEL_RWX powerpc/numa: improve control of topology updates block: fix use-after-free on gendisk iio: adc: stm32-dfsdm: fix unmet direct dependencies detected media: pvrusb2: Prevent a buffer overflow media: au0828: Fix NULL pointer dereference in au0828_analog_stream_enable() media: stm32-dcmi: fix crash when subdev do not expose any formats audit: fix a memory leak bug media: ov2659: make S_FMT succeed even if requested format doesn't match media: au0828: stop video streaming only when last user stops media: ov6650: Move v4l2_clk_get() to ov6650_video_probe() helper media: coda: clear error return value before picture run dmaengine: at_xdmac: remove BUG_ON macro in tasklet perf/arm-cci: Remove broken race mitigation clk: rockchip: undo several noc and special clocks as critical on rk3288 pinctrl: samsung: fix leaked of_node references pinctrl: pistachio: fix leaked of_node references HID: logitech-hidpp: use RAP instead of FAP to get the protocol version Bluetooth: hci_qca: Give enough time to ROME controller to bootup. mm/uaccess: Use 'unsigned long' to placate UBSAN warnings on older GCC versions x86/mm: Remove in_nmi() warning from 64-bit implementation of vmalloc_fault() smpboot: Place the __percpu annotation correctly x86/build: Move _etext to actual end of .text vfio-ccw: Release any channel program when releasing/removing vfio-ccw mdev vfio-ccw: Do not call flush_workqueue while holding the spinlock RDMA/cma: Consider scope_id while binding to ipv6 ll address bcache: avoid clang -Wunintialized warning bcache: add failure check to run_cache_set() for journal replay bcache: fix failure in journal relplay bcache: return error immediately in bch_journal_replay() bcache: avoid potential memleak of list of journal_replay(s) in the CACHE_SYNC branch of run_cache_set crypto: sun4i-ss - Fix invalid calculation of hash end nvme-rdma: fix a NULL deref when an admin connect times out nvme: set 0 capacity if namespace block size exceeds PAGE_SIZE net: cw1200: fix a NULL pointer dereference rsi: Fix NULL pointer dereference in kmalloc mwifiex: prevent an array overflow ASoC: fsl_sai: Update is_slave_mode with correct value slimbus: fix a potential NULL pointer dereference in of_qcom_slim_ngd_register libbpf: fix samples/bpf build failure due to undefined UINT32_MAX mac80211/cfg80211: update bss channel on channel switch dmaengine: pl330: _stop: clear interrupt status s390: qeth: address type mismatch warning w1: fix the resume command API sched/nohz: Run NOHZ idle load balancer on HK_FLAG_MISC CPUs s390/kexec_file: Fix detection of text segment in ELF loader scsi: qedi: Abort ep termination if offload not scheduled rtc: stm32: manage the get_irq probe defer case rtc: 88pm860x: prevent use-after-free on device remove iwlwifi: pcie: don't crash on invalid RX interrupt btrfs: Don't panic when we can't find a root key btrfs: fix panic during relocation after ENOSPC before writeback happens Btrfs: fix data bytes_may_use underflow with fallocate due to failed quota reserve x86/modules: Avoid breaking W^X while loading modules scsi: qla2xxx: Fix hardirq-unsafe locking scsi: qla2xxx: Avoid that lockdep complains about unsafe locking in tcm_qla2xxx_close_session() scsi: qla2xxx: Fix abort handling in tcm_qla2xxx_write_pending() scsi: qla2xxx: Fix a qla24xx_enable_msix() error path sched/cpufreq: Fix kobject memleak powerpc/watchdog: Use hrtimers for per-CPU heartbeat arm64: Fix compiler warning from pte_unmap() with -Wunused-but-set-variable ARM: vdso: Remove dependency with the arch_timer driver internals media: stm32-dcmi: return appropriate error codes during probe drm/nouveau/bar/nv50: ensure BAR is mapped ACPI / property: fix handling of data_nodes in acpi_get_next_subnode() brcm80211: potential NULL dereference in brcmf_cfg80211_vndr_cmds_dcmd_handler() spi: pxa2xx: fix SCR (divisor) calculation ASoC: imx: fix fiq dependencies powerpc/perf: Fix loop exit condition in nest_imc_event_init powerpc/boot: Fix missing check of lseek() return value powerpc/perf: Return accordingly on invalid chip-id in ASoC: hdmi-codec: unlock the device on startup errors usb: dwc3: move synchronize_irq() out of the spinlock protected block usb: dwc2: gadget: Increase descriptors count for ISOC's ASoC: Intel: kbl_da7219_max98357a: Map BTN_0 to KEY_PLAYPAUSE pinctrl: zte: fix leaked of_node references Bluetooth: Ignore CC events not matching the last HCI command hv_netvsc: fix race that may miss tx queue wakeup net: ena: gcc 8: fix compilation warning dmaengine: tegra210-dma: free dma controller in remove() bpftool: exclude bash-completion/bpftool from .gitignore pattern selftests/bpf: set RLIMIT_MEMLOCK properly for test_libbpf_open.c tools/bpf: fix perf build error with uClibc (seen on ARC) mmc: core: Verify SD bus width gfs2: Fix occasional glock use-after-free IB/hfi1: Fix WQ_MEM_RECLAIM warning NFS: make nfs_match_client killable cxgb4: Fix error path in cxgb4_init_module gfs2: Fix lru_count going negative Revert "btrfs: Honour FITRIM range constraints during free space trim" acct_on(): don't mess with freeze protection at76c50x-usb: Don't register led_trigger if usb_register_driver failed batman-adv: mcast: fix multicast tt/tvlv worker locking bpf: devmap: fix use-after-free Read in __dev_map_entry_free ssb: Fix possible NULL pointer dereference in ssb_host_pcmcia_exit media: vivid: use vfree() instead of kfree() for dev->bitmap_cap media: vb2: add waiting_in_dqbuf flag media: serial_ir: Fix use-after-free in serial_ir_init_module media: cpia2: Fix use-after-free in cpia2_exit fbdev: fix WARNING in __alloc_pages_nodemask bug ovl: relax WARN_ON() for overlapping layers use case btrfs: honor path->skip_locking in backref code arm64: errata: Add workaround for Cortex-A76 erratum #1463225 brcmfmac: add subtype check for event handling in data path brcmfmac: assure SSID length from firmware is limited bpf: add bpf_jit_limit knob to restrict unpriv allocations NFSv4.1 fix incorrect return value in copy_file_range NFSv4.2 fix unnecessary retry in nfs4_copy_file_range fbdev: fix divide error in fb_var_to_videomode udlfb: fix some inconsistent NULL checking btrfs: sysfs: don't leak memory when failing add fsid btrfs: sysfs: Fix error path kobject memory leak Btrfs: fix race between ranged fsync and writeback of adjacent ranges Btrfs: avoid fallback to transaction commit during fsync of files with holes Btrfs: do not abort transaction at btrfs_update_root() after failure to COW path btrfs: don't double unlock on error in btrfs_punch_hole gfs2: Fix sign extension bug in gfs2_update_stats arm64/iommu: handle non-remapped addresses in ->mmap and ->get_sgtable arm64/kernel: kaslr: reduce module randomization range to 2 GB libnvdimm/pmem: Bypass CONFIG_HARDENED_USERCOPY overhead kvm: svm/avic: fix off-by-one in checking host APIC ID mmc: sdhci-iproc: Set NO_HISPD bit to fix HS50 data hold time problem mmc: sdhci-iproc: cygnus: Set NO_HISPD bit to fix HS50 data hold time problem crypto: vmx - CTR: always increment IV as quadword Revert "scsi: sd: Keep disk read-only when re-reading partition" sbitmap: fix improper use of smp_mb__before_atomic() bio: fix improper use of smp_mb__before_atomic() KVM: x86: fix return value for reserved EFER f2fs: Fix use of number of devices ext4: wait for outstanding dio during truncate in nojournal mode ext4: do not delete unlinked inode from orphan list on failed truncate x86: Hide the int3_emulate_call/jmp functions from UML x86: Hide the int3_emulate_call/jmp functions from UML f2fs: link f2fs quota ops for sysfile Conflicts: arch/arm64/Kconfig arch/arm64/include/asm/cpucaps.h arch/arm64/include/asm/cputype.h arch/arm64/include/asm/pgtable.h arch/arm64/kernel/cpu_errata.c arch/arm64/mm/dma-mapping.c arch/x86/include/asm/text-patching.h drivers/scsi/ufs/ufshcd.c drivers/slimbus/qcom-ngd-ctrl.c kernel/sched/fair.c Change-Id: Ie70cae851ffdbac1b9dbf611fc361c275f4826fd Signed-off-by: Ivaylo Georgiev <irgeorgiev@codeaurora.org>
875 lines
22 KiB
C
875 lines
22 KiB
C
/*
|
|
* Copyright (C) 2001 Jens Axboe <axboe@suse.de>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
*
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public Licens
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-
|
|
*/
|
|
#ifndef __LINUX_BIO_H
|
|
#define __LINUX_BIO_H
|
|
|
|
#include <linux/highmem.h>
|
|
#include <linux/mempool.h>
|
|
#include <linux/ioprio.h>
|
|
#include <linux/bug.h>
|
|
|
|
#ifdef CONFIG_BLOCK
|
|
|
|
#include <asm/io.h>
|
|
|
|
/* struct bio, bio_vec and BIO_* flags are defined in blk_types.h */
|
|
#include <linux/blk_types.h>
|
|
|
|
#define BIO_DEBUG
|
|
|
|
#ifdef BIO_DEBUG
|
|
#define BIO_BUG_ON BUG_ON
|
|
#else
|
|
#define BIO_BUG_ON
|
|
#endif
|
|
|
|
#ifdef CONFIG_THP_SWAP
|
|
#if HPAGE_PMD_NR > 256
|
|
#define BIO_MAX_PAGES HPAGE_PMD_NR
|
|
#else
|
|
#define BIO_MAX_PAGES 256
|
|
#endif
|
|
#else
|
|
#define BIO_MAX_PAGES 256
|
|
#endif
|
|
|
|
#define bio_prio(bio) (bio)->bi_ioprio
|
|
#define bio_set_prio(bio, prio) ((bio)->bi_ioprio = prio)
|
|
|
|
#define bio_iter_iovec(bio, iter) \
|
|
bvec_iter_bvec((bio)->bi_io_vec, (iter))
|
|
|
|
#define bio_iter_page(bio, iter) \
|
|
bvec_iter_page((bio)->bi_io_vec, (iter))
|
|
#define bio_iter_len(bio, iter) \
|
|
bvec_iter_len((bio)->bi_io_vec, (iter))
|
|
#define bio_iter_offset(bio, iter) \
|
|
bvec_iter_offset((bio)->bi_io_vec, (iter))
|
|
|
|
#define bio_page(bio) bio_iter_page((bio), (bio)->bi_iter)
|
|
#define bio_offset(bio) bio_iter_offset((bio), (bio)->bi_iter)
|
|
#define bio_iovec(bio) bio_iter_iovec((bio), (bio)->bi_iter)
|
|
|
|
#define bio_multiple_segments(bio) \
|
|
((bio)->bi_iter.bi_size != bio_iovec(bio).bv_len)
|
|
|
|
#define bvec_iter_sectors(iter) ((iter).bi_size >> 9)
|
|
#define bvec_iter_end_sector(iter) ((iter).bi_sector + bvec_iter_sectors((iter)))
|
|
|
|
#define bio_sectors(bio) bvec_iter_sectors((bio)->bi_iter)
|
|
#define bio_end_sector(bio) bvec_iter_end_sector((bio)->bi_iter)
|
|
#define bio_dun(bio) ((bio)->bi_iter.bi_dun)
|
|
#define bio_duns(bio) (bio_sectors(bio) >> 3) /* 4KB unit */
|
|
#define bio_end_dun(bio) (bio_dun(bio) + bio_duns(bio))
|
|
|
|
/*
|
|
* Return the data direction, READ or WRITE.
|
|
*/
|
|
#define bio_data_dir(bio) \
|
|
(op_is_write(bio_op(bio)) ? WRITE : READ)
|
|
|
|
/*
|
|
* Check whether this bio carries any data or not. A NULL bio is allowed.
|
|
*/
|
|
static inline bool bio_has_data(struct bio *bio)
|
|
{
|
|
if (bio &&
|
|
bio->bi_iter.bi_size &&
|
|
bio_op(bio) != REQ_OP_DISCARD &&
|
|
bio_op(bio) != REQ_OP_SECURE_ERASE &&
|
|
bio_op(bio) != REQ_OP_WRITE_ZEROES)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
static inline bool bio_no_advance_iter(struct bio *bio)
|
|
{
|
|
return bio_op(bio) == REQ_OP_DISCARD ||
|
|
bio_op(bio) == REQ_OP_SECURE_ERASE ||
|
|
bio_op(bio) == REQ_OP_WRITE_SAME ||
|
|
bio_op(bio) == REQ_OP_WRITE_ZEROES;
|
|
}
|
|
|
|
static inline bool bio_mergeable(struct bio *bio)
|
|
{
|
|
if (bio->bi_opf & REQ_NOMERGE_FLAGS)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
static inline unsigned int bio_cur_bytes(struct bio *bio)
|
|
{
|
|
if (bio_has_data(bio))
|
|
return bio_iovec(bio).bv_len;
|
|
else /* dataless requests such as discard */
|
|
return bio->bi_iter.bi_size;
|
|
}
|
|
|
|
static inline void *bio_data(struct bio *bio)
|
|
{
|
|
if (bio_has_data(bio))
|
|
return page_address(bio_page(bio)) + bio_offset(bio);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static inline bool bio_full(struct bio *bio)
|
|
{
|
|
return bio->bi_vcnt >= bio->bi_max_vecs;
|
|
}
|
|
|
|
/*
|
|
* will die
|
|
*/
|
|
#define bvec_to_phys(bv) (page_to_phys((bv)->bv_page) + (unsigned long) (bv)->bv_offset)
|
|
|
|
/*
|
|
* merge helpers etc
|
|
*/
|
|
|
|
/* Default implementation of BIOVEC_PHYS_MERGEABLE */
|
|
#define __BIOVEC_PHYS_MERGEABLE(vec1, vec2) \
|
|
((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2)))
|
|
|
|
/*
|
|
* allow arch override, for eg virtualized architectures (put in asm/io.h)
|
|
*/
|
|
#ifndef BIOVEC_PHYS_MERGEABLE
|
|
#define BIOVEC_PHYS_MERGEABLE(vec1, vec2) \
|
|
__BIOVEC_PHYS_MERGEABLE(vec1, vec2)
|
|
#endif
|
|
|
|
#define __BIO_SEG_BOUNDARY(addr1, addr2, mask) \
|
|
(((addr1) | (mask)) == (((addr2) - 1) | (mask)))
|
|
#define BIOVEC_SEG_BOUNDARY(q, b1, b2) \
|
|
__BIO_SEG_BOUNDARY(bvec_to_phys((b1)), bvec_to_phys((b2)) + (b2)->bv_len, queue_segment_boundary((q)))
|
|
|
|
/*
|
|
* drivers should _never_ use the all version - the bio may have been split
|
|
* before it got to the driver and the driver won't own all of it
|
|
*/
|
|
#define bio_for_each_segment_all(bvl, bio, i) \
|
|
for (i = 0, bvl = (bio)->bi_io_vec; i < (bio)->bi_vcnt; i++, bvl++)
|
|
|
|
static inline void bio_advance_iter(struct bio *bio, struct bvec_iter *iter,
|
|
unsigned bytes)
|
|
{
|
|
iter->bi_sector += bytes >> 9;
|
|
|
|
#ifdef CONFIG_PFK
|
|
if (iter->bi_dun)
|
|
iter->bi_dun += bytes >> 12;
|
|
#endif
|
|
|
|
if (bio_no_advance_iter(bio)) {
|
|
iter->bi_size -= bytes;
|
|
iter->bi_done += bytes;
|
|
} else {
|
|
bvec_iter_advance(bio->bi_io_vec, iter, bytes);
|
|
/* TODO: It is reasonable to complete bio with error here. */
|
|
}
|
|
}
|
|
|
|
static inline bool bio_rewind_iter(struct bio *bio, struct bvec_iter *iter,
|
|
unsigned int bytes)
|
|
{
|
|
iter->bi_sector -= bytes >> 9;
|
|
|
|
if (bio_no_advance_iter(bio)) {
|
|
iter->bi_size += bytes;
|
|
iter->bi_done -= bytes;
|
|
return true;
|
|
}
|
|
|
|
return bvec_iter_rewind(bio->bi_io_vec, iter, bytes);
|
|
}
|
|
|
|
#define __bio_for_each_segment(bvl, bio, iter, start) \
|
|
for (iter = (start); \
|
|
(iter).bi_size && \
|
|
((bvl = bio_iter_iovec((bio), (iter))), 1); \
|
|
bio_advance_iter((bio), &(iter), (bvl).bv_len))
|
|
|
|
#define bio_for_each_segment(bvl, bio, iter) \
|
|
__bio_for_each_segment(bvl, bio, iter, (bio)->bi_iter)
|
|
|
|
#define bio_iter_last(bvec, iter) ((iter).bi_size == (bvec).bv_len)
|
|
|
|
static inline unsigned bio_segments(struct bio *bio)
|
|
{
|
|
unsigned segs = 0;
|
|
struct bio_vec bv;
|
|
struct bvec_iter iter;
|
|
|
|
/*
|
|
* We special case discard/write same/write zeroes, because they
|
|
* interpret bi_size differently:
|
|
*/
|
|
|
|
switch (bio_op(bio)) {
|
|
case REQ_OP_DISCARD:
|
|
case REQ_OP_SECURE_ERASE:
|
|
case REQ_OP_WRITE_ZEROES:
|
|
return 0;
|
|
case REQ_OP_WRITE_SAME:
|
|
return 1;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
bio_for_each_segment(bv, bio, iter)
|
|
segs++;
|
|
|
|
return segs;
|
|
}
|
|
|
|
/*
|
|
* get a reference to a bio, so it won't disappear. the intended use is
|
|
* something like:
|
|
*
|
|
* bio_get(bio);
|
|
* submit_bio(rw, bio);
|
|
* if (bio->bi_flags ...)
|
|
* do_something
|
|
* bio_put(bio);
|
|
*
|
|
* without the bio_get(), it could potentially complete I/O before submit_bio
|
|
* returns. and then bio would be freed memory when if (bio->bi_flags ...)
|
|
* runs
|
|
*/
|
|
static inline void bio_get(struct bio *bio)
|
|
{
|
|
bio->bi_flags |= (1 << BIO_REFFED);
|
|
smp_mb__before_atomic();
|
|
atomic_inc(&bio->__bi_cnt);
|
|
}
|
|
|
|
static inline void bio_cnt_set(struct bio *bio, unsigned int count)
|
|
{
|
|
if (count != 1) {
|
|
bio->bi_flags |= (1 << BIO_REFFED);
|
|
smp_mb();
|
|
}
|
|
atomic_set(&bio->__bi_cnt, count);
|
|
}
|
|
|
|
static inline bool bio_flagged(struct bio *bio, unsigned int bit)
|
|
{
|
|
return (bio->bi_flags & (1U << bit)) != 0;
|
|
}
|
|
|
|
static inline void bio_set_flag(struct bio *bio, unsigned int bit)
|
|
{
|
|
bio->bi_flags |= (1U << bit);
|
|
}
|
|
|
|
static inline void bio_clear_flag(struct bio *bio, unsigned int bit)
|
|
{
|
|
bio->bi_flags &= ~(1U << bit);
|
|
}
|
|
|
|
static inline void bio_get_first_bvec(struct bio *bio, struct bio_vec *bv)
|
|
{
|
|
*bv = bio_iovec(bio);
|
|
}
|
|
|
|
static inline void bio_get_last_bvec(struct bio *bio, struct bio_vec *bv)
|
|
{
|
|
struct bvec_iter iter = bio->bi_iter;
|
|
int idx;
|
|
|
|
if (unlikely(!bio_multiple_segments(bio))) {
|
|
*bv = bio_iovec(bio);
|
|
return;
|
|
}
|
|
|
|
bio_advance_iter(bio, &iter, iter.bi_size);
|
|
|
|
if (!iter.bi_bvec_done)
|
|
idx = iter.bi_idx - 1;
|
|
else /* in the middle of bvec */
|
|
idx = iter.bi_idx;
|
|
|
|
*bv = bio->bi_io_vec[idx];
|
|
|
|
/*
|
|
* iter.bi_bvec_done records actual length of the last bvec
|
|
* if this bio ends in the middle of one io vector
|
|
*/
|
|
if (iter.bi_bvec_done)
|
|
bv->bv_len = iter.bi_bvec_done;
|
|
}
|
|
|
|
static inline unsigned bio_pages_all(struct bio *bio)
|
|
{
|
|
WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED));
|
|
return bio->bi_vcnt;
|
|
}
|
|
|
|
static inline struct bio_vec *bio_first_bvec_all(struct bio *bio)
|
|
{
|
|
WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED));
|
|
return bio->bi_io_vec;
|
|
}
|
|
|
|
static inline struct page *bio_first_page_all(struct bio *bio)
|
|
{
|
|
return bio_first_bvec_all(bio)->bv_page;
|
|
}
|
|
|
|
static inline struct bio_vec *bio_last_bvec_all(struct bio *bio)
|
|
{
|
|
WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED));
|
|
return &bio->bi_io_vec[bio->bi_vcnt - 1];
|
|
}
|
|
|
|
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 */
|
|
};
|
|
|
|
/*
|
|
* bio integrity payload
|
|
*/
|
|
struct bio_integrity_payload {
|
|
struct bio *bip_bio; /* parent bio */
|
|
|
|
struct bvec_iter bip_iter;
|
|
|
|
unsigned short bip_slab; /* slab the bip came from */
|
|
unsigned short bip_vcnt; /* # of integrity bio_vecs */
|
|
unsigned short bip_max_vcnt; /* integrity bio_vec slots */
|
|
unsigned short bip_flags; /* control flags */
|
|
|
|
struct work_struct bip_work; /* I/O completion */
|
|
|
|
struct bio_vec *bip_vec;
|
|
struct bio_vec bip_inline_vecs[0];/* 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 */
|
|
|
|
extern void bio_trim(struct bio *bio, int offset, int size);
|
|
extern struct bio *bio_split(struct bio *bio, int sectors,
|
|
gfp_t gfp, struct bio_set *bs);
|
|
|
|
/**
|
|
* bio_next_split - get next @sectors from a bio, splitting if necessary
|
|
* @bio: bio to split
|
|
* @sectors: number of sectors to split from the front of @bio
|
|
* @gfp: gfp mask
|
|
* @bs: bio set to allocate from
|
|
*
|
|
* Returns a bio representing the next @sectors of @bio - if the bio is smaller
|
|
* than @sectors, returns the original bio unchanged.
|
|
*/
|
|
static inline struct bio *bio_next_split(struct bio *bio, int sectors,
|
|
gfp_t gfp, struct bio_set *bs)
|
|
{
|
|
if (sectors >= bio_sectors(bio))
|
|
return bio;
|
|
|
|
return bio_split(bio, sectors, gfp, bs);
|
|
}
|
|
|
|
enum {
|
|
BIOSET_NEED_BVECS = BIT(0),
|
|
BIOSET_NEED_RESCUER = BIT(1),
|
|
};
|
|
extern int bioset_init(struct bio_set *, unsigned int, unsigned int, int flags);
|
|
extern void bioset_exit(struct bio_set *);
|
|
extern int biovec_init_pool(mempool_t *pool, int pool_entries);
|
|
extern int bioset_init_from_src(struct bio_set *bs, struct bio_set *src);
|
|
|
|
extern struct bio *bio_alloc_bioset(gfp_t, unsigned int, struct bio_set *);
|
|
extern void bio_put(struct bio *);
|
|
|
|
extern void __bio_clone_fast(struct bio *, struct bio *);
|
|
extern struct bio *bio_clone_fast(struct bio *, gfp_t, struct bio_set *);
|
|
|
|
extern struct bio_set fs_bio_set;
|
|
|
|
static inline struct bio *bio_alloc(gfp_t gfp_mask, unsigned int nr_iovecs)
|
|
{
|
|
return bio_alloc_bioset(gfp_mask, nr_iovecs, &fs_bio_set);
|
|
}
|
|
|
|
static inline struct bio *bio_kmalloc(gfp_t gfp_mask, unsigned int nr_iovecs)
|
|
{
|
|
return bio_alloc_bioset(gfp_mask, nr_iovecs, NULL);
|
|
}
|
|
|
|
extern blk_qc_t submit_bio(struct bio *);
|
|
|
|
extern void bio_endio(struct bio *);
|
|
|
|
static inline void bio_io_error(struct bio *bio)
|
|
{
|
|
bio->bi_status = BLK_STS_IOERR;
|
|
bio_endio(bio);
|
|
}
|
|
|
|
static inline void bio_wouldblock_error(struct bio *bio)
|
|
{
|
|
bio->bi_status = BLK_STS_AGAIN;
|
|
bio_endio(bio);
|
|
}
|
|
|
|
struct request_queue;
|
|
extern int bio_phys_segments(struct request_queue *, struct bio *);
|
|
|
|
extern int submit_bio_wait(struct bio *bio);
|
|
extern void bio_advance(struct bio *, unsigned);
|
|
|
|
extern void bio_init(struct bio *bio, struct bio_vec *table,
|
|
unsigned short max_vecs);
|
|
extern void bio_uninit(struct bio *);
|
|
extern void bio_reset(struct bio *);
|
|
void bio_chain(struct bio *, struct bio *);
|
|
|
|
extern int bio_add_page(struct bio *, struct page *, unsigned int,unsigned int);
|
|
extern int bio_add_pc_page(struct request_queue *, struct bio *, struct page *,
|
|
unsigned int, unsigned int);
|
|
bool __bio_try_merge_page(struct bio *bio, struct page *page,
|
|
unsigned int len, unsigned int off);
|
|
void __bio_add_page(struct bio *bio, struct page *page,
|
|
unsigned int len, unsigned int off);
|
|
int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter);
|
|
struct rq_map_data;
|
|
extern struct bio *bio_map_user_iov(struct request_queue *,
|
|
struct iov_iter *, gfp_t);
|
|
extern void bio_unmap_user(struct bio *);
|
|
extern struct bio *bio_map_kern(struct request_queue *, void *, unsigned int,
|
|
gfp_t);
|
|
extern struct bio *bio_copy_kern(struct request_queue *, void *, unsigned int,
|
|
gfp_t, int);
|
|
extern void bio_set_pages_dirty(struct bio *bio);
|
|
extern void bio_check_pages_dirty(struct bio *bio);
|
|
|
|
void generic_start_io_acct(struct request_queue *q, int op,
|
|
unsigned long sectors, struct hd_struct *part);
|
|
void generic_end_io_acct(struct request_queue *q, int op,
|
|
struct hd_struct *part,
|
|
unsigned long start_time);
|
|
|
|
#ifndef ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE
|
|
# error "You should define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE for your platform"
|
|
#endif
|
|
#if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE
|
|
extern void bio_flush_dcache_pages(struct bio *bi);
|
|
#else
|
|
static inline void bio_flush_dcache_pages(struct bio *bi)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
extern void bio_copy_data_iter(struct bio *dst, struct bvec_iter *dst_iter,
|
|
struct bio *src, struct bvec_iter *src_iter);
|
|
extern void bio_copy_data(struct bio *dst, struct bio *src);
|
|
extern void bio_list_copy_data(struct bio *dst, struct bio *src);
|
|
extern void bio_free_pages(struct bio *bio);
|
|
|
|
extern struct bio *bio_copy_user_iov(struct request_queue *,
|
|
struct rq_map_data *,
|
|
struct iov_iter *,
|
|
gfp_t);
|
|
extern int bio_uncopy_user(struct bio *);
|
|
void zero_fill_bio_iter(struct bio *bio, struct bvec_iter iter);
|
|
|
|
static inline void zero_fill_bio(struct bio *bio)
|
|
{
|
|
zero_fill_bio_iter(bio, bio->bi_iter);
|
|
}
|
|
|
|
extern struct bio_vec *bvec_alloc(gfp_t, int, unsigned long *, mempool_t *);
|
|
extern void bvec_free(mempool_t *, struct bio_vec *, unsigned int);
|
|
extern unsigned int bvec_nr_vecs(unsigned short idx);
|
|
extern const char *bio_devname(struct bio *bio, char *buffer);
|
|
|
|
#define bio_set_dev(bio, bdev) \
|
|
do { \
|
|
if ((bio)->bi_disk != (bdev)->bd_disk) \
|
|
bio_clear_flag(bio, BIO_THROTTLED);\
|
|
(bio)->bi_disk = (bdev)->bd_disk; \
|
|
(bio)->bi_partno = (bdev)->bd_partno; \
|
|
} while (0)
|
|
|
|
#define bio_copy_dev(dst, src) \
|
|
do { \
|
|
(dst)->bi_disk = (src)->bi_disk; \
|
|
(dst)->bi_partno = (src)->bi_partno; \
|
|
} while (0)
|
|
|
|
#define bio_dev(bio) \
|
|
disk_devt((bio)->bi_disk)
|
|
|
|
#if defined(CONFIG_MEMCG) && defined(CONFIG_BLK_CGROUP)
|
|
int bio_associate_blkcg_from_page(struct bio *bio, struct page *page);
|
|
#else
|
|
static inline int bio_associate_blkcg_from_page(struct bio *bio,
|
|
struct page *page) { return 0; }
|
|
#endif
|
|
|
|
#ifdef CONFIG_BLK_CGROUP
|
|
int bio_associate_blkcg(struct bio *bio, struct cgroup_subsys_state *blkcg_css);
|
|
int bio_associate_blkg(struct bio *bio, struct blkcg_gq *blkg);
|
|
void bio_disassociate_task(struct bio *bio);
|
|
void bio_clone_blkcg_association(struct bio *dst, struct bio *src);
|
|
#else /* CONFIG_BLK_CGROUP */
|
|
static inline int bio_associate_blkcg(struct bio *bio,
|
|
struct cgroup_subsys_state *blkcg_css) { return 0; }
|
|
static inline void bio_disassociate_task(struct bio *bio) { }
|
|
static inline void bio_clone_blkcg_association(struct bio *dst,
|
|
struct bio *src) { }
|
|
#endif /* CONFIG_BLK_CGROUP */
|
|
|
|
#ifdef CONFIG_HIGHMEM
|
|
/*
|
|
* remember never ever reenable interrupts between a bvec_kmap_irq and
|
|
* bvec_kunmap_irq!
|
|
*/
|
|
static inline char *bvec_kmap_irq(struct bio_vec *bvec, unsigned long *flags)
|
|
{
|
|
unsigned long addr;
|
|
|
|
/*
|
|
* might not be a highmem page, but the preempt/irq count
|
|
* balancing is a lot nicer this way
|
|
*/
|
|
local_irq_save(*flags);
|
|
addr = (unsigned long) kmap_atomic(bvec->bv_page);
|
|
|
|
BUG_ON(addr & ~PAGE_MASK);
|
|
|
|
return (char *) addr + bvec->bv_offset;
|
|
}
|
|
|
|
static inline void bvec_kunmap_irq(char *buffer, unsigned long *flags)
|
|
{
|
|
unsigned long ptr = (unsigned long) buffer & PAGE_MASK;
|
|
|
|
kunmap_atomic((void *) ptr);
|
|
local_irq_restore(*flags);
|
|
}
|
|
|
|
#else
|
|
static inline char *bvec_kmap_irq(struct bio_vec *bvec, unsigned long *flags)
|
|
{
|
|
return page_address(bvec->bv_page) + bvec->bv_offset;
|
|
}
|
|
|
|
static inline void bvec_kunmap_irq(char *buffer, unsigned long *flags)
|
|
{
|
|
*flags = 0;
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* BIO list management for use by remapping drivers (e.g. DM or MD) and loop.
|
|
*
|
|
* A bio_list anchors a singly-linked list of bios chained through the bi_next
|
|
* member of the bio. The bio_list also caches the last list member to allow
|
|
* fast access to the tail.
|
|
*/
|
|
struct bio_list {
|
|
struct bio *head;
|
|
struct bio *tail;
|
|
};
|
|
|
|
static inline int bio_list_empty(const struct bio_list *bl)
|
|
{
|
|
return bl->head == NULL;
|
|
}
|
|
|
|
static inline void bio_list_init(struct bio_list *bl)
|
|
{
|
|
bl->head = bl->tail = NULL;
|
|
}
|
|
|
|
#define BIO_EMPTY_LIST { NULL, NULL }
|
|
|
|
#define bio_list_for_each(bio, bl) \
|
|
for (bio = (bl)->head; bio; bio = bio->bi_next)
|
|
|
|
static inline unsigned bio_list_size(const struct bio_list *bl)
|
|
{
|
|
unsigned sz = 0;
|
|
struct bio *bio;
|
|
|
|
bio_list_for_each(bio, bl)
|
|
sz++;
|
|
|
|
return sz;
|
|
}
|
|
|
|
static inline void bio_list_add(struct bio_list *bl, struct bio *bio)
|
|
{
|
|
bio->bi_next = NULL;
|
|
|
|
if (bl->tail)
|
|
bl->tail->bi_next = bio;
|
|
else
|
|
bl->head = bio;
|
|
|
|
bl->tail = bio;
|
|
}
|
|
|
|
static inline void bio_list_add_head(struct bio_list *bl, struct bio *bio)
|
|
{
|
|
bio->bi_next = bl->head;
|
|
|
|
bl->head = bio;
|
|
|
|
if (!bl->tail)
|
|
bl->tail = bio;
|
|
}
|
|
|
|
static inline void bio_list_merge(struct bio_list *bl, struct bio_list *bl2)
|
|
{
|
|
if (!bl2->head)
|
|
return;
|
|
|
|
if (bl->tail)
|
|
bl->tail->bi_next = bl2->head;
|
|
else
|
|
bl->head = bl2->head;
|
|
|
|
bl->tail = bl2->tail;
|
|
}
|
|
|
|
static inline void bio_list_merge_head(struct bio_list *bl,
|
|
struct bio_list *bl2)
|
|
{
|
|
if (!bl2->head)
|
|
return;
|
|
|
|
if (bl->head)
|
|
bl2->tail->bi_next = bl->head;
|
|
else
|
|
bl->tail = bl2->tail;
|
|
|
|
bl->head = bl2->head;
|
|
}
|
|
|
|
static inline struct bio *bio_list_peek(struct bio_list *bl)
|
|
{
|
|
return bl->head;
|
|
}
|
|
|
|
static inline struct bio *bio_list_pop(struct bio_list *bl)
|
|
{
|
|
struct bio *bio = bl->head;
|
|
|
|
if (bio) {
|
|
bl->head = bl->head->bi_next;
|
|
if (!bl->head)
|
|
bl->tail = NULL;
|
|
|
|
bio->bi_next = NULL;
|
|
}
|
|
|
|
return bio;
|
|
}
|
|
|
|
static inline struct bio *bio_list_get(struct bio_list *bl)
|
|
{
|
|
struct bio *bio = bl->head;
|
|
|
|
bl->head = bl->tail = NULL;
|
|
|
|
return bio;
|
|
}
|
|
|
|
/*
|
|
* Increment chain count for the bio. Make sure the CHAIN flag update
|
|
* is visible before the raised count.
|
|
*/
|
|
static inline void bio_inc_remaining(struct bio *bio)
|
|
{
|
|
bio_set_flag(bio, BIO_CHAIN);
|
|
smp_mb__before_atomic();
|
|
atomic_inc(&bio->__bi_remaining);
|
|
}
|
|
|
|
/*
|
|
* bio_set is used to allow other portions of the IO system to
|
|
* allocate their own private memory pools for bio and iovec structures.
|
|
* These memory pools in turn all allocate from the bio_slab
|
|
* and the bvec_slabs[].
|
|
*/
|
|
#define BIO_POOL_SIZE 2
|
|
|
|
struct bio_set {
|
|
struct kmem_cache *bio_slab;
|
|
unsigned int front_pad;
|
|
|
|
mempool_t bio_pool;
|
|
mempool_t bvec_pool;
|
|
#if defined(CONFIG_BLK_DEV_INTEGRITY)
|
|
mempool_t bio_integrity_pool;
|
|
mempool_t bvec_integrity_pool;
|
|
#endif
|
|
|
|
/*
|
|
* Deadlock avoidance for stacking block drivers: see comments in
|
|
* bio_alloc_bioset() for details
|
|
*/
|
|
spinlock_t rescue_lock;
|
|
struct bio_list rescue_list;
|
|
struct work_struct rescue_work;
|
|
struct workqueue_struct *rescue_workqueue;
|
|
};
|
|
|
|
struct biovec_slab {
|
|
int nr_vecs;
|
|
char *name;
|
|
struct kmem_cache *slab;
|
|
};
|
|
|
|
static inline bool bioset_initialized(struct bio_set *bs)
|
|
{
|
|
return bs->bio_slab != NULL;
|
|
}
|
|
|
|
/*
|
|
* a small number of entries is fine, not going to be performance critical.
|
|
* basically we just need to survive
|
|
*/
|
|
#define BIO_SPLIT_ENTRIES 2
|
|
|
|
#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)
|
|
|
|
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;
|
|
}
|
|
|
|
#endif /* CONFIG_BLK_DEV_INTEGRITY */
|
|
|
|
#endif /* CONFIG_BLOCK */
|
|
#endif /* __LINUX_BIO_H */
|