This is the 5.4.215 stable release

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAmM0DhEACgkQONu9yGCS
 aT4CBA/9FmkhfUpJXWhlEAHaZX/aiskQS1vgauXP/TBy/8InVr/kY8sD6n5RUsi0
 Qkt3M4a+VDsKBPiyRV+KgfiHA4Sms09IRcRpFmwslR8OzPkmZBApqHoeQCCu+/kt
 OTFsbiHa+tfFhOOyAXL7Q0an+yOHxPe+/RxokBYDknp1CAWbVgDTLWGY2EfX6Xa6
 EjsjTKwb3WkDfbAgdvnblYcQkfUJB3kF3tk8yZnyPWQ/soZMrzVroocAK6JgzzXi
 hO+VHG7yfC0gTF4w4R+DY5qPzCO6I7cq5K2fL7PFzwDX7D8uotaDS8QNHPyxsjZW
 gLltTdhEa2HZyjTnuUeiXBmQ5vA6pLULcHP96neUWB+vULDIqXzi/TKyq6Ybetak
 3yQgldQB81apEzKTRMaQKPqoNlP11qfq1jsGIFXKY5ZPxNL2IOuePA8+LGFXO2/H
 KrALeTmPe+f3vLyf/tDdDTM3fHWmN3bKwyxCXCdR5hvqCBWsExA+Q64NEZ24PYZ6
 O5SFhEvTMpuAWpeMiiAsftuxC/OnyTzPdCzMUfiWrk1UDYcYxYSxdOpGd18St+ir
 1OzhI+TO/R2heMhAHBsxrHBzO4ZdFhK+nCivPRSzyPSITyD7rMJdxE3cNJDWc9Ye
 DnIBm6IGJGo3rCCnPXFEsWulvElwDU0+QWxeX3uxIYkEKxbeMPo=
 =gmE/
 -----END PGP SIGNATURE-----

Merge 5.4.215 into android11-5.4-lts

Changes in 5.4.215
	of: fdt: fix off-by-one error in unflatten_dt_nodes()
	NFSv4: Turn off open-by-filehandle and NFS re-export for NFSv4.0
	gpio: mpc8xxx: Fix support for IRQ_TYPE_LEVEL_LOW flow_type in mpc85xx
	drm/meson: Correct OSD1 global alpha value
	drm/meson: Fix OSD1 RGB to YCbCr coefficient
	parisc: ccio-dma: Add missing iounmap in error path in ccio_probe()
	ALSA: pcm: oss: Fix race at SNDCTL_DSP_SYNC
	task_stack, x86/cea: Force-inline stack helpers
	tracing: hold caller_addr to hardirq_{enable,disable}_ip
	cifs: revalidate mapping when doing direct writes
	cifs: don't send down the destination address to sendmsg for a SOCK_STREAM
	MAINTAINERS: add Chandan as xfs maintainer for 5.4.y
	iomap: iomap that extends beyond EOF should be marked dirty
	ASoC: nau8824: Fix semaphore unbalance at error paths
	regulator: pfuze100: Fix the global-out-of-bounds access in pfuze100_regulator_probe()
	rxrpc: Fix local destruction being repeated
	rxrpc: Fix calc of resend age
	ALSA: hda/sigmatel: Keep power up while beep is enabled
	ALSA: hda/tegra: Align BDL entry to 4KB boundary
	net: usb: qmi_wwan: add Quectel RM520N
	afs: Return -EAGAIN, not -EREMOTEIO, when a file already locked
	MIPS: OCTEON: irq: Fix octeon_irq_force_ciu_mapping()
	mksysmap: Fix the mismatch of 'L0' symbols in System.map
	video: fbdev: pxa3xx-gcu: Fix integer overflow in pxa3xx_gcu_write
	cgroup: Add missing cpus_read_lock() to cgroup_attach_task_all()
	ALSA: hda/sigmatel: Fix unused variable warning for beep power change
	usb: dwc3: gadget: Avoid starting DWC3 gadget during UDC unbind
	usb: dwc3: Issue core soft reset before enabling run/stop
	usb: dwc3: gadget: Prevent repeat pullup()
	usb: dwc3: gadget: Refactor pullup()
	usb: dwc3: gadget: Don't modify GEVNTCOUNT in pullup()
	usb: dwc3: gadget: Avoid duplicate requests to enable Run/Stop
	usb: xhci-mtk: get the microframe boundary for ESIT
	usb: xhci-mtk: add only one extra CS for FS/LS INTR
	usb: xhci-mtk: use @sch_tt to check whether need do TT schedule
	usb: xhci-mtk: add a function to (un)load bandwidth info
	usb: xhci-mtk: add some schedule error number
	usb: xhci-mtk: allow multiple Start-Split in a microframe
	usb: xhci-mtk: relax TT periodic bandwidth allocation
	wifi: mac80211: Fix UAF in ieee80211_scan_rx()
	tty/serial: atmel: RS485 & ISO7816: wait for TXRDY before sending data
	serial: atmel: remove redundant assignment in rs485_config
	tty: serial: atmel: Preserve previous USART mode if RS485 disabled
	usb: add quirks for Lenovo OneLink+ Dock
	usb: gadget: udc-xilinx: replace memcpy with memcpy_toio
	usb: cdns3: fix issue with rearming ISO OUT endpoint
	Revert "usb: add quirks for Lenovo OneLink+ Dock"
	Revert "usb: gadget: udc-xilinx: replace memcpy with memcpy_toio"
	USB: core: Fix RST error in hub.c
	USB: serial: option: add Quectel BG95 0x0203 composition
	USB: serial: option: add Quectel RM520N
	ALSA: hda/tegra: set depop delay for tegra
	ALSA: hda: add Intel 5 Series / 3400 PCI DID
	ALSA: hda/realtek: Add quirk for Huawei WRT-WX9
	ALSA: hda/realtek: Re-arrange quirk table entries
	ALSA: hda/realtek: Add pincfg for ASUS G513 HP jack
	ALSA: hda/realtek: Add pincfg for ASUS G533Z HP jack
	ALSA: hda/realtek: Add quirk for ASUS GA503R laptop
	ALSA: hda/realtek: Enable 4-speaker output Dell Precision 5530 laptop
	efi: libstub: check Shim mode using MokSBStateRT
	mm/slub: fix to return errno if kmalloc() fails
	arm64: dts: rockchip: Pull up wlan wake# on Gru-Bob
	arm64: dts: rockchip: Set RK3399-Gru PCLK_EDP to 24 MHz
	arm64: dts: rockchip: Remove 'enable-active-low' from rk3399-puma
	netfilter: nf_conntrack_sip: fix ct_sip_walk_headers
	netfilter: nf_conntrack_irc: Tighten matching on DCC message
	netfilter: nfnetlink_osf: fix possible bogus match in nf_osf_find()
	iavf: Fix cached head and tail value for iavf_get_tx_pending
	ipvlan: Fix out-of-bound bugs caused by unset skb->mac_header
	net: team: Unsync device addresses on ndo_stop
	MIPS: lantiq: export clk_get_io() for lantiq_wdt.ko
	MIPS: Loongson32: Fix PHY-mode being left unspecified
	iavf: Fix bad page state
	iavf: Fix set max MTU size with port VLAN and jumbo frames
	i40e: Fix VF set max MTU size
	i40e: Fix set max_tx_rate when it is lower than 1 Mbps
	of: mdio: Add of_node_put() when breaking out of for_each_xx
	net/sched: taprio: avoid disabling offload when it was never enabled
	net/sched: taprio: make qdisc_leaf() see the per-netdev-queue pfifo child qdiscs
	netfilter: ebtables: fix memory leak when blob is malformed
	can: gs_usb: gs_can_open(): fix race dev->can.state condition
	perf jit: Include program header in ELF files
	perf kcore_copy: Do not check /proc/modules is unchanged
	net: sunhme: Fix packet reception for len < RX_COPY_THRESHOLD
	net: sched: fix possible refcount leak in tc_new_tfilter()
	serial: Create uart_xmit_advance()
	serial: tegra: Use uart_xmit_advance(), fixes icount.tx accounting
	serial: tegra-tcu: Use uart_xmit_advance(), fixes icount.tx accounting
	s390/dasd: fix Oops in dasd_alias_get_start_dev due to missing pavgroup
	usb: xhci-mtk: fix issue of out-of-bounds array access
	cifs: always initialize struct msghdr smb_msg completely
	Drivers: hv: Never allocate anything besides framebuffer from framebuffer memory region
	drm/amdgpu: use dirty framebuffer helper
	drm/amd/display: Limit user regamma to a valid value
	drm/rockchip: Fix return type of cdn_dp_connector_mode_valid
	workqueue: don't skip lockdep work dependency in cancel_work_sync()
	ext4: fix bug in extents parsing when eh_entries == 0 and eh_depth > 0
	xfs: replace -EIO with -EFSCORRUPTED for corrupt metadata
	xfs: slightly tweak an assert in xfs_fs_map_blocks
	xfs: add missing assert in xfs_fsmap_owner_from_rmap
	xfs: range check ri_cnt when recovering log items
	xfs: attach dquots and reserve quota blocks during unwritten conversion
	xfs: Fix deadlock between AGI and AGF when target_ip exists in xfs_rename()
	xfs: convert EIO to EFSCORRUPTED when log contents are invalid
	xfs: constify the buffer pointer arguments to error functions
	xfs: always log corruption errors
	xfs: fix some memory leaks in log recovery
	xfs: stabilize insert range start boundary to avoid COW writeback race
	xfs: use bitops interface for buf log item AIL flag check
	xfs: refactor agfl length computation function
	xfs: split the sunit parameter update into two parts
	xfs: don't commit sunit/swidth updates to disk if that would cause repair failures
	xfs: fix an ABBA deadlock in xfs_rename
	xfs: fix use-after-free when aborting corrupt attr inactivation
	ext4: make directory inode spreading reflect flexbg size
	Linux 5.4.215

Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: Ic4723318e38b6d2502091cfb41fe602e59c1a538
This commit is contained in:
Greg Kroah-Hartman 2022-09-28 12:48:08 +02:00
commit 79e1dca55a
114 changed files with 1068 additions and 399 deletions

View File

@ -17876,7 +17876,8 @@ S: Supported
F: sound/xen/*
XFS FILESYSTEM
M: Darrick J. Wong <darrick.wong@oracle.com>
M: Chandan Babu R <chandan.babu@oracle.com>
M: Darrick J. Wong <djwong@kernel.org>
M: linux-xfs@vger.kernel.org
L: linux-xfs@vger.kernel.org
W: http://xfs.org/

View File

@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
VERSION = 5
PATCHLEVEL = 4
SUBLEVEL = 214
SUBLEVEL = 215
EXTRAVERSION =
NAME = Kleptomaniac Octopus

View File

@ -77,3 +77,8 @@
};
};
};
&wlan_host_wake_l {
/* Kevin has an external pull up, but Bob does not. */
rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>;
};

View File

@ -237,6 +237,14 @@
&edp {
status = "okay";
/*
* eDP PHY/clk don't sync reliably at anything other than 24 MHz. Only
* set this here, because rk3399-gru.dtsi ensures we can generate this
* off GPLL=600MHz, whereas some other RK3399 boards may not.
*/
assigned-clocks = <&cru PCLK_EDP>;
assigned-clock-rates = <24000000>;
ports {
edp_out: port@1 {
reg = <1>;
@ -397,6 +405,7 @@ ap_i2c_tp: &i2c5 {
};
wlan_host_wake_l: wlan-host-wake-l {
/* Kevin has an external pull up, but Bob does not */
rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
};
};

View File

@ -102,7 +102,6 @@
vcc5v0_host: vcc5v0-host-regulator {
compatible = "regulator-fixed";
gpio = <&gpio4 RK_PA3 GPIO_ACTIVE_LOW>;
enable-active-low;
pinctrl-names = "default";
pinctrl-0 = <&vcc5v0_host_en>;
regulator-name = "vcc5v0_host";

View File

@ -127,6 +127,16 @@ static void octeon_irq_free_cd(struct irq_domain *d, unsigned int irq)
static int octeon_irq_force_ciu_mapping(struct irq_domain *domain,
int irq, int line, int bit)
{
struct device_node *of_node;
int ret;
of_node = irq_domain_get_of_node(domain);
if (!of_node)
return -EINVAL;
ret = irq_alloc_desc_at(irq, of_node_to_nid(of_node));
if (ret < 0)
return ret;
return irq_domain_associate(domain, irq, line << 6 | bit);
}

View File

@ -50,6 +50,7 @@ struct clk *clk_get_io(void)
{
return &cpu_clk_generic[2];
}
EXPORT_SYMBOL_GPL(clk_get_io);
struct clk *clk_get_ppe(void)
{

View File

@ -98,7 +98,7 @@ int ls1x_eth_mux_init(struct platform_device *pdev, void *priv)
if (plat_dat->bus_id) {
__raw_writel(__raw_readl(LS1X_MUX_CTRL0) | GMAC1_USE_UART1 |
GMAC1_USE_UART0, LS1X_MUX_CTRL0);
switch (plat_dat->interface) {
switch (plat_dat->phy_interface) {
case PHY_INTERFACE_MODE_RGMII:
val &= ~(GMAC1_USE_TXCLK | GMAC1_USE_PWM23);
break;
@ -107,12 +107,12 @@ int ls1x_eth_mux_init(struct platform_device *pdev, void *priv)
break;
default:
pr_err("unsupported mii mode %d\n",
plat_dat->interface);
plat_dat->phy_interface);
return -ENOTSUPP;
}
val &= ~GMAC1_SHUT;
} else {
switch (plat_dat->interface) {
switch (plat_dat->phy_interface) {
case PHY_INTERFACE_MODE_RGMII:
val &= ~(GMAC0_USE_TXCLK | GMAC0_USE_PWM01);
break;
@ -121,7 +121,7 @@ int ls1x_eth_mux_init(struct platform_device *pdev, void *priv)
break;
default:
pr_err("unsupported mii mode %d\n",
plat_dat->interface);
plat_dat->phy_interface);
return -ENOTSUPP;
}
val &= ~GMAC0_SHUT;
@ -131,7 +131,7 @@ int ls1x_eth_mux_init(struct platform_device *pdev, void *priv)
plat_dat = dev_get_platdata(&pdev->dev);
val &= ~PHY_INTF_SELI;
if (plat_dat->interface == PHY_INTERFACE_MODE_RMII)
if (plat_dat->phy_interface == PHY_INTERFACE_MODE_RMII)
val |= 0x4 << PHY_INTF_SELI_SHIFT;
__raw_writel(val, LS1X_MUX_CTRL1);
@ -146,9 +146,9 @@ static struct plat_stmmacenet_data ls1x_eth0_pdata = {
.bus_id = 0,
.phy_addr = -1,
#if defined(CONFIG_LOONGSON1_LS1B)
.interface = PHY_INTERFACE_MODE_MII,
.phy_interface = PHY_INTERFACE_MODE_MII,
#elif defined(CONFIG_LOONGSON1_LS1C)
.interface = PHY_INTERFACE_MODE_RMII,
.phy_interface = PHY_INTERFACE_MODE_RMII,
#endif
.mdio_bus_data = &ls1x_mdio_bus_data,
.dma_cfg = &ls1x_eth_dma_cfg,
@ -186,7 +186,7 @@ struct platform_device ls1x_eth0_pdev = {
static struct plat_stmmacenet_data ls1x_eth1_pdata = {
.bus_id = 1,
.phy_addr = -1,
.interface = PHY_INTERFACE_MODE_MII,
.phy_interface = PHY_INTERFACE_MODE_MII,
.mdio_bus_data = &ls1x_mdio_bus_data,
.dma_cfg = &ls1x_eth_dma_cfg,
.has_gmac = 1,

View File

@ -133,7 +133,7 @@ extern void cea_set_pte(void *cea_vaddr, phys_addr_t pa, pgprot_t flags);
extern struct cpu_entry_area *get_cpu_entry_area(int cpu);
static inline struct entry_stack *cpu_entry_stack(int cpu)
static __always_inline struct entry_stack *cpu_entry_stack(int cpu)
{
return &get_cpu_entry_area(cpu)->entry_stack_page.stack;
}

View File

@ -19,7 +19,7 @@ static const efi_char16_t efi_SetupMode_name[] = L"SetupMode";
/* SHIM variables */
static const efi_guid_t shim_guid = EFI_SHIM_LOCK_GUID;
static const efi_char16_t shim_MokSBState_name[] = L"MokSBState";
static const efi_char16_t shim_MokSBState_name[] = L"MokSBStateRT";
#define get_efi_var(name, vendor, ...) \
efi_call_runtime(get_variable, \
@ -58,8 +58,8 @@ enum efi_secureboot_mode efi_get_secureboot(efi_system_table_t *sys_table_arg)
/*
* See if a user has put the shim into insecure mode. If so, and if the
* variable doesn't have the runtime attribute set, we might as well
* honor that.
* variable doesn't have the non-volatile attribute set, we might as
* well honor that.
*/
size = sizeof(moksbstate);
status = get_efi_var(shim_MokSBState_name, &shim_guid,
@ -68,7 +68,7 @@ enum efi_secureboot_mode efi_get_secureboot(efi_system_table_t *sys_table_arg)
/* If it fails, we don't care why. Default to secure */
if (status != EFI_SUCCESS)
goto secure_boot_enabled;
if (!(attr & EFI_VARIABLE_RUNTIME_ACCESS) && moksbstate == 1)
if (!(attr & EFI_VARIABLE_NON_VOLATILE) && moksbstate == 1)
return efi_secureboot_mode_disabled;
secure_boot_enabled:

View File

@ -190,6 +190,7 @@ static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
switch (flow_type) {
case IRQ_TYPE_EDGE_FALLING:
case IRQ_TYPE_LEVEL_LOW:
raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
gc->write_reg(mpc8xxx_gc->regs + GPIO_ICR,
gc->read_reg(mpc8xxx_gc->regs + GPIO_ICR)

View File

@ -35,6 +35,7 @@
#include <linux/pci.h>
#include <linux/pm_runtime.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_fb_helper.h>
@ -495,6 +496,7 @@ bool amdgpu_display_ddc_probe(struct amdgpu_connector *amdgpu_connector,
static const struct drm_framebuffer_funcs amdgpu_fb_funcs = {
.destroy = drm_gem_fb_destroy,
.create_handle = drm_gem_fb_create_handle,
.dirty = drm_atomic_helper_dirtyfb,
};
uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev,

View File

@ -1486,6 +1486,7 @@ static void interpolate_user_regamma(uint32_t hw_points_num,
struct fixed31_32 lut2;
struct fixed31_32 delta_lut;
struct fixed31_32 delta_index;
const struct fixed31_32 one = dc_fixpt_from_int(1);
i = 0;
/* fixed_pt library has problems handling too small values */
@ -1514,6 +1515,9 @@ static void interpolate_user_regamma(uint32_t hw_points_num,
} else
hw_x = coordinates_x[i].x;
if (dc_fixpt_le(one, hw_x))
hw_x = one;
norm_x = dc_fixpt_mul(norm_factor, hw_x);
index = dc_fixpt_floor(norm_x);
if (index < 0 || index > 255)

View File

@ -128,7 +128,7 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
/* Enable OSD and BLK0, set max global alpha */
priv->viu.osd1_ctrl_stat = OSD_ENABLE |
(0xFF << OSD_GLOBAL_ALPHA_SHIFT) |
(0x100 << OSD_GLOBAL_ALPHA_SHIFT) |
OSD_BLK0_ENABLE;
canvas_id_osd1 = priv->canvas_id_osd1;

View File

@ -91,7 +91,7 @@ static void meson_viu_set_g12a_osd1_matrix(struct meson_drm *priv,
priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF11_12));
writel(((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff),
priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF20_21));
writel((m[11] & 0x1fff) << 16,
writel((m[11] & 0x1fff),
priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF22));
writel(((m[18] & 0xfff) << 16) | (m[19] & 0xfff),

View File

@ -275,8 +275,9 @@ static int cdn_dp_connector_get_modes(struct drm_connector *connector)
return ret;
}
static int cdn_dp_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
static enum drm_mode_status
cdn_dp_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct cdn_dp_device *dp = connector_to_dp(connector);
struct drm_display_info *display_info = &dp->connector.display_info;

View File

@ -2075,7 +2075,7 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
bool fb_overlap_ok)
{
struct resource *iter, *shadow;
resource_size_t range_min, range_max, start;
resource_size_t range_min, range_max, start, end;
const char *dev_n = dev_name(&device_obj->device);
int retval;
@ -2110,6 +2110,14 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
range_max = iter->end;
start = (range_min + align - 1) & ~(align - 1);
for (; start + size - 1 <= range_max; start += align) {
end = start + size - 1;
/* Skip the whole fb_mmio region if not fb_overlap_ok */
if (!fb_overlap_ok && fb_mmio &&
(((start >= fb_mmio->start) && (start <= fb_mmio->end)) ||
((end >= fb_mmio->start) && (end <= fb_mmio->end))))
continue;
shadow = __request_region(iter, start, size, NULL,
IORESOURCE_BUSY);
if (!shadow)

View File

@ -678,6 +678,7 @@ static int gs_can_open(struct net_device *netdev)
flags |= GS_CAN_MODE_TRIPLE_SAMPLE;
/* finally start device */
dev->can.state = CAN_STATE_ERROR_ACTIVE;
dm->mode = cpu_to_le32(GS_CAN_MODE_START);
dm->flags = cpu_to_le32(flags);
rc = usb_control_msg(interface_to_usbdev(dev->iface),
@ -694,13 +695,12 @@ static int gs_can_open(struct net_device *netdev)
if (rc < 0) {
netdev_err(netdev, "Couldn't start device (err=%d)\n", rc);
kfree(dm);
dev->can.state = CAN_STATE_STOPPED;
return rc;
}
kfree(dm);
dev->can.state = CAN_STATE_ERROR_ACTIVE;
parent->active_channels++;
if (!(dev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
netif_start_queue(netdev);

View File

@ -5638,6 +5638,26 @@ static int i40e_get_link_speed(struct i40e_vsi *vsi)
}
}
/**
* i40e_bw_bytes_to_mbits - Convert max_tx_rate from bytes to mbits
* @vsi: Pointer to vsi structure
* @max_tx_rate: max TX rate in bytes to be converted into Mbits
*
* Helper function to convert units before send to set BW limit
**/
static u64 i40e_bw_bytes_to_mbits(struct i40e_vsi *vsi, u64 max_tx_rate)
{
if (max_tx_rate < I40E_BW_MBPS_DIVISOR) {
dev_warn(&vsi->back->pdev->dev,
"Setting max tx rate to minimum usable value of 50Mbps.\n");
max_tx_rate = I40E_BW_CREDIT_DIVISOR;
} else {
do_div(max_tx_rate, I40E_BW_MBPS_DIVISOR);
}
return max_tx_rate;
}
/**
* i40e_set_bw_limit - setup BW limit for Tx traffic based on max_tx_rate
* @vsi: VSI to be configured
@ -5660,10 +5680,10 @@ int i40e_set_bw_limit(struct i40e_vsi *vsi, u16 seid, u64 max_tx_rate)
max_tx_rate, seid);
return -EINVAL;
}
if (max_tx_rate && max_tx_rate < 50) {
if (max_tx_rate && max_tx_rate < I40E_BW_CREDIT_DIVISOR) {
dev_warn(&pf->pdev->dev,
"Setting max tx rate to minimum usable value of 50Mbps.\n");
max_tx_rate = 50;
max_tx_rate = I40E_BW_CREDIT_DIVISOR;
}
/* Tx rate credits are in values of 50Mbps, 0 is disabled */
@ -7591,9 +7611,9 @@ static int i40e_setup_tc(struct net_device *netdev, void *type_data)
if (pf->flags & I40E_FLAG_TC_MQPRIO) {
if (vsi->mqprio_qopt.max_rate[0]) {
u64 max_tx_rate = vsi->mqprio_qopt.max_rate[0];
u64 max_tx_rate = i40e_bw_bytes_to_mbits(vsi,
vsi->mqprio_qopt.max_rate[0]);
do_div(max_tx_rate, I40E_BW_MBPS_DIVISOR);
ret = i40e_set_bw_limit(vsi, vsi->seid, max_tx_rate);
if (!ret) {
u64 credits = max_tx_rate;
@ -10247,10 +10267,10 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
}
if (vsi->mqprio_qopt.max_rate[0]) {
u64 max_tx_rate = vsi->mqprio_qopt.max_rate[0];
u64 max_tx_rate = i40e_bw_bytes_to_mbits(vsi,
vsi->mqprio_qopt.max_rate[0]);
u64 credits = 0;
do_div(max_tx_rate, I40E_BW_MBPS_DIVISOR);
ret = i40e_set_bw_limit(vsi, vsi->seid, max_tx_rate);
if (ret)
goto end_unlock;

View File

@ -1873,6 +1873,25 @@ static void i40e_del_qch(struct i40e_vf *vf)
}
}
/**
* i40e_vc_get_max_frame_size
* @vf: pointer to the VF
*
* Max frame size is determined based on the current port's max frame size and
* whether a port VLAN is configured on this VF. The VF is not aware whether
* it's in a port VLAN so the PF needs to account for this in max frame size
* checks and sending the max frame size to the VF.
**/
static u16 i40e_vc_get_max_frame_size(struct i40e_vf *vf)
{
u16 max_frame_size = vf->pf->hw.phy.link_info.max_frame_size;
if (vf->port_vlan_id)
max_frame_size -= VLAN_HLEN;
return max_frame_size;
}
/**
* i40e_vc_get_vf_resources_msg
* @vf: pointer to the VF info
@ -1973,6 +1992,7 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg)
vfres->max_vectors = pf->hw.func_caps.num_msix_vectors_vf;
vfres->rss_key_size = I40E_HKEY_ARRAY_SIZE;
vfres->rss_lut_size = I40E_VF_HLUT_ARRAY_SIZE;
vfres->max_mtu = i40e_vc_get_max_frame_size(vf);
if (vf->lan_vsi_idx) {
vfres->vsi_res[0].vsi_id = vf->lan_vsi_id;

View File

@ -114,8 +114,11 @@ u32 iavf_get_tx_pending(struct iavf_ring *ring, bool in_sw)
{
u32 head, tail;
/* underlying hardware might not allow access and/or always return
* 0 for the head/tail registers so just use the cached values
*/
head = ring->next_to_clean;
tail = readl(ring->tail);
tail = ring->next_to_use;
if (head != tail)
return (head < tail) ?
@ -1371,7 +1374,7 @@ static struct sk_buff *iavf_build_skb(struct iavf_ring *rx_ring,
#endif
struct sk_buff *skb;
if (!rx_buffer)
if (!rx_buffer || !size)
return NULL;
/* prefetch first cache line of first page */
va = page_address(rx_buffer->page) + rx_buffer->page_offset;
@ -1531,7 +1534,7 @@ static int iavf_clean_rx_irq(struct iavf_ring *rx_ring, int budget)
/* exit if we failed to retrieve a buffer */
if (!skb) {
rx_ring->rx_stats.alloc_buff_failed++;
if (rx_buffer)
if (rx_buffer && size)
rx_buffer->pagecnt_bias++;
break;
}

View File

@ -241,11 +241,14 @@ int iavf_get_vf_config(struct iavf_adapter *adapter)
void iavf_configure_queues(struct iavf_adapter *adapter)
{
struct virtchnl_vsi_queue_config_info *vqci;
struct virtchnl_queue_pair_info *vqpi;
int i, max_frame = adapter->vf_res->max_mtu;
int pairs = adapter->num_active_queues;
int i, max_frame = IAVF_MAX_RXBUFFER;
struct virtchnl_queue_pair_info *vqpi;
size_t len;
if (max_frame > IAVF_MAX_RXBUFFER || !max_frame)
max_frame = IAVF_MAX_RXBUFFER;
if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
/* bail because we already have a command pending */
dev_err(&adapter->pdev->dev, "Cannot configure queues, command %d pending\n",

View File

@ -2064,9 +2064,9 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev)
skb_reserve(copy_skb, 2);
skb_put(copy_skb, len);
dma_sync_single_for_cpu(hp->dma_dev, dma_addr, len, DMA_FROM_DEVICE);
dma_sync_single_for_cpu(hp->dma_dev, dma_addr, len + 2, DMA_FROM_DEVICE);
skb_copy_from_linear_data(skb, copy_skb->data, len);
dma_sync_single_for_device(hp->dma_dev, dma_addr, len, DMA_FROM_DEVICE);
dma_sync_single_for_device(hp->dma_dev, dma_addr, len + 2, DMA_FROM_DEVICE);
/* Reuse original ring buffer. */
hme_write_rxd(hp, this,
(RXFLAG_OWN|((RX_BUF_ALLOC_SIZE-RX_OFFSET)<<16)),

View File

@ -496,7 +496,6 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb)
static int ipvlan_process_outbound(struct sk_buff *skb)
{
struct ethhdr *ethh = eth_hdr(skb);
int ret = NET_XMIT_DROP;
/* The ipvlan is a pseudo-L2 device, so the packets that we receive
@ -506,6 +505,8 @@ static int ipvlan_process_outbound(struct sk_buff *skb)
if (skb_mac_header_was_set(skb)) {
/* In this mode we dont care about
* multicast and broadcast traffic */
struct ethhdr *ethh = eth_hdr(skb);
if (is_multicast_ether_addr(ethh->h_dest)) {
pr_debug_ratelimited(
"Dropped {multi|broad}cast of type=[%x]\n",
@ -590,7 +591,7 @@ static int ipvlan_xmit_mode_l3(struct sk_buff *skb, struct net_device *dev)
static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev)
{
const struct ipvl_dev *ipvlan = netdev_priv(dev);
struct ethhdr *eth = eth_hdr(skb);
struct ethhdr *eth = skb_eth_hdr(skb);
struct ipvl_addr *addr;
void *lyr3h;
int addr_type;
@ -620,6 +621,7 @@ static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev)
return dev_forward_skb(ipvlan->phy_dev, skb);
} else if (is_multicast_ether_addr(eth->h_dest)) {
skb_reset_mac_header(skb);
ipvlan_skb_crossing_ns(skb, NULL);
ipvlan_multicast_enqueue(ipvlan->port, skb, true);
return NET_XMIT_SUCCESS;

View File

@ -1270,10 +1270,12 @@ static int team_port_add(struct team *team, struct net_device *port_dev,
}
}
netif_addr_lock_bh(dev);
dev_uc_sync_multiple(port_dev, dev);
dev_mc_sync_multiple(port_dev, dev);
netif_addr_unlock_bh(dev);
if (dev->flags & IFF_UP) {
netif_addr_lock_bh(dev);
dev_uc_sync_multiple(port_dev, dev);
dev_mc_sync_multiple(port_dev, dev);
netif_addr_unlock_bh(dev);
}
port->index = -1;
list_add_tail_rcu(&port->list, &team->port_list);
@ -1344,8 +1346,10 @@ static int team_port_del(struct team *team, struct net_device *port_dev)
netdev_rx_handler_unregister(port_dev);
team_port_disable_netpoll(port);
vlan_vids_del_by_dev(port_dev, dev);
dev_uc_unsync(port_dev, dev);
dev_mc_unsync(port_dev, dev);
if (dev->flags & IFF_UP) {
dev_uc_unsync(port_dev, dev);
dev_mc_unsync(port_dev, dev);
}
dev_close(port_dev);
team_port_leave(team, port);
@ -1694,6 +1698,14 @@ static int team_open(struct net_device *dev)
static int team_close(struct net_device *dev)
{
struct team *team = netdev_priv(dev);
struct team_port *port;
list_for_each_entry(port, &team->port_list, list) {
dev_uc_unsync(port->dev, dev);
dev_mc_unsync(port->dev, dev);
}
return 0;
}

View File

@ -1046,6 +1046,7 @@ static const struct usb_device_id products[] = {
{QMI_MATCH_FF_FF_FF(0x2c7c, 0x0512)}, /* Quectel EG12/EM12 */
{QMI_MATCH_FF_FF_FF(0x2c7c, 0x0620)}, /* Quectel EM160R-GL */
{QMI_MATCH_FF_FF_FF(0x2c7c, 0x0800)}, /* Quectel RM500Q-GL */
{QMI_MATCH_FF_FF_FF(0x2c7c, 0x0801)}, /* Quectel RM520N */
/* 3. Combined interface devices matching on interface number */
{QMI_FIXED_INTF(0x0408, 0xea42, 4)}, /* Yota / Megafon M100-1 */

View File

@ -315,7 +315,7 @@ static int unflatten_dt_nodes(const void *blob,
for (offset = 0;
offset >= 0 && depth >= initial_depth;
offset = fdt_next_node(blob, offset, &depth)) {
if (WARN_ON_ONCE(depth >= FDT_MAX_DEPTH))
if (WARN_ON_ONCE(depth >= FDT_MAX_DEPTH - 1))
continue;
if (!IS_ENABLED(CONFIG_OF_KOBJ) &&

View File

@ -281,6 +281,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
return 0;
unregister:
of_node_put(child);
mdiobus_unregister(mdio);
return rc;
}

View File

@ -1544,6 +1544,7 @@ static int __init ccio_probe(struct parisc_device *dev)
}
ccio_ioc_init(ioc);
if (ccio_init_resources(ioc)) {
iounmap(ioc->ioc_regs);
kfree(ioc);
return -ENOMEM;
}

View File

@ -788,7 +788,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
((pfuze_chip->chip_id == PFUZE3000) ? "3000" : "3001"))));
memcpy(pfuze_chip->regulator_descs, pfuze_chip->pfuze_regulators,
sizeof(pfuze_chip->regulator_descs));
regulator_num * sizeof(struct pfuze_regulator));
ret = pfuze_parse_regulators_dt(pfuze_chip);
if (ret)

View File

@ -675,12 +675,12 @@ int dasd_alias_remove_device(struct dasd_device *device)
struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *base_device)
{
struct dasd_eckd_private *alias_priv, *private = base_device->private;
struct alias_pav_group *group = private->pavgroup;
struct alias_lcu *lcu = private->lcu;
struct dasd_device *alias_device;
struct alias_pav_group *group;
unsigned long flags;
if (!group || !lcu)
if (!lcu)
return NULL;
if (lcu->pav == NO_PAV ||
lcu->flags & (NEED_UAC_UPDATE | UPDATE_PENDING))
@ -697,6 +697,11 @@ struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *base_device)
}
spin_lock_irqsave(&lcu->lock, flags);
group = private->pavgroup;
if (!group) {
spin_unlock_irqrestore(&lcu->lock, flags);
return NULL;
}
alias_device = group->next;
if (!alias_device) {
if (list_empty(&group->aliaslist)) {

View File

@ -306,16 +306,16 @@ static int atmel_config_rs485(struct uart_port *port,
mode = atmel_uart_readl(port, ATMEL_US_MR);
/* Resetting serial mode to RS232 (0x0) */
mode &= ~ATMEL_US_USMODE;
port->rs485 = *rs485conf;
if (rs485conf->flags & SER_RS485_ENABLED) {
dev_dbg(port->dev, "Setting UART to RS485\n");
atmel_port->tx_done_mask = ATMEL_US_TXEMPTY;
if (rs485conf->flags & SER_RS485_RX_DURING_TX)
atmel_port->tx_done_mask = ATMEL_US_TXRDY;
else
atmel_port->tx_done_mask = ATMEL_US_TXEMPTY;
atmel_uart_writel(port, ATMEL_US_TTGR,
rs485conf->delay_rts_after_send);
mode &= ~ATMEL_US_USMODE;
mode |= ATMEL_US_USMODE_RS485;
} else {
dev_dbg(port->dev, "Setting UART to RS232\n");
@ -832,7 +832,7 @@ static void atmel_tx_chars(struct uart_port *port)
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
if (port->x_char &&
(atmel_uart_readl(port, ATMEL_US_CSR) & atmel_port->tx_done_mask)) {
(atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXRDY)) {
atmel_uart_write_char(port, port->x_char);
port->icount.tx++;
port->x_char = 0;
@ -840,8 +840,7 @@ static void atmel_tx_chars(struct uart_port *port)
if (uart_circ_empty(xmit) || uart_tx_stopped(port))
return;
while (atmel_uart_readl(port, ATMEL_US_CSR) &
atmel_port->tx_done_mask) {
while (atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXRDY) {
atmel_uart_write_char(port, xmit->buf[xmit->tail]);
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
port->icount.tx++;
@ -852,10 +851,20 @@ static void atmel_tx_chars(struct uart_port *port)
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(port);
if (!uart_circ_empty(xmit))
if (!uart_circ_empty(xmit)) {
/* we still have characters to transmit, so we should continue
* transmitting them when TX is ready, regardless of
* mode or duplexity
*/
atmel_port->tx_done_mask |= ATMEL_US_TXRDY;
/* Enable interrupts */
atmel_uart_writel(port, ATMEL_US_IER,
atmel_port->tx_done_mask);
} else {
if (atmel_uart_is_half_duplex(port))
atmel_port->tx_done_mask &= ~ATMEL_US_TXRDY;
}
}
static void atmel_complete_tx_dma(void *arg)
@ -2541,8 +2550,7 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port,
* Use TXEMPTY for interrupt when rs485 or ISO7816 else TXRDY or
* ENDTX|TXBUFE
*/
if (port->rs485.flags & SER_RS485_ENABLED ||
port->iso7816.flags & SER_ISO7816_ENABLED)
if (atmel_uart_is_half_duplex(port))
atmel_port->tx_done_mask = ATMEL_US_TXEMPTY;
else if (atmel_use_pdc_tx(port)) {
port->fifosize = PDC_BUFFER_SIZE;

View File

@ -519,7 +519,7 @@ static void tegra_uart_tx_dma_complete(void *args)
count = tup->tx_bytes_requested - state.residue;
async_tx_ack(tup->tx_dma_desc);
spin_lock_irqsave(&tup->uport.lock, flags);
xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1);
uart_xmit_advance(&tup->uport, count);
tup->tx_in_progress = 0;
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(&tup->uport);
@ -606,7 +606,6 @@ static unsigned int tegra_uart_tx_empty(struct uart_port *u)
static void tegra_uart_stop_tx(struct uart_port *u)
{
struct tegra_uart_port *tup = to_tegra_uport(u);
struct circ_buf *xmit = &tup->uport.state->xmit;
struct dma_tx_state state;
unsigned int count;
@ -617,7 +616,7 @@ static void tegra_uart_stop_tx(struct uart_port *u)
dmaengine_tx_status(tup->tx_dma_chan, tup->tx_cookie, &state);
count = tup->tx_bytes_requested - state.residue;
async_tx_ack(tup->tx_dma_desc);
xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1);
uart_xmit_advance(&tup->uport, count);
tup->tx_in_progress = 0;
}

View File

@ -101,7 +101,7 @@ static void tegra_tcu_uart_start_tx(struct uart_port *port)
break;
tegra_tcu_write(tcu, &xmit->buf[xmit->tail], count);
xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1);
uart_xmit_advance(port, count);
}
uart_write_wakeup(port);

View File

@ -1259,6 +1259,7 @@ static int cdns3_check_ep_interrupt_proceed(struct cdns3_endpoint *priv_ep)
ep_cfg &= ~EP_CFG_ENABLE;
writel(ep_cfg, &priv_dev->regs->ep_cfg);
priv_ep->flags &= ~EP_QUIRK_ISO_OUT_EN;
priv_ep->flags |= EP_UPDATE_EP_TRBADDR;
}
cdns3_transfer_completed(priv_dev, priv_ep);
} else if (!(priv_ep->flags & EP_STALLED) &&

View File

@ -227,7 +227,7 @@ u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type)
* dwc3_core_soft_reset - Issues core soft reset and PHY reset
* @dwc: pointer to our context structure
*/
static int dwc3_core_soft_reset(struct dwc3 *dwc)
int dwc3_core_soft_reset(struct dwc3 *dwc)
{
u32 reg;
int retries = 1000;

View File

@ -998,6 +998,7 @@ struct dwc3_scratchpad_array {
* @tx_max_burst_prd: max periodic ESS transmit burst size
* @hsphy_interface: "utmi" or "ulpi"
* @connected: true when we're connected to a host, false otherwise
* @softconnect: true when gadget connect is called, false when disconnect runs
* @delayed_status: true when gadget driver asks for delayed status
* @ep0_bounced: true when we used bounce buffer
* @ep0_expect_in: true when we expect a DATA IN transfer
@ -1202,6 +1203,7 @@ struct dwc3 {
const char *hsphy_interface;
unsigned connected:1;
unsigned softconnect:1;
unsigned delayed_status:1;
unsigned ep0_bounced:1;
unsigned ep0_expect_in:1;
@ -1426,6 +1428,8 @@ bool dwc3_has_imod(struct dwc3 *dwc);
int dwc3_event_buffers_setup(struct dwc3 *dwc);
void dwc3_event_buffers_cleanup(struct dwc3 *dwc);
int dwc3_core_soft_reset(struct dwc3 *dwc);
#if IS_ENABLED(CONFIG_USB_DWC3_HOST) || IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)
int dwc3_host_init(struct dwc3 *dwc);
void dwc3_host_exit(struct dwc3 *dwc);

View File

@ -2008,14 +2008,42 @@ static void dwc3_gadget_disable_irq(struct dwc3 *dwc);
static void __dwc3_gadget_stop(struct dwc3 *dwc);
static int __dwc3_gadget_start(struct dwc3 *dwc);
static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc)
{
unsigned long flags;
spin_lock_irqsave(&dwc->lock, flags);
dwc->connected = false;
/*
* In the Synopsys DesignWare Cores USB3 Databook Rev. 3.30a
* Section 4.1.8 Table 4-7, it states that for a device-initiated
* disconnect, the SW needs to ensure that it sends "a DEPENDXFER
* command for any active transfers" before clearing the RunStop
* bit.
*/
dwc3_stop_active_transfers(dwc);
__dwc3_gadget_stop(dwc);
spin_unlock_irqrestore(&dwc->lock, flags);
/*
* Note: if the GEVNTCOUNT indicates events in the event buffer, the
* driver needs to acknowledge them before the controller can halt.
* Simply let the interrupt handler acknowledges and handle the
* remaining event generated by the controller while polling for
* DSTS.DEVCTLHLT.
*/
return dwc3_gadget_run_stop(dwc, false, false);
}
static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
{
struct dwc3 *dwc = gadget_to_dwc(g);
unsigned long flags;
int ret;
is_on = !!is_on;
dwc->softconnect = is_on;
/*
* Per databook, when we want to stop the gadget, if a control transfer
* is still in process, complete it and get the core into setup phase.
@ -2051,49 +2079,26 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
return 0;
}
/*
* Synchronize and disable any further event handling while controller
* is being enabled/disabled.
*/
disable_irq(dwc->irq_gadget);
spin_lock_irqsave(&dwc->lock, flags);
if (!is_on) {
u32 count;
dwc->connected = false;
/*
* In the Synopsis DesignWare Cores USB3 Databook Rev. 3.30a
* Section 4.1.8 Table 4-7, it states that for a device-initiated
* disconnect, the SW needs to ensure that it sends "a DEPENDXFER
* command for any active transfers" before clearing the RunStop
* bit.
*/
dwc3_stop_active_transfers(dwc);
__dwc3_gadget_stop(dwc);
/*
* In the Synopsis DesignWare Cores USB3 Databook Rev. 3.30a
* Section 1.3.4, it mentions that for the DEVCTRLHLT bit, the
* "software needs to acknowledge the events that are generated
* (by writing to GEVNTCOUNTn) while it is waiting for this bit
* to be set to '1'."
*/
count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
count &= DWC3_GEVNTCOUNT_MASK;
if (count > 0) {
dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), count);
dwc->ev_buf->lpos = (dwc->ev_buf->lpos + count) %
dwc->ev_buf->length;
}
} else {
__dwc3_gadget_start(dwc);
if (dwc->pullups_connected == is_on) {
pm_runtime_put(dwc->dev);
return 0;
}
ret = dwc3_gadget_run_stop(dwc, is_on, false);
spin_unlock_irqrestore(&dwc->lock, flags);
enable_irq(dwc->irq_gadget);
if (!is_on) {
ret = dwc3_gadget_soft_disconnect(dwc);
} else {
/*
* In the Synopsys DWC_usb31 1.90a programming guide section
* 4.1.9, it specifies that for a reconnect after a
* device-initiated disconnect requires a core soft reset
* (DCTL.CSftRst) before enabling the run/stop bit.
*/
dwc3_core_soft_reset(dwc);
dwc3_event_buffers_setup(dwc);
__dwc3_gadget_start(dwc);
ret = dwc3_gadget_run_stop(dwc, true, false);
}
pm_runtime_put(dwc->dev);
@ -3791,7 +3796,7 @@ int dwc3_gadget_resume(struct dwc3 *dwc)
{
int ret;
if (!dwc->gadget_driver)
if (!dwc->gadget_driver || !dwc->softconnect)
return 0;
ret = __dwc3_gadget_start(dwc);

View File

@ -25,6 +25,13 @@
*/
#define TT_MICROFRAMES_MAX 9
/* schedule error type */
#define ESCH_SS_Y6 1001
#define ESCH_SS_OVERLAP 1002
#define ESCH_CS_OVERFLOW 1003
#define ESCH_BW_OVERFLOW 1004
#define ESCH_FIXME 1005
/* mtk scheduler bitmasks */
#define EP_BPKTS(p) ((p) & 0x7f)
#define EP_BCSCOUNT(p) (((p) & 0x7) << 8)
@ -32,6 +39,24 @@
#define EP_BOFFSET(p) ((p) & 0x3fff)
#define EP_BREPEAT(p) (((p) & 0x7fff) << 16)
static char *sch_error_string(int err_num)
{
switch (err_num) {
case ESCH_SS_Y6:
return "Can't schedule Start-Split in Y6";
case ESCH_SS_OVERLAP:
return "Can't find a suitable Start-Split location";
case ESCH_CS_OVERFLOW:
return "The last Complete-Split is greater than 7";
case ESCH_BW_OVERFLOW:
return "Bandwidth exceeds the maximum limit";
case ESCH_FIXME:
return "FIXME, to be resolved";
default:
return "Unknown";
}
}
static int is_fs_or_ls(enum usb_device_speed speed)
{
return speed == USB_SPEED_FULL || speed == USB_SPEED_LOW;
@ -375,7 +400,6 @@ static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw,
sch_ep->bw_budget_table[j];
}
}
sch_ep->allocated = used;
}
static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset)
@ -384,19 +408,20 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset)
u32 num_esit, tmp;
int base;
int i, j;
u8 uframes = DIV_ROUND_UP(sch_ep->maxpkt, FS_PAYLOAD_MAX);
num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
if (sch_ep->ep_type == INT_IN_EP || sch_ep->ep_type == ISOC_IN_EP)
offset++;
for (i = 0; i < num_esit; i++) {
base = offset + i * sch_ep->esit;
/*
* Compared with hs bus, no matter what ep type,
* the hub will always delay one uframe to send data
*/
for (j = 0; j < sch_ep->cs_count; j++) {
for (j = 0; j < uframes; j++) {
tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_cost_per_microframe;
if (tmp > FS_PAYLOAD_MAX)
return -ERANGE;
return -ESCH_BW_OVERFLOW;
}
}
@ -406,15 +431,11 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset)
static int check_sch_tt(struct usb_device *udev,
struct mu3h_sch_ep_info *sch_ep, u32 offset)
{
struct mu3h_sch_tt *tt = sch_ep->sch_tt;
u32 extra_cs_count;
u32 fs_budget_start;
u32 start_ss, last_ss;
u32 start_cs, last_cs;
int i;
start_ss = offset % 8;
fs_budget_start = (start_ss + 1) % 8;
if (sch_ep->ep_type == ISOC_OUT_EP) {
last_ss = start_ss + sch_ep->cs_count - 1;
@ -424,11 +445,7 @@ static int check_sch_tt(struct usb_device *udev,
* must never schedule Start-Split in Y6
*/
if (!(start_ss == 7 || last_ss < 6))
return -ERANGE;
for (i = 0; i < sch_ep->cs_count; i++)
if (test_bit(offset + i, tt->ss_bit_map))
return -ERANGE;
return -ESCH_SS_Y6;
} else {
u32 cs_count = DIV_ROUND_UP(sch_ep->maxpkt, FS_PAYLOAD_MAX);
@ -438,29 +455,24 @@ static int check_sch_tt(struct usb_device *udev,
* must never schedule Start-Split in Y6
*/
if (start_ss == 6)
return -ERANGE;
return -ESCH_SS_Y6;
/* one uframe for ss + one uframe for idle */
start_cs = (start_ss + 2) % 8;
last_cs = start_cs + cs_count - 1;
if (last_cs > 7)
return -ERANGE;
return -ESCH_CS_OVERFLOW;
if (sch_ep->ep_type == ISOC_IN_EP)
extra_cs_count = (last_cs == 7) ? 1 : 2;
else /* ep_type : INTR IN / INTR OUT */
extra_cs_count = (fs_budget_start == 6) ? 1 : 2;
extra_cs_count = 1;
cs_count += extra_cs_count;
if (cs_count > 7)
cs_count = 7; /* HW limit */
for (i = 0; i < cs_count + 2; i++) {
if (test_bit(offset + i, tt->ss_bit_map))
return -ERANGE;
}
sch_ep->cs_count = cs_count;
/* one for ss, the other for idle */
sch_ep->num_budget_microframes = cs_count + 2;
@ -482,28 +494,24 @@ static void update_sch_tt(struct usb_device *udev,
struct mu3h_sch_tt *tt = sch_ep->sch_tt;
u32 base, num_esit;
int bw_updated;
int bits;
int i, j;
int offset = sch_ep->offset;
u8 uframes = DIV_ROUND_UP(sch_ep->maxpkt, FS_PAYLOAD_MAX);
num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
bits = (sch_ep->ep_type == ISOC_OUT_EP) ? sch_ep->cs_count : 1;
if (used)
bw_updated = sch_ep->bw_cost_per_microframe;
else
bw_updated = -sch_ep->bw_cost_per_microframe;
if (sch_ep->ep_type == INT_IN_EP || sch_ep->ep_type == ISOC_IN_EP)
offset++;
for (i = 0; i < num_esit; i++) {
base = sch_ep->offset + i * sch_ep->esit;
base = offset + i * sch_ep->esit;
for (j = 0; j < bits; j++) {
if (used)
set_bit(base + j, tt->ss_bit_map);
else
clear_bit(base + j, tt->ss_bit_map);
}
for (j = 0; j < sch_ep->cs_count; j++)
for (j = 0; j < uframes; j++)
tt->fs_bus_bw[base + j] += bw_updated;
}
@ -513,21 +521,48 @@ static void update_sch_tt(struct usb_device *udev,
list_del(&sch_ep->tt_endpoint);
}
static int load_ep_bw(struct usb_device *udev, struct mu3h_sch_bw_info *sch_bw,
struct mu3h_sch_ep_info *sch_ep, bool loaded)
{
if (sch_ep->sch_tt)
update_sch_tt(udev, sch_ep, loaded);
/* update bus bandwidth info */
update_bus_bw(sch_bw, sch_ep, loaded);
sch_ep->allocated = loaded;
return 0;
}
static u32 get_esit_boundary(struct mu3h_sch_ep_info *sch_ep)
{
u32 boundary = sch_ep->esit;
if (sch_ep->sch_tt) { /* LS/FS with TT */
/*
* tune for CS, normally esit >= 8 for FS/LS,
* not add one for other types to avoid access array
* out of boundary
*/
if (sch_ep->ep_type == ISOC_OUT_EP && boundary > 1)
boundary--;
}
return boundary;
}
static int check_sch_bw(struct usb_device *udev,
struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep)
{
u32 offset;
u32 esit;
u32 min_bw;
u32 min_index;
u32 worst_bw;
u32 bw_boundary;
u32 esit_boundary;
u32 min_num_budget;
u32 min_cs_count;
bool tt_offset_ok = false;
int ret;
esit = sch_ep->esit;
int ret = 0;
/*
* Search through all possible schedule microframes.
@ -537,16 +572,15 @@ static int check_sch_bw(struct usb_device *udev,
min_index = 0;
min_cs_count = sch_ep->cs_count;
min_num_budget = sch_ep->num_budget_microframes;
for (offset = 0; offset < esit; offset++) {
if (is_fs_or_ls(udev->speed)) {
esit_boundary = get_esit_boundary(sch_ep);
for (offset = 0; offset < sch_ep->esit; offset++) {
if (sch_ep->sch_tt) {
ret = check_sch_tt(udev, sch_ep, offset);
if (ret)
continue;
else
tt_offset_ok = true;
}
if ((offset + sch_ep->num_budget_microframes) > sch_ep->esit)
if ((offset + sch_ep->num_budget_microframes) > esit_boundary)
break;
worst_bw = get_max_bw(sch_bw, sch_ep, offset);
@ -569,35 +603,21 @@ static int check_sch_bw(struct usb_device *udev,
/* check bandwidth */
if (min_bw > bw_boundary)
return -ERANGE;
return ret ? ret : -ESCH_BW_OVERFLOW;
sch_ep->offset = min_index;
sch_ep->cs_count = min_cs_count;
sch_ep->num_budget_microframes = min_num_budget;
if (is_fs_or_ls(udev->speed)) {
/* all offset for tt is not ok*/
if (!tt_offset_ok)
return -ERANGE;
update_sch_tt(udev, sch_ep, 1);
}
/* update bus bandwidth info */
update_bus_bw(sch_bw, sch_ep, 1);
return 0;
return load_ep_bw(udev, sch_bw, sch_ep, true);
}
static void destroy_sch_ep(struct usb_device *udev,
struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep)
{
/* only release ep bw check passed by check_sch_bw() */
if (sch_ep->allocated) {
update_bus_bw(sch_bw, sch_ep, 0);
if (sch_ep->sch_tt)
update_sch_tt(udev, sch_ep, 0);
}
if (sch_ep->allocated)
load_ep_bw(udev, sch_bw, sch_ep, false);
if (sch_ep->sch_tt)
drop_tt(udev);
@ -760,7 +780,8 @@ int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
ret = check_sch_bw(udev, sch_bw, sch_ep);
if (ret) {
xhci_err(xhci, "Not enough bandwidth!\n");
xhci_err(xhci, "Not enough bandwidth! (%s)\n",
sch_error_string(-ret));
return -ENOSPC;
}
}

View File

@ -20,14 +20,12 @@
#define XHCI_MTK_MAX_ESIT 64
/**
* @ss_bit_map: used to avoid start split microframes overlay
* @fs_bus_bw: array to keep track of bandwidth already used for FS
* @ep_list: Endpoints using this TT
* @usb_tt: usb TT related
* @tt_port: TT port number
*/
struct mu3h_sch_tt {
DECLARE_BITMAP(ss_bit_map, XHCI_MTK_MAX_ESIT);
u32 fs_bus_bw[XHCI_MTK_MAX_ESIT];
struct list_head ep_list;
struct usb_tt *usb_tt;

View File

@ -256,6 +256,7 @@ static void option_instat_callback(struct urb *urb);
#define QUECTEL_PRODUCT_EM060K 0x030b
#define QUECTEL_PRODUCT_EM12 0x0512
#define QUECTEL_PRODUCT_RM500Q 0x0800
#define QUECTEL_PRODUCT_RM520N 0x0801
#define QUECTEL_PRODUCT_EC200S_CN 0x6002
#define QUECTEL_PRODUCT_EC200T 0x6026
#define QUECTEL_PRODUCT_RM500K 0x7001
@ -1138,6 +1139,8 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG95, 0xff, 0xff, 0xff),
.driver_info = NUMEP2 },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG95, 0xff, 0, 0) },
{ USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, 0x0203, 0xff), /* BG95-M3 */
.driver_info = ZLP },
{ USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96),
.driver_info = RSVD(4) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff),
@ -1159,6 +1162,9 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x10),
.driver_info = ZLP },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500K, 0xff, 0x00, 0x00) },

View File

@ -382,7 +382,7 @@ pxa3xx_gcu_write(struct file *file, const char *buff,
struct pxa3xx_gcu_batch *buffer;
struct pxa3xx_gcu_priv *priv = to_pxa3xx_gcu_priv(file);
int words = count / 4;
size_t words = count / 4;
/* Does not need to be atomic. There's a lock in user space,
* but anyhow, this is just for statistics. */

View File

@ -69,6 +69,7 @@ int afs_abort_to_error(u32 abort_code)
/* Unified AFS error table */
case UAEPERM: return -EPERM;
case UAENOENT: return -ENOENT;
case UAEAGAIN: return -EAGAIN;
case UAEACCES: return -EACCES;
case UAEBUSY: return -EBUSY;
case UAEEXIST: return -EEXIST;

View File

@ -791,9 +791,6 @@ cifs_readv_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg)
int length = 0;
int total_read;
smb_msg->msg_control = NULL;
smb_msg->msg_controllen = 0;
for (total_read = 0; msg_data_left(smb_msg); total_read += length) {
try_to_freeze();
@ -844,7 +841,7 @@ int
cifs_read_from_socket(struct TCP_Server_Info *server, char *buf,
unsigned int to_read)
{
struct msghdr smb_msg;
struct msghdr smb_msg = {};
struct kvec iov = {.iov_base = buf, .iov_len = to_read};
iov_iter_kvec(&smb_msg.msg_iter, READ, &iov, 1, to_read);
@ -855,7 +852,7 @@ int
cifs_read_page_from_socket(struct TCP_Server_Info *server, struct page *page,
unsigned int page_offset, unsigned int to_read)
{
struct msghdr smb_msg;
struct msghdr smb_msg = {};
struct bio_vec bv = {
.bv_page = page, .bv_len = to_read, .bv_offset = page_offset};
iov_iter_bvec(&smb_msg.msg_iter, READ, &bv, 1, to_read);

View File

@ -3194,6 +3194,9 @@ static ssize_t __cifs_writev(
ssize_t cifs_direct_writev(struct kiocb *iocb, struct iov_iter *from)
{
struct file *file = iocb->ki_filp;
cifs_revalidate_mapping(file->f_inode);
return __cifs_writev(iocb, from, true);
}

View File

@ -209,10 +209,6 @@ smb_send_kvec(struct TCP_Server_Info *server, struct msghdr *smb_msg,
*sent = 0;
smb_msg->msg_name = (struct sockaddr *) &server->dstaddr;
smb_msg->msg_namelen = sizeof(struct sockaddr);
smb_msg->msg_control = NULL;
smb_msg->msg_controllen = 0;
if (server->noblocksnd)
smb_msg->msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL;
else
@ -324,7 +320,7 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
sigset_t mask, oldmask;
size_t total_len = 0, sent, size;
struct socket *ssocket = server->ssocket;
struct msghdr smb_msg;
struct msghdr smb_msg = {};
int val = 1;
__be32 rfc1002_marker;

View File

@ -500,6 +500,10 @@ static int __ext4_ext_check(const char *function, unsigned int line,
error_msg = "invalid eh_entries";
goto corrupted;
}
if (unlikely((eh->eh_entries == 0) && (depth > 0))) {
error_msg = "eh_entries is 0 but eh_depth is > 0";
goto corrupted;
}
if (!ext4_valid_extent_entries(inode, eh, lblk, &pblk, depth)) {
error_msg = "invalid extent entries";
goto corrupted;

View File

@ -500,7 +500,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent,
goto fallback;
}
max_dirs = ndirs / ngroups + inodes_per_group / 16;
max_dirs = ndirs / ngroups + inodes_per_group*flex_size / 16;
min_inodes = avefreei - inodes_per_group*flex_size / 4;
if (min_inodes < 1)
min_inodes = 1;

View File

@ -2375,22 +2375,31 @@ void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info)
if (data && data->bsize)
sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits);
if (server->nfs_client->rpc_ops->version != 2) {
/* The VFS shouldn't apply the umask to mode bits. We will do
* so ourselves when necessary.
switch (server->nfs_client->rpc_ops->version) {
case 2:
sb->s_time_gran = 1000;
sb->s_time_min = 0;
sb->s_time_max = U32_MAX;
break;
case 3:
/*
* The VFS shouldn't apply the umask to mode bits.
* We will do so ourselves when necessary.
*/
sb->s_flags |= SB_POSIXACL;
sb->s_time_gran = 1;
sb->s_export_op = &nfs_export_ops;
} else
sb->s_time_gran = 1000;
if (server->nfs_client->rpc_ops->version != 4) {
sb->s_time_min = 0;
sb->s_time_max = U32_MAX;
} else {
sb->s_export_op = &nfs_export_ops;
break;
case 4:
sb->s_flags |= SB_POSIXACL;
sb->s_time_gran = 1;
sb->s_time_min = S64_MIN;
sb->s_time_max = S64_MAX;
if (server->caps & NFS_CAP_ATOMIC_OPEN_V1)
sb->s_export_op = &nfs_export_ops;
break;
}
nfs_initialise_sb(sb);

View File

@ -684,8 +684,10 @@ xfs_alloc_update_counters(
xfs_trans_agblocks_delta(tp, len);
if (unlikely(be32_to_cpu(agf->agf_freeblks) >
be32_to_cpu(agf->agf_length)))
be32_to_cpu(agf->agf_length))) {
xfs_buf_corruption_error(agbp);
return -EFSCORRUPTED;
}
xfs_alloc_log_agf(tp, agbp, XFS_AGF_FREEBLKS);
return 0;
@ -751,6 +753,7 @@ xfs_alloc_ag_vextent_small(
bp = xfs_btree_get_bufs(args->mp, args->tp, args->agno, fbno);
if (!bp) {
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, args->mp);
error = -EFSCORRUPTED;
goto error;
}
@ -1995,24 +1998,32 @@ xfs_alloc_longest_free_extent(
return pag->pagf_flcount > 0 || pag->pagf_longest > 0;
}
/*
* Compute the minimum length of the AGFL in the given AG. If @pag is NULL,
* return the largest possible minimum length.
*/
unsigned int
xfs_alloc_min_freelist(
struct xfs_mount *mp,
struct xfs_perag *pag)
{
/* AG btrees have at least 1 level. */
static const uint8_t fake_levels[XFS_BTNUM_AGF] = {1, 1, 1};
const uint8_t *levels = pag ? pag->pagf_levels : fake_levels;
unsigned int min_free;
ASSERT(mp->m_ag_maxlevels > 0);
/* space needed by-bno freespace btree */
min_free = min_t(unsigned int, pag->pagf_levels[XFS_BTNUM_BNOi] + 1,
min_free = min_t(unsigned int, levels[XFS_BTNUM_BNOi] + 1,
mp->m_ag_maxlevels);
/* space needed by-size freespace btree */
min_free += min_t(unsigned int, pag->pagf_levels[XFS_BTNUM_CNTi] + 1,
min_free += min_t(unsigned int, levels[XFS_BTNUM_CNTi] + 1,
mp->m_ag_maxlevels);
/* space needed reverse mapping used space btree */
if (xfs_sb_version_hasrmapbt(&mp->m_sb))
min_free += min_t(unsigned int,
pag->pagf_levels[XFS_BTNUM_RMAPi] + 1,
mp->m_rmap_maxlevels);
min_free += min_t(unsigned int, levels[XFS_BTNUM_RMAPi] + 1,
mp->m_rmap_maxlevels);
return min_free;
}
@ -2087,8 +2098,10 @@ xfs_free_agfl_block(
return error;
bp = xfs_btree_get_bufs(tp->t_mountp, tp, agno, agbno);
if (!bp)
if (!bp) {
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, tp->t_mountp);
return -EFSCORRUPTED;
}
xfs_trans_binval(tp, bp);
return 0;

View File

@ -2287,8 +2287,10 @@ xfs_attr3_leaf_lookup_int(
leaf = bp->b_addr;
xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
entries = xfs_attr3_leaf_entryp(leaf);
if (ichdr.count >= args->geo->blksize / 8)
if (ichdr.count >= args->geo->blksize / 8) {
xfs_buf_corruption_error(bp);
return -EFSCORRUPTED;
}
/*
* Binary search. (note: small blocks will skip this loop)
@ -2304,10 +2306,14 @@ xfs_attr3_leaf_lookup_int(
else
break;
}
if (!(probe >= 0 && (!ichdr.count || probe < ichdr.count)))
if (!(probe >= 0 && (!ichdr.count || probe < ichdr.count))) {
xfs_buf_corruption_error(bp);
return -EFSCORRUPTED;
if (!(span <= 4 || be32_to_cpu(entry->hashval) == hashval))
}
if (!(span <= 4 || be32_to_cpu(entry->hashval) == hashval)) {
xfs_buf_corruption_error(bp);
return -EFSCORRUPTED;
}
/*
* Since we may have duplicate hashval's, find the first matching

View File

@ -729,6 +729,7 @@ xfs_bmap_extents_to_btree(
xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L);
abp = xfs_btree_get_bufl(mp, tp, args.fsbno);
if (!abp) {
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp);
error = -EFSCORRUPTED;
goto out_unreserve_dquot;
}
@ -1084,6 +1085,7 @@ xfs_bmap_add_attrfork(
if (XFS_IFORK_Q(ip))
goto trans_cancel;
if (ip->i_d.di_anextents != 0) {
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp);
error = -EFSCORRUPTED;
goto trans_cancel;
}
@ -1374,7 +1376,8 @@ xfs_bmap_last_before(
case XFS_DINODE_FMT_EXTENTS:
break;
default:
return -EIO;
ASSERT(0);
return -EFSCORRUPTED;
}
if (!(ifp->if_flags & XFS_IFEXTENTS)) {
@ -1474,8 +1477,10 @@ xfs_bmap_last_offset(
return 0;
if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)
return -EIO;
XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) {
ASSERT(0);
return -EFSCORRUPTED;
}
error = xfs_bmap_last_extent(NULL, ip, whichfork, &rec, &is_empty);
if (error || is_empty)
@ -5871,8 +5876,9 @@ xfs_bmap_insert_extents(
XFS_WANT_CORRUPTED_GOTO(mp, !isnullstartblock(got.br_startblock),
del_cursor);
if (stop_fsb >= got.br_startoff + got.br_blockcount) {
error = -EIO;
if (stop_fsb > got.br_startoff) {
ASSERT(0);
error = -EFSCORRUPTED;
goto del_cursor;
}

View File

@ -1820,6 +1820,7 @@ xfs_btree_lookup_get_block(
out_bad:
*blkp = NULL;
xfs_buf_corruption_error(bp);
xfs_trans_brelse(cur->bc_tp, bp);
return -EFSCORRUPTED;
}
@ -1867,8 +1868,10 @@ xfs_btree_lookup(
XFS_BTREE_STATS_INC(cur, lookup);
/* No such thing as a zero-level tree. */
if (cur->bc_nlevels == 0)
if (cur->bc_nlevels == 0) {
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, cur->bc_mp);
return -EFSCORRUPTED;
}
block = NULL;
keyno = 0;

View File

@ -504,6 +504,7 @@ xfs_da3_split(
node = oldblk->bp->b_addr;
if (node->hdr.info.forw) {
if (be32_to_cpu(node->hdr.info.forw) != addblk->blkno) {
xfs_buf_corruption_error(oldblk->bp);
error = -EFSCORRUPTED;
goto out;
}
@ -516,6 +517,7 @@ xfs_da3_split(
node = oldblk->bp->b_addr;
if (node->hdr.info.back) {
if (be32_to_cpu(node->hdr.info.back) != addblk->blkno) {
xfs_buf_corruption_error(oldblk->bp);
error = -EFSCORRUPTED;
goto out;
}
@ -1541,8 +1543,10 @@ xfs_da3_node_lookup_int(
break;
}
if (magic != XFS_DA_NODE_MAGIC && magic != XFS_DA3_NODE_MAGIC)
if (magic != XFS_DA_NODE_MAGIC && magic != XFS_DA3_NODE_MAGIC) {
xfs_buf_corruption_error(blk->bp);
return -EFSCORRUPTED;
}
blk->magic = XFS_DA_NODE_MAGIC;
@ -1554,15 +1558,18 @@ xfs_da3_node_lookup_int(
btree = dp->d_ops->node_tree_p(node);
/* Tree taller than we can handle; bail out! */
if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH)
if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH) {
xfs_buf_corruption_error(blk->bp);
return -EFSCORRUPTED;
}
/* Check the level from the root. */
if (blkno == args->geo->leafblk)
expected_level = nodehdr.level - 1;
else if (expected_level != nodehdr.level)
else if (expected_level != nodehdr.level) {
xfs_buf_corruption_error(blk->bp);
return -EFSCORRUPTED;
else
} else
expected_level--;
max = nodehdr.count;
@ -1612,12 +1619,17 @@ xfs_da3_node_lookup_int(
}
/* We can't point back to the root. */
if (blkno == args->geo->leafblk)
if (blkno == args->geo->leafblk) {
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW,
dp->i_mount);
return -EFSCORRUPTED;
}
}
if (expected_level != 0)
if (expected_level != 0) {
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, dp->i_mount);
return -EFSCORRUPTED;
}
/*
* A leaf block that ends in the hashval that we are interested in

View File

@ -600,8 +600,10 @@ xfs_dir2_isblock(
if ((rval = xfs_bmap_last_offset(args->dp, &last, XFS_DATA_FORK)))
return rval;
rval = XFS_FSB_TO_B(args->dp->i_mount, last) == args->geo->blksize;
if (rval != 0 && args->dp->i_d.di_size != args->geo->blksize)
if (rval != 0 && args->dp->i_d.di_size != args->geo->blksize) {
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, args->dp->i_mount);
return -EFSCORRUPTED;
}
*vp = rval;
return 0;
}

View File

@ -1343,8 +1343,10 @@ xfs_dir2_leaf_removename(
oldbest = be16_to_cpu(bf[0].length);
ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
bestsp = xfs_dir2_leaf_bests_p(ltp);
if (be16_to_cpu(bestsp[db]) != oldbest)
if (be16_to_cpu(bestsp[db]) != oldbest) {
xfs_buf_corruption_error(lbp);
return -EFSCORRUPTED;
}
/*
* Mark the former data entry unused.
*/

View File

@ -374,8 +374,10 @@ xfs_dir2_leaf_to_node(
leaf = lbp->b_addr;
ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
if (be32_to_cpu(ltp->bestcount) >
(uint)dp->i_d.di_size / args->geo->blksize)
(uint)dp->i_d.di_size / args->geo->blksize) {
xfs_buf_corruption_error(lbp);
return -EFSCORRUPTED;
}
/*
* Copy freespace entries from the leaf block to the new block.
@ -446,8 +448,10 @@ xfs_dir2_leafn_add(
* Quick check just to make sure we are not going to index
* into other peoples memory
*/
if (index < 0)
if (index < 0) {
xfs_buf_corruption_error(bp);
return -EFSCORRUPTED;
}
/*
* If there are already the maximum number of leaf entries in
@ -740,8 +744,10 @@ xfs_dir2_leafn_lookup_for_entry(
ents = dp->d_ops->leaf_ents_p(leaf);
xfs_dir3_leaf_check(dp, bp);
if (leafhdr.count <= 0)
if (leafhdr.count <= 0) {
xfs_buf_corruption_error(bp);
return -EFSCORRUPTED;
}
/*
* Look up the hash value in the leaf entries.

View File

@ -944,6 +944,27 @@ xfs_dir2_sf_removename(
return 0;
}
/*
* Check whether the sf dir replace operation need more blocks.
*/
static bool
xfs_dir2_sf_replace_needblock(
struct xfs_inode *dp,
xfs_ino_t inum)
{
int newsize;
struct xfs_dir2_sf_hdr *sfp;
if (dp->i_d.di_format != XFS_DINODE_FMT_LOCAL)
return false;
sfp = (struct xfs_dir2_sf_hdr *)dp->i_df.if_u1.if_data;
newsize = dp->i_df.if_bytes + (sfp->count + 1) * XFS_INO64_DIFF;
return inum > XFS_DIR2_MAX_SHORT_INUM &&
sfp->i8count == 0 && newsize > XFS_IFORK_DSIZE(dp);
}
/*
* Replace the inode number of an entry in a shortform directory.
*/
@ -980,17 +1001,14 @@ xfs_dir2_sf_replace(
*/
if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && sfp->i8count == 0) {
int error; /* error return value */
int newsize; /* new inode size */
newsize = dp->i_df.if_bytes + (sfp->count + 1) * XFS_INO64_DIFF;
/*
* Won't fit as shortform, convert to block then do replace.
*/
if (newsize > XFS_IFORK_DSIZE(dp)) {
if (xfs_dir2_sf_replace_needblock(dp, args->inumber)) {
error = xfs_dir2_sf_to_block(args);
if (error) {
if (error)
return error;
}
return xfs_dir2_block_replace(args);
}
/*

View File

@ -2854,3 +2854,67 @@ xfs_ialloc_setup_geometry(
else
igeo->ialloc_align = 0;
}
/* Compute the location of the root directory inode that is laid out by mkfs. */
xfs_ino_t
xfs_ialloc_calc_rootino(
struct xfs_mount *mp,
int sunit)
{
struct xfs_ino_geometry *igeo = M_IGEO(mp);
xfs_agblock_t first_bno;
/*
* Pre-calculate the geometry of AG 0. We know what it looks like
* because libxfs knows how to create allocation groups now.
*
* first_bno is the first block in which mkfs could possibly have
* allocated the root directory inode, once we factor in the metadata
* that mkfs formats before it. Namely, the four AG headers...
*/
first_bno = howmany(4 * mp->m_sb.sb_sectsize, mp->m_sb.sb_blocksize);
/* ...the two free space btree roots... */
first_bno += 2;
/* ...the inode btree root... */
first_bno += 1;
/* ...the initial AGFL... */
first_bno += xfs_alloc_min_freelist(mp, NULL);
/* ...the free inode btree root... */
if (xfs_sb_version_hasfinobt(&mp->m_sb))
first_bno++;
/* ...the reverse mapping btree root... */
if (xfs_sb_version_hasrmapbt(&mp->m_sb))
first_bno++;
/* ...the reference count btree... */
if (xfs_sb_version_hasreflink(&mp->m_sb))
first_bno++;
/*
* ...and the log, if it is allocated in the first allocation group.
*
* This can happen with filesystems that only have a single
* allocation group, or very odd geometries created by old mkfs
* versions on very small filesystems.
*/
if (mp->m_sb.sb_logstart &&
XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart) == 0)
first_bno += mp->m_sb.sb_logblocks;
/*
* Now round first_bno up to whatever allocation alignment is given
* by the filesystem or was passed in.
*/
if (xfs_sb_version_hasdalign(&mp->m_sb) && igeo->ialloc_align > 0)
first_bno = roundup(first_bno, sunit);
else if (xfs_sb_version_hasalign(&mp->m_sb) &&
mp->m_sb.sb_inoalignmt > 1)
first_bno = roundup(first_bno, mp->m_sb.sb_inoalignmt);
return XFS_AGINO_TO_INO(mp, 0, XFS_AGB_TO_AGINO(mp, first_bno));
}

View File

@ -152,5 +152,6 @@ int xfs_inobt_insert_rec(struct xfs_btree_cur *cur, uint16_t holemask,
int xfs_ialloc_cluster_alignment(struct xfs_mount *mp);
void xfs_ialloc_setup_geometry(struct xfs_mount *mp);
xfs_ino_t xfs_ialloc_calc_rootino(struct xfs_mount *mp, int sunit);
#endif /* __XFS_IALLOC_H__ */

View File

@ -75,11 +75,15 @@ xfs_iformat_fork(
error = xfs_iformat_btree(ip, dip, XFS_DATA_FORK);
break;
default:
xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__,
dip, sizeof(*dip), __this_address);
return -EFSCORRUPTED;
}
break;
default:
xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip,
sizeof(*dip), __this_address);
return -EFSCORRUPTED;
}
if (error)
@ -110,6 +114,8 @@ xfs_iformat_fork(
error = xfs_iformat_btree(ip, dip, XFS_ATTR_FORK);
break;
default:
xfs_inode_verifier_error(ip, error, __func__, dip,
sizeof(*dip), __this_address);
error = -EFSCORRUPTED;
break;
}

View File

@ -1591,8 +1591,10 @@ xfs_refcount_recover_extent(
struct list_head *debris = priv;
struct xfs_refcount_recovery *rr;
if (be32_to_cpu(rec->refc.rc_refcount) != 1)
if (be32_to_cpu(rec->refc.rc_refcount) != 1) {
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, cur->bc_mp);
return -EFSCORRUPTED;
}
rr = kmem_alloc(sizeof(struct xfs_refcount_recovery), 0);
xfs_refcount_btrec_to_irec(rec, &rr->rr_rrec);

View File

@ -15,7 +15,7 @@
#include "xfs_bmap.h"
#include "xfs_trans.h"
#include "xfs_rtalloc.h"
#include "xfs_error.h"
/*
* Realtime allocator bitmap functions shared with userspace.
@ -70,8 +70,10 @@ xfs_rtbuf_get(
if (error)
return error;
if (nmap == 0 || !xfs_bmap_is_real_extent(&map))
if (nmap == 0 || !xfs_bmap_is_real_extent(&map)) {
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp);
return -EFSCORRUPTED;
}
ASSERT(map.br_startblock != NULLFSBLOCK);
error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,

View File

@ -12,6 +12,7 @@
#include "xfs_inode.h"
#include "xfs_attr.h"
#include "xfs_trace.h"
#include "xfs_error.h"
#include <linux/posix_acl_xattr.h>
@ -23,6 +24,7 @@
STATIC struct posix_acl *
xfs_acl_from_disk(
struct xfs_mount *mp,
const struct xfs_acl *aclp,
int len,
int max_entries)
@ -32,11 +34,18 @@ xfs_acl_from_disk(
const struct xfs_acl_entry *ace;
unsigned int count, i;
if (len < sizeof(*aclp))
if (len < sizeof(*aclp)) {
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, aclp,
len);
return ERR_PTR(-EFSCORRUPTED);
}
count = be32_to_cpu(aclp->acl_cnt);
if (count > max_entries || XFS_ACL_SIZE(count) != len)
if (count > max_entries || XFS_ACL_SIZE(count) != len) {
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, aclp,
len);
return ERR_PTR(-EFSCORRUPTED);
}
acl = posix_acl_alloc(count, GFP_KERNEL);
if (!acl)
@ -145,7 +154,7 @@ xfs_get_acl(struct inode *inode, int type)
if (error != -ENOATTR)
acl = ERR_PTR(error);
} else {
acl = xfs_acl_from_disk(xfs_acl, len,
acl = xfs_acl_from_disk(ip->i_mount, xfs_acl, len,
XFS_ACL_MAX_ENTRIES(ip->i_mount));
kmem_free(xfs_acl);
}

View File

@ -22,6 +22,7 @@
#include "xfs_attr_leaf.h"
#include "xfs_quota.h"
#include "xfs_dir2.h"
#include "xfs_error.h"
/*
* Look at all the extents for this logical region,
@ -208,8 +209,9 @@ xfs_attr3_node_inactive(
* Since this code is recursive (gasp!) we must protect ourselves.
*/
if (level > XFS_DA_NODE_MAXDEPTH) {
xfs_buf_corruption_error(bp);
xfs_trans_brelse(*trans, bp); /* no locks for later trans */
return -EIO;
return -EFSCORRUPTED;
}
node = bp->b_addr;
@ -258,8 +260,9 @@ xfs_attr3_node_inactive(
error = xfs_attr3_leaf_inactive(trans, dp, child_bp);
break;
default:
error = -EIO;
xfs_buf_corruption_error(child_bp);
xfs_trans_brelse(*trans, child_bp);
error = -EFSCORRUPTED;
break;
}
if (error)
@ -341,7 +344,8 @@ xfs_attr3_root_inactive(
error = xfs_attr3_leaf_inactive(trans, dp, bp);
break;
default:
error = -EIO;
error = -EFSCORRUPTED;
xfs_buf_corruption_error(bp);
xfs_trans_brelse(*trans, bp);
break;
}

View File

@ -258,8 +258,10 @@ xfs_attr_node_list_lookup(
return 0;
/* We can't point back to the root. */
if (cursor->blkno == 0)
if (cursor->blkno == 0) {
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp);
return -EFSCORRUPTED;
}
}
if (expected_level != 0)
@ -269,6 +271,7 @@ xfs_attr_node_list_lookup(
return 0;
out_corruptbuf:
xfs_buf_corruption_error(bp);
xfs_trans_brelse(tp, bp);
return -EFSCORRUPTED;
}

View File

@ -21,7 +21,7 @@
#include "xfs_icache.h"
#include "xfs_bmap_btree.h"
#include "xfs_trans_space.h"
#include "xfs_error.h"
kmem_zone_t *xfs_bui_zone;
kmem_zone_t *xfs_bud_zone;
@ -456,7 +456,7 @@ xfs_bui_recover(
if (buip->bui_format.bui_nextents != XFS_BUI_MAX_FAST_EXTENTS) {
set_bit(XFS_BUI_RECOVERED, &buip->bui_flags);
xfs_bui_release(buip);
return -EIO;
return -EFSCORRUPTED;
}
/*
@ -490,7 +490,7 @@ xfs_bui_recover(
*/
set_bit(XFS_BUI_RECOVERED, &buip->bui_flags);
xfs_bui_release(buip);
return -EIO;
return -EFSCORRUPTED;
}
error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate,
@ -525,6 +525,7 @@ xfs_bui_recover(
type = bui_type;
break;
default:
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp);
error = -EFSCORRUPTED;
goto err_inode;
}

View File

@ -1167,6 +1167,7 @@ xfs_prepare_shift(
struct xfs_inode *ip,
loff_t offset)
{
struct xfs_mount *mp = ip->i_mount;
int error;
/*
@ -1179,6 +1180,17 @@ xfs_prepare_shift(
return error;
}
/*
* Shift operations must stabilize the start block offset boundary along
* with the full range of the operation. If we don't, a COW writeback
* completion could race with an insert, front merge with the start
* extent (after split) during the shift and corrupt the file. Start
* with the block just prior to the start to stabilize the boundary.
*/
offset = round_down(offset, 1 << mp->m_sb.sb_blocklog);
if (offset)
offset -= (1 << mp->m_sb.sb_blocklog);
/*
* Writeback and invalidate cache for the remainder of the file as we're
* about to shift down every extent from offset to EOF.

View File

@ -956,7 +956,7 @@ xfs_buf_item_relse(
struct xfs_buf_log_item *bip = bp->b_log_item;
trace_xfs_buf_item_relse(bp, _RET_IP_);
ASSERT(!(bip->bli_item.li_flags & XFS_LI_IN_AIL));
ASSERT(!test_bit(XFS_LI_IN_AIL, &bip->bli_item.li_flags));
bp->b_log_item = NULL;
if (list_empty(&bp->b_li_list))

View File

@ -1125,7 +1125,7 @@ xfs_qm_dqflush(
xfs_buf_relse(bp);
xfs_dqfunlock(dqp);
xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
return -EIO;
return -EFSCORRUPTED;
}
/* This is the only portion of data that needs to persist */

View File

@ -329,7 +329,7 @@ xfs_corruption_error(
const char *tag,
int level,
struct xfs_mount *mp,
void *buf,
const void *buf,
size_t bufsize,
const char *filename,
int linenum,
@ -341,6 +341,27 @@ xfs_corruption_error(
xfs_alert(mp, "Corruption detected. Unmount and run xfs_repair");
}
/*
* Complain about the kinds of metadata corruption that we can't detect from a
* verifier, such as incorrect inter-block relationship data. Does not set
* bp->b_error.
*/
void
xfs_buf_corruption_error(
struct xfs_buf *bp)
{
struct xfs_mount *mp = bp->b_mount;
xfs_alert_tag(mp, XFS_PTAG_VERIFIER_ERROR,
"Metadata corruption detected at %pS, %s block 0x%llx",
__return_address, bp->b_ops->name, bp->b_bn);
xfs_alert(mp, "Unmount and run xfs_repair");
if (xfs_error_level >= XFS_ERRLEVEL_HIGH)
xfs_stack_trace();
}
/*
* Warnings specifically for verifier errors. Differentiate CRC vs. invalid
* values, and omit the stack trace unless the error level is tuned high.
@ -350,7 +371,7 @@ xfs_buf_verifier_error(
struct xfs_buf *bp,
int error,
const char *name,
void *buf,
const void *buf,
size_t bufsz,
xfs_failaddr_t failaddr)
{
@ -402,7 +423,7 @@ xfs_inode_verifier_error(
struct xfs_inode *ip,
int error,
const char *name,
void *buf,
const void *buf,
size_t bufsz,
xfs_failaddr_t failaddr)
{

View File

@ -12,16 +12,17 @@ extern void xfs_error_report(const char *tag, int level, struct xfs_mount *mp,
const char *filename, int linenum,
xfs_failaddr_t failaddr);
extern void xfs_corruption_error(const char *tag, int level,
struct xfs_mount *mp, void *buf, size_t bufsize,
struct xfs_mount *mp, const void *buf, size_t bufsize,
const char *filename, int linenum,
xfs_failaddr_t failaddr);
void xfs_buf_corruption_error(struct xfs_buf *bp);
extern void xfs_buf_verifier_error(struct xfs_buf *bp, int error,
const char *name, void *buf, size_t bufsz,
const char *name, const void *buf, size_t bufsz,
xfs_failaddr_t failaddr);
extern void xfs_verifier_error(struct xfs_buf *bp, int error,
xfs_failaddr_t failaddr);
extern void xfs_inode_verifier_error(struct xfs_inode *ip, int error,
const char *name, void *buf, size_t bufsz,
const char *name, const void *buf, size_t bufsz,
xfs_failaddr_t failaddr);
#define XFS_ERROR_REPORT(e, lvl, mp) \

View File

@ -21,7 +21,7 @@
#include "xfs_alloc.h"
#include "xfs_bmap.h"
#include "xfs_trace.h"
#include "xfs_error.h"
kmem_zone_t *xfs_efi_zone;
kmem_zone_t *xfs_efd_zone;
@ -228,6 +228,7 @@ xfs_efi_copy_format(xfs_log_iovec_t *buf, xfs_efi_log_format_t *dst_efi_fmt)
}
return 0;
}
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL);
return -EFSCORRUPTED;
}
@ -624,7 +625,7 @@ xfs_efi_recover(
*/
set_bit(XFS_EFI_RECOVERED, &efip->efi_flags);
xfs_efi_release(efip);
return -EIO;
return -EFSCORRUPTED;
}
}

View File

@ -146,6 +146,7 @@ xfs_fsmap_owner_from_rmap(
dest->fmr_owner = XFS_FMR_OWN_FREE;
break;
default:
ASSERT(0);
return -EFSCORRUPTED;
}
return 0;

View File

@ -2149,8 +2149,10 @@ xfs_iunlink_update_bucket(
* passed in because either we're adding or removing ourselves from the
* head of the list.
*/
if (old_value == new_agino)
if (old_value == new_agino) {
xfs_buf_corruption_error(agibp);
return -EFSCORRUPTED;
}
agi->agi_unlinked[bucket_index] = cpu_to_be32(new_agino);
offset = offsetof(struct xfs_agi, agi_unlinked) +
@ -2213,6 +2215,8 @@ xfs_iunlink_update_inode(
/* Make sure the old pointer isn't garbage. */
old_value = be32_to_cpu(dip->di_next_unlinked);
if (!xfs_verify_agino_or_null(mp, agno, old_value)) {
xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip,
sizeof(*dip), __this_address);
error = -EFSCORRUPTED;
goto out;
}
@ -2224,8 +2228,11 @@ xfs_iunlink_update_inode(
*/
*old_next_agino = old_value;
if (old_value == next_agino) {
if (next_agino != NULLAGINO)
if (next_agino != NULLAGINO) {
xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__,
dip, sizeof(*dip), __this_address);
error = -EFSCORRUPTED;
}
goto out;
}
@ -2276,8 +2283,10 @@ xfs_iunlink(
*/
next_agino = be32_to_cpu(agi->agi_unlinked[bucket_index]);
if (next_agino == agino ||
!xfs_verify_agino_or_null(mp, agno, next_agino))
!xfs_verify_agino_or_null(mp, agno, next_agino)) {
xfs_buf_corruption_error(agibp);
return -EFSCORRUPTED;
}
if (next_agino != NULLAGINO) {
struct xfs_perag *pag;
@ -3215,6 +3224,7 @@ xfs_rename(
struct xfs_trans *tp;
struct xfs_inode *wip = NULL; /* whiteout inode */
struct xfs_inode *inodes[__XFS_SORT_INODES];
int i;
int num_inodes = __XFS_SORT_INODES;
bool new_parent = (src_dp != target_dp);
bool src_is_directory = S_ISDIR(VFS_I(src_ip)->i_mode);
@ -3326,6 +3336,30 @@ xfs_rename(
}
}
/*
* Lock the AGI buffers we need to handle bumping the nlink of the
* whiteout inode off the unlinked list and to handle dropping the
* nlink of the target inode. Per locking order rules, do this in
* increasing AG order and before directory block allocation tries to
* grab AGFs because we grab AGIs before AGFs.
*
* The (vfs) caller must ensure that if src is a directory then
* target_ip is either null or an empty directory.
*/
for (i = 0; i < num_inodes && inodes[i] != NULL; i++) {
if (inodes[i] == wip ||
(inodes[i] == target_ip &&
(VFS_I(target_ip)->i_nlink == 1 || src_is_directory))) {
struct xfs_buf *bp;
xfs_agnumber_t agno;
agno = XFS_INO_TO_AGNO(mp, inodes[i]->i_ino);
error = xfs_read_agi(mp, tp, agno, &bp);
if (error)
goto out_trans_cancel;
}
}
/*
* Directory entry creation below may acquire the AGF. Remove
* the whiteout from the unlinked list first to preserve correct

View File

@ -17,6 +17,7 @@
#include "xfs_trans_priv.h"
#include "xfs_buf_item.h"
#include "xfs_log.h"
#include "xfs_error.h"
#include <linux/iversion.h>
@ -828,8 +829,10 @@ xfs_inode_item_format_convert(
{
struct xfs_inode_log_format_32 *in_f32 = buf->i_addr;
if (buf->i_len != sizeof(*in_f32))
if (buf->i_len != sizeof(*in_f32)) {
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL);
return -EFSCORRUPTED;
}
in_f->ilf_type = in_f32->ilf_type;
in_f->ilf_size = in_f32->ilf_size;

View File

@ -765,6 +765,11 @@ xfs_iomap_write_unwritten(
*/
resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0) << 1;
/* Attach dquots so that bmbt splits are accounted correctly. */
error = xfs_qm_dqattach(ip);
if (error)
return error;
do {
/*
* Set up a transaction to convert the range of extents
@ -783,6 +788,11 @@ xfs_iomap_write_unwritten(
xfs_ilock(ip, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, ip, 0);
error = xfs_trans_reserve_quota_nblks(tp, ip, resblks, 0,
XFS_QMOPT_RES_REGBLKS);
if (error)
goto error_on_bmapi_transaction;
/*
* Modify the unwritten extent state of the buffer.
*/
@ -1055,6 +1065,13 @@ xfs_file_iomap_begin(
trace_xfs_iomap_alloc(ip, offset, length, XFS_DATA_FORK, &imap);
out_finish:
/*
* Writes that span EOF might trigger an IO size update on completion,
* so consider them to be dirty for the purposes of O_DSYNC even if
* there is no other metadata changes pending or have been made here.
*/
if ((flags & IOMAP_WRITE) && offset + length > i_size_read(inode))
iomap->flags |= IOMAP_F_DIRTY;
return xfs_bmbt_to_iomap(ip, iomap, &imap, shared);
out_found:

View File

@ -20,6 +20,7 @@
#include "xfs_symlink.h"
#include "xfs_dir2.h"
#include "xfs_iomap.h"
#include "xfs_error.h"
#include <linux/xattr.h>
#include <linux/posix_acl.h>
@ -470,17 +471,20 @@ xfs_vn_get_link_inline(
struct inode *inode,
struct delayed_call *done)
{
struct xfs_inode *ip = XFS_I(inode);
char *link;
ASSERT(XFS_I(inode)->i_df.if_flags & XFS_IFINLINE);
ASSERT(ip->i_df.if_flags & XFS_IFINLINE);
/*
* The VFS crashes on a NULL pointer, so return -EFSCORRUPTED if
* if_data is junk.
*/
link = XFS_I(inode)->i_df.if_u1.if_data;
if (!link)
link = ip->i_df.if_u1.if_data;
if (!link) {
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, ip->i_mount);
return ERR_PTR(-EFSCORRUPTED);
}
return link;
}

View File

@ -471,7 +471,7 @@ xlog_find_verify_log_record(
xfs_warn(log->l_mp,
"Log inconsistent (didn't find previous header)");
ASSERT(0);
error = -EIO;
error = -EFSCORRUPTED;
goto out;
}
@ -1347,10 +1347,11 @@ xlog_find_tail(
error = xlog_rseek_logrec_hdr(log, *head_blk, *head_blk, 1, buffer,
&rhead_blk, &rhead, &wrapped);
if (error < 0)
return error;
goto done;
if (!error) {
xfs_warn(log->l_mp, "%s: couldn't find sync record", __func__);
return -EIO;
error = -EFSCORRUPTED;
goto done;
}
*tail_blk = BLOCK_LSN(be64_to_cpu(rhead->h_tail_lsn));
@ -3166,7 +3167,7 @@ xlog_recover_inode_pass2(
default:
xfs_warn(log->l_mp, "%s: Invalid flag", __func__);
ASSERT(0);
error = -EIO;
error = -EFSCORRUPTED;
goto out_release;
}
}
@ -3247,12 +3248,12 @@ xlog_recover_dquot_pass2(
recddq = item->ri_buf[1].i_addr;
if (recddq == NULL) {
xfs_alert(log->l_mp, "NULL dquot in %s.", __func__);
return -EIO;
return -EFSCORRUPTED;
}
if (item->ri_buf[1].i_len < sizeof(xfs_disk_dquot_t)) {
xfs_alert(log->l_mp, "dquot too small (%d) in %s.",
item->ri_buf[1].i_len, __func__);
return -EIO;
return -EFSCORRUPTED;
}
/*
@ -3279,7 +3280,7 @@ xlog_recover_dquot_pass2(
if (fa) {
xfs_alert(mp, "corrupt dquot ID 0x%x in log at %pS",
dq_f->qlf_id, fa);
return -EIO;
return -EFSCORRUPTED;
}
ASSERT(dq_f->qlf_len == 1);
@ -3537,6 +3538,7 @@ xfs_cui_copy_format(
memcpy(dst_cui_fmt, src_cui_fmt, len);
return 0;
}
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL);
return -EFSCORRUPTED;
}
@ -3601,8 +3603,10 @@ xlog_recover_cud_pass2(
struct xfs_ail *ailp = log->l_ailp;
cud_formatp = item->ri_buf[0].i_addr;
if (item->ri_buf[0].i_len != sizeof(struct xfs_cud_log_format))
if (item->ri_buf[0].i_len != sizeof(struct xfs_cud_log_format)) {
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, log->l_mp);
return -EFSCORRUPTED;
}
cui_id = cud_formatp->cud_cui_id;
/*
@ -3654,6 +3658,7 @@ xfs_bui_copy_format(
memcpy(dst_bui_fmt, src_bui_fmt, len);
return 0;
}
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL);
return -EFSCORRUPTED;
}
@ -3677,8 +3682,10 @@ xlog_recover_bui_pass2(
bui_formatp = item->ri_buf[0].i_addr;
if (bui_formatp->bui_nextents != XFS_BUI_MAX_FAST_EXTENTS)
if (bui_formatp->bui_nextents != XFS_BUI_MAX_FAST_EXTENTS) {
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, log->l_mp);
return -EFSCORRUPTED;
}
buip = xfs_bui_init(mp);
error = xfs_bui_copy_format(&item->ri_buf[0], &buip->bui_format);
if (error) {
@ -3720,8 +3727,10 @@ xlog_recover_bud_pass2(
struct xfs_ail *ailp = log->l_ailp;
bud_formatp = item->ri_buf[0].i_addr;
if (item->ri_buf[0].i_len != sizeof(struct xfs_bud_log_format))
if (item->ri_buf[0].i_len != sizeof(struct xfs_bud_log_format)) {
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, log->l_mp);
return -EFSCORRUPTED;
}
bui_id = bud_formatp->bud_bui_id;
/*
@ -4018,7 +4027,7 @@ xlog_recover_commit_pass1(
xfs_warn(log->l_mp, "%s: invalid item type (%d)",
__func__, ITEM_TYPE(item));
ASSERT(0);
return -EIO;
return -EFSCORRUPTED;
}
}
@ -4066,7 +4075,7 @@ xlog_recover_commit_pass2(
xfs_warn(log->l_mp, "%s: invalid item type (%d)",
__func__, ITEM_TYPE(item));
ASSERT(0);
return -EIO;
return -EFSCORRUPTED;
}
}
@ -4187,7 +4196,7 @@ xlog_recover_add_to_cont_trans(
ASSERT(len <= sizeof(struct xfs_trans_header));
if (len > sizeof(struct xfs_trans_header)) {
xfs_warn(log->l_mp, "%s: bad header length", __func__);
return -EIO;
return -EFSCORRUPTED;
}
xlog_recover_add_item(&trans->r_itemq);
@ -4243,13 +4252,13 @@ xlog_recover_add_to_trans(
xfs_warn(log->l_mp, "%s: bad header magic number",
__func__);
ASSERT(0);
return -EIO;
return -EFSCORRUPTED;
}
if (len > sizeof(struct xfs_trans_header)) {
xfs_warn(log->l_mp, "%s: bad header length", __func__);
ASSERT(0);
return -EIO;
return -EFSCORRUPTED;
}
/*
@ -4285,7 +4294,7 @@ xlog_recover_add_to_trans(
in_f->ilf_size);
ASSERT(0);
kmem_free(ptr);
return -EIO;
return -EFSCORRUPTED;
}
item->ri_total = in_f->ilf_size;
@ -4293,7 +4302,16 @@ xlog_recover_add_to_trans(
kmem_zalloc(item->ri_total * sizeof(xfs_log_iovec_t),
0);
}
ASSERT(item->ri_total > item->ri_cnt);
if (item->ri_total <= item->ri_cnt) {
xfs_warn(log->l_mp,
"log item region count (%d) overflowed size (%d)",
item->ri_cnt, item->ri_total);
ASSERT(0);
kmem_free(ptr);
return -EFSCORRUPTED;
}
/* Description region is ri_buf[0] */
item->ri_buf[item->ri_cnt].i_addr = ptr;
item->ri_buf[item->ri_cnt].i_len = len;
@ -4380,7 +4398,7 @@ xlog_recovery_process_trans(
default:
xfs_warn(log->l_mp, "%s: bad flag 0x%x", __func__, flags);
ASSERT(0);
error = -EIO;
error = -EFSCORRUPTED;
break;
}
if (error || freeit)
@ -4460,7 +4478,7 @@ xlog_recover_process_ophdr(
xfs_warn(log->l_mp, "%s: bad clientid 0x%x",
__func__, ohead->oh_clientid);
ASSERT(0);
return -EIO;
return -EFSCORRUPTED;
}
/*
@ -4470,7 +4488,7 @@ xlog_recover_process_ophdr(
if (dp + len > end) {
xfs_warn(log->l_mp, "%s: bad length 0x%x", __func__, len);
WARN_ON(1);
return -EIO;
return -EFSCORRUPTED;
}
trans = xlog_recover_ophdr_to_trans(rhash, rhead, ohead);
@ -5172,8 +5190,10 @@ xlog_recover_process(
* If the filesystem is CRC enabled, this mismatch becomes a
* fatal log corruption failure.
*/
if (xfs_sb_version_hascrc(&log->l_mp->m_sb))
if (xfs_sb_version_hascrc(&log->l_mp->m_sb)) {
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, log->l_mp);
return -EFSCORRUPTED;
}
}
xlog_unpack_data(rhead, dp, log);
@ -5200,7 +5220,7 @@ xlog_valid_rec_header(
(be32_to_cpu(rhead->h_version) & (~XLOG_VERSION_OKBITS))))) {
xfs_warn(log->l_mp, "%s: unrecognised log version (%d).",
__func__, be32_to_cpu(rhead->h_version));
return -EIO;
return -EFSCORRUPTED;
}
/* LR body must have data or it wouldn't have been written */
@ -5296,8 +5316,12 @@ xlog_do_recovery_pass(
"invalid iclog size (%d bytes), using lsunit (%d bytes)",
h_size, log->l_mp->m_logbsize);
h_size = log->l_mp->m_logbsize;
} else
return -EFSCORRUPTED;
} else {
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW,
log->l_mp);
error = -EFSCORRUPTED;
goto bread_err1;
}
}
if ((be32_to_cpu(rhead->h_version) & XLOG_VERSION_2) &&

View File

@ -105,7 +105,7 @@ assfail(char *expr, char *file, int line)
}
void
xfs_hex_dump(void *p, int length)
xfs_hex_dump(const void *p, int length)
{
print_hex_dump(KERN_ALERT, "", DUMP_PREFIX_OFFSET, 16, 1, p, length, 1);
}

View File

@ -60,6 +60,6 @@ do { \
extern void assfail(char *expr, char *f, int l);
extern void asswarn(char *expr, char *f, int l);
extern void xfs_hex_dump(void *p, int length);
extern void xfs_hex_dump(const void *p, int length);
#endif /* __XFS_MESSAGE_H */

View File

@ -31,7 +31,7 @@
#include "xfs_reflink.h"
#include "xfs_extent_busy.h"
#include "xfs_health.h"
#include "xfs_trace.h"
static DEFINE_MUTEX(xfs_uuid_table_mutex);
static int xfs_uuid_table_size;
@ -365,66 +365,119 @@ xfs_readsb(
}
/*
* Update alignment values based on mount options and sb values
* If the sunit/swidth change would move the precomputed root inode value, we
* must reject the ondisk change because repair will stumble over that.
* However, we allow the mount to proceed because we never rejected this
* combination before. Returns true to update the sb, false otherwise.
*/
static inline int
xfs_check_new_dalign(
struct xfs_mount *mp,
int new_dalign,
bool *update_sb)
{
struct xfs_sb *sbp = &mp->m_sb;
xfs_ino_t calc_ino;
calc_ino = xfs_ialloc_calc_rootino(mp, new_dalign);
trace_xfs_check_new_dalign(mp, new_dalign, calc_ino);
if (sbp->sb_rootino == calc_ino) {
*update_sb = true;
return 0;
}
xfs_warn(mp,
"Cannot change stripe alignment; would require moving root inode.");
/*
* XXX: Next time we add a new incompat feature, this should start
* returning -EINVAL to fail the mount. Until then, spit out a warning
* that we're ignoring the administrator's instructions.
*/
xfs_warn(mp, "Skipping superblock stripe alignment update.");
*update_sb = false;
return 0;
}
/*
* If we were provided with new sunit/swidth values as mount options, make sure
* that they pass basic alignment and superblock feature checks, and convert
* them into the same units (FSB) that everything else expects. This step
* /must/ be done before computing the inode geometry.
*/
STATIC int
xfs_update_alignment(xfs_mount_t *mp)
xfs_validate_new_dalign(
struct xfs_mount *mp)
{
xfs_sb_t *sbp = &(mp->m_sb);
if (mp->m_dalign == 0)
return 0;
/*
* If stripe unit and stripe width are not multiples
* of the fs blocksize turn off alignment.
*/
if ((BBTOB(mp->m_dalign) & mp->m_blockmask) ||
(BBTOB(mp->m_swidth) & mp->m_blockmask)) {
xfs_warn(mp,
"alignment check failed: sunit/swidth vs. blocksize(%d)",
mp->m_sb.sb_blocksize);
return -EINVAL;
} else {
/*
* Convert the stripe unit and width to FSBs.
*/
mp->m_dalign = XFS_BB_TO_FSBT(mp, mp->m_dalign);
if (mp->m_dalign && (mp->m_sb.sb_agblocks % mp->m_dalign)) {
xfs_warn(mp,
"alignment check failed: sunit/swidth vs. agsize(%d)",
mp->m_sb.sb_agblocks);
return -EINVAL;
} else if (mp->m_dalign) {
mp->m_swidth = XFS_BB_TO_FSBT(mp, mp->m_swidth);
} else {
xfs_warn(mp,
"alignment check failed: sunit(%d) less than bsize(%d)",
mp->m_dalign, mp->m_sb.sb_blocksize);
return -EINVAL;
}
}
if (!xfs_sb_version_hasdalign(&mp->m_sb)) {
xfs_warn(mp,
"cannot change alignment: superblock does not support data alignment");
return -EINVAL;
}
return 0;
}
/* Update alignment values based on mount options and sb values. */
STATIC int
xfs_update_alignment(
struct xfs_mount *mp)
{
struct xfs_sb *sbp = &mp->m_sb;
if (mp->m_dalign) {
/*
* If stripe unit and stripe width are not multiples
* of the fs blocksize turn off alignment.
*/
if ((BBTOB(mp->m_dalign) & mp->m_blockmask) ||
(BBTOB(mp->m_swidth) & mp->m_blockmask)) {
xfs_warn(mp,
"alignment check failed: sunit/swidth vs. blocksize(%d)",
sbp->sb_blocksize);
return -EINVAL;
} else {
/*
* Convert the stripe unit and width to FSBs.
*/
mp->m_dalign = XFS_BB_TO_FSBT(mp, mp->m_dalign);
if (mp->m_dalign && (sbp->sb_agblocks % mp->m_dalign)) {
xfs_warn(mp,
"alignment check failed: sunit/swidth vs. agsize(%d)",
sbp->sb_agblocks);
return -EINVAL;
} else if (mp->m_dalign) {
mp->m_swidth = XFS_BB_TO_FSBT(mp, mp->m_swidth);
} else {
xfs_warn(mp,
"alignment check failed: sunit(%d) less than bsize(%d)",
mp->m_dalign, sbp->sb_blocksize);
return -EINVAL;
}
}
bool update_sb;
int error;
/*
* Update superblock with new values
* and log changes
*/
if (xfs_sb_version_hasdalign(sbp)) {
if (sbp->sb_unit != mp->m_dalign) {
sbp->sb_unit = mp->m_dalign;
mp->m_update_sb = true;
}
if (sbp->sb_width != mp->m_swidth) {
sbp->sb_width = mp->m_swidth;
mp->m_update_sb = true;
}
} else {
xfs_warn(mp,
"cannot change alignment: superblock does not support data alignment");
return -EINVAL;
}
if (sbp->sb_unit == mp->m_dalign &&
sbp->sb_width == mp->m_swidth)
return 0;
error = xfs_check_new_dalign(mp, mp->m_dalign, &update_sb);
if (error || !update_sb)
return error;
sbp->sb_unit = mp->m_dalign;
sbp->sb_width = mp->m_swidth;
mp->m_update_sb = true;
} else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN &&
xfs_sb_version_hasdalign(&mp->m_sb)) {
mp->m_dalign = sbp->sb_unit;
mp->m_swidth = sbp->sb_width;
mp->m_dalign = sbp->sb_unit;
mp->m_swidth = sbp->sb_width;
}
return 0;
@ -692,12 +745,12 @@ xfs_mountfs(
}
/*
* Check if sb_agblocks is aligned at stripe boundary
* If sb_agblocks is NOT aligned turn off m_dalign since
* allocator alignment is within an ag, therefore ag has
* to be aligned at stripe boundary.
* If we were given new sunit/swidth options, do some basic validation
* checks and convert the incore dalign and swidth values to the
* same units (FSB) that everything else uses. This /must/ happen
* before computing the inode geometry.
*/
error = xfs_update_alignment(mp);
error = xfs_validate_new_dalign(mp);
if (error)
goto out;
@ -708,6 +761,17 @@ xfs_mountfs(
xfs_rmapbt_compute_maxlevels(mp);
xfs_refcountbt_compute_maxlevels(mp);
/*
* Check if sb_agblocks is aligned at stripe boundary. If sb_agblocks
* is NOT aligned turn off m_dalign since allocator alignment is within
* an ag, therefore ag has to be aligned at stripe boundary. Note that
* we must compute the free space and rmap btree geometry before doing
* this.
*/
error = xfs_update_alignment(mp);
if (error)
goto out;
/* enable fail_at_unmount as default */
mp->m_fail_unmount = true;

View File

@ -147,11 +147,11 @@ xfs_fs_map_blocks(
if (error)
goto out_unlock;
ASSERT(!nimaps || imap.br_startblock != DELAYSTARTBLOCK);
if (write) {
enum xfs_prealloc_flags flags = 0;
ASSERT(imap.br_startblock != DELAYSTARTBLOCK);
if (!nimaps || imap.br_startblock == HOLESTARTBLOCK) {
/*
* xfs_iomap_write_direct() expects to take ownership of

View File

@ -22,6 +22,7 @@
#include "xfs_qm.h"
#include "xfs_trace.h"
#include "xfs_icache.h"
#include "xfs_error.h"
/*
* The global quota manager. There is only one of these for the entire
@ -754,11 +755,19 @@ xfs_qm_qino_alloc(
if ((flags & XFS_QMOPT_PQUOTA) &&
(mp->m_sb.sb_gquotino != NULLFSINO)) {
ino = mp->m_sb.sb_gquotino;
ASSERT(mp->m_sb.sb_pquotino == NULLFSINO);
if (mp->m_sb.sb_pquotino != NULLFSINO) {
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW,
mp);
return -EFSCORRUPTED;
}
} else if ((flags & XFS_QMOPT_GQUOTA) &&
(mp->m_sb.sb_pquotino != NULLFSINO)) {
ino = mp->m_sb.sb_pquotino;
ASSERT(mp->m_sb.sb_gquotino == NULLFSINO);
if (mp->m_sb.sb_gquotino != NULLFSINO) {
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW,
mp);
return -EFSCORRUPTED;
}
}
if (ino != NULLFSINO) {
error = xfs_iget(mp, NULL, ino, 0, 0, ip);

View File

@ -17,7 +17,7 @@
#include "xfs_refcount_item.h"
#include "xfs_log.h"
#include "xfs_refcount.h"
#include "xfs_error.h"
kmem_zone_t *xfs_cui_zone;
kmem_zone_t *xfs_cud_zone;
@ -497,7 +497,7 @@ xfs_cui_recover(
*/
set_bit(XFS_CUI_RECOVERED, &cuip->cui_flags);
xfs_cui_release(cuip);
return -EIO;
return -EFSCORRUPTED;
}
}
@ -536,6 +536,7 @@ xfs_cui_recover(
type = refc_type;
break;
default:
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp);
error = -EFSCORRUPTED;
goto abort_error;
}

View File

@ -17,7 +17,7 @@
#include "xfs_rmap_item.h"
#include "xfs_log.h"
#include "xfs_rmap.h"
#include "xfs_error.h"
kmem_zone_t *xfs_rui_zone;
kmem_zone_t *xfs_rud_zone;
@ -171,8 +171,10 @@ xfs_rui_copy_format(
src_rui_fmt = buf->i_addr;
len = xfs_rui_log_format_sizeof(src_rui_fmt->rui_nextents);
if (buf->i_len != len)
if (buf->i_len != len) {
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL);
return -EFSCORRUPTED;
}
memcpy(dst_rui_fmt, src_rui_fmt, len);
return 0;
@ -539,7 +541,7 @@ xfs_rui_recover(
*/
set_bit(XFS_RUI_RECOVERED, &ruip->rui_flags);
xfs_rui_release(ruip);
return -EIO;
return -EFSCORRUPTED;
}
}
@ -581,6 +583,7 @@ xfs_rui_recover(
type = XFS_RMAP_FREE;
break;
default:
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL);
error = -EFSCORRUPTED;
goto abort_error;
}

View File

@ -3609,6 +3609,27 @@ DEFINE_KMEM_EVENT(kmem_alloc_large);
DEFINE_KMEM_EVENT(kmem_realloc);
DEFINE_KMEM_EVENT(kmem_zone_alloc);
TRACE_EVENT(xfs_check_new_dalign,
TP_PROTO(struct xfs_mount *mp, int new_dalign, xfs_ino_t calc_rootino),
TP_ARGS(mp, new_dalign, calc_rootino),
TP_STRUCT__entry(
__field(dev_t, dev)
__field(int, new_dalign)
__field(xfs_ino_t, sb_rootino)
__field(xfs_ino_t, calc_rootino)
),
TP_fast_assign(
__entry->dev = mp->m_super->s_dev;
__entry->new_dalign = new_dalign;
__entry->sb_rootino = mp->m_sb.sb_rootino;
__entry->calc_rootino = calc_rootino;
),
TP_printk("dev %d:%d new_dalign %d sb_rootino %llu calc_rootino %llu",
MAJOR(__entry->dev), MINOR(__entry->dev),
__entry->new_dalign, __entry->sb_rootino,
__entry->calc_rootino)
)
#endif /* _TRACE_XFS_H */
#undef TRACE_INCLUDE_PATH

View File

@ -33,6 +33,8 @@ struct vm_fault;
*
* IOMAP_F_DIRTY indicates the inode has uncommitted metadata needed to access
* written data and requires fdatasync to commit them to persistent storage.
* This needs to take into account metadata changes that *may* be made at IO
* completion, such as file size updates from direct IO.
*/
#define IOMAP_F_NEW 0x01 /* blocks have been newly allocated */
#define IOMAP_F_DIRTY 0x02 /* uncommitted metadata */

View File

@ -16,7 +16,7 @@
* try_get_task_stack() instead. task_stack_page will return a pointer
* that could get freed out from under you.
*/
static inline void *task_stack_page(const struct task_struct *task)
static __always_inline void *task_stack_page(const struct task_struct *task)
{
return task->stack;
}

View File

@ -297,6 +297,23 @@ struct uart_state {
/* number of characters left in xmit buffer before we ask for more */
#define WAKEUP_CHARS 256
/**
* uart_xmit_advance - Advance xmit buffer and account Tx'ed chars
* @up: uart_port structure describing the port
* @chars: number of characters sent
*
* This function advances the tail of circular xmit buffer by the number of
* @chars transmitted and handles accounting of transmitted bytes (into
* @up's icount.tx).
*/
static inline void uart_xmit_advance(struct uart_port *up, unsigned int chars)
{
struct circ_buf *xmit = &up->state->xmit;
xmit->tail = (xmit->tail + chars) & (UART_XMIT_SIZE - 1);
up->icount.tx += chars;
}
struct module;
struct tty_driver;

View File

@ -15,6 +15,7 @@
#include <linux/pid_namespace.h>
#include <linux/cgroupstats.h>
#include <linux/fs_parser.h>
#include <linux/cpu.h>
#include <trace/events/cgroup.h>
#include <trace/hooks/cgroup.h>
@ -63,6 +64,7 @@ int cgroup_attach_task_all(struct task_struct *from, struct task_struct *tsk)
int retval = 0;
mutex_lock(&cgroup_mutex);
cpus_read_lock();
percpu_down_write(&cgroup_threadgroup_rwsem);
for_each_root(root) {
struct cgroup *from_cgrp;
@ -79,6 +81,7 @@ int cgroup_attach_task_all(struct task_struct *from, struct task_struct *tsk)
break;
}
percpu_up_write(&cgroup_threadgroup_rwsem);
cpus_read_unlock();
mutex_unlock(&cgroup_mutex);
return retval;

View File

@ -56,14 +56,14 @@ __visible void trace_hardirqs_on_caller(unsigned long caller_addr)
this_cpu_write(tracing_irq_cpu, 0);
}
lockdep_hardirqs_on(CALLER_ADDR0);
lockdep_hardirqs_on(caller_addr);
}
EXPORT_SYMBOL(trace_hardirqs_on_caller);
NOKPROBE_SYMBOL(trace_hardirqs_on_caller);
__visible void trace_hardirqs_off_caller(unsigned long caller_addr)
{
lockdep_hardirqs_off(CALLER_ADDR0);
lockdep_hardirqs_off(caller_addr);
if (!this_cpu_read(tracing_irq_cpu)) {
this_cpu_write(tracing_irq_cpu, 1);

View File

@ -3055,10 +3055,8 @@ static bool __flush_work(struct work_struct *work, bool from_cancel)
if (WARN_ON(!work->func))
return false;
if (!from_cancel) {
lock_map_acquire(&work->lockdep_map);
lock_map_release(&work->lockdep_map);
}
lock_map_acquire(&work->lockdep_map);
lock_map_release(&work->lockdep_map);
if (start_flush_work(work, &barr, from_cancel)) {
wait_for_completion(&barr.done);

View File

@ -5745,7 +5745,8 @@ static char *create_unique_id(struct kmem_cache *s)
char *name = kmalloc(ID_STR_LENGTH, GFP_KERNEL);
char *p = name;
BUG_ON(!name);
if (!name)
return ERR_PTR(-ENOMEM);
*p++ = ':';
/*
@ -5827,6 +5828,8 @@ static int sysfs_slab_add(struct kmem_cache *s)
* for the symlinks.
*/
name = create_unique_id(s);
if (IS_ERR(name))
return PTR_ERR(name);
}
s->kobj.kset = kset;

View File

@ -999,8 +999,10 @@ static int do_replace_finish(struct net *net, struct ebt_replace *repl,
goto free_iterate;
}
if (repl->valid_hooks != t->valid_hooks)
if (repl->valid_hooks != t->valid_hooks) {
ret = -EINVAL;
goto free_unlock;
}
if (repl->num_counters && repl->num_counters != t->private->nentries) {
ret = -EINVAL;

View File

@ -435,16 +435,19 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
scan_req = rcu_dereference_protected(local->scan_req,
lockdep_is_held(&local->mtx));
if (scan_req != local->int_scan_req) {
local->scan_info.aborted = aborted;
cfg80211_scan_done(scan_req, &local->scan_info);
}
RCU_INIT_POINTER(local->scan_req, NULL);
RCU_INIT_POINTER(local->scan_sdata, NULL);
local->scanning = 0;
local->scan_chandef.chan = NULL;
synchronize_rcu();
if (scan_req != local->int_scan_req) {
local->scan_info.aborted = aborted;
cfg80211_scan_done(scan_req, &local->scan_info);
}
/* Set power back to normal operating levels. */
ieee80211_hw_config(local, 0);

View File

@ -148,15 +148,37 @@ static int help(struct sk_buff *skb, unsigned int protoff,
data = ib_ptr;
data_limit = ib_ptr + skb->len - dataoff;
/* strlen("\1DCC SENT t AAAAAAAA P\1\n")=24
* 5+MINMATCHLEN+strlen("t AAAAAAAA P\1\n")=14 */
while (data < data_limit - (19 + MINMATCHLEN)) {
if (memcmp(data, "\1DCC ", 5)) {
/* Skip any whitespace */
while (data < data_limit - 10) {
if (*data == ' ' || *data == '\r' || *data == '\n')
data++;
else
break;
}
/* strlen("PRIVMSG x ")=10 */
if (data < data_limit - 10) {
if (strncasecmp("PRIVMSG ", data, 8))
goto out;
data += 8;
}
/* strlen(" :\1DCC SENT t AAAAAAAA P\1\n")=26
* 7+MINMATCHLEN+strlen("t AAAAAAAA P\1\n")=26
*/
while (data < data_limit - (21 + MINMATCHLEN)) {
/* Find first " :", the start of message */
if (memcmp(data, " :", 2)) {
data++;
continue;
}
data += 2;
/* then check that place only for the DCC command */
if (memcmp(data, "\1DCC ", 5))
goto out;
data += 5;
/* we have at least (19+MINMATCHLEN)-5 bytes valid data left */
/* we have at least (21+MINMATCHLEN)-(2+5) bytes valid data left */
iph = ip_hdr(skb);
pr_debug("DCC found in master %pI4:%u %pI4:%u\n",
@ -172,7 +194,7 @@ static int help(struct sk_buff *skb, unsigned int protoff,
pr_debug("DCC %s detected\n", dccprotos[i]);
/* we have at least
* (19+MINMATCHLEN)-5-dccprotos[i].matchlen bytes valid
* (21+MINMATCHLEN)-7-dccprotos[i].matchlen bytes valid
* data left (== 14/13 bytes) */
if (parse_dcc(data, data_limit, &dcc_ip,
&dcc_port, &addr_beg_p, &addr_end_p)) {

View File

@ -477,7 +477,7 @@ static int ct_sip_walk_headers(const struct nf_conn *ct, const char *dptr,
return ret;
if (ret == 0)
break;
dataoff += *matchoff;
dataoff = *matchoff;
}
*in_header = 0;
}
@ -489,7 +489,7 @@ static int ct_sip_walk_headers(const struct nf_conn *ct, const char *dptr,
break;
if (ret == 0)
return ret;
dataoff += *matchoff;
dataoff = *matchoff;
}
if (in_header)

View File

@ -269,6 +269,7 @@ bool nf_osf_find(const struct sk_buff *skb,
struct nf_osf_hdr_ctx ctx;
const struct tcphdr *tcp;
struct tcphdr _tcph;
bool found = false;
memset(&ctx, 0, sizeof(ctx));
@ -283,10 +284,11 @@ bool nf_osf_find(const struct sk_buff *skb,
data->genre = f->genre;
data->version = f->version;
found = true;
break;
}
return true;
return found;
}
EXPORT_SYMBOL_GPL(nf_osf_find);

View File

@ -166,7 +166,7 @@ static void rxrpc_resend(struct rxrpc_call *call, unsigned long now_j)
_enter("{%d,%d}", call->tx_hard_ack, call->tx_top);
now = ktime_get_real();
max_age = ktime_sub(now, jiffies_to_usecs(call->peer->rto_j));
max_age = ktime_sub_us(now, jiffies_to_usecs(call->peer->rto_j));
spin_lock_bh(&call->lock);

Some files were not shown because too many files have changed in this diff Show More