-----BEGIN PGP SIGNATURE-----
iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAmDu+p0ACgkQONu9yGCS
aT5SOw/9F58e4gz7PSTn4A9oCTNodRPe9B9rzf3y1Ol0k7T1aeQoWsPFOkZpNSOJ
tdOGEXnwYnLpMC7nuFshWv1uKGAL/weHADyGV6J37AntYFjpEFhJhSH7pGGhDk7V
EeIl98luBynPXOKNnDvcrQweeRaHKOInQBT8JJzwwsZbF2oqfOqdU0A787BiRu+3
zoi/mV0upDB443ji/JY0xj+o4jlbsuD0WxEqgkcD2YHL+QvU5Wr0mGys7m5gG9x7
TpKpMic0ILrF1vt/znLL5rOlX497prTvZ74ZXV/DYizeYxqtl/UG3CZjo1uf2yqk
pAXA57paz6DY2Ct+3QbJBeuer27bTz6SCClSS1om9AcUk6oNSdULmMdTGvQb0SLU
wx1Cy8b2ei04SVl96+McKKZ6ln47LJediGn0qIdwC6O/XHHrLq4u5PkSnQxRU4pA
GH1tP5oYy4GzL9RbBeiDJQETFiXwkexSEWVyuSc6BhqQXao9yVzmLQbL1zgjH/zO
m/tckZ3vEg+ll8j4QJCisHRyqYhwfru4PsJQH9Q7q6CtIuGOsd0Z/OUcLuF6knXg
jDOrDIykE/PnkQ2Dc2RhdONP1ud5j3oBnHvNHs6FDghRKjaixMQzg3g/RNtnAaTj
+7Xsfbi6ntpZSDOaY7YNgt+ZH3l4YRnUL/xBA6qIygayz374nzI=
=LU0G
-----END PGP SIGNATURE-----
Merge 5.4.132 into android11-5.4-lts
Changes in 5.4.132
ALSA: usb-audio: fix rate on Ozone Z90 USB headset
ALSA: usb-audio: Fix OOB access at proc output
ALSA: usb-audio: scarlett2: Fix wrong resume call
ALSA: intel8x0: Fix breakage at ac97 clock measurement
ALSA: hda/realtek: Add another ALC236 variant support
ALSA: hda/realtek: Improve fixup for HP Spectre x360 15-df0xxx
ALSA: hda/realtek: Fix bass speaker DAC mapping for Asus UM431D
ALSA: hda/realtek: Apply LED fixup for HP Dragonfly G1, too
media: dvb-usb: fix wrong definition
Input: usbtouchscreen - fix control-request directions
net: can: ems_usb: fix use-after-free in ems_usb_disconnect()
usb: gadget: eem: fix echo command packet response issue
USB: cdc-acm: blacklist Heimann USB Appset device
usb: dwc3: Fix debugfs creation flow
usb: typec: Add the missed altmode_id_remove() in typec_register_altmode()
xhci: solve a double free problem while doing s4
ntfs: fix validity check for file name attribute
copy_page_to_iter(): fix ITER_DISCARD case
iov_iter_fault_in_readable() should do nothing in xarray case
Input: joydev - prevent use of not validated data in JSIOCSBTNMAP ioctl
arm_pmu: Fix write counter incorrect in ARMv7 big-endian mode
ARM: dts: at91: sama5d4: fix pinctrl muxing
btrfs: send: fix invalid path for unlink operations after parent orphanization
btrfs: clear defrag status of a root if starting transaction fails
ext4: cleanup in-core orphan list if ext4_truncate() failed to get a transaction handle
ext4: fix kernel infoleak via ext4_extent_header
ext4: return error code when ext4_fill_flex_info() fails
ext4: correct the cache_nr in tracepoint ext4_es_shrink_exit
ext4: remove check for zero nr_to_scan in ext4_es_scan()
ext4: fix avefreec in find_group_orlov
ext4: use ext4_grp_locked_error in mb_find_extent
can: bcm: delay release of struct bcm_op after synchronize_rcu()
can: gw: synchronize rcu operations before removing gw job entry
can: j1939: j1939_sk_init(): set SOCK_RCU_FREE to call sk_destruct() after RCU is done
can: peak_pciefd: pucan_handle_status(): fix a potential starvation issue in TX path
mac80211: remove iwlwifi specific workaround that broke sta NDP tx
SUNRPC: Fix the batch tasks count wraparound.
SUNRPC: Should wake up the privileged task firstly.
perf/smmuv3: Don't trample existing events with global filter
KVM: PPC: Book3S HV: Workaround high stack usage with clang
s390/cio: dont call css_wait_for_slow_path() inside a lock
rtc: stm32: Fix unbalanced clk_disable_unprepare() on probe error path
iio: light: tcs3472: do not free unallocated IRQ
iio: ltr501: mark register holding upper 8 bits of ALS_DATA{0,1} and PS_DATA as volatile, too
iio: ltr501: ltr559: fix initialization of LTR501_ALS_CONTR
iio: ltr501: ltr501_read_ps(): add missing endianness conversion
serial: mvebu-uart: fix calculation of clock divisor
serial: sh-sci: Stop dmaengine transfer in sci_stop_tx()
serial_cs: Add Option International GSM-Ready 56K/ISDN modem
serial_cs: remove wrong GLOBETROTTER.cis entry
ath9k: Fix kernel NULL pointer dereference during ath_reset_internal()
ssb: sdio: Don't overwrite const buffer if block_write fails
rsi: Assign beacon rate settings to the correct rate_info descriptor field
rsi: fix AP mode with WPA failure due to encrypted EAPOL
tracing/histograms: Fix parsing of "sym-offset" modifier
tracepoint: Add tracepoint_probe_register_may_exist() for BPF tracing
seq_buf: Make trace_seq_putmem_hex() support data longer than 8
powerpc/stacktrace: Fix spurious "stale" traces in raise_backtrace_ipi()
evm: Execute evm_inode_init_security() only when an HMAC key is loaded
evm: Refuse EVM_ALLOW_METADATA_WRITES only if an HMAC key is loaded
fuse: ignore PG_workingset after stealing
fuse: check connected before queueing on fpq->io
fuse: reject internal errno
spi: Make of_register_spi_device also set the fwnode
media: mdk-mdp: fix pm_runtime_get_sync() usage count
media: s5p: fix pm_runtime_get_sync() usage count
media: sh_vou: fix pm_runtime_get_sync() usage count
media: mtk-vcodec: fix PM runtime get logic
media: s5p-jpeg: fix pm_runtime_get_sync() usage count
media: sti/bdisp: fix pm_runtime_get_sync() usage count
media: exynos-gsc: fix pm_runtime_get_sync() usage count
spi: spi-loopback-test: Fix 'tx_buf' might be 'rx_buf'
spi: spi-topcliff-pch: Fix potential double free in pch_spi_process_messages()
spi: omap-100k: Fix the length judgment problem
regulator: uniphier: Add missing MODULE_DEVICE_TABLE
hwrng: exynos - Fix runtime PM imbalance on error
crypto: nx - add missing MODULE_DEVICE_TABLE
media: sti: fix obj-$(config) targets
media: cpia2: fix memory leak in cpia2_usb_probe
media: cobalt: fix race condition in setting HPD
media: pvrusb2: fix warning in pvr2_i2c_core_done
media: imx: imx7_mipi_csis: Fix logging of only error event counters
crypto: qat - check return code of qat_hal_rd_rel_reg()
crypto: qat - remove unused macro in FW loader
sched/fair: Fix ascii art by relpacing tabs
media: em28xx: Fix possible memory leak of em28xx struct
media: v4l2-core: Avoid the dangling pointer in v4l2_fh_release
media: bt8xx: Fix a missing check bug in bt878_probe
media: st-hva: Fix potential NULL pointer dereferences
Makefile: fix GDB warning with CONFIG_RELR
media: dvd_usb: memory leak in cinergyt2_fe_attach
memstick: rtsx_usb_ms: fix UAF
mmc: sdhci-sprd: use sdhci_sprd_writew
mmc: via-sdmmc: add a check against NULL pointer dereference
crypto: shash - avoid comparing pointers to exported functions under CFI
media: dvb_net: avoid speculation from net slot
media: siano: fix device register error path
media: imx-csi: Skip first few frames from a BT.656 source
hwmon: (max31790) Report correct current pwm duty cycles
hwmon: (max31790) Fix pwmX_enable attributes
drivers/perf: fix the missed ida_simple_remove() in ddr_perf_probe()
KVM: PPC: Book3S HV: Fix TLB management on SMT8 POWER9 and POWER10 processors
btrfs: fix error handling in __btrfs_update_delayed_inode
btrfs: abort transaction if we fail to update the delayed inode
btrfs: disable build on platforms having page size 256K
locking/lockdep: Fix the dep path printing for backwards BFS
lockding/lockdep: Avoid to find wrong lock dep path in check_irq_usage()
KVM: s390: get rid of register asm usage
regulator: mt6358: Fix vdram2 .vsel_mask
regulator: da9052: Ensure enough delay time for .set_voltage_time_sel
media: Fix Media Controller API config checks
HID: do not use down_interruptible() when unbinding devices
EDAC/ti: Add missing MODULE_DEVICE_TABLE
ACPI: processor idle: Fix up C-state latency if not ordered
hv_utils: Fix passing zero to 'PTR_ERR' warning
lib: vsprintf: Fix handling of number field widths in vsscanf
ACPI: EC: Make more Asus laptops use ECDT _GPE
block_dump: remove block_dump feature in mark_inode_dirty()
fs: dlm: cancel work sync othercon
random32: Fix implicit truncation warning in prandom_seed_state()
fs: dlm: fix memory leak when fenced
ACPICA: Fix memory leak caused by _CID repair function
ACPI: bus: Call kobject_put() in acpi_init() error path
ACPI: resources: Add checks for ACPI IRQ override
block: fix race between adding/removing rq qos and normal IO
platform/x86: toshiba_acpi: Fix missing error code in toshiba_acpi_setup_keyboard()
nvmet-fc: do not check for invalid target port in nvmet_fc_handle_fcp_rqst()
EDAC/Intel: Do not load EDAC driver when running as a guest
PCI: hv: Add check for hyperv_initialized in init_hv_pci_drv()
clocksource: Retry clock read if long delays detected
ACPI: tables: Add custom DSDT file as makefile prerequisite
HID: wacom: Correct base usage for capacitive ExpressKey status bits
cifs: fix missing spinlock around update to ses->status
block: fix discard request merge
kthread_worker: fix return value when kthread_mod_delayed_work() races with kthread_cancel_delayed_work_sync()
ia64: mca_drv: fix incorrect array size calculation
writeback, cgroup: increment isw_nr_in_flight before grabbing an inode
media: s5p_cec: decrement usage count if disabled
crypto: ixp4xx - dma_unmap the correct address
crypto: ux500 - Fix error return code in hash_hw_final()
sata_highbank: fix deferred probing
pata_rb532_cf: fix deferred probing
media: I2C: change 'RST' to "RSET" to fix multiple build errors
sched/uclamp: Fix wrong implementation of cpu.uclamp.min
sched/uclamp: Fix locking around cpu_util_update_eff()
kbuild: run the checker after the compiler
kbuild: Fix objtool dependency for 'OBJECT_FILES_NON_STANDARD_<obj> := n'
pata_octeon_cf: avoid WARN_ON() in ata_host_activate()
evm: fix writing <securityfs>/evm overflow
crypto: ccp - Fix a resource leak in an error handling path
media: rc: i2c: Fix an error message
pata_ep93xx: fix deferred probing
media: exynos4-is: Fix a use after free in isp_video_release
media: au0828: fix a NULL vs IS_ERR() check
media: tc358743: Fix error return code in tc358743_probe_of()
media: gspca/gl860: fix zero-length control requests
m68k: atari: Fix ATARI_KBD_CORE kconfig unmet dependency warning
media: siano: Fix out-of-bounds warnings in smscore_load_firmware_family2()
crypto: nitrox - fix unchecked variable in nitrox_register_interrupts
crypto: omap-sham - Fix PM reference leak in omap sham ops
mmc: usdhi6rol0: fix error return code in usdhi6_probe()
arm64: consistently use reserved_pg_dir
arm64/mm: Fix ttbr0 values stored in struct thread_info for software-pan
media: s5p-g2d: Fix a memory leak on ctx->fh.m2m_ctx
hwmon: (max31722) Remove non-standard ACPI device IDs
hwmon: (max31790) Fix fan speed reporting for fan7..12
KVM: nVMX: Ensure 64-bit shift when checking VMFUNC bitmap
regulator: hi655x: Fix pass wrong pointer to config.driver_data
btrfs: clear log tree recovering status if starting transaction fails
sched/rt: Fix RT utilization tracking during policy change
sched/rt: Fix Deadline utilization tracking during policy change
sched/uclamp: Fix uclamp_tg_restrict()
spi: spi-sun6i: Fix chipselect/clock bug
crypto: nx - Fix RCU warning in nx842_OF_upd_status
ACPI: sysfs: Fix a buffer overrun problem with description_show()
extcon: extcon-max8997: Fix IRQ freeing at error path
blk-wbt: introduce a new disable state to prevent false positive by rwb_enabled()
blk-wbt: make sure throttle is enabled properly
ACPI: Use DEVICE_ATTR_<RW|RO|WO> macros
ACPI: bgrt: Fix CFI violation
cpufreq: Make cpufreq_online() call driver->offline() on errors
ocfs2: fix snprintf() checking
dax: fix ENOMEM handling in grab_mapping_entry()
xfrm: xfrm_state_mtu should return at least 1280 for ipv6
video: fbdev: imxfb: Fix an error message
net: mvpp2: Put fwnode in error case during ->probe()
net: pch_gbe: Propagate error from devm_gpio_request_one()
pinctrl: renesas: r8a7796: Add missing bias for PRESET# pin
pinctrl: renesas: r8a77990: JTAG pins do not have pull-down capabilities
clk: meson: g12a: fix gp0 and hifi ranges
net: ftgmac100: add missing error return code in ftgmac100_probe()
drm/rockchip: cdn-dp-core: add missing clk_disable_unprepare() on error in cdn_dp_grf_write()
drm/rockchip: dsi: move all lane config except LCDC mux to bind()
ehea: fix error return code in ehea_restart_qps()
net/sched: act_vlan: Fix modify to allow 0
RDMA/core: Sanitize WQ state received from the userspace
RDMA/rxe: Fix failure during driver load
drm: qxl: ensure surf.data is ininitialized
tools/bpftool: Fix error return code in do_batch()
ath10k: go to path err_unsupported when chip id is not supported
ath10k: add missing error return code in ath10k_pci_probe()
wireless: carl9170: fix LEDS build errors & warnings
ieee802154: hwsim: Fix possible memory leak in hwsim_subscribe_all_others
wcn36xx: Move hal_buf allocation to devm_kmalloc in probe
ssb: Fix error return code in ssb_bus_scan()
brcmfmac: fix setting of station info chains bitmask
brcmfmac: correctly report average RSSI in station info
brcmsmac: mac80211_if: Fix a resource leak in an error handling path
ath10k: Fix an error code in ath10k_add_interface()
netlabel: Fix memory leak in netlbl_mgmt_add_common
RDMA/mlx5: Don't add slave port to unaffiliated list
netfilter: nft_exthdr: check for IPv6 packet before further processing
netfilter: nft_osf: check for TCP packet before further processing
netfilter: nft_tproxy: restrict support to TCP and UDP transport protocols
RDMA/rxe: Fix qp reference counting for atomic ops
samples/bpf: Fix the error return code of xdp_redirect's main()
net: ethernet: aeroflex: fix UAF in greth_of_remove
net: ethernet: ezchip: fix UAF in nps_enet_remove
net: ethernet: ezchip: fix error handling
vrf: do not push non-ND strict packets with a source LLA through packet taps again
net: sched: add barrier to ensure correct ordering for lockless qdisc
tls: prevent oversized sendfile() hangs by ignoring MSG_MORE
pkt_sched: sch_qfq: fix qfq_change_class() error path
vxlan: add missing rcu_read_lock() in neigh_reduce()
net/ipv4: swap flow ports when validating source
tc-testing: fix list handling
ieee802154: hwsim: Fix memory leak in hwsim_add_one
ieee802154: hwsim: avoid possible crash in hwsim_del_edge_nl()
mac80211: remove iwlwifi specific workaround NDPs of null_response
net: bcmgenet: Fix attaching to PYH failed on RPi 4B
ipv6: exthdrs: do not blindly use init_net
bpf: Do not change gso_size during bpf_skb_change_proto()
i40e: Fix error handling in i40e_vsi_open
i40e: Fix autoneg disabling for non-10GBaseT links
Revert "ibmvnic: remove duplicate napi_schedule call in open function"
ibmvnic: free tx_pool if tso_pool alloc fails
ipv6: fix out-of-bound access in ip6_parse_tlv()
e1000e: Check the PCIm state
bpfilter: Specify the log level for the kmsg message
gve: Fix swapped vars when fetching max queues
Revert "be2net: disable bh with spin_lock in be_process_mcc"
Bluetooth: mgmt: Fix slab-out-of-bounds in tlv_data_is_valid
Bluetooth: Fix handling of HCI_LE_Advertising_Set_Terminated event
clk: actions: Fix UART clock dividers on Owl S500 SoC
clk: actions: Fix SD clocks factor table on Owl S500 SoC
clk: actions: Fix bisp_factor_table based clocks on Owl S500 SoC
clk: si5341: Avoid divide errors due to bogus register contents
clk: si5341: Update initialization magic
writeback: fix obtain a reference to a freeing memcg css
net: lwtunnel: handle MTU calculation in forwading
net: sched: fix warning in tcindex_alloc_perfect_hash
RDMA/mlx5: Don't access NULL-cleared mpi pointer
MIPS: Fix PKMAP with 32-bit MIPS huge page support
staging: fbtft: Rectify GPIO handling
rcu: Invoke rcu_spawn_core_kthreads() from rcu_spawn_gp_kthread()
tty: nozomi: Fix a resource leak in an error handling function
mwifiex: re-fix for unaligned accesses
iio: adis_buffer: do not return ints in irq handlers
iio: adis16400: do not return ints in irq handlers
iio: accel: bma180: Fix buffer alignment in iio_push_to_buffers_with_timestamp()
iio: accel: bma220: Fix buffer alignment in iio_push_to_buffers_with_timestamp()
iio: accel: hid: Fix buffer alignment in iio_push_to_buffers_with_timestamp()
iio: accel: kxcjk-1013: Fix buffer alignment in iio_push_to_buffers_with_timestamp()
iio:accel:mxc4005: Drop unnecessary explicit casts in regmap_bulk_read calls
iio: accel: mxc4005: Fix overread of data and alignment issue.
iio: accel: stk8312: Fix buffer alignment in iio_push_to_buffers_with_timestamp()
iio: accel: stk8ba50: Fix buffer alignment in iio_push_to_buffers_with_timestamp()
iio: adc: ti-ads1015: Fix buffer alignment in iio_push_to_buffers_with_timestamp()
iio: adc: vf610: Fix buffer alignment in iio_push_to_buffers_with_timestamp()
iio: gyro: bmg160: Fix buffer alignment in iio_push_to_buffers_with_timestamp()
iio: humidity: am2315: Fix buffer alignment in iio_push_to_buffers_with_timestamp()
iio: prox: srf08: Fix buffer alignment in iio_push_to_buffers_with_timestamp()
iio: prox: pulsed-light: Fix buffer alignment in iio_push_to_buffers_with_timestamp()
iio: prox: as3935: Fix buffer alignment in iio_push_to_buffers_with_timestamp()
iio: magn: hmc5843: Fix buffer alignment in iio_push_to_buffers_with_timestamp()
iio: magn: bmc150: Fix buffer alignment in iio_push_to_buffers_with_timestamp()
iio: light: isl29125: Fix buffer alignment in iio_push_to_buffers_with_timestamp()
iio: light: tcs3414: Fix buffer alignment in iio_push_to_buffers_with_timestamp()
iio: light: tcs3472: Fix buffer alignment in iio_push_to_buffers_with_timestamp()
iio: cros_ec_sensors: Fix alignment of buffer in iio_push_to_buffers_with_timestamp()
iio: potentiostat: lmp91000: Fix alignment of buffer in iio_push_to_buffers_with_timestamp()
ASoC: rk3328: fix missing clk_disable_unprepare() on error in rk3328_platform_probe()
ASoC: hisilicon: fix missing clk_disable_unprepare() on error in hi6210_i2s_startup()
backlight: lm3630a_bl: Put fwnode in error case during ->probe()
ASoC: rsnd: tidyup loop on rsnd_adg_clk_query()
Input: hil_kbd - fix error return code in hil_dev_connect()
mtd: partitions: redboot: seek fis-index-block in the right node
char: pcmcia: error out if 'num_bytes_read' is greater than 4 in set_protocol()
firmware: stratix10-svc: Fix a resource leak in an error handling path
tty: nozomi: Fix the error handling path of 'nozomi_card_init()'
leds: lm3532: select regmap I2C API
leds: lm36274: cosmetic: rename lm36274_data to chip
leds: lm3692x: Put fwnode in any case during ->probe()
scsi: FlashPoint: Rename si_flags field
fsi: core: Fix return of error values on failures
fsi: scom: Reset the FSI2PIB engine for any error
fsi: occ: Don't accept response from un-initialized OCC
fsi/sbefifo: Clean up correct FIFO when receiving reset request from SBE
fsi/sbefifo: Fix reset timeout
visorbus: fix error return code in visorchipset_init()
s390: appldata depends on PROC_SYSCTL
iommu/dma: Fix IOVA reserve dma ranges
ASoC: mediatek: mtk-btcvsd: Fix an error handling path in 'mtk_btcvsd_snd_probe()'
usb: gadget: f_fs: Fix setting of device and driver data cross-references
usb: dwc2: Don't reset the core after setting turnaround time
eeprom: idt_89hpesx: Put fwnode in matching case during ->probe()
eeprom: idt_89hpesx: Restore printing the unsupported fwnode name
iio: at91-sama5d2_adc: remove usage of iio_priv_to_dev() helper
iio: adc: at91-sama5d2: Fix buffer alignment in iio_push_to_buffers_with_timestamp()
iio: adc: hx711: Fix buffer alignment in iio_push_to_buffers_with_timestamp()
iio: adc: mxs-lradc: Fix buffer alignment in iio_push_to_buffers_with_timestamp()
iio: adc: ti-ads8688: Fix alignment of buffer in iio_push_to_buffers_with_timestamp()
iio: magn: rm3100: Fix alignment of buffer in iio_push_to_buffers_with_timestamp()
staging: gdm724x: check for buffer overflow in gdm_lte_multi_sdu_pkt()
staging: gdm724x: check for overflow in gdm_lte_netif_rx()
staging: rtl8712: remove redundant check in r871xu_drv_init
staging: rtl8712: fix memory leak in rtl871x_load_fw_cb
staging: mt7621-dts: fix pci address for PCI memory range
serial: 8250: Actually allow UPF_MAGIC_MULTIPLIER baud rates
iio: light: vcnl4035: Fix buffer alignment in iio_push_to_buffers_with_timestamp()
iio: prox: isl29501: Fix buffer alignment in iio_push_to_buffers_with_timestamp()
ASoC: cs42l42: Correct definition of CS42L42_ADC_PDN_MASK
of: Fix truncation of memory sizes on 32-bit platforms
mtd: rawnand: marvell: add missing clk_disable_unprepare() on error in marvell_nfc_resume()
scsi: mpt3sas: Fix error return value in _scsih_expander_add()
soundwire: stream: Fix test for DP prepare complete
phy: uniphier-pcie: Fix updating phy parameters
phy: ti: dm816x: Fix the error handling path in 'dm816x_usb_phy_probe()
extcon: sm5502: Drop invalid register write in sm5502_reg_data
extcon: max8997: Add missing modalias string
ASoC: atmel-i2s: Fix usage of capture and playback at the same time
configfs: fix memleak in configfs_release_bin_file
leds: as3645a: Fix error return code in as3645a_parse_node()
leds: ktd2692: Fix an error handling path
powerpc: Offline CPU in stop_this_cpu()
serial: mvebu-uart: do not allow changing baudrate when uartclk is not available
serial: mvebu-uart: correctly calculate minimal possible baudrate
arm64: dts: marvell: armada-37xx: Fix reg for standard variant of UART
vfio/pci: Handle concurrent vma faults
mm/huge_memory.c: don't discard hugepage if other processes are mapping it
mm/z3fold: fix potential memory leak in z3fold_destroy_pool()
selftests/vm/pkeys: fix alloc_random_pkey() to make it really, really random
perf llvm: Return -ENOMEM when asprintf() fails
scsi: target: cxgbit: Unmap DMA buffer before calling target_execute_cmd()
block: return the correct bvec when checking for gaps
mmc: block: Disable CMDQ on the ioctl path
mmc: vub3000: fix control-request direction
scsi: core: Retry I/O for Notify (Enable Spinup) Required error
iommu/dma: Fix compile warning in 32-bit builds
Linux 5.4.132
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: I36eef11d7d5fed3388f0c90904a4e9c495327826
845 lines
21 KiB
C
845 lines
21 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Copyright (C) 2001 Jens Axboe <axboe@suse.de>
|
|
*/
|
|
#ifndef __LINUX_BIO_H
|
|
#define __LINUX_BIO_H
|
|
|
|
#include <linux/highmem.h>
|
|
#include <linux/mempool.h>
|
|
#include <linux/ioprio.h>
|
|
#include <linux/bio-crypt-ctx.h>
|
|
#include <linux/android_kabi.h>
|
|
|
|
#ifdef CONFIG_BLOCK
|
|
/* 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
|
|
|
|
#define BIO_MAX_PAGES 256
|
|
|
|
#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 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)
|
|
|
|
/*
|
|
* 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;
|
|
}
|
|
|
|
/**
|
|
* bio_full - check if the bio is full
|
|
* @bio: bio to check
|
|
* @len: length of one segment to be added
|
|
*
|
|
* Return true if @bio is full and one segment with @len bytes can't be
|
|
* added to the bio, otherwise return false
|
|
*/
|
|
static inline bool bio_full(struct bio *bio, unsigned len)
|
|
{
|
|
if (bio->bi_vcnt >= bio->bi_max_vecs)
|
|
return true;
|
|
|
|
if (bio->bi_iter.bi_size > UINT_MAX - len)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
static inline bool bio_next_segment(const struct bio *bio,
|
|
struct bvec_iter_all *iter)
|
|
{
|
|
if (iter->idx >= bio->bi_vcnt)
|
|
return false;
|
|
|
|
bvec_advance(&bio->bi_io_vec[iter->idx], iter);
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* 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, iter) \
|
|
for (bvl = bvec_init_iter_all(&iter); bio_next_segment((bio), &iter); )
|
|
|
|
static inline void bio_advance_iter(struct bio *bio, struct bvec_iter *iter,
|
|
unsigned bytes)
|
|
{
|
|
iter->bi_sector += bytes >> 9;
|
|
|
|
if (bio_no_advance_iter(bio))
|
|
iter->bi_size -= bytes;
|
|
else
|
|
bvec_iter_advance(bio->bi_io_vec, iter, bytes);
|
|
/* TODO: It is reasonable to complete bio with error here. */
|
|
}
|
|
|
|
#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_for_each_bvec(bvl, bio, iter, start) \
|
|
for (iter = (start); \
|
|
(iter).bi_size && \
|
|
((bvl = mp_bvec_iter_bvec((bio)->bi_io_vec, (iter))), 1); \
|
|
bio_advance_iter((bio), &(iter), (bvl).bv_len))
|
|
|
|
/* iterate over multi-page bvec */
|
|
#define bio_for_each_bvec(bvl, bio, iter) \
|
|
__bio_for_each_bvec(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 = mp_bvec_iter_bvec(bio->bi_io_vec, bio->bi_iter);
|
|
}
|
|
|
|
static inline void bio_get_last_bvec(struct bio *bio, struct bio_vec *bv)
|
|
{
|
|
struct bvec_iter iter = bio->bi_iter;
|
|
int idx;
|
|
|
|
bio_get_first_bvec(bio, bv);
|
|
if (bv->bv_len == bio->bi_iter.bi_size)
|
|
return; /* this bio only has a single bvec */
|
|
|
|
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 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 bvec_iter bio_iter; /* for rewinding parent bio */
|
|
|
|
struct work_struct bip_work; /* I/O completion */
|
|
|
|
struct bio_vec *bip_vec;
|
|
|
|
ANDROID_KABI_RESERVE(1);
|
|
ANDROID_KABI_RESERVE(2);
|
|
|
|
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 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, bool *same_page);
|
|
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);
|
|
void bio_release_pages(struct bio *bio, bool mark_dirty);
|
|
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);
|
|
|
|
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);
|
|
void bio_truncate(struct bio *bio, unsigned new_size);
|
|
|
|
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; \
|
|
bio_associate_blkg(bio); \
|
|
} while (0)
|
|
|
|
#define bio_copy_dev(dst, src) \
|
|
do { \
|
|
(dst)->bi_disk = (src)->bi_disk; \
|
|
(dst)->bi_partno = (src)->bi_partno; \
|
|
bio_clone_blkg_association(dst, src); \
|
|
} while (0)
|
|
|
|
#define bio_dev(bio) \
|
|
disk_devt((bio)->bi_disk)
|
|
|
|
#if defined(CONFIG_MEMCG) && defined(CONFIG_BLK_CGROUP)
|
|
void bio_associate_blkg_from_page(struct bio *bio, struct page *page);
|
|
#else
|
|
static inline void bio_associate_blkg_from_page(struct bio *bio,
|
|
struct page *page) { }
|
|
#endif
|
|
|
|
#ifdef CONFIG_BLK_CGROUP
|
|
void bio_disassociate_blkg(struct bio *bio);
|
|
void bio_associate_blkg(struct bio *bio);
|
|
void bio_associate_blkg_from_css(struct bio *bio,
|
|
struct cgroup_subsys_state *css);
|
|
void bio_clone_blkg_association(struct bio *dst, struct bio *src);
|
|
#else /* CONFIG_BLK_CGROUP */
|
|
static inline void bio_disassociate_blkg(struct bio *bio) { }
|
|
static inline void bio_associate_blkg(struct bio *bio) { }
|
|
static inline void bio_associate_blkg_from_css(struct bio *bio,
|
|
struct cgroup_subsys_state *css)
|
|
{ }
|
|
static inline void bio_clone_blkg_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;
|
|
|
|
ANDROID_KABI_RESERVE(1);
|
|
ANDROID_KABI_RESERVE(2);
|
|
ANDROID_KABI_RESERVE(3);
|
|
ANDROID_KABI_RESERVE(4);
|
|
};
|
|
|
|
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 */
|
|
|
|
/*
|
|
* 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).
|
|
* We cannot block waiting for requests on polled IO, as those completions
|
|
* must be found by the caller. This is different than IRQ driven IO, where
|
|
* it's safe to wait for IO to complete.
|
|
*/
|
|
static inline void bio_set_polled(struct bio *bio, struct kiocb *kiocb)
|
|
{
|
|
bio->bi_opf |= REQ_HIPRI;
|
|
if (!is_sync_kiocb(kiocb))
|
|
bio->bi_opf |= REQ_NOWAIT;
|
|
}
|
|
|
|
#endif /* CONFIG_BLOCK */
|
|
#endif /* __LINUX_BIO_H */
|