Contents of /trunk/kernel-alx/patches-5.4/0314-5.4.215-all-fixes.patch
Parent Directory | Revision Log
Revision 3635 -
(show annotations)
(download)
Mon Oct 24 12:34:12 2022 UTC (23 months ago) by niro
File size: 132438 byte(s)
Mon Oct 24 12:34:12 2022 UTC (23 months ago) by niro
File size: 132438 byte(s)
-sync kernel patches
1 | diff --git a/MAINTAINERS b/MAINTAINERS |
2 | index f45d6548a4aa8..973fcc9143d1e 100644 |
3 | --- a/MAINTAINERS |
4 | +++ b/MAINTAINERS |
5 | @@ -17864,7 +17864,8 @@ S: Supported |
6 | F: sound/xen/* |
7 | |
8 | XFS FILESYSTEM |
9 | -M: Darrick J. Wong <darrick.wong@oracle.com> |
10 | +M: Chandan Babu R <chandan.babu@oracle.com> |
11 | +M: Darrick J. Wong <djwong@kernel.org> |
12 | M: linux-xfs@vger.kernel.org |
13 | L: linux-xfs@vger.kernel.org |
14 | W: http://xfs.org/ |
15 | diff --git a/Makefile b/Makefile |
16 | index 59f34d7f6f3b2..0c501d2c6a3b0 100644 |
17 | --- a/Makefile |
18 | +++ b/Makefile |
19 | @@ -1,7 +1,7 @@ |
20 | # SPDX-License-Identifier: GPL-2.0 |
21 | VERSION = 5 |
22 | PATCHLEVEL = 4 |
23 | -SUBLEVEL = 214 |
24 | +SUBLEVEL = 215 |
25 | EXTRAVERSION = |
26 | NAME = Kleptomaniac Octopus |
27 | |
28 | diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru-bob.dts b/arch/arm64/boot/dts/rockchip/rk3399-gru-bob.dts |
29 | index a9f4d6d7d2b75..586351340da66 100644 |
30 | --- a/arch/arm64/boot/dts/rockchip/rk3399-gru-bob.dts |
31 | +++ b/arch/arm64/boot/dts/rockchip/rk3399-gru-bob.dts |
32 | @@ -77,3 +77,8 @@ |
33 | }; |
34 | }; |
35 | }; |
36 | + |
37 | +&wlan_host_wake_l { |
38 | + /* Kevin has an external pull up, but Bob does not. */ |
39 | + rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>; |
40 | +}; |
41 | diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi |
42 | index 7cd6d470c1cbd..7416db3d27a77 100644 |
43 | --- a/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi |
44 | +++ b/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi |
45 | @@ -237,6 +237,14 @@ |
46 | &edp { |
47 | status = "okay"; |
48 | |
49 | + /* |
50 | + * eDP PHY/clk don't sync reliably at anything other than 24 MHz. Only |
51 | + * set this here, because rk3399-gru.dtsi ensures we can generate this |
52 | + * off GPLL=600MHz, whereas some other RK3399 boards may not. |
53 | + */ |
54 | + assigned-clocks = <&cru PCLK_EDP>; |
55 | + assigned-clock-rates = <24000000>; |
56 | + |
57 | ports { |
58 | edp_out: port@1 { |
59 | reg = <1>; |
60 | @@ -397,6 +405,7 @@ ap_i2c_tp: &i2c5 { |
61 | }; |
62 | |
63 | wlan_host_wake_l: wlan-host-wake-l { |
64 | + /* Kevin has an external pull up, but Bob does not */ |
65 | rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; |
66 | }; |
67 | }; |
68 | diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi |
69 | index 390b86ec65389..365fa9a3c5bfb 100644 |
70 | --- a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi |
71 | +++ b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi |
72 | @@ -102,7 +102,6 @@ |
73 | vcc5v0_host: vcc5v0-host-regulator { |
74 | compatible = "regulator-fixed"; |
75 | gpio = <&gpio4 RK_PA3 GPIO_ACTIVE_LOW>; |
76 | - enable-active-low; |
77 | pinctrl-names = "default"; |
78 | pinctrl-0 = <&vcc5v0_host_en>; |
79 | regulator-name = "vcc5v0_host"; |
80 | diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c |
81 | index 3ad1f76c063a9..2d5e7b21d9600 100644 |
82 | --- a/arch/mips/cavium-octeon/octeon-irq.c |
83 | +++ b/arch/mips/cavium-octeon/octeon-irq.c |
84 | @@ -127,6 +127,16 @@ static void octeon_irq_free_cd(struct irq_domain *d, unsigned int irq) |
85 | static int octeon_irq_force_ciu_mapping(struct irq_domain *domain, |
86 | int irq, int line, int bit) |
87 | { |
88 | + struct device_node *of_node; |
89 | + int ret; |
90 | + |
91 | + of_node = irq_domain_get_of_node(domain); |
92 | + if (!of_node) |
93 | + return -EINVAL; |
94 | + ret = irq_alloc_desc_at(irq, of_node_to_nid(of_node)); |
95 | + if (ret < 0) |
96 | + return ret; |
97 | + |
98 | return irq_domain_associate(domain, irq, line << 6 | bit); |
99 | } |
100 | |
101 | diff --git a/arch/mips/lantiq/clk.c b/arch/mips/lantiq/clk.c |
102 | index 7a623684d9b5e..2d5a0bcb0cec1 100644 |
103 | --- a/arch/mips/lantiq/clk.c |
104 | +++ b/arch/mips/lantiq/clk.c |
105 | @@ -50,6 +50,7 @@ struct clk *clk_get_io(void) |
106 | { |
107 | return &cpu_clk_generic[2]; |
108 | } |
109 | +EXPORT_SYMBOL_GPL(clk_get_io); |
110 | |
111 | struct clk *clk_get_ppe(void) |
112 | { |
113 | diff --git a/arch/mips/loongson32/common/platform.c b/arch/mips/loongson32/common/platform.c |
114 | index 794c96c2a4cdd..311dc1580bbde 100644 |
115 | --- a/arch/mips/loongson32/common/platform.c |
116 | +++ b/arch/mips/loongson32/common/platform.c |
117 | @@ -98,7 +98,7 @@ int ls1x_eth_mux_init(struct platform_device *pdev, void *priv) |
118 | if (plat_dat->bus_id) { |
119 | __raw_writel(__raw_readl(LS1X_MUX_CTRL0) | GMAC1_USE_UART1 | |
120 | GMAC1_USE_UART0, LS1X_MUX_CTRL0); |
121 | - switch (plat_dat->interface) { |
122 | + switch (plat_dat->phy_interface) { |
123 | case PHY_INTERFACE_MODE_RGMII: |
124 | val &= ~(GMAC1_USE_TXCLK | GMAC1_USE_PWM23); |
125 | break; |
126 | @@ -107,12 +107,12 @@ int ls1x_eth_mux_init(struct platform_device *pdev, void *priv) |
127 | break; |
128 | default: |
129 | pr_err("unsupported mii mode %d\n", |
130 | - plat_dat->interface); |
131 | + plat_dat->phy_interface); |
132 | return -ENOTSUPP; |
133 | } |
134 | val &= ~GMAC1_SHUT; |
135 | } else { |
136 | - switch (plat_dat->interface) { |
137 | + switch (plat_dat->phy_interface) { |
138 | case PHY_INTERFACE_MODE_RGMII: |
139 | val &= ~(GMAC0_USE_TXCLK | GMAC0_USE_PWM01); |
140 | break; |
141 | @@ -121,7 +121,7 @@ int ls1x_eth_mux_init(struct platform_device *pdev, void *priv) |
142 | break; |
143 | default: |
144 | pr_err("unsupported mii mode %d\n", |
145 | - plat_dat->interface); |
146 | + plat_dat->phy_interface); |
147 | return -ENOTSUPP; |
148 | } |
149 | val &= ~GMAC0_SHUT; |
150 | @@ -131,7 +131,7 @@ int ls1x_eth_mux_init(struct platform_device *pdev, void *priv) |
151 | plat_dat = dev_get_platdata(&pdev->dev); |
152 | |
153 | val &= ~PHY_INTF_SELI; |
154 | - if (plat_dat->interface == PHY_INTERFACE_MODE_RMII) |
155 | + if (plat_dat->phy_interface == PHY_INTERFACE_MODE_RMII) |
156 | val |= 0x4 << PHY_INTF_SELI_SHIFT; |
157 | __raw_writel(val, LS1X_MUX_CTRL1); |
158 | |
159 | @@ -146,9 +146,9 @@ static struct plat_stmmacenet_data ls1x_eth0_pdata = { |
160 | .bus_id = 0, |
161 | .phy_addr = -1, |
162 | #if defined(CONFIG_LOONGSON1_LS1B) |
163 | - .interface = PHY_INTERFACE_MODE_MII, |
164 | + .phy_interface = PHY_INTERFACE_MODE_MII, |
165 | #elif defined(CONFIG_LOONGSON1_LS1C) |
166 | - .interface = PHY_INTERFACE_MODE_RMII, |
167 | + .phy_interface = PHY_INTERFACE_MODE_RMII, |
168 | #endif |
169 | .mdio_bus_data = &ls1x_mdio_bus_data, |
170 | .dma_cfg = &ls1x_eth_dma_cfg, |
171 | @@ -186,7 +186,7 @@ struct platform_device ls1x_eth0_pdev = { |
172 | static struct plat_stmmacenet_data ls1x_eth1_pdata = { |
173 | .bus_id = 1, |
174 | .phy_addr = -1, |
175 | - .interface = PHY_INTERFACE_MODE_MII, |
176 | + .phy_interface = PHY_INTERFACE_MODE_MII, |
177 | .mdio_bus_data = &ls1x_mdio_bus_data, |
178 | .dma_cfg = &ls1x_eth_dma_cfg, |
179 | .has_gmac = 1, |
180 | diff --git a/arch/x86/include/asm/cpu_entry_area.h b/arch/x86/include/asm/cpu_entry_area.h |
181 | index ea866c7bf31d3..0d1d37d8b279f 100644 |
182 | --- a/arch/x86/include/asm/cpu_entry_area.h |
183 | +++ b/arch/x86/include/asm/cpu_entry_area.h |
184 | @@ -133,7 +133,7 @@ extern void cea_set_pte(void *cea_vaddr, phys_addr_t pa, pgprot_t flags); |
185 | |
186 | extern struct cpu_entry_area *get_cpu_entry_area(int cpu); |
187 | |
188 | -static inline struct entry_stack *cpu_entry_stack(int cpu) |
189 | +static __always_inline struct entry_stack *cpu_entry_stack(int cpu) |
190 | { |
191 | return &get_cpu_entry_area(cpu)->entry_stack_page.stack; |
192 | } |
193 | diff --git a/drivers/firmware/efi/libstub/secureboot.c b/drivers/firmware/efi/libstub/secureboot.c |
194 | index edba5e7a37437..c8a1ef872e0d9 100644 |
195 | --- a/drivers/firmware/efi/libstub/secureboot.c |
196 | +++ b/drivers/firmware/efi/libstub/secureboot.c |
197 | @@ -19,7 +19,7 @@ static const efi_char16_t efi_SetupMode_name[] = L"SetupMode"; |
198 | |
199 | /* SHIM variables */ |
200 | static const efi_guid_t shim_guid = EFI_SHIM_LOCK_GUID; |
201 | -static const efi_char16_t shim_MokSBState_name[] = L"MokSBState"; |
202 | +static const efi_char16_t shim_MokSBState_name[] = L"MokSBStateRT"; |
203 | |
204 | #define get_efi_var(name, vendor, ...) \ |
205 | efi_call_runtime(get_variable, \ |
206 | @@ -58,8 +58,8 @@ enum efi_secureboot_mode efi_get_secureboot(efi_system_table_t *sys_table_arg) |
207 | |
208 | /* |
209 | * See if a user has put the shim into insecure mode. If so, and if the |
210 | - * variable doesn't have the runtime attribute set, we might as well |
211 | - * honor that. |
212 | + * variable doesn't have the non-volatile attribute set, we might as |
213 | + * well honor that. |
214 | */ |
215 | size = sizeof(moksbstate); |
216 | status = get_efi_var(shim_MokSBState_name, &shim_guid, |
217 | @@ -68,7 +68,7 @@ enum efi_secureboot_mode efi_get_secureboot(efi_system_table_t *sys_table_arg) |
218 | /* If it fails, we don't care why. Default to secure */ |
219 | if (status != EFI_SUCCESS) |
220 | goto secure_boot_enabled; |
221 | - if (!(attr & EFI_VARIABLE_RUNTIME_ACCESS) && moksbstate == 1) |
222 | + if (!(attr & EFI_VARIABLE_NON_VOLATILE) && moksbstate == 1) |
223 | return efi_secureboot_mode_disabled; |
224 | |
225 | secure_boot_enabled: |
226 | diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c |
227 | index d72a3a5507b01..f3bf82efea8e3 100644 |
228 | --- a/drivers/gpio/gpio-mpc8xxx.c |
229 | +++ b/drivers/gpio/gpio-mpc8xxx.c |
230 | @@ -190,6 +190,7 @@ static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type) |
231 | |
232 | switch (flow_type) { |
233 | case IRQ_TYPE_EDGE_FALLING: |
234 | + case IRQ_TYPE_LEVEL_LOW: |
235 | raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); |
236 | gc->write_reg(mpc8xxx_gc->regs + GPIO_ICR, |
237 | gc->read_reg(mpc8xxx_gc->regs + GPIO_ICR) |
238 | diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c |
239 | index b588e0e409e72..d8687868407de 100644 |
240 | --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c |
241 | +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c |
242 | @@ -35,6 +35,7 @@ |
243 | #include <linux/pci.h> |
244 | #include <linux/pm_runtime.h> |
245 | #include <drm/drm_crtc_helper.h> |
246 | +#include <drm/drm_damage_helper.h> |
247 | #include <drm/drm_edid.h> |
248 | #include <drm/drm_gem_framebuffer_helper.h> |
249 | #include <drm/drm_fb_helper.h> |
250 | @@ -495,6 +496,7 @@ bool amdgpu_display_ddc_probe(struct amdgpu_connector *amdgpu_connector, |
251 | static const struct drm_framebuffer_funcs amdgpu_fb_funcs = { |
252 | .destroy = drm_gem_fb_destroy, |
253 | .create_handle = drm_gem_fb_create_handle, |
254 | + .dirty = drm_atomic_helper_dirtyfb, |
255 | }; |
256 | |
257 | uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev, |
258 | diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c |
259 | index e042d8ce05b4a..22d105635e338 100644 |
260 | --- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c |
261 | +++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c |
262 | @@ -1486,6 +1486,7 @@ static void interpolate_user_regamma(uint32_t hw_points_num, |
263 | struct fixed31_32 lut2; |
264 | struct fixed31_32 delta_lut; |
265 | struct fixed31_32 delta_index; |
266 | + const struct fixed31_32 one = dc_fixpt_from_int(1); |
267 | |
268 | i = 0; |
269 | /* fixed_pt library has problems handling too small values */ |
270 | @@ -1514,6 +1515,9 @@ static void interpolate_user_regamma(uint32_t hw_points_num, |
271 | } else |
272 | hw_x = coordinates_x[i].x; |
273 | |
274 | + if (dc_fixpt_le(one, hw_x)) |
275 | + hw_x = one; |
276 | + |
277 | norm_x = dc_fixpt_mul(norm_factor, hw_x); |
278 | index = dc_fixpt_floor(norm_x); |
279 | if (index < 0 || index > 255) |
280 | diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c |
281 | index ed543227b00dd..53f5d0581c355 100644 |
282 | --- a/drivers/gpu/drm/meson/meson_plane.c |
283 | +++ b/drivers/gpu/drm/meson/meson_plane.c |
284 | @@ -128,7 +128,7 @@ static void meson_plane_atomic_update(struct drm_plane *plane, |
285 | |
286 | /* Enable OSD and BLK0, set max global alpha */ |
287 | priv->viu.osd1_ctrl_stat = OSD_ENABLE | |
288 | - (0xFF << OSD_GLOBAL_ALPHA_SHIFT) | |
289 | + (0x100 << OSD_GLOBAL_ALPHA_SHIFT) | |
290 | OSD_BLK0_ENABLE; |
291 | |
292 | canvas_id_osd1 = priv->canvas_id_osd1; |
293 | diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c |
294 | index 9991f0a43b1ab..8d09385259780 100644 |
295 | --- a/drivers/gpu/drm/meson/meson_viu.c |
296 | +++ b/drivers/gpu/drm/meson/meson_viu.c |
297 | @@ -91,7 +91,7 @@ static void meson_viu_set_g12a_osd1_matrix(struct meson_drm *priv, |
298 | priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF11_12)); |
299 | writel(((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff), |
300 | priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF20_21)); |
301 | - writel((m[11] & 0x1fff) << 16, |
302 | + writel((m[11] & 0x1fff), |
303 | priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF22)); |
304 | |
305 | writel(((m[18] & 0xfff) << 16) | (m[19] & 0xfff), |
306 | diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c |
307 | index 8f299d76b69b8..67dae1354aa65 100644 |
308 | --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c |
309 | +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c |
310 | @@ -275,8 +275,9 @@ static int cdn_dp_connector_get_modes(struct drm_connector *connector) |
311 | return ret; |
312 | } |
313 | |
314 | -static int cdn_dp_connector_mode_valid(struct drm_connector *connector, |
315 | - struct drm_display_mode *mode) |
316 | +static enum drm_mode_status |
317 | +cdn_dp_connector_mode_valid(struct drm_connector *connector, |
318 | + struct drm_display_mode *mode) |
319 | { |
320 | struct cdn_dp_device *dp = connector_to_dp(connector); |
321 | struct drm_display_info *display_info = &dp->connector.display_info; |
322 | diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c |
323 | index 56918274c48cf..d4c5efc6e157b 100644 |
324 | --- a/drivers/hv/vmbus_drv.c |
325 | +++ b/drivers/hv/vmbus_drv.c |
326 | @@ -2075,7 +2075,7 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj, |
327 | bool fb_overlap_ok) |
328 | { |
329 | struct resource *iter, *shadow; |
330 | - resource_size_t range_min, range_max, start; |
331 | + resource_size_t range_min, range_max, start, end; |
332 | const char *dev_n = dev_name(&device_obj->device); |
333 | int retval; |
334 | |
335 | @@ -2110,6 +2110,14 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj, |
336 | range_max = iter->end; |
337 | start = (range_min + align - 1) & ~(align - 1); |
338 | for (; start + size - 1 <= range_max; start += align) { |
339 | + end = start + size - 1; |
340 | + |
341 | + /* Skip the whole fb_mmio region if not fb_overlap_ok */ |
342 | + if (!fb_overlap_ok && fb_mmio && |
343 | + (((start >= fb_mmio->start) && (start <= fb_mmio->end)) || |
344 | + ((end >= fb_mmio->start) && (end <= fb_mmio->end)))) |
345 | + continue; |
346 | + |
347 | shadow = __request_region(iter, start, size, NULL, |
348 | IORESOURCE_BUSY); |
349 | if (!shadow) |
350 | diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c |
351 | index bf4ab30186aff..abd2a57b18cbb 100644 |
352 | --- a/drivers/net/can/usb/gs_usb.c |
353 | +++ b/drivers/net/can/usb/gs_usb.c |
354 | @@ -678,6 +678,7 @@ static int gs_can_open(struct net_device *netdev) |
355 | flags |= GS_CAN_MODE_TRIPLE_SAMPLE; |
356 | |
357 | /* finally start device */ |
358 | + dev->can.state = CAN_STATE_ERROR_ACTIVE; |
359 | dm->mode = cpu_to_le32(GS_CAN_MODE_START); |
360 | dm->flags = cpu_to_le32(flags); |
361 | rc = usb_control_msg(interface_to_usbdev(dev->iface), |
362 | @@ -694,13 +695,12 @@ static int gs_can_open(struct net_device *netdev) |
363 | if (rc < 0) { |
364 | netdev_err(netdev, "Couldn't start device (err=%d)\n", rc); |
365 | kfree(dm); |
366 | + dev->can.state = CAN_STATE_STOPPED; |
367 | return rc; |
368 | } |
369 | |
370 | kfree(dm); |
371 | |
372 | - dev->can.state = CAN_STATE_ERROR_ACTIVE; |
373 | - |
374 | parent->active_channels++; |
375 | if (!(dev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)) |
376 | netif_start_queue(netdev); |
377 | diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c |
378 | index 2d01eaeb703af..15f177185d71d 100644 |
379 | --- a/drivers/net/ethernet/intel/i40e/i40e_main.c |
380 | +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c |
381 | @@ -5638,6 +5638,26 @@ static int i40e_get_link_speed(struct i40e_vsi *vsi) |
382 | } |
383 | } |
384 | |
385 | +/** |
386 | + * i40e_bw_bytes_to_mbits - Convert max_tx_rate from bytes to mbits |
387 | + * @vsi: Pointer to vsi structure |
388 | + * @max_tx_rate: max TX rate in bytes to be converted into Mbits |
389 | + * |
390 | + * Helper function to convert units before send to set BW limit |
391 | + **/ |
392 | +static u64 i40e_bw_bytes_to_mbits(struct i40e_vsi *vsi, u64 max_tx_rate) |
393 | +{ |
394 | + if (max_tx_rate < I40E_BW_MBPS_DIVISOR) { |
395 | + dev_warn(&vsi->back->pdev->dev, |
396 | + "Setting max tx rate to minimum usable value of 50Mbps.\n"); |
397 | + max_tx_rate = I40E_BW_CREDIT_DIVISOR; |
398 | + } else { |
399 | + do_div(max_tx_rate, I40E_BW_MBPS_DIVISOR); |
400 | + } |
401 | + |
402 | + return max_tx_rate; |
403 | +} |
404 | + |
405 | /** |
406 | * i40e_set_bw_limit - setup BW limit for Tx traffic based on max_tx_rate |
407 | * @vsi: VSI to be configured |
408 | @@ -5660,10 +5680,10 @@ int i40e_set_bw_limit(struct i40e_vsi *vsi, u16 seid, u64 max_tx_rate) |
409 | max_tx_rate, seid); |
410 | return -EINVAL; |
411 | } |
412 | - if (max_tx_rate && max_tx_rate < 50) { |
413 | + if (max_tx_rate && max_tx_rate < I40E_BW_CREDIT_DIVISOR) { |
414 | dev_warn(&pf->pdev->dev, |
415 | "Setting max tx rate to minimum usable value of 50Mbps.\n"); |
416 | - max_tx_rate = 50; |
417 | + max_tx_rate = I40E_BW_CREDIT_DIVISOR; |
418 | } |
419 | |
420 | /* Tx rate credits are in values of 50Mbps, 0 is disabled */ |
421 | @@ -7591,9 +7611,9 @@ config_tc: |
422 | |
423 | if (pf->flags & I40E_FLAG_TC_MQPRIO) { |
424 | if (vsi->mqprio_qopt.max_rate[0]) { |
425 | - u64 max_tx_rate = vsi->mqprio_qopt.max_rate[0]; |
426 | + u64 max_tx_rate = i40e_bw_bytes_to_mbits(vsi, |
427 | + vsi->mqprio_qopt.max_rate[0]); |
428 | |
429 | - do_div(max_tx_rate, I40E_BW_MBPS_DIVISOR); |
430 | ret = i40e_set_bw_limit(vsi, vsi->seid, max_tx_rate); |
431 | if (!ret) { |
432 | u64 credits = max_tx_rate; |
433 | @@ -10247,10 +10267,10 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired) |
434 | } |
435 | |
436 | if (vsi->mqprio_qopt.max_rate[0]) { |
437 | - u64 max_tx_rate = vsi->mqprio_qopt.max_rate[0]; |
438 | + u64 max_tx_rate = i40e_bw_bytes_to_mbits(vsi, |
439 | + vsi->mqprio_qopt.max_rate[0]); |
440 | u64 credits = 0; |
441 | |
442 | - do_div(max_tx_rate, I40E_BW_MBPS_DIVISOR); |
443 | ret = i40e_set_bw_limit(vsi, vsi->seid, max_tx_rate); |
444 | if (ret) |
445 | goto end_unlock; |
446 | diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c |
447 | index 4080fdacca4cc..16f5baafbbd52 100644 |
448 | --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c |
449 | +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c |
450 | @@ -1873,6 +1873,25 @@ static void i40e_del_qch(struct i40e_vf *vf) |
451 | } |
452 | } |
453 | |
454 | +/** |
455 | + * i40e_vc_get_max_frame_size |
456 | + * @vf: pointer to the VF |
457 | + * |
458 | + * Max frame size is determined based on the current port's max frame size and |
459 | + * whether a port VLAN is configured on this VF. The VF is not aware whether |
460 | + * it's in a port VLAN so the PF needs to account for this in max frame size |
461 | + * checks and sending the max frame size to the VF. |
462 | + **/ |
463 | +static u16 i40e_vc_get_max_frame_size(struct i40e_vf *vf) |
464 | +{ |
465 | + u16 max_frame_size = vf->pf->hw.phy.link_info.max_frame_size; |
466 | + |
467 | + if (vf->port_vlan_id) |
468 | + max_frame_size -= VLAN_HLEN; |
469 | + |
470 | + return max_frame_size; |
471 | +} |
472 | + |
473 | /** |
474 | * i40e_vc_get_vf_resources_msg |
475 | * @vf: pointer to the VF info |
476 | @@ -1973,6 +1992,7 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg) |
477 | vfres->max_vectors = pf->hw.func_caps.num_msix_vectors_vf; |
478 | vfres->rss_key_size = I40E_HKEY_ARRAY_SIZE; |
479 | vfres->rss_lut_size = I40E_VF_HLUT_ARRAY_SIZE; |
480 | + vfres->max_mtu = i40e_vc_get_max_frame_size(vf); |
481 | |
482 | if (vf->lan_vsi_idx) { |
483 | vfres->vsi_res[0].vsi_id = vf->lan_vsi_id; |
484 | diff --git a/drivers/net/ethernet/intel/iavf/iavf_txrx.c b/drivers/net/ethernet/intel/iavf/iavf_txrx.c |
485 | index c6905d1b6182c..1f7b842c67638 100644 |
486 | --- a/drivers/net/ethernet/intel/iavf/iavf_txrx.c |
487 | +++ b/drivers/net/ethernet/intel/iavf/iavf_txrx.c |
488 | @@ -114,8 +114,11 @@ u32 iavf_get_tx_pending(struct iavf_ring *ring, bool in_sw) |
489 | { |
490 | u32 head, tail; |
491 | |
492 | + /* underlying hardware might not allow access and/or always return |
493 | + * 0 for the head/tail registers so just use the cached values |
494 | + */ |
495 | head = ring->next_to_clean; |
496 | - tail = readl(ring->tail); |
497 | + tail = ring->next_to_use; |
498 | |
499 | if (head != tail) |
500 | return (head < tail) ? |
501 | @@ -1371,7 +1374,7 @@ static struct sk_buff *iavf_build_skb(struct iavf_ring *rx_ring, |
502 | #endif |
503 | struct sk_buff *skb; |
504 | |
505 | - if (!rx_buffer) |
506 | + if (!rx_buffer || !size) |
507 | return NULL; |
508 | /* prefetch first cache line of first page */ |
509 | va = page_address(rx_buffer->page) + rx_buffer->page_offset; |
510 | @@ -1531,7 +1534,7 @@ static int iavf_clean_rx_irq(struct iavf_ring *rx_ring, int budget) |
511 | /* exit if we failed to retrieve a buffer */ |
512 | if (!skb) { |
513 | rx_ring->rx_stats.alloc_buff_failed++; |
514 | - if (rx_buffer) |
515 | + if (rx_buffer && size) |
516 | rx_buffer->pagecnt_bias++; |
517 | break; |
518 | } |
519 | diff --git a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c |
520 | index 4d471a6f2946f..7a17694b6a0b1 100644 |
521 | --- a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c |
522 | +++ b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c |
523 | @@ -241,11 +241,14 @@ out: |
524 | void iavf_configure_queues(struct iavf_adapter *adapter) |
525 | { |
526 | struct virtchnl_vsi_queue_config_info *vqci; |
527 | - struct virtchnl_queue_pair_info *vqpi; |
528 | + int i, max_frame = adapter->vf_res->max_mtu; |
529 | int pairs = adapter->num_active_queues; |
530 | - int i, max_frame = IAVF_MAX_RXBUFFER; |
531 | + struct virtchnl_queue_pair_info *vqpi; |
532 | size_t len; |
533 | |
534 | + if (max_frame > IAVF_MAX_RXBUFFER || !max_frame) |
535 | + max_frame = IAVF_MAX_RXBUFFER; |
536 | + |
537 | if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) { |
538 | /* bail because we already have a command pending */ |
539 | dev_err(&adapter->pdev->dev, "Cannot configure queues, command %d pending\n", |
540 | diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c |
541 | index 3133f903279ce..dbbbb6ea9f2b6 100644 |
542 | --- a/drivers/net/ethernet/sun/sunhme.c |
543 | +++ b/drivers/net/ethernet/sun/sunhme.c |
544 | @@ -2064,9 +2064,9 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev) |
545 | |
546 | skb_reserve(copy_skb, 2); |
547 | skb_put(copy_skb, len); |
548 | - dma_sync_single_for_cpu(hp->dma_dev, dma_addr, len, DMA_FROM_DEVICE); |
549 | + dma_sync_single_for_cpu(hp->dma_dev, dma_addr, len + 2, DMA_FROM_DEVICE); |
550 | skb_copy_from_linear_data(skb, copy_skb->data, len); |
551 | - dma_sync_single_for_device(hp->dma_dev, dma_addr, len, DMA_FROM_DEVICE); |
552 | + dma_sync_single_for_device(hp->dma_dev, dma_addr, len + 2, DMA_FROM_DEVICE); |
553 | /* Reuse original ring buffer. */ |
554 | hme_write_rxd(hp, this, |
555 | (RXFLAG_OWN|((RX_BUF_ALLOC_SIZE-RX_OFFSET)<<16)), |
556 | diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c |
557 | index 8801d093135c3..a33149ee0ddcf 100644 |
558 | --- a/drivers/net/ipvlan/ipvlan_core.c |
559 | +++ b/drivers/net/ipvlan/ipvlan_core.c |
560 | @@ -496,7 +496,6 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb) |
561 | |
562 | static int ipvlan_process_outbound(struct sk_buff *skb) |
563 | { |
564 | - struct ethhdr *ethh = eth_hdr(skb); |
565 | int ret = NET_XMIT_DROP; |
566 | |
567 | /* The ipvlan is a pseudo-L2 device, so the packets that we receive |
568 | @@ -506,6 +505,8 @@ static int ipvlan_process_outbound(struct sk_buff *skb) |
569 | if (skb_mac_header_was_set(skb)) { |
570 | /* In this mode we dont care about |
571 | * multicast and broadcast traffic */ |
572 | + struct ethhdr *ethh = eth_hdr(skb); |
573 | + |
574 | if (is_multicast_ether_addr(ethh->h_dest)) { |
575 | pr_debug_ratelimited( |
576 | "Dropped {multi|broad}cast of type=[%x]\n", |
577 | @@ -590,7 +591,7 @@ out: |
578 | static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev) |
579 | { |
580 | const struct ipvl_dev *ipvlan = netdev_priv(dev); |
581 | - struct ethhdr *eth = eth_hdr(skb); |
582 | + struct ethhdr *eth = skb_eth_hdr(skb); |
583 | struct ipvl_addr *addr; |
584 | void *lyr3h; |
585 | int addr_type; |
586 | @@ -620,6 +621,7 @@ static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev) |
587 | return dev_forward_skb(ipvlan->phy_dev, skb); |
588 | |
589 | } else if (is_multicast_ether_addr(eth->h_dest)) { |
590 | + skb_reset_mac_header(skb); |
591 | ipvlan_skb_crossing_ns(skb, NULL); |
592 | ipvlan_multicast_enqueue(ipvlan->port, skb, true); |
593 | return NET_XMIT_SUCCESS; |
594 | diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c |
595 | index 0eb894b7c0bda..da74ec778b6e7 100644 |
596 | --- a/drivers/net/team/team.c |
597 | +++ b/drivers/net/team/team.c |
598 | @@ -1270,10 +1270,12 @@ static int team_port_add(struct team *team, struct net_device *port_dev, |
599 | } |
600 | } |
601 | |
602 | - netif_addr_lock_bh(dev); |
603 | - dev_uc_sync_multiple(port_dev, dev); |
604 | - dev_mc_sync_multiple(port_dev, dev); |
605 | - netif_addr_unlock_bh(dev); |
606 | + if (dev->flags & IFF_UP) { |
607 | + netif_addr_lock_bh(dev); |
608 | + dev_uc_sync_multiple(port_dev, dev); |
609 | + dev_mc_sync_multiple(port_dev, dev); |
610 | + netif_addr_unlock_bh(dev); |
611 | + } |
612 | |
613 | port->index = -1; |
614 | list_add_tail_rcu(&port->list, &team->port_list); |
615 | @@ -1344,8 +1346,10 @@ static int team_port_del(struct team *team, struct net_device *port_dev) |
616 | netdev_rx_handler_unregister(port_dev); |
617 | team_port_disable_netpoll(port); |
618 | vlan_vids_del_by_dev(port_dev, dev); |
619 | - dev_uc_unsync(port_dev, dev); |
620 | - dev_mc_unsync(port_dev, dev); |
621 | + if (dev->flags & IFF_UP) { |
622 | + dev_uc_unsync(port_dev, dev); |
623 | + dev_mc_unsync(port_dev, dev); |
624 | + } |
625 | dev_close(port_dev); |
626 | team_port_leave(team, port); |
627 | |
628 | @@ -1694,6 +1698,14 @@ static int team_open(struct net_device *dev) |
629 | |
630 | static int team_close(struct net_device *dev) |
631 | { |
632 | + struct team *team = netdev_priv(dev); |
633 | + struct team_port *port; |
634 | + |
635 | + list_for_each_entry(port, &team->port_list, list) { |
636 | + dev_uc_unsync(port->dev, dev); |
637 | + dev_mc_unsync(port->dev, dev); |
638 | + } |
639 | + |
640 | return 0; |
641 | } |
642 | |
643 | diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c |
644 | index 8ef0a013874c5..cee90e505d175 100644 |
645 | --- a/drivers/net/usb/qmi_wwan.c |
646 | +++ b/drivers/net/usb/qmi_wwan.c |
647 | @@ -1046,6 +1046,7 @@ static const struct usb_device_id products[] = { |
648 | {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0512)}, /* Quectel EG12/EM12 */ |
649 | {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0620)}, /* Quectel EM160R-GL */ |
650 | {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0800)}, /* Quectel RM500Q-GL */ |
651 | + {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0801)}, /* Quectel RM520N */ |
652 | |
653 | /* 3. Combined interface devices matching on interface number */ |
654 | {QMI_FIXED_INTF(0x0408, 0xea42, 4)}, /* Yota / Megafon M100-1 */ |
655 | diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c |
656 | index 943d2a60bfdf9..6d519ef3c5da4 100644 |
657 | --- a/drivers/of/fdt.c |
658 | +++ b/drivers/of/fdt.c |
659 | @@ -315,7 +315,7 @@ static int unflatten_dt_nodes(const void *blob, |
660 | for (offset = 0; |
661 | offset >= 0 && depth >= initial_depth; |
662 | offset = fdt_next_node(blob, offset, &depth)) { |
663 | - if (WARN_ON_ONCE(depth >= FDT_MAX_DEPTH)) |
664 | + if (WARN_ON_ONCE(depth >= FDT_MAX_DEPTH - 1)) |
665 | continue; |
666 | |
667 | if (!IS_ENABLED(CONFIG_OF_KOBJ) && |
668 | diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c |
669 | index 26ddb4cc675a9..7a3de2b5de0cd 100644 |
670 | --- a/drivers/of/of_mdio.c |
671 | +++ b/drivers/of/of_mdio.c |
672 | @@ -281,6 +281,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) |
673 | return 0; |
674 | |
675 | unregister: |
676 | + of_node_put(child); |
677 | mdiobus_unregister(mdio); |
678 | return rc; |
679 | } |
680 | diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c |
681 | index 6209d58e9492a..fdd302d0a1c90 100644 |
682 | --- a/drivers/parisc/ccio-dma.c |
683 | +++ b/drivers/parisc/ccio-dma.c |
684 | @@ -1544,6 +1544,7 @@ static int __init ccio_probe(struct parisc_device *dev) |
685 | } |
686 | ccio_ioc_init(ioc); |
687 | if (ccio_init_resources(ioc)) { |
688 | + iounmap(ioc->ioc_regs); |
689 | kfree(ioc); |
690 | return -ENOMEM; |
691 | } |
692 | diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c |
693 | index f873d97100e28..13609942d45c0 100644 |
694 | --- a/drivers/regulator/pfuze100-regulator.c |
695 | +++ b/drivers/regulator/pfuze100-regulator.c |
696 | @@ -788,7 +788,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client, |
697 | ((pfuze_chip->chip_id == PFUZE3000) ? "3000" : "3001")))); |
698 | |
699 | memcpy(pfuze_chip->regulator_descs, pfuze_chip->pfuze_regulators, |
700 | - sizeof(pfuze_chip->regulator_descs)); |
701 | + regulator_num * sizeof(struct pfuze_regulator)); |
702 | |
703 | ret = pfuze_parse_regulators_dt(pfuze_chip); |
704 | if (ret) |
705 | diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c |
706 | index dc78a523a69f2..b6b938aa66158 100644 |
707 | --- a/drivers/s390/block/dasd_alias.c |
708 | +++ b/drivers/s390/block/dasd_alias.c |
709 | @@ -675,12 +675,12 @@ int dasd_alias_remove_device(struct dasd_device *device) |
710 | struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *base_device) |
711 | { |
712 | struct dasd_eckd_private *alias_priv, *private = base_device->private; |
713 | - struct alias_pav_group *group = private->pavgroup; |
714 | struct alias_lcu *lcu = private->lcu; |
715 | struct dasd_device *alias_device; |
716 | + struct alias_pav_group *group; |
717 | unsigned long flags; |
718 | |
719 | - if (!group || !lcu) |
720 | + if (!lcu) |
721 | return NULL; |
722 | if (lcu->pav == NO_PAV || |
723 | lcu->flags & (NEED_UAC_UPDATE | UPDATE_PENDING)) |
724 | @@ -697,6 +697,11 @@ struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *base_device) |
725 | } |
726 | |
727 | spin_lock_irqsave(&lcu->lock, flags); |
728 | + group = private->pavgroup; |
729 | + if (!group) { |
730 | + spin_unlock_irqrestore(&lcu->lock, flags); |
731 | + return NULL; |
732 | + } |
733 | alias_device = group->next; |
734 | if (!alias_device) { |
735 | if (list_empty(&group->aliaslist)) { |
736 | diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c |
737 | index 3b2c25bd2e06b..3bd93558b4435 100644 |
738 | --- a/drivers/tty/serial/atmel_serial.c |
739 | +++ b/drivers/tty/serial/atmel_serial.c |
740 | @@ -306,16 +306,16 @@ static int atmel_config_rs485(struct uart_port *port, |
741 | |
742 | mode = atmel_uart_readl(port, ATMEL_US_MR); |
743 | |
744 | - /* Resetting serial mode to RS232 (0x0) */ |
745 | - mode &= ~ATMEL_US_USMODE; |
746 | - |
747 | - port->rs485 = *rs485conf; |
748 | - |
749 | if (rs485conf->flags & SER_RS485_ENABLED) { |
750 | dev_dbg(port->dev, "Setting UART to RS485\n"); |
751 | - atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; |
752 | + if (rs485conf->flags & SER_RS485_RX_DURING_TX) |
753 | + atmel_port->tx_done_mask = ATMEL_US_TXRDY; |
754 | + else |
755 | + atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; |
756 | + |
757 | atmel_uart_writel(port, ATMEL_US_TTGR, |
758 | rs485conf->delay_rts_after_send); |
759 | + mode &= ~ATMEL_US_USMODE; |
760 | mode |= ATMEL_US_USMODE_RS485; |
761 | } else { |
762 | dev_dbg(port->dev, "Setting UART to RS232\n"); |
763 | @@ -832,7 +832,7 @@ static void atmel_tx_chars(struct uart_port *port) |
764 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
765 | |
766 | if (port->x_char && |
767 | - (atmel_uart_readl(port, ATMEL_US_CSR) & atmel_port->tx_done_mask)) { |
768 | + (atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXRDY)) { |
769 | atmel_uart_write_char(port, port->x_char); |
770 | port->icount.tx++; |
771 | port->x_char = 0; |
772 | @@ -840,8 +840,7 @@ static void atmel_tx_chars(struct uart_port *port) |
773 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) |
774 | return; |
775 | |
776 | - while (atmel_uart_readl(port, ATMEL_US_CSR) & |
777 | - atmel_port->tx_done_mask) { |
778 | + while (atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXRDY) { |
779 | atmel_uart_write_char(port, xmit->buf[xmit->tail]); |
780 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); |
781 | port->icount.tx++; |
782 | @@ -852,10 +851,20 @@ static void atmel_tx_chars(struct uart_port *port) |
783 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
784 | uart_write_wakeup(port); |
785 | |
786 | - if (!uart_circ_empty(xmit)) |
787 | + if (!uart_circ_empty(xmit)) { |
788 | + /* we still have characters to transmit, so we should continue |
789 | + * transmitting them when TX is ready, regardless of |
790 | + * mode or duplexity |
791 | + */ |
792 | + atmel_port->tx_done_mask |= ATMEL_US_TXRDY; |
793 | + |
794 | /* Enable interrupts */ |
795 | atmel_uart_writel(port, ATMEL_US_IER, |
796 | atmel_port->tx_done_mask); |
797 | + } else { |
798 | + if (atmel_uart_is_half_duplex(port)) |
799 | + atmel_port->tx_done_mask &= ~ATMEL_US_TXRDY; |
800 | + } |
801 | } |
802 | |
803 | static void atmel_complete_tx_dma(void *arg) |
804 | @@ -2541,8 +2550,7 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port, |
805 | * Use TXEMPTY for interrupt when rs485 or ISO7816 else TXRDY or |
806 | * ENDTX|TXBUFE |
807 | */ |
808 | - if (port->rs485.flags & SER_RS485_ENABLED || |
809 | - port->iso7816.flags & SER_ISO7816_ENABLED) |
810 | + if (atmel_uart_is_half_duplex(port)) |
811 | atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; |
812 | else if (atmel_use_pdc_tx(port)) { |
813 | port->fifosize = PDC_BUFFER_SIZE; |
814 | diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c |
815 | index 74c21152367ae..c5f43cd39664a 100644 |
816 | --- a/drivers/tty/serial/serial-tegra.c |
817 | +++ b/drivers/tty/serial/serial-tegra.c |
818 | @@ -519,7 +519,7 @@ static void tegra_uart_tx_dma_complete(void *args) |
819 | count = tup->tx_bytes_requested - state.residue; |
820 | async_tx_ack(tup->tx_dma_desc); |
821 | spin_lock_irqsave(&tup->uport.lock, flags); |
822 | - xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); |
823 | + uart_xmit_advance(&tup->uport, count); |
824 | tup->tx_in_progress = 0; |
825 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
826 | uart_write_wakeup(&tup->uport); |
827 | @@ -606,7 +606,6 @@ static unsigned int tegra_uart_tx_empty(struct uart_port *u) |
828 | static void tegra_uart_stop_tx(struct uart_port *u) |
829 | { |
830 | struct tegra_uart_port *tup = to_tegra_uport(u); |
831 | - struct circ_buf *xmit = &tup->uport.state->xmit; |
832 | struct dma_tx_state state; |
833 | unsigned int count; |
834 | |
835 | @@ -617,7 +616,7 @@ static void tegra_uart_stop_tx(struct uart_port *u) |
836 | dmaengine_tx_status(tup->tx_dma_chan, tup->tx_cookie, &state); |
837 | count = tup->tx_bytes_requested - state.residue; |
838 | async_tx_ack(tup->tx_dma_desc); |
839 | - xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); |
840 | + uart_xmit_advance(&tup->uport, count); |
841 | tup->tx_in_progress = 0; |
842 | } |
843 | |
844 | diff --git a/drivers/tty/serial/tegra-tcu.c b/drivers/tty/serial/tegra-tcu.c |
845 | index aaf8748a61479..31ae705aa38b7 100644 |
846 | --- a/drivers/tty/serial/tegra-tcu.c |
847 | +++ b/drivers/tty/serial/tegra-tcu.c |
848 | @@ -101,7 +101,7 @@ static void tegra_tcu_uart_start_tx(struct uart_port *port) |
849 | break; |
850 | |
851 | tegra_tcu_write(tcu, &xmit->buf[xmit->tail], count); |
852 | - xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); |
853 | + uart_xmit_advance(port, count); |
854 | } |
855 | |
856 | uart_write_wakeup(port); |
857 | diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c |
858 | index 8bedf0504e92f..d111cf81cecef 100644 |
859 | --- a/drivers/usb/cdns3/gadget.c |
860 | +++ b/drivers/usb/cdns3/gadget.c |
861 | @@ -1259,6 +1259,7 @@ static int cdns3_check_ep_interrupt_proceed(struct cdns3_endpoint *priv_ep) |
862 | ep_cfg &= ~EP_CFG_ENABLE; |
863 | writel(ep_cfg, &priv_dev->regs->ep_cfg); |
864 | priv_ep->flags &= ~EP_QUIRK_ISO_OUT_EN; |
865 | + priv_ep->flags |= EP_UPDATE_EP_TRBADDR; |
866 | } |
867 | cdns3_transfer_completed(priv_dev, priv_ep); |
868 | } else if (!(priv_ep->flags & EP_STALLED) && |
869 | diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c |
870 | index 68d860a3fd617..50c7df59f7e87 100644 |
871 | --- a/drivers/usb/core/hub.c |
872 | +++ b/drivers/usb/core/hub.c |
873 | @@ -5924,7 +5924,7 @@ re_enumerate_no_bos: |
874 | * |
875 | * Return: The same as for usb_reset_and_verify_device(). |
876 | * However, if a reset is already in progress (for instance, if a |
877 | - * driver doesn't have pre_ or post_reset() callbacks, and while |
878 | + * driver doesn't have pre_reset() or post_reset() callbacks, and while |
879 | * being unbound or re-bound during the ongoing reset its disconnect() |
880 | * or probe() routine tries to perform a second, nested reset), the |
881 | * routine returns -EINPROGRESS. |
882 | diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c |
883 | index f4655665a1b5c..a9c49b2ce511b 100644 |
884 | --- a/drivers/usb/dwc3/core.c |
885 | +++ b/drivers/usb/dwc3/core.c |
886 | @@ -227,7 +227,7 @@ u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type) |
887 | * dwc3_core_soft_reset - Issues core soft reset and PHY reset |
888 | * @dwc: pointer to our context structure |
889 | */ |
890 | -static int dwc3_core_soft_reset(struct dwc3 *dwc) |
891 | +int dwc3_core_soft_reset(struct dwc3 *dwc) |
892 | { |
893 | u32 reg; |
894 | int retries = 1000; |
895 | diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h |
896 | index da296f888f45d..f320b989abd21 100644 |
897 | --- a/drivers/usb/dwc3/core.h |
898 | +++ b/drivers/usb/dwc3/core.h |
899 | @@ -994,6 +994,7 @@ struct dwc3_scratchpad_array { |
900 | * @tx_max_burst_prd: max periodic ESS transmit burst size |
901 | * @hsphy_interface: "utmi" or "ulpi" |
902 | * @connected: true when we're connected to a host, false otherwise |
903 | + * @softconnect: true when gadget connect is called, false when disconnect runs |
904 | * @delayed_status: true when gadget driver asks for delayed status |
905 | * @ep0_bounced: true when we used bounce buffer |
906 | * @ep0_expect_in: true when we expect a DATA IN transfer |
907 | @@ -1196,6 +1197,7 @@ struct dwc3 { |
908 | const char *hsphy_interface; |
909 | |
910 | unsigned connected:1; |
911 | + unsigned softconnect:1; |
912 | unsigned delayed_status:1; |
913 | unsigned ep0_bounced:1; |
914 | unsigned ep0_expect_in:1; |
915 | @@ -1420,6 +1422,8 @@ bool dwc3_has_imod(struct dwc3 *dwc); |
916 | int dwc3_event_buffers_setup(struct dwc3 *dwc); |
917 | void dwc3_event_buffers_cleanup(struct dwc3 *dwc); |
918 | |
919 | +int dwc3_core_soft_reset(struct dwc3 *dwc); |
920 | + |
921 | #if IS_ENABLED(CONFIG_USB_DWC3_HOST) || IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE) |
922 | int dwc3_host_init(struct dwc3 *dwc); |
923 | void dwc3_host_exit(struct dwc3 *dwc); |
924 | diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c |
925 | index 80fee7ea83ca4..a40935f3592bc 100644 |
926 | --- a/drivers/usb/dwc3/gadget.c |
927 | +++ b/drivers/usb/dwc3/gadget.c |
928 | @@ -2008,14 +2008,42 @@ static void dwc3_gadget_disable_irq(struct dwc3 *dwc); |
929 | static void __dwc3_gadget_stop(struct dwc3 *dwc); |
930 | static int __dwc3_gadget_start(struct dwc3 *dwc); |
931 | |
932 | +static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc) |
933 | +{ |
934 | + unsigned long flags; |
935 | + |
936 | + spin_lock_irqsave(&dwc->lock, flags); |
937 | + dwc->connected = false; |
938 | + |
939 | + /* |
940 | + * In the Synopsys DesignWare Cores USB3 Databook Rev. 3.30a |
941 | + * Section 4.1.8 Table 4-7, it states that for a device-initiated |
942 | + * disconnect, the SW needs to ensure that it sends "a DEPENDXFER |
943 | + * command for any active transfers" before clearing the RunStop |
944 | + * bit. |
945 | + */ |
946 | + dwc3_stop_active_transfers(dwc); |
947 | + __dwc3_gadget_stop(dwc); |
948 | + spin_unlock_irqrestore(&dwc->lock, flags); |
949 | + |
950 | + /* |
951 | + * Note: if the GEVNTCOUNT indicates events in the event buffer, the |
952 | + * driver needs to acknowledge them before the controller can halt. |
953 | + * Simply let the interrupt handler acknowledges and handle the |
954 | + * remaining event generated by the controller while polling for |
955 | + * DSTS.DEVCTLHLT. |
956 | + */ |
957 | + return dwc3_gadget_run_stop(dwc, false, false); |
958 | +} |
959 | + |
960 | static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) |
961 | { |
962 | struct dwc3 *dwc = gadget_to_dwc(g); |
963 | - unsigned long flags; |
964 | int ret; |
965 | |
966 | is_on = !!is_on; |
967 | |
968 | + dwc->softconnect = is_on; |
969 | /* |
970 | * Per databook, when we want to stop the gadget, if a control transfer |
971 | * is still in process, complete it and get the core into setup phase. |
972 | @@ -2051,50 +2079,27 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) |
973 | return 0; |
974 | } |
975 | |
976 | - /* |
977 | - * Synchronize and disable any further event handling while controller |
978 | - * is being enabled/disabled. |
979 | - */ |
980 | - disable_irq(dwc->irq_gadget); |
981 | - |
982 | - spin_lock_irqsave(&dwc->lock, flags); |
983 | + if (dwc->pullups_connected == is_on) { |
984 | + pm_runtime_put(dwc->dev); |
985 | + return 0; |
986 | + } |
987 | |
988 | if (!is_on) { |
989 | - u32 count; |
990 | - |
991 | - dwc->connected = false; |
992 | + ret = dwc3_gadget_soft_disconnect(dwc); |
993 | + } else { |
994 | /* |
995 | - * In the Synopsis DesignWare Cores USB3 Databook Rev. 3.30a |
996 | - * Section 4.1.8 Table 4-7, it states that for a device-initiated |
997 | - * disconnect, the SW needs to ensure that it sends "a DEPENDXFER |
998 | - * command for any active transfers" before clearing the RunStop |
999 | - * bit. |
1000 | + * In the Synopsys DWC_usb31 1.90a programming guide section |
1001 | + * 4.1.9, it specifies that for a reconnect after a |
1002 | + * device-initiated disconnect requires a core soft reset |
1003 | + * (DCTL.CSftRst) before enabling the run/stop bit. |
1004 | */ |
1005 | - dwc3_stop_active_transfers(dwc); |
1006 | - __dwc3_gadget_stop(dwc); |
1007 | + dwc3_core_soft_reset(dwc); |
1008 | |
1009 | - /* |
1010 | - * In the Synopsis DesignWare Cores USB3 Databook Rev. 3.30a |
1011 | - * Section 1.3.4, it mentions that for the DEVCTRLHLT bit, the |
1012 | - * "software needs to acknowledge the events that are generated |
1013 | - * (by writing to GEVNTCOUNTn) while it is waiting for this bit |
1014 | - * to be set to '1'." |
1015 | - */ |
1016 | - count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0)); |
1017 | - count &= DWC3_GEVNTCOUNT_MASK; |
1018 | - if (count > 0) { |
1019 | - dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), count); |
1020 | - dwc->ev_buf->lpos = (dwc->ev_buf->lpos + count) % |
1021 | - dwc->ev_buf->length; |
1022 | - } |
1023 | - } else { |
1024 | + dwc3_event_buffers_setup(dwc); |
1025 | __dwc3_gadget_start(dwc); |
1026 | + ret = dwc3_gadget_run_stop(dwc, true, false); |
1027 | } |
1028 | |
1029 | - ret = dwc3_gadget_run_stop(dwc, is_on, false); |
1030 | - spin_unlock_irqrestore(&dwc->lock, flags); |
1031 | - enable_irq(dwc->irq_gadget); |
1032 | - |
1033 | pm_runtime_put(dwc->dev); |
1034 | |
1035 | return ret; |
1036 | @@ -3791,7 +3796,7 @@ int dwc3_gadget_resume(struct dwc3 *dwc) |
1037 | { |
1038 | int ret; |
1039 | |
1040 | - if (!dwc->gadget_driver) |
1041 | + if (!dwc->gadget_driver || !dwc->softconnect) |
1042 | return 0; |
1043 | |
1044 | ret = __dwc3_gadget_start(dwc); |
1045 | diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c |
1046 | index 8950d1f10a7fb..86c4bc9df3b80 100644 |
1047 | --- a/drivers/usb/host/xhci-mtk-sch.c |
1048 | +++ b/drivers/usb/host/xhci-mtk-sch.c |
1049 | @@ -25,6 +25,13 @@ |
1050 | */ |
1051 | #define TT_MICROFRAMES_MAX 9 |
1052 | |
1053 | +/* schedule error type */ |
1054 | +#define ESCH_SS_Y6 1001 |
1055 | +#define ESCH_SS_OVERLAP 1002 |
1056 | +#define ESCH_CS_OVERFLOW 1003 |
1057 | +#define ESCH_BW_OVERFLOW 1004 |
1058 | +#define ESCH_FIXME 1005 |
1059 | + |
1060 | /* mtk scheduler bitmasks */ |
1061 | #define EP_BPKTS(p) ((p) & 0x7f) |
1062 | #define EP_BCSCOUNT(p) (((p) & 0x7) << 8) |
1063 | @@ -32,6 +39,24 @@ |
1064 | #define EP_BOFFSET(p) ((p) & 0x3fff) |
1065 | #define EP_BREPEAT(p) (((p) & 0x7fff) << 16) |
1066 | |
1067 | +static char *sch_error_string(int err_num) |
1068 | +{ |
1069 | + switch (err_num) { |
1070 | + case ESCH_SS_Y6: |
1071 | + return "Can't schedule Start-Split in Y6"; |
1072 | + case ESCH_SS_OVERLAP: |
1073 | + return "Can't find a suitable Start-Split location"; |
1074 | + case ESCH_CS_OVERFLOW: |
1075 | + return "The last Complete-Split is greater than 7"; |
1076 | + case ESCH_BW_OVERFLOW: |
1077 | + return "Bandwidth exceeds the maximum limit"; |
1078 | + case ESCH_FIXME: |
1079 | + return "FIXME, to be resolved"; |
1080 | + default: |
1081 | + return "Unknown"; |
1082 | + } |
1083 | +} |
1084 | + |
1085 | static int is_fs_or_ls(enum usb_device_speed speed) |
1086 | { |
1087 | return speed == USB_SPEED_FULL || speed == USB_SPEED_LOW; |
1088 | @@ -375,7 +400,6 @@ static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw, |
1089 | sch_ep->bw_budget_table[j]; |
1090 | } |
1091 | } |
1092 | - sch_ep->allocated = used; |
1093 | } |
1094 | |
1095 | static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset) |
1096 | @@ -384,19 +408,20 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset) |
1097 | u32 num_esit, tmp; |
1098 | int base; |
1099 | int i, j; |
1100 | + u8 uframes = DIV_ROUND_UP(sch_ep->maxpkt, FS_PAYLOAD_MAX); |
1101 | |
1102 | num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; |
1103 | + |
1104 | + if (sch_ep->ep_type == INT_IN_EP || sch_ep->ep_type == ISOC_IN_EP) |
1105 | + offset++; |
1106 | + |
1107 | for (i = 0; i < num_esit; i++) { |
1108 | base = offset + i * sch_ep->esit; |
1109 | |
1110 | - /* |
1111 | - * Compared with hs bus, no matter what ep type, |
1112 | - * the hub will always delay one uframe to send data |
1113 | - */ |
1114 | - for (j = 0; j < sch_ep->cs_count; j++) { |
1115 | + for (j = 0; j < uframes; j++) { |
1116 | tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_cost_per_microframe; |
1117 | if (tmp > FS_PAYLOAD_MAX) |
1118 | - return -ERANGE; |
1119 | + return -ESCH_BW_OVERFLOW; |
1120 | } |
1121 | } |
1122 | |
1123 | @@ -406,15 +431,11 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset) |
1124 | static int check_sch_tt(struct usb_device *udev, |
1125 | struct mu3h_sch_ep_info *sch_ep, u32 offset) |
1126 | { |
1127 | - struct mu3h_sch_tt *tt = sch_ep->sch_tt; |
1128 | u32 extra_cs_count; |
1129 | - u32 fs_budget_start; |
1130 | u32 start_ss, last_ss; |
1131 | u32 start_cs, last_cs; |
1132 | - int i; |
1133 | |
1134 | start_ss = offset % 8; |
1135 | - fs_budget_start = (start_ss + 1) % 8; |
1136 | |
1137 | if (sch_ep->ep_type == ISOC_OUT_EP) { |
1138 | last_ss = start_ss + sch_ep->cs_count - 1; |
1139 | @@ -424,11 +445,7 @@ static int check_sch_tt(struct usb_device *udev, |
1140 | * must never schedule Start-Split in Y6 |
1141 | */ |
1142 | if (!(start_ss == 7 || last_ss < 6)) |
1143 | - return -ERANGE; |
1144 | - |
1145 | - for (i = 0; i < sch_ep->cs_count; i++) |
1146 | - if (test_bit(offset + i, tt->ss_bit_map)) |
1147 | - return -ERANGE; |
1148 | + return -ESCH_SS_Y6; |
1149 | |
1150 | } else { |
1151 | u32 cs_count = DIV_ROUND_UP(sch_ep->maxpkt, FS_PAYLOAD_MAX); |
1152 | @@ -438,29 +455,24 @@ static int check_sch_tt(struct usb_device *udev, |
1153 | * must never schedule Start-Split in Y6 |
1154 | */ |
1155 | if (start_ss == 6) |
1156 | - return -ERANGE; |
1157 | + return -ESCH_SS_Y6; |
1158 | |
1159 | /* one uframe for ss + one uframe for idle */ |
1160 | start_cs = (start_ss + 2) % 8; |
1161 | last_cs = start_cs + cs_count - 1; |
1162 | |
1163 | if (last_cs > 7) |
1164 | - return -ERANGE; |
1165 | + return -ESCH_CS_OVERFLOW; |
1166 | |
1167 | if (sch_ep->ep_type == ISOC_IN_EP) |
1168 | extra_cs_count = (last_cs == 7) ? 1 : 2; |
1169 | else /* ep_type : INTR IN / INTR OUT */ |
1170 | - extra_cs_count = (fs_budget_start == 6) ? 1 : 2; |
1171 | + extra_cs_count = 1; |
1172 | |
1173 | cs_count += extra_cs_count; |
1174 | if (cs_count > 7) |
1175 | cs_count = 7; /* HW limit */ |
1176 | |
1177 | - for (i = 0; i < cs_count + 2; i++) { |
1178 | - if (test_bit(offset + i, tt->ss_bit_map)) |
1179 | - return -ERANGE; |
1180 | - } |
1181 | - |
1182 | sch_ep->cs_count = cs_count; |
1183 | /* one for ss, the other for idle */ |
1184 | sch_ep->num_budget_microframes = cs_count + 2; |
1185 | @@ -482,28 +494,24 @@ static void update_sch_tt(struct usb_device *udev, |
1186 | struct mu3h_sch_tt *tt = sch_ep->sch_tt; |
1187 | u32 base, num_esit; |
1188 | int bw_updated; |
1189 | - int bits; |
1190 | int i, j; |
1191 | + int offset = sch_ep->offset; |
1192 | + u8 uframes = DIV_ROUND_UP(sch_ep->maxpkt, FS_PAYLOAD_MAX); |
1193 | |
1194 | num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; |
1195 | - bits = (sch_ep->ep_type == ISOC_OUT_EP) ? sch_ep->cs_count : 1; |
1196 | |
1197 | if (used) |
1198 | bw_updated = sch_ep->bw_cost_per_microframe; |
1199 | else |
1200 | bw_updated = -sch_ep->bw_cost_per_microframe; |
1201 | |
1202 | - for (i = 0; i < num_esit; i++) { |
1203 | - base = sch_ep->offset + i * sch_ep->esit; |
1204 | + if (sch_ep->ep_type == INT_IN_EP || sch_ep->ep_type == ISOC_IN_EP) |
1205 | + offset++; |
1206 | |
1207 | - for (j = 0; j < bits; j++) { |
1208 | - if (used) |
1209 | - set_bit(base + j, tt->ss_bit_map); |
1210 | - else |
1211 | - clear_bit(base + j, tt->ss_bit_map); |
1212 | - } |
1213 | + for (i = 0; i < num_esit; i++) { |
1214 | + base = offset + i * sch_ep->esit; |
1215 | |
1216 | - for (j = 0; j < sch_ep->cs_count; j++) |
1217 | + for (j = 0; j < uframes; j++) |
1218 | tt->fs_bus_bw[base + j] += bw_updated; |
1219 | } |
1220 | |
1221 | @@ -513,21 +521,48 @@ static void update_sch_tt(struct usb_device *udev, |
1222 | list_del(&sch_ep->tt_endpoint); |
1223 | } |
1224 | |
1225 | +static int load_ep_bw(struct usb_device *udev, struct mu3h_sch_bw_info *sch_bw, |
1226 | + struct mu3h_sch_ep_info *sch_ep, bool loaded) |
1227 | +{ |
1228 | + if (sch_ep->sch_tt) |
1229 | + update_sch_tt(udev, sch_ep, loaded); |
1230 | + |
1231 | + /* update bus bandwidth info */ |
1232 | + update_bus_bw(sch_bw, sch_ep, loaded); |
1233 | + sch_ep->allocated = loaded; |
1234 | + |
1235 | + return 0; |
1236 | +} |
1237 | + |
1238 | +static u32 get_esit_boundary(struct mu3h_sch_ep_info *sch_ep) |
1239 | +{ |
1240 | + u32 boundary = sch_ep->esit; |
1241 | + |
1242 | + if (sch_ep->sch_tt) { /* LS/FS with TT */ |
1243 | + /* |
1244 | + * tune for CS, normally esit >= 8 for FS/LS, |
1245 | + * not add one for other types to avoid access array |
1246 | + * out of boundary |
1247 | + */ |
1248 | + if (sch_ep->ep_type == ISOC_OUT_EP && boundary > 1) |
1249 | + boundary--; |
1250 | + } |
1251 | + |
1252 | + return boundary; |
1253 | +} |
1254 | + |
1255 | static int check_sch_bw(struct usb_device *udev, |
1256 | struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep) |
1257 | { |
1258 | u32 offset; |
1259 | - u32 esit; |
1260 | u32 min_bw; |
1261 | u32 min_index; |
1262 | u32 worst_bw; |
1263 | u32 bw_boundary; |
1264 | + u32 esit_boundary; |
1265 | u32 min_num_budget; |
1266 | u32 min_cs_count; |
1267 | - bool tt_offset_ok = false; |
1268 | - int ret; |
1269 | - |
1270 | - esit = sch_ep->esit; |
1271 | + int ret = 0; |
1272 | |
1273 | /* |
1274 | * Search through all possible schedule microframes. |
1275 | @@ -537,16 +572,15 @@ static int check_sch_bw(struct usb_device *udev, |
1276 | min_index = 0; |
1277 | min_cs_count = sch_ep->cs_count; |
1278 | min_num_budget = sch_ep->num_budget_microframes; |
1279 | - for (offset = 0; offset < esit; offset++) { |
1280 | - if (is_fs_or_ls(udev->speed)) { |
1281 | + esit_boundary = get_esit_boundary(sch_ep); |
1282 | + for (offset = 0; offset < sch_ep->esit; offset++) { |
1283 | + if (sch_ep->sch_tt) { |
1284 | ret = check_sch_tt(udev, sch_ep, offset); |
1285 | if (ret) |
1286 | continue; |
1287 | - else |
1288 | - tt_offset_ok = true; |
1289 | } |
1290 | |
1291 | - if ((offset + sch_ep->num_budget_microframes) > sch_ep->esit) |
1292 | + if ((offset + sch_ep->num_budget_microframes) > esit_boundary) |
1293 | break; |
1294 | |
1295 | worst_bw = get_max_bw(sch_bw, sch_ep, offset); |
1296 | @@ -569,35 +603,21 @@ static int check_sch_bw(struct usb_device *udev, |
1297 | |
1298 | /* check bandwidth */ |
1299 | if (min_bw > bw_boundary) |
1300 | - return -ERANGE; |
1301 | + return ret ? ret : -ESCH_BW_OVERFLOW; |
1302 | |
1303 | sch_ep->offset = min_index; |
1304 | sch_ep->cs_count = min_cs_count; |
1305 | sch_ep->num_budget_microframes = min_num_budget; |
1306 | |
1307 | - if (is_fs_or_ls(udev->speed)) { |
1308 | - /* all offset for tt is not ok*/ |
1309 | - if (!tt_offset_ok) |
1310 | - return -ERANGE; |
1311 | - |
1312 | - update_sch_tt(udev, sch_ep, 1); |
1313 | - } |
1314 | - |
1315 | - /* update bus bandwidth info */ |
1316 | - update_bus_bw(sch_bw, sch_ep, 1); |
1317 | - |
1318 | - return 0; |
1319 | + return load_ep_bw(udev, sch_bw, sch_ep, true); |
1320 | } |
1321 | |
1322 | static void destroy_sch_ep(struct usb_device *udev, |
1323 | struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep) |
1324 | { |
1325 | /* only release ep bw check passed by check_sch_bw() */ |
1326 | - if (sch_ep->allocated) { |
1327 | - update_bus_bw(sch_bw, sch_ep, 0); |
1328 | - if (sch_ep->sch_tt) |
1329 | - update_sch_tt(udev, sch_ep, 0); |
1330 | - } |
1331 | + if (sch_ep->allocated) |
1332 | + load_ep_bw(udev, sch_bw, sch_ep, false); |
1333 | |
1334 | if (sch_ep->sch_tt) |
1335 | drop_tt(udev); |
1336 | @@ -760,7 +780,8 @@ int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) |
1337 | |
1338 | ret = check_sch_bw(udev, sch_bw, sch_ep); |
1339 | if (ret) { |
1340 | - xhci_err(xhci, "Not enough bandwidth!\n"); |
1341 | + xhci_err(xhci, "Not enough bandwidth! (%s)\n", |
1342 | + sch_error_string(-ret)); |
1343 | return -ENOSPC; |
1344 | } |
1345 | } |
1346 | diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h |
1347 | index 985e7a19f6f6c..2f702342de666 100644 |
1348 | --- a/drivers/usb/host/xhci-mtk.h |
1349 | +++ b/drivers/usb/host/xhci-mtk.h |
1350 | @@ -20,14 +20,12 @@ |
1351 | #define XHCI_MTK_MAX_ESIT 64 |
1352 | |
1353 | /** |
1354 | - * @ss_bit_map: used to avoid start split microframes overlay |
1355 | * @fs_bus_bw: array to keep track of bandwidth already used for FS |
1356 | * @ep_list: Endpoints using this TT |
1357 | * @usb_tt: usb TT related |
1358 | * @tt_port: TT port number |
1359 | */ |
1360 | struct mu3h_sch_tt { |
1361 | - DECLARE_BITMAP(ss_bit_map, XHCI_MTK_MAX_ESIT); |
1362 | u32 fs_bus_bw[XHCI_MTK_MAX_ESIT]; |
1363 | struct list_head ep_list; |
1364 | struct usb_tt *usb_tt; |
1365 | diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c |
1366 | index cbe8ad3cd61fd..14aa8500221b8 100644 |
1367 | --- a/drivers/usb/serial/option.c |
1368 | +++ b/drivers/usb/serial/option.c |
1369 | @@ -256,6 +256,7 @@ static void option_instat_callback(struct urb *urb); |
1370 | #define QUECTEL_PRODUCT_EM060K 0x030b |
1371 | #define QUECTEL_PRODUCT_EM12 0x0512 |
1372 | #define QUECTEL_PRODUCT_RM500Q 0x0800 |
1373 | +#define QUECTEL_PRODUCT_RM520N 0x0801 |
1374 | #define QUECTEL_PRODUCT_EC200S_CN 0x6002 |
1375 | #define QUECTEL_PRODUCT_EC200T 0x6026 |
1376 | #define QUECTEL_PRODUCT_RM500K 0x7001 |
1377 | @@ -1138,6 +1139,8 @@ static const struct usb_device_id option_ids[] = { |
1378 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG95, 0xff, 0xff, 0xff), |
1379 | .driver_info = NUMEP2 }, |
1380 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG95, 0xff, 0, 0) }, |
1381 | + { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, 0x0203, 0xff), /* BG95-M3 */ |
1382 | + .driver_info = ZLP }, |
1383 | { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96), |
1384 | .driver_info = RSVD(4) }, |
1385 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff), |
1386 | @@ -1159,6 +1162,9 @@ static const struct usb_device_id option_ids[] = { |
1387 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) }, |
1388 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x10), |
1389 | .driver_info = ZLP }, |
1390 | + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0xff, 0x30) }, |
1391 | + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0, 0x40) }, |
1392 | + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0, 0) }, |
1393 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) }, |
1394 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) }, |
1395 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500K, 0xff, 0x00, 0x00) }, |
1396 | diff --git a/drivers/video/fbdev/pxa3xx-gcu.c b/drivers/video/fbdev/pxa3xx-gcu.c |
1397 | index 7c4694d70dac1..15162b37f302f 100644 |
1398 | --- a/drivers/video/fbdev/pxa3xx-gcu.c |
1399 | +++ b/drivers/video/fbdev/pxa3xx-gcu.c |
1400 | @@ -382,7 +382,7 @@ pxa3xx_gcu_write(struct file *file, const char *buff, |
1401 | struct pxa3xx_gcu_batch *buffer; |
1402 | struct pxa3xx_gcu_priv *priv = to_pxa3xx_gcu_priv(file); |
1403 | |
1404 | - int words = count / 4; |
1405 | + size_t words = count / 4; |
1406 | |
1407 | /* Does not need to be atomic. There's a lock in user space, |
1408 | * but anyhow, this is just for statistics. */ |
1409 | diff --git a/fs/afs/misc.c b/fs/afs/misc.c |
1410 | index 5334f1bd2bca7..5171d6d990315 100644 |
1411 | --- a/fs/afs/misc.c |
1412 | +++ b/fs/afs/misc.c |
1413 | @@ -69,6 +69,7 @@ int afs_abort_to_error(u32 abort_code) |
1414 | /* Unified AFS error table */ |
1415 | case UAEPERM: return -EPERM; |
1416 | case UAENOENT: return -ENOENT; |
1417 | + case UAEAGAIN: return -EAGAIN; |
1418 | case UAEACCES: return -EACCES; |
1419 | case UAEBUSY: return -EBUSY; |
1420 | case UAEEXIST: return -EEXIST; |
1421 | diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c |
1422 | index 86bdebd2ece65..f8127edb89730 100644 |
1423 | --- a/fs/cifs/connect.c |
1424 | +++ b/fs/cifs/connect.c |
1425 | @@ -791,9 +791,6 @@ cifs_readv_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg) |
1426 | int length = 0; |
1427 | int total_read; |
1428 | |
1429 | - smb_msg->msg_control = NULL; |
1430 | - smb_msg->msg_controllen = 0; |
1431 | - |
1432 | for (total_read = 0; msg_data_left(smb_msg); total_read += length) { |
1433 | try_to_freeze(); |
1434 | |
1435 | @@ -844,7 +841,7 @@ int |
1436 | cifs_read_from_socket(struct TCP_Server_Info *server, char *buf, |
1437 | unsigned int to_read) |
1438 | { |
1439 | - struct msghdr smb_msg; |
1440 | + struct msghdr smb_msg = {}; |
1441 | struct kvec iov = {.iov_base = buf, .iov_len = to_read}; |
1442 | iov_iter_kvec(&smb_msg.msg_iter, READ, &iov, 1, to_read); |
1443 | |
1444 | @@ -855,7 +852,7 @@ int |
1445 | cifs_read_page_from_socket(struct TCP_Server_Info *server, struct page *page, |
1446 | unsigned int page_offset, unsigned int to_read) |
1447 | { |
1448 | - struct msghdr smb_msg; |
1449 | + struct msghdr smb_msg = {}; |
1450 | struct bio_vec bv = { |
1451 | .bv_page = page, .bv_len = to_read, .bv_offset = page_offset}; |
1452 | iov_iter_bvec(&smb_msg.msg_iter, READ, &bv, 1, to_read); |
1453 | diff --git a/fs/cifs/file.c b/fs/cifs/file.c |
1454 | index 03c85beecec10..eb61cecf42d66 100644 |
1455 | --- a/fs/cifs/file.c |
1456 | +++ b/fs/cifs/file.c |
1457 | @@ -3194,6 +3194,9 @@ static ssize_t __cifs_writev( |
1458 | |
1459 | ssize_t cifs_direct_writev(struct kiocb *iocb, struct iov_iter *from) |
1460 | { |
1461 | + struct file *file = iocb->ki_filp; |
1462 | + |
1463 | + cifs_revalidate_mapping(file->f_inode); |
1464 | return __cifs_writev(iocb, from, true); |
1465 | } |
1466 | |
1467 | diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c |
1468 | index 61e7df4d9cb11..b98ae69edb8fe 100644 |
1469 | --- a/fs/cifs/transport.c |
1470 | +++ b/fs/cifs/transport.c |
1471 | @@ -209,10 +209,6 @@ smb_send_kvec(struct TCP_Server_Info *server, struct msghdr *smb_msg, |
1472 | |
1473 | *sent = 0; |
1474 | |
1475 | - smb_msg->msg_name = (struct sockaddr *) &server->dstaddr; |
1476 | - smb_msg->msg_namelen = sizeof(struct sockaddr); |
1477 | - smb_msg->msg_control = NULL; |
1478 | - smb_msg->msg_controllen = 0; |
1479 | if (server->noblocksnd) |
1480 | smb_msg->msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; |
1481 | else |
1482 | @@ -324,7 +320,7 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, |
1483 | sigset_t mask, oldmask; |
1484 | size_t total_len = 0, sent, size; |
1485 | struct socket *ssocket = server->ssocket; |
1486 | - struct msghdr smb_msg; |
1487 | + struct msghdr smb_msg = {}; |
1488 | int val = 1; |
1489 | __be32 rfc1002_marker; |
1490 | |
1491 | diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c |
1492 | index d5e649e578cb1..ace8d6145253f 100644 |
1493 | --- a/fs/ext4/extents.c |
1494 | +++ b/fs/ext4/extents.c |
1495 | @@ -500,6 +500,10 @@ static int __ext4_ext_check(const char *function, unsigned int line, |
1496 | error_msg = "invalid eh_entries"; |
1497 | goto corrupted; |
1498 | } |
1499 | + if (unlikely((eh->eh_entries == 0) && (depth > 0))) { |
1500 | + error_msg = "eh_entries is 0 but eh_depth is > 0"; |
1501 | + goto corrupted; |
1502 | + } |
1503 | if (!ext4_valid_extent_entries(inode, eh, lblk, &pblk, depth)) { |
1504 | error_msg = "invalid extent entries"; |
1505 | goto corrupted; |
1506 | diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c |
1507 | index 83846cc814850..cbde5a096c7bf 100644 |
1508 | --- a/fs/ext4/ialloc.c |
1509 | +++ b/fs/ext4/ialloc.c |
1510 | @@ -500,7 +500,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent, |
1511 | goto fallback; |
1512 | } |
1513 | |
1514 | - max_dirs = ndirs / ngroups + inodes_per_group / 16; |
1515 | + max_dirs = ndirs / ngroups + inodes_per_group*flex_size / 16; |
1516 | min_inodes = avefreei - inodes_per_group*flex_size / 4; |
1517 | if (min_inodes < 1) |
1518 | min_inodes = 1; |
1519 | diff --git a/fs/nfs/super.c b/fs/nfs/super.c |
1520 | index a84df7d634032..ecc7277b3eda4 100644 |
1521 | --- a/fs/nfs/super.c |
1522 | +++ b/fs/nfs/super.c |
1523 | @@ -2375,22 +2375,31 @@ void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info) |
1524 | if (data && data->bsize) |
1525 | sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits); |
1526 | |
1527 | - if (server->nfs_client->rpc_ops->version != 2) { |
1528 | - /* The VFS shouldn't apply the umask to mode bits. We will do |
1529 | - * so ourselves when necessary. |
1530 | + switch (server->nfs_client->rpc_ops->version) { |
1531 | + case 2: |
1532 | + sb->s_time_gran = 1000; |
1533 | + sb->s_time_min = 0; |
1534 | + sb->s_time_max = U32_MAX; |
1535 | + break; |
1536 | + case 3: |
1537 | + /* |
1538 | + * The VFS shouldn't apply the umask to mode bits. |
1539 | + * We will do so ourselves when necessary. |
1540 | */ |
1541 | sb->s_flags |= SB_POSIXACL; |
1542 | sb->s_time_gran = 1; |
1543 | - sb->s_export_op = &nfs_export_ops; |
1544 | - } else |
1545 | - sb->s_time_gran = 1000; |
1546 | - |
1547 | - if (server->nfs_client->rpc_ops->version != 4) { |
1548 | sb->s_time_min = 0; |
1549 | sb->s_time_max = U32_MAX; |
1550 | - } else { |
1551 | + sb->s_export_op = &nfs_export_ops; |
1552 | + break; |
1553 | + case 4: |
1554 | + sb->s_flags |= SB_POSIXACL; |
1555 | + sb->s_time_gran = 1; |
1556 | sb->s_time_min = S64_MIN; |
1557 | sb->s_time_max = S64_MAX; |
1558 | + if (server->caps & NFS_CAP_ATOMIC_OPEN_V1) |
1559 | + sb->s_export_op = &nfs_export_ops; |
1560 | + break; |
1561 | } |
1562 | |
1563 | nfs_initialise_sb(sb); |
1564 | diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c |
1565 | index 436f686a98918..084d39d8856bd 100644 |
1566 | --- a/fs/xfs/libxfs/xfs_alloc.c |
1567 | +++ b/fs/xfs/libxfs/xfs_alloc.c |
1568 | @@ -684,8 +684,10 @@ xfs_alloc_update_counters( |
1569 | |
1570 | xfs_trans_agblocks_delta(tp, len); |
1571 | if (unlikely(be32_to_cpu(agf->agf_freeblks) > |
1572 | - be32_to_cpu(agf->agf_length))) |
1573 | + be32_to_cpu(agf->agf_length))) { |
1574 | + xfs_buf_corruption_error(agbp); |
1575 | return -EFSCORRUPTED; |
1576 | + } |
1577 | |
1578 | xfs_alloc_log_agf(tp, agbp, XFS_AGF_FREEBLKS); |
1579 | return 0; |
1580 | @@ -751,6 +753,7 @@ xfs_alloc_ag_vextent_small( |
1581 | |
1582 | bp = xfs_btree_get_bufs(args->mp, args->tp, args->agno, fbno); |
1583 | if (!bp) { |
1584 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, args->mp); |
1585 | error = -EFSCORRUPTED; |
1586 | goto error; |
1587 | } |
1588 | @@ -1995,24 +1998,32 @@ xfs_alloc_longest_free_extent( |
1589 | return pag->pagf_flcount > 0 || pag->pagf_longest > 0; |
1590 | } |
1591 | |
1592 | +/* |
1593 | + * Compute the minimum length of the AGFL in the given AG. If @pag is NULL, |
1594 | + * return the largest possible minimum length. |
1595 | + */ |
1596 | unsigned int |
1597 | xfs_alloc_min_freelist( |
1598 | struct xfs_mount *mp, |
1599 | struct xfs_perag *pag) |
1600 | { |
1601 | + /* AG btrees have at least 1 level. */ |
1602 | + static const uint8_t fake_levels[XFS_BTNUM_AGF] = {1, 1, 1}; |
1603 | + const uint8_t *levels = pag ? pag->pagf_levels : fake_levels; |
1604 | unsigned int min_free; |
1605 | |
1606 | + ASSERT(mp->m_ag_maxlevels > 0); |
1607 | + |
1608 | /* space needed by-bno freespace btree */ |
1609 | - min_free = min_t(unsigned int, pag->pagf_levels[XFS_BTNUM_BNOi] + 1, |
1610 | + min_free = min_t(unsigned int, levels[XFS_BTNUM_BNOi] + 1, |
1611 | mp->m_ag_maxlevels); |
1612 | /* space needed by-size freespace btree */ |
1613 | - min_free += min_t(unsigned int, pag->pagf_levels[XFS_BTNUM_CNTi] + 1, |
1614 | + min_free += min_t(unsigned int, levels[XFS_BTNUM_CNTi] + 1, |
1615 | mp->m_ag_maxlevels); |
1616 | /* space needed reverse mapping used space btree */ |
1617 | if (xfs_sb_version_hasrmapbt(&mp->m_sb)) |
1618 | - min_free += min_t(unsigned int, |
1619 | - pag->pagf_levels[XFS_BTNUM_RMAPi] + 1, |
1620 | - mp->m_rmap_maxlevels); |
1621 | + min_free += min_t(unsigned int, levels[XFS_BTNUM_RMAPi] + 1, |
1622 | + mp->m_rmap_maxlevels); |
1623 | |
1624 | return min_free; |
1625 | } |
1626 | @@ -2087,8 +2098,10 @@ xfs_free_agfl_block( |
1627 | return error; |
1628 | |
1629 | bp = xfs_btree_get_bufs(tp->t_mountp, tp, agno, agbno); |
1630 | - if (!bp) |
1631 | + if (!bp) { |
1632 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, tp->t_mountp); |
1633 | return -EFSCORRUPTED; |
1634 | + } |
1635 | xfs_trans_binval(tp, bp); |
1636 | |
1637 | return 0; |
1638 | diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c |
1639 | index de33efc9b4f94..0c23127347aca 100644 |
1640 | --- a/fs/xfs/libxfs/xfs_attr_leaf.c |
1641 | +++ b/fs/xfs/libxfs/xfs_attr_leaf.c |
1642 | @@ -2287,8 +2287,10 @@ xfs_attr3_leaf_lookup_int( |
1643 | leaf = bp->b_addr; |
1644 | xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf); |
1645 | entries = xfs_attr3_leaf_entryp(leaf); |
1646 | - if (ichdr.count >= args->geo->blksize / 8) |
1647 | + if (ichdr.count >= args->geo->blksize / 8) { |
1648 | + xfs_buf_corruption_error(bp); |
1649 | return -EFSCORRUPTED; |
1650 | + } |
1651 | |
1652 | /* |
1653 | * Binary search. (note: small blocks will skip this loop) |
1654 | @@ -2304,10 +2306,14 @@ xfs_attr3_leaf_lookup_int( |
1655 | else |
1656 | break; |
1657 | } |
1658 | - if (!(probe >= 0 && (!ichdr.count || probe < ichdr.count))) |
1659 | + if (!(probe >= 0 && (!ichdr.count || probe < ichdr.count))) { |
1660 | + xfs_buf_corruption_error(bp); |
1661 | return -EFSCORRUPTED; |
1662 | - if (!(span <= 4 || be32_to_cpu(entry->hashval) == hashval)) |
1663 | + } |
1664 | + if (!(span <= 4 || be32_to_cpu(entry->hashval) == hashval)) { |
1665 | + xfs_buf_corruption_error(bp); |
1666 | return -EFSCORRUPTED; |
1667 | + } |
1668 | |
1669 | /* |
1670 | * Since we may have duplicate hashval's, find the first matching |
1671 | diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c |
1672 | index c114d24be6193..8d035842fe51d 100644 |
1673 | --- a/fs/xfs/libxfs/xfs_bmap.c |
1674 | +++ b/fs/xfs/libxfs/xfs_bmap.c |
1675 | @@ -729,6 +729,7 @@ xfs_bmap_extents_to_btree( |
1676 | xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L); |
1677 | abp = xfs_btree_get_bufl(mp, tp, args.fsbno); |
1678 | if (!abp) { |
1679 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); |
1680 | error = -EFSCORRUPTED; |
1681 | goto out_unreserve_dquot; |
1682 | } |
1683 | @@ -1084,6 +1085,7 @@ xfs_bmap_add_attrfork( |
1684 | if (XFS_IFORK_Q(ip)) |
1685 | goto trans_cancel; |
1686 | if (ip->i_d.di_anextents != 0) { |
1687 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); |
1688 | error = -EFSCORRUPTED; |
1689 | goto trans_cancel; |
1690 | } |
1691 | @@ -1374,7 +1376,8 @@ xfs_bmap_last_before( |
1692 | case XFS_DINODE_FMT_EXTENTS: |
1693 | break; |
1694 | default: |
1695 | - return -EIO; |
1696 | + ASSERT(0); |
1697 | + return -EFSCORRUPTED; |
1698 | } |
1699 | |
1700 | if (!(ifp->if_flags & XFS_IFEXTENTS)) { |
1701 | @@ -1474,8 +1477,10 @@ xfs_bmap_last_offset( |
1702 | return 0; |
1703 | |
1704 | if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && |
1705 | - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) |
1706 | - return -EIO; |
1707 | + XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) { |
1708 | + ASSERT(0); |
1709 | + return -EFSCORRUPTED; |
1710 | + } |
1711 | |
1712 | error = xfs_bmap_last_extent(NULL, ip, whichfork, &rec, &is_empty); |
1713 | if (error || is_empty) |
1714 | @@ -5871,8 +5876,9 @@ xfs_bmap_insert_extents( |
1715 | XFS_WANT_CORRUPTED_GOTO(mp, !isnullstartblock(got.br_startblock), |
1716 | del_cursor); |
1717 | |
1718 | - if (stop_fsb >= got.br_startoff + got.br_blockcount) { |
1719 | - error = -EIO; |
1720 | + if (stop_fsb > got.br_startoff) { |
1721 | + ASSERT(0); |
1722 | + error = -EFSCORRUPTED; |
1723 | goto del_cursor; |
1724 | } |
1725 | |
1726 | diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c |
1727 | index 71de937f9e64d..a13a25e922ec6 100644 |
1728 | --- a/fs/xfs/libxfs/xfs_btree.c |
1729 | +++ b/fs/xfs/libxfs/xfs_btree.c |
1730 | @@ -1820,6 +1820,7 @@ xfs_btree_lookup_get_block( |
1731 | |
1732 | out_bad: |
1733 | *blkp = NULL; |
1734 | + xfs_buf_corruption_error(bp); |
1735 | xfs_trans_brelse(cur->bc_tp, bp); |
1736 | return -EFSCORRUPTED; |
1737 | } |
1738 | @@ -1867,8 +1868,10 @@ xfs_btree_lookup( |
1739 | XFS_BTREE_STATS_INC(cur, lookup); |
1740 | |
1741 | /* No such thing as a zero-level tree. */ |
1742 | - if (cur->bc_nlevels == 0) |
1743 | + if (cur->bc_nlevels == 0) { |
1744 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, cur->bc_mp); |
1745 | return -EFSCORRUPTED; |
1746 | + } |
1747 | |
1748 | block = NULL; |
1749 | keyno = 0; |
1750 | diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c |
1751 | index 4fd1223c1bd5d..1e2dc65adeb85 100644 |
1752 | --- a/fs/xfs/libxfs/xfs_da_btree.c |
1753 | +++ b/fs/xfs/libxfs/xfs_da_btree.c |
1754 | @@ -504,6 +504,7 @@ xfs_da3_split( |
1755 | node = oldblk->bp->b_addr; |
1756 | if (node->hdr.info.forw) { |
1757 | if (be32_to_cpu(node->hdr.info.forw) != addblk->blkno) { |
1758 | + xfs_buf_corruption_error(oldblk->bp); |
1759 | error = -EFSCORRUPTED; |
1760 | goto out; |
1761 | } |
1762 | @@ -516,6 +517,7 @@ xfs_da3_split( |
1763 | node = oldblk->bp->b_addr; |
1764 | if (node->hdr.info.back) { |
1765 | if (be32_to_cpu(node->hdr.info.back) != addblk->blkno) { |
1766 | + xfs_buf_corruption_error(oldblk->bp); |
1767 | error = -EFSCORRUPTED; |
1768 | goto out; |
1769 | } |
1770 | @@ -1541,8 +1543,10 @@ xfs_da3_node_lookup_int( |
1771 | break; |
1772 | } |
1773 | |
1774 | - if (magic != XFS_DA_NODE_MAGIC && magic != XFS_DA3_NODE_MAGIC) |
1775 | + if (magic != XFS_DA_NODE_MAGIC && magic != XFS_DA3_NODE_MAGIC) { |
1776 | + xfs_buf_corruption_error(blk->bp); |
1777 | return -EFSCORRUPTED; |
1778 | + } |
1779 | |
1780 | blk->magic = XFS_DA_NODE_MAGIC; |
1781 | |
1782 | @@ -1554,15 +1558,18 @@ xfs_da3_node_lookup_int( |
1783 | btree = dp->d_ops->node_tree_p(node); |
1784 | |
1785 | /* Tree taller than we can handle; bail out! */ |
1786 | - if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH) |
1787 | + if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH) { |
1788 | + xfs_buf_corruption_error(blk->bp); |
1789 | return -EFSCORRUPTED; |
1790 | + } |
1791 | |
1792 | /* Check the level from the root. */ |
1793 | if (blkno == args->geo->leafblk) |
1794 | expected_level = nodehdr.level - 1; |
1795 | - else if (expected_level != nodehdr.level) |
1796 | + else if (expected_level != nodehdr.level) { |
1797 | + xfs_buf_corruption_error(blk->bp); |
1798 | return -EFSCORRUPTED; |
1799 | - else |
1800 | + } else |
1801 | expected_level--; |
1802 | |
1803 | max = nodehdr.count; |
1804 | @@ -1612,12 +1619,17 @@ xfs_da3_node_lookup_int( |
1805 | } |
1806 | |
1807 | /* We can't point back to the root. */ |
1808 | - if (blkno == args->geo->leafblk) |
1809 | + if (blkno == args->geo->leafblk) { |
1810 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, |
1811 | + dp->i_mount); |
1812 | return -EFSCORRUPTED; |
1813 | + } |
1814 | } |
1815 | |
1816 | - if (expected_level != 0) |
1817 | + if (expected_level != 0) { |
1818 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, dp->i_mount); |
1819 | return -EFSCORRUPTED; |
1820 | + } |
1821 | |
1822 | /* |
1823 | * A leaf block that ends in the hashval that we are interested in |
1824 | diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c |
1825 | index 867c5dee07518..452d04ae10ceb 100644 |
1826 | --- a/fs/xfs/libxfs/xfs_dir2.c |
1827 | +++ b/fs/xfs/libxfs/xfs_dir2.c |
1828 | @@ -600,8 +600,10 @@ xfs_dir2_isblock( |
1829 | if ((rval = xfs_bmap_last_offset(args->dp, &last, XFS_DATA_FORK))) |
1830 | return rval; |
1831 | rval = XFS_FSB_TO_B(args->dp->i_mount, last) == args->geo->blksize; |
1832 | - if (rval != 0 && args->dp->i_d.di_size != args->geo->blksize) |
1833 | + if (rval != 0 && args->dp->i_d.di_size != args->geo->blksize) { |
1834 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, args->dp->i_mount); |
1835 | return -EFSCORRUPTED; |
1836 | + } |
1837 | *vp = rval; |
1838 | return 0; |
1839 | } |
1840 | diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c |
1841 | index a53e4585a2f3a..388b5da122287 100644 |
1842 | --- a/fs/xfs/libxfs/xfs_dir2_leaf.c |
1843 | +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c |
1844 | @@ -1343,8 +1343,10 @@ xfs_dir2_leaf_removename( |
1845 | oldbest = be16_to_cpu(bf[0].length); |
1846 | ltp = xfs_dir2_leaf_tail_p(args->geo, leaf); |
1847 | bestsp = xfs_dir2_leaf_bests_p(ltp); |
1848 | - if (be16_to_cpu(bestsp[db]) != oldbest) |
1849 | + if (be16_to_cpu(bestsp[db]) != oldbest) { |
1850 | + xfs_buf_corruption_error(lbp); |
1851 | return -EFSCORRUPTED; |
1852 | + } |
1853 | /* |
1854 | * Mark the former data entry unused. |
1855 | */ |
1856 | diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c |
1857 | index 99d5b2ed67f2e..35e698fa85fd7 100644 |
1858 | --- a/fs/xfs/libxfs/xfs_dir2_node.c |
1859 | +++ b/fs/xfs/libxfs/xfs_dir2_node.c |
1860 | @@ -374,8 +374,10 @@ xfs_dir2_leaf_to_node( |
1861 | leaf = lbp->b_addr; |
1862 | ltp = xfs_dir2_leaf_tail_p(args->geo, leaf); |
1863 | if (be32_to_cpu(ltp->bestcount) > |
1864 | - (uint)dp->i_d.di_size / args->geo->blksize) |
1865 | + (uint)dp->i_d.di_size / args->geo->blksize) { |
1866 | + xfs_buf_corruption_error(lbp); |
1867 | return -EFSCORRUPTED; |
1868 | + } |
1869 | |
1870 | /* |
1871 | * Copy freespace entries from the leaf block to the new block. |
1872 | @@ -446,8 +448,10 @@ xfs_dir2_leafn_add( |
1873 | * Quick check just to make sure we are not going to index |
1874 | * into other peoples memory |
1875 | */ |
1876 | - if (index < 0) |
1877 | + if (index < 0) { |
1878 | + xfs_buf_corruption_error(bp); |
1879 | return -EFSCORRUPTED; |
1880 | + } |
1881 | |
1882 | /* |
1883 | * If there are already the maximum number of leaf entries in |
1884 | @@ -740,8 +744,10 @@ xfs_dir2_leafn_lookup_for_entry( |
1885 | ents = dp->d_ops->leaf_ents_p(leaf); |
1886 | |
1887 | xfs_dir3_leaf_check(dp, bp); |
1888 | - if (leafhdr.count <= 0) |
1889 | + if (leafhdr.count <= 0) { |
1890 | + xfs_buf_corruption_error(bp); |
1891 | return -EFSCORRUPTED; |
1892 | + } |
1893 | |
1894 | /* |
1895 | * Look up the hash value in the leaf entries. |
1896 | diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c |
1897 | index ae16ca7c422a9..f980c3f3d2f66 100644 |
1898 | --- a/fs/xfs/libxfs/xfs_dir2_sf.c |
1899 | +++ b/fs/xfs/libxfs/xfs_dir2_sf.c |
1900 | @@ -944,6 +944,27 @@ xfs_dir2_sf_removename( |
1901 | return 0; |
1902 | } |
1903 | |
1904 | +/* |
1905 | + * Check whether the sf dir replace operation need more blocks. |
1906 | + */ |
1907 | +static bool |
1908 | +xfs_dir2_sf_replace_needblock( |
1909 | + struct xfs_inode *dp, |
1910 | + xfs_ino_t inum) |
1911 | +{ |
1912 | + int newsize; |
1913 | + struct xfs_dir2_sf_hdr *sfp; |
1914 | + |
1915 | + if (dp->i_d.di_format != XFS_DINODE_FMT_LOCAL) |
1916 | + return false; |
1917 | + |
1918 | + sfp = (struct xfs_dir2_sf_hdr *)dp->i_df.if_u1.if_data; |
1919 | + newsize = dp->i_df.if_bytes + (sfp->count + 1) * XFS_INO64_DIFF; |
1920 | + |
1921 | + return inum > XFS_DIR2_MAX_SHORT_INUM && |
1922 | + sfp->i8count == 0 && newsize > XFS_IFORK_DSIZE(dp); |
1923 | +} |
1924 | + |
1925 | /* |
1926 | * Replace the inode number of an entry in a shortform directory. |
1927 | */ |
1928 | @@ -980,17 +1001,14 @@ xfs_dir2_sf_replace( |
1929 | */ |
1930 | if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && sfp->i8count == 0) { |
1931 | int error; /* error return value */ |
1932 | - int newsize; /* new inode size */ |
1933 | |
1934 | - newsize = dp->i_df.if_bytes + (sfp->count + 1) * XFS_INO64_DIFF; |
1935 | /* |
1936 | * Won't fit as shortform, convert to block then do replace. |
1937 | */ |
1938 | - if (newsize > XFS_IFORK_DSIZE(dp)) { |
1939 | + if (xfs_dir2_sf_replace_needblock(dp, args->inumber)) { |
1940 | error = xfs_dir2_sf_to_block(args); |
1941 | - if (error) { |
1942 | + if (error) |
1943 | return error; |
1944 | - } |
1945 | return xfs_dir2_block_replace(args); |
1946 | } |
1947 | /* |
1948 | diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c |
1949 | index 443cf33f66668..c3e0c2f61be4d 100644 |
1950 | --- a/fs/xfs/libxfs/xfs_ialloc.c |
1951 | +++ b/fs/xfs/libxfs/xfs_ialloc.c |
1952 | @@ -2854,3 +2854,67 @@ xfs_ialloc_setup_geometry( |
1953 | else |
1954 | igeo->ialloc_align = 0; |
1955 | } |
1956 | + |
1957 | +/* Compute the location of the root directory inode that is laid out by mkfs. */ |
1958 | +xfs_ino_t |
1959 | +xfs_ialloc_calc_rootino( |
1960 | + struct xfs_mount *mp, |
1961 | + int sunit) |
1962 | +{ |
1963 | + struct xfs_ino_geometry *igeo = M_IGEO(mp); |
1964 | + xfs_agblock_t first_bno; |
1965 | + |
1966 | + /* |
1967 | + * Pre-calculate the geometry of AG 0. We know what it looks like |
1968 | + * because libxfs knows how to create allocation groups now. |
1969 | + * |
1970 | + * first_bno is the first block in which mkfs could possibly have |
1971 | + * allocated the root directory inode, once we factor in the metadata |
1972 | + * that mkfs formats before it. Namely, the four AG headers... |
1973 | + */ |
1974 | + first_bno = howmany(4 * mp->m_sb.sb_sectsize, mp->m_sb.sb_blocksize); |
1975 | + |
1976 | + /* ...the two free space btree roots... */ |
1977 | + first_bno += 2; |
1978 | + |
1979 | + /* ...the inode btree root... */ |
1980 | + first_bno += 1; |
1981 | + |
1982 | + /* ...the initial AGFL... */ |
1983 | + first_bno += xfs_alloc_min_freelist(mp, NULL); |
1984 | + |
1985 | + /* ...the free inode btree root... */ |
1986 | + if (xfs_sb_version_hasfinobt(&mp->m_sb)) |
1987 | + first_bno++; |
1988 | + |
1989 | + /* ...the reverse mapping btree root... */ |
1990 | + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) |
1991 | + first_bno++; |
1992 | + |
1993 | + /* ...the reference count btree... */ |
1994 | + if (xfs_sb_version_hasreflink(&mp->m_sb)) |
1995 | + first_bno++; |
1996 | + |
1997 | + /* |
1998 | + * ...and the log, if it is allocated in the first allocation group. |
1999 | + * |
2000 | + * This can happen with filesystems that only have a single |
2001 | + * allocation group, or very odd geometries created by old mkfs |
2002 | + * versions on very small filesystems. |
2003 | + */ |
2004 | + if (mp->m_sb.sb_logstart && |
2005 | + XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart) == 0) |
2006 | + first_bno += mp->m_sb.sb_logblocks; |
2007 | + |
2008 | + /* |
2009 | + * Now round first_bno up to whatever allocation alignment is given |
2010 | + * by the filesystem or was passed in. |
2011 | + */ |
2012 | + if (xfs_sb_version_hasdalign(&mp->m_sb) && igeo->ialloc_align > 0) |
2013 | + first_bno = roundup(first_bno, sunit); |
2014 | + else if (xfs_sb_version_hasalign(&mp->m_sb) && |
2015 | + mp->m_sb.sb_inoalignmt > 1) |
2016 | + first_bno = roundup(first_bno, mp->m_sb.sb_inoalignmt); |
2017 | + |
2018 | + return XFS_AGINO_TO_INO(mp, 0, XFS_AGB_TO_AGINO(mp, first_bno)); |
2019 | +} |
2020 | diff --git a/fs/xfs/libxfs/xfs_ialloc.h b/fs/xfs/libxfs/xfs_ialloc.h |
2021 | index 323592d563d52..72b3468b97b15 100644 |
2022 | --- a/fs/xfs/libxfs/xfs_ialloc.h |
2023 | +++ b/fs/xfs/libxfs/xfs_ialloc.h |
2024 | @@ -152,5 +152,6 @@ int xfs_inobt_insert_rec(struct xfs_btree_cur *cur, uint16_t holemask, |
2025 | |
2026 | int xfs_ialloc_cluster_alignment(struct xfs_mount *mp); |
2027 | void xfs_ialloc_setup_geometry(struct xfs_mount *mp); |
2028 | +xfs_ino_t xfs_ialloc_calc_rootino(struct xfs_mount *mp, int sunit); |
2029 | |
2030 | #endif /* __XFS_IALLOC_H__ */ |
2031 | diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c |
2032 | index 8fdd0424070e0..15d6f947620ff 100644 |
2033 | --- a/fs/xfs/libxfs/xfs_inode_fork.c |
2034 | +++ b/fs/xfs/libxfs/xfs_inode_fork.c |
2035 | @@ -75,11 +75,15 @@ xfs_iformat_fork( |
2036 | error = xfs_iformat_btree(ip, dip, XFS_DATA_FORK); |
2037 | break; |
2038 | default: |
2039 | + xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, |
2040 | + dip, sizeof(*dip), __this_address); |
2041 | return -EFSCORRUPTED; |
2042 | } |
2043 | break; |
2044 | |
2045 | default: |
2046 | + xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip, |
2047 | + sizeof(*dip), __this_address); |
2048 | return -EFSCORRUPTED; |
2049 | } |
2050 | if (error) |
2051 | @@ -110,6 +114,8 @@ xfs_iformat_fork( |
2052 | error = xfs_iformat_btree(ip, dip, XFS_ATTR_FORK); |
2053 | break; |
2054 | default: |
2055 | + xfs_inode_verifier_error(ip, error, __func__, dip, |
2056 | + sizeof(*dip), __this_address); |
2057 | error = -EFSCORRUPTED; |
2058 | break; |
2059 | } |
2060 | diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c |
2061 | index 9a7fadb1361cb..78236bd6c64f0 100644 |
2062 | --- a/fs/xfs/libxfs/xfs_refcount.c |
2063 | +++ b/fs/xfs/libxfs/xfs_refcount.c |
2064 | @@ -1591,8 +1591,10 @@ xfs_refcount_recover_extent( |
2065 | struct list_head *debris = priv; |
2066 | struct xfs_refcount_recovery *rr; |
2067 | |
2068 | - if (be32_to_cpu(rec->refc.rc_refcount) != 1) |
2069 | + if (be32_to_cpu(rec->refc.rc_refcount) != 1) { |
2070 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, cur->bc_mp); |
2071 | return -EFSCORRUPTED; |
2072 | + } |
2073 | |
2074 | rr = kmem_alloc(sizeof(struct xfs_refcount_recovery), 0); |
2075 | xfs_refcount_btrec_to_irec(rec, &rr->rr_rrec); |
2076 | diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c |
2077 | index 42085e70c01ac..85f123b3dfcc1 100644 |
2078 | --- a/fs/xfs/libxfs/xfs_rtbitmap.c |
2079 | +++ b/fs/xfs/libxfs/xfs_rtbitmap.c |
2080 | @@ -15,7 +15,7 @@ |
2081 | #include "xfs_bmap.h" |
2082 | #include "xfs_trans.h" |
2083 | #include "xfs_rtalloc.h" |
2084 | - |
2085 | +#include "xfs_error.h" |
2086 | |
2087 | /* |
2088 | * Realtime allocator bitmap functions shared with userspace. |
2089 | @@ -70,8 +70,10 @@ xfs_rtbuf_get( |
2090 | if (error) |
2091 | return error; |
2092 | |
2093 | - if (nmap == 0 || !xfs_bmap_is_real_extent(&map)) |
2094 | + if (nmap == 0 || !xfs_bmap_is_real_extent(&map)) { |
2095 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); |
2096 | return -EFSCORRUPTED; |
2097 | + } |
2098 | |
2099 | ASSERT(map.br_startblock != NULLFSBLOCK); |
2100 | error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, |
2101 | diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c |
2102 | index 96d7071cfa468..3f2292c7835ca 100644 |
2103 | --- a/fs/xfs/xfs_acl.c |
2104 | +++ b/fs/xfs/xfs_acl.c |
2105 | @@ -12,6 +12,7 @@ |
2106 | #include "xfs_inode.h" |
2107 | #include "xfs_attr.h" |
2108 | #include "xfs_trace.h" |
2109 | +#include "xfs_error.h" |
2110 | #include <linux/posix_acl_xattr.h> |
2111 | |
2112 | |
2113 | @@ -23,6 +24,7 @@ |
2114 | |
2115 | STATIC struct posix_acl * |
2116 | xfs_acl_from_disk( |
2117 | + struct xfs_mount *mp, |
2118 | const struct xfs_acl *aclp, |
2119 | int len, |
2120 | int max_entries) |
2121 | @@ -32,11 +34,18 @@ xfs_acl_from_disk( |
2122 | const struct xfs_acl_entry *ace; |
2123 | unsigned int count, i; |
2124 | |
2125 | - if (len < sizeof(*aclp)) |
2126 | + if (len < sizeof(*aclp)) { |
2127 | + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, aclp, |
2128 | + len); |
2129 | return ERR_PTR(-EFSCORRUPTED); |
2130 | + } |
2131 | + |
2132 | count = be32_to_cpu(aclp->acl_cnt); |
2133 | - if (count > max_entries || XFS_ACL_SIZE(count) != len) |
2134 | + if (count > max_entries || XFS_ACL_SIZE(count) != len) { |
2135 | + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, aclp, |
2136 | + len); |
2137 | return ERR_PTR(-EFSCORRUPTED); |
2138 | + } |
2139 | |
2140 | acl = posix_acl_alloc(count, GFP_KERNEL); |
2141 | if (!acl) |
2142 | @@ -145,7 +154,7 @@ xfs_get_acl(struct inode *inode, int type) |
2143 | if (error != -ENOATTR) |
2144 | acl = ERR_PTR(error); |
2145 | } else { |
2146 | - acl = xfs_acl_from_disk(xfs_acl, len, |
2147 | + acl = xfs_acl_from_disk(ip->i_mount, xfs_acl, len, |
2148 | XFS_ACL_MAX_ENTRIES(ip->i_mount)); |
2149 | kmem_free(xfs_acl); |
2150 | } |
2151 | diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c |
2152 | index a640a285cc521..766b1386402a0 100644 |
2153 | --- a/fs/xfs/xfs_attr_inactive.c |
2154 | +++ b/fs/xfs/xfs_attr_inactive.c |
2155 | @@ -22,6 +22,7 @@ |
2156 | #include "xfs_attr_leaf.h" |
2157 | #include "xfs_quota.h" |
2158 | #include "xfs_dir2.h" |
2159 | +#include "xfs_error.h" |
2160 | |
2161 | /* |
2162 | * Look at all the extents for this logical region, |
2163 | @@ -208,8 +209,9 @@ xfs_attr3_node_inactive( |
2164 | * Since this code is recursive (gasp!) we must protect ourselves. |
2165 | */ |
2166 | if (level > XFS_DA_NODE_MAXDEPTH) { |
2167 | + xfs_buf_corruption_error(bp); |
2168 | xfs_trans_brelse(*trans, bp); /* no locks for later trans */ |
2169 | - return -EIO; |
2170 | + return -EFSCORRUPTED; |
2171 | } |
2172 | |
2173 | node = bp->b_addr; |
2174 | @@ -258,8 +260,9 @@ xfs_attr3_node_inactive( |
2175 | error = xfs_attr3_leaf_inactive(trans, dp, child_bp); |
2176 | break; |
2177 | default: |
2178 | - error = -EIO; |
2179 | + xfs_buf_corruption_error(child_bp); |
2180 | xfs_trans_brelse(*trans, child_bp); |
2181 | + error = -EFSCORRUPTED; |
2182 | break; |
2183 | } |
2184 | if (error) |
2185 | @@ -341,7 +344,8 @@ xfs_attr3_root_inactive( |
2186 | error = xfs_attr3_leaf_inactive(trans, dp, bp); |
2187 | break; |
2188 | default: |
2189 | - error = -EIO; |
2190 | + error = -EFSCORRUPTED; |
2191 | + xfs_buf_corruption_error(bp); |
2192 | xfs_trans_brelse(*trans, bp); |
2193 | break; |
2194 | } |
2195 | diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c |
2196 | index 00758fdc2fecf..8b9b500e75e81 100644 |
2197 | --- a/fs/xfs/xfs_attr_list.c |
2198 | +++ b/fs/xfs/xfs_attr_list.c |
2199 | @@ -258,8 +258,10 @@ xfs_attr_node_list_lookup( |
2200 | return 0; |
2201 | |
2202 | /* We can't point back to the root. */ |
2203 | - if (cursor->blkno == 0) |
2204 | + if (cursor->blkno == 0) { |
2205 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); |
2206 | return -EFSCORRUPTED; |
2207 | + } |
2208 | } |
2209 | |
2210 | if (expected_level != 0) |
2211 | @@ -269,6 +271,7 @@ xfs_attr_node_list_lookup( |
2212 | return 0; |
2213 | |
2214 | out_corruptbuf: |
2215 | + xfs_buf_corruption_error(bp); |
2216 | xfs_trans_brelse(tp, bp); |
2217 | return -EFSCORRUPTED; |
2218 | } |
2219 | diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c |
2220 | index 83d24e983d4c2..243e5e0f82a30 100644 |
2221 | --- a/fs/xfs/xfs_bmap_item.c |
2222 | +++ b/fs/xfs/xfs_bmap_item.c |
2223 | @@ -21,7 +21,7 @@ |
2224 | #include "xfs_icache.h" |
2225 | #include "xfs_bmap_btree.h" |
2226 | #include "xfs_trans_space.h" |
2227 | - |
2228 | +#include "xfs_error.h" |
2229 | |
2230 | kmem_zone_t *xfs_bui_zone; |
2231 | kmem_zone_t *xfs_bud_zone; |
2232 | @@ -456,7 +456,7 @@ xfs_bui_recover( |
2233 | if (buip->bui_format.bui_nextents != XFS_BUI_MAX_FAST_EXTENTS) { |
2234 | set_bit(XFS_BUI_RECOVERED, &buip->bui_flags); |
2235 | xfs_bui_release(buip); |
2236 | - return -EIO; |
2237 | + return -EFSCORRUPTED; |
2238 | } |
2239 | |
2240 | /* |
2241 | @@ -490,7 +490,7 @@ xfs_bui_recover( |
2242 | */ |
2243 | set_bit(XFS_BUI_RECOVERED, &buip->bui_flags); |
2244 | xfs_bui_release(buip); |
2245 | - return -EIO; |
2246 | + return -EFSCORRUPTED; |
2247 | } |
2248 | |
2249 | error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, |
2250 | @@ -525,6 +525,7 @@ xfs_bui_recover( |
2251 | type = bui_type; |
2252 | break; |
2253 | default: |
2254 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); |
2255 | error = -EFSCORRUPTED; |
2256 | goto err_inode; |
2257 | } |
2258 | diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c |
2259 | index d6d78e1276254..113bed28bc310 100644 |
2260 | --- a/fs/xfs/xfs_bmap_util.c |
2261 | +++ b/fs/xfs/xfs_bmap_util.c |
2262 | @@ -1167,6 +1167,7 @@ xfs_prepare_shift( |
2263 | struct xfs_inode *ip, |
2264 | loff_t offset) |
2265 | { |
2266 | + struct xfs_mount *mp = ip->i_mount; |
2267 | int error; |
2268 | |
2269 | /* |
2270 | @@ -1179,6 +1180,17 @@ xfs_prepare_shift( |
2271 | return error; |
2272 | } |
2273 | |
2274 | + /* |
2275 | + * Shift operations must stabilize the start block offset boundary along |
2276 | + * with the full range of the operation. If we don't, a COW writeback |
2277 | + * completion could race with an insert, front merge with the start |
2278 | + * extent (after split) during the shift and corrupt the file. Start |
2279 | + * with the block just prior to the start to stabilize the boundary. |
2280 | + */ |
2281 | + offset = round_down(offset, 1 << mp->m_sb.sb_blocklog); |
2282 | + if (offset) |
2283 | + offset -= (1 << mp->m_sb.sb_blocklog); |
2284 | + |
2285 | /* |
2286 | * Writeback and invalidate cache for the remainder of the file as we're |
2287 | * about to shift down every extent from offset to EOF. |
2288 | diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c |
2289 | index d74fbd1e9d3ea..b1452117e4429 100644 |
2290 | --- a/fs/xfs/xfs_buf_item.c |
2291 | +++ b/fs/xfs/xfs_buf_item.c |
2292 | @@ -956,7 +956,7 @@ xfs_buf_item_relse( |
2293 | struct xfs_buf_log_item *bip = bp->b_log_item; |
2294 | |
2295 | trace_xfs_buf_item_relse(bp, _RET_IP_); |
2296 | - ASSERT(!(bip->bli_item.li_flags & XFS_LI_IN_AIL)); |
2297 | + ASSERT(!test_bit(XFS_LI_IN_AIL, &bip->bli_item.li_flags)); |
2298 | |
2299 | bp->b_log_item = NULL; |
2300 | if (list_empty(&bp->b_li_list)) |
2301 | diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c |
2302 | index 3cbf248af51ff..aa50841802703 100644 |
2303 | --- a/fs/xfs/xfs_dquot.c |
2304 | +++ b/fs/xfs/xfs_dquot.c |
2305 | @@ -1125,7 +1125,7 @@ xfs_qm_dqflush( |
2306 | xfs_buf_relse(bp); |
2307 | xfs_dqfunlock(dqp); |
2308 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); |
2309 | - return -EIO; |
2310 | + return -EFSCORRUPTED; |
2311 | } |
2312 | |
2313 | /* This is the only portion of data that needs to persist */ |
2314 | diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c |
2315 | index 849fd4476950a..d8cdb27fe6ed3 100644 |
2316 | --- a/fs/xfs/xfs_error.c |
2317 | +++ b/fs/xfs/xfs_error.c |
2318 | @@ -329,7 +329,7 @@ xfs_corruption_error( |
2319 | const char *tag, |
2320 | int level, |
2321 | struct xfs_mount *mp, |
2322 | - void *buf, |
2323 | + const void *buf, |
2324 | size_t bufsize, |
2325 | const char *filename, |
2326 | int linenum, |
2327 | @@ -341,6 +341,27 @@ xfs_corruption_error( |
2328 | xfs_alert(mp, "Corruption detected. Unmount and run xfs_repair"); |
2329 | } |
2330 | |
2331 | +/* |
2332 | + * Complain about the kinds of metadata corruption that we can't detect from a |
2333 | + * verifier, such as incorrect inter-block relationship data. Does not set |
2334 | + * bp->b_error. |
2335 | + */ |
2336 | +void |
2337 | +xfs_buf_corruption_error( |
2338 | + struct xfs_buf *bp) |
2339 | +{ |
2340 | + struct xfs_mount *mp = bp->b_mount; |
2341 | + |
2342 | + xfs_alert_tag(mp, XFS_PTAG_VERIFIER_ERROR, |
2343 | + "Metadata corruption detected at %pS, %s block 0x%llx", |
2344 | + __return_address, bp->b_ops->name, bp->b_bn); |
2345 | + |
2346 | + xfs_alert(mp, "Unmount and run xfs_repair"); |
2347 | + |
2348 | + if (xfs_error_level >= XFS_ERRLEVEL_HIGH) |
2349 | + xfs_stack_trace(); |
2350 | +} |
2351 | + |
2352 | /* |
2353 | * Warnings specifically for verifier errors. Differentiate CRC vs. invalid |
2354 | * values, and omit the stack trace unless the error level is tuned high. |
2355 | @@ -350,7 +371,7 @@ xfs_buf_verifier_error( |
2356 | struct xfs_buf *bp, |
2357 | int error, |
2358 | const char *name, |
2359 | - void *buf, |
2360 | + const void *buf, |
2361 | size_t bufsz, |
2362 | xfs_failaddr_t failaddr) |
2363 | { |
2364 | @@ -402,7 +423,7 @@ xfs_inode_verifier_error( |
2365 | struct xfs_inode *ip, |
2366 | int error, |
2367 | const char *name, |
2368 | - void *buf, |
2369 | + const void *buf, |
2370 | size_t bufsz, |
2371 | xfs_failaddr_t failaddr) |
2372 | { |
2373 | diff --git a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h |
2374 | index 602aa7d62b66e..c319379f7d1a3 100644 |
2375 | --- a/fs/xfs/xfs_error.h |
2376 | +++ b/fs/xfs/xfs_error.h |
2377 | @@ -12,16 +12,17 @@ extern void xfs_error_report(const char *tag, int level, struct xfs_mount *mp, |
2378 | const char *filename, int linenum, |
2379 | xfs_failaddr_t failaddr); |
2380 | extern void xfs_corruption_error(const char *tag, int level, |
2381 | - struct xfs_mount *mp, void *buf, size_t bufsize, |
2382 | + struct xfs_mount *mp, const void *buf, size_t bufsize, |
2383 | const char *filename, int linenum, |
2384 | xfs_failaddr_t failaddr); |
2385 | +void xfs_buf_corruption_error(struct xfs_buf *bp); |
2386 | extern void xfs_buf_verifier_error(struct xfs_buf *bp, int error, |
2387 | - const char *name, void *buf, size_t bufsz, |
2388 | + const char *name, const void *buf, size_t bufsz, |
2389 | xfs_failaddr_t failaddr); |
2390 | extern void xfs_verifier_error(struct xfs_buf *bp, int error, |
2391 | xfs_failaddr_t failaddr); |
2392 | extern void xfs_inode_verifier_error(struct xfs_inode *ip, int error, |
2393 | - const char *name, void *buf, size_t bufsz, |
2394 | + const char *name, const void *buf, size_t bufsz, |
2395 | xfs_failaddr_t failaddr); |
2396 | |
2397 | #define XFS_ERROR_REPORT(e, lvl, mp) \ |
2398 | diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c |
2399 | index e44efc41a0412..a05a1074e8f81 100644 |
2400 | --- a/fs/xfs/xfs_extfree_item.c |
2401 | +++ b/fs/xfs/xfs_extfree_item.c |
2402 | @@ -21,7 +21,7 @@ |
2403 | #include "xfs_alloc.h" |
2404 | #include "xfs_bmap.h" |
2405 | #include "xfs_trace.h" |
2406 | - |
2407 | +#include "xfs_error.h" |
2408 | |
2409 | kmem_zone_t *xfs_efi_zone; |
2410 | kmem_zone_t *xfs_efd_zone; |
2411 | @@ -228,6 +228,7 @@ xfs_efi_copy_format(xfs_log_iovec_t *buf, xfs_efi_log_format_t *dst_efi_fmt) |
2412 | } |
2413 | return 0; |
2414 | } |
2415 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL); |
2416 | return -EFSCORRUPTED; |
2417 | } |
2418 | |
2419 | @@ -624,7 +625,7 @@ xfs_efi_recover( |
2420 | */ |
2421 | set_bit(XFS_EFI_RECOVERED, &efip->efi_flags); |
2422 | xfs_efi_release(efip); |
2423 | - return -EIO; |
2424 | + return -EFSCORRUPTED; |
2425 | } |
2426 | } |
2427 | |
2428 | diff --git a/fs/xfs/xfs_fsmap.c b/fs/xfs/xfs_fsmap.c |
2429 | index 01c0933a4d10d..79e8af8f4669c 100644 |
2430 | --- a/fs/xfs/xfs_fsmap.c |
2431 | +++ b/fs/xfs/xfs_fsmap.c |
2432 | @@ -146,6 +146,7 @@ xfs_fsmap_owner_from_rmap( |
2433 | dest->fmr_owner = XFS_FMR_OWN_FREE; |
2434 | break; |
2435 | default: |
2436 | + ASSERT(0); |
2437 | return -EFSCORRUPTED; |
2438 | } |
2439 | return 0; |
2440 | diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c |
2441 | index 7a9048c4c2f95..7b72c189cff0b 100644 |
2442 | --- a/fs/xfs/xfs_inode.c |
2443 | +++ b/fs/xfs/xfs_inode.c |
2444 | @@ -2149,8 +2149,10 @@ xfs_iunlink_update_bucket( |
2445 | * passed in because either we're adding or removing ourselves from the |
2446 | * head of the list. |
2447 | */ |
2448 | - if (old_value == new_agino) |
2449 | + if (old_value == new_agino) { |
2450 | + xfs_buf_corruption_error(agibp); |
2451 | return -EFSCORRUPTED; |
2452 | + } |
2453 | |
2454 | agi->agi_unlinked[bucket_index] = cpu_to_be32(new_agino); |
2455 | offset = offsetof(struct xfs_agi, agi_unlinked) + |
2456 | @@ -2213,6 +2215,8 @@ xfs_iunlink_update_inode( |
2457 | /* Make sure the old pointer isn't garbage. */ |
2458 | old_value = be32_to_cpu(dip->di_next_unlinked); |
2459 | if (!xfs_verify_agino_or_null(mp, agno, old_value)) { |
2460 | + xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip, |
2461 | + sizeof(*dip), __this_address); |
2462 | error = -EFSCORRUPTED; |
2463 | goto out; |
2464 | } |
2465 | @@ -2224,8 +2228,11 @@ xfs_iunlink_update_inode( |
2466 | */ |
2467 | *old_next_agino = old_value; |
2468 | if (old_value == next_agino) { |
2469 | - if (next_agino != NULLAGINO) |
2470 | + if (next_agino != NULLAGINO) { |
2471 | + xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, |
2472 | + dip, sizeof(*dip), __this_address); |
2473 | error = -EFSCORRUPTED; |
2474 | + } |
2475 | goto out; |
2476 | } |
2477 | |
2478 | @@ -2276,8 +2283,10 @@ xfs_iunlink( |
2479 | */ |
2480 | next_agino = be32_to_cpu(agi->agi_unlinked[bucket_index]); |
2481 | if (next_agino == agino || |
2482 | - !xfs_verify_agino_or_null(mp, agno, next_agino)) |
2483 | + !xfs_verify_agino_or_null(mp, agno, next_agino)) { |
2484 | + xfs_buf_corruption_error(agibp); |
2485 | return -EFSCORRUPTED; |
2486 | + } |
2487 | |
2488 | if (next_agino != NULLAGINO) { |
2489 | struct xfs_perag *pag; |
2490 | @@ -3215,6 +3224,7 @@ xfs_rename( |
2491 | struct xfs_trans *tp; |
2492 | struct xfs_inode *wip = NULL; /* whiteout inode */ |
2493 | struct xfs_inode *inodes[__XFS_SORT_INODES]; |
2494 | + int i; |
2495 | int num_inodes = __XFS_SORT_INODES; |
2496 | bool new_parent = (src_dp != target_dp); |
2497 | bool src_is_directory = S_ISDIR(VFS_I(src_ip)->i_mode); |
2498 | @@ -3326,6 +3336,30 @@ xfs_rename( |
2499 | } |
2500 | } |
2501 | |
2502 | + /* |
2503 | + * Lock the AGI buffers we need to handle bumping the nlink of the |
2504 | + * whiteout inode off the unlinked list and to handle dropping the |
2505 | + * nlink of the target inode. Per locking order rules, do this in |
2506 | + * increasing AG order and before directory block allocation tries to |
2507 | + * grab AGFs because we grab AGIs before AGFs. |
2508 | + * |
2509 | + * The (vfs) caller must ensure that if src is a directory then |
2510 | + * target_ip is either null or an empty directory. |
2511 | + */ |
2512 | + for (i = 0; i < num_inodes && inodes[i] != NULL; i++) { |
2513 | + if (inodes[i] == wip || |
2514 | + (inodes[i] == target_ip && |
2515 | + (VFS_I(target_ip)->i_nlink == 1 || src_is_directory))) { |
2516 | + struct xfs_buf *bp; |
2517 | + xfs_agnumber_t agno; |
2518 | + |
2519 | + agno = XFS_INO_TO_AGNO(mp, inodes[i]->i_ino); |
2520 | + error = xfs_read_agi(mp, tp, agno, &bp); |
2521 | + if (error) |
2522 | + goto out_trans_cancel; |
2523 | + } |
2524 | + } |
2525 | + |
2526 | /* |
2527 | * Directory entry creation below may acquire the AGF. Remove |
2528 | * the whiteout from the unlinked list first to preserve correct |
2529 | diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c |
2530 | index bb8f076805b9e..726aa3bfd6e84 100644 |
2531 | --- a/fs/xfs/xfs_inode_item.c |
2532 | +++ b/fs/xfs/xfs_inode_item.c |
2533 | @@ -17,6 +17,7 @@ |
2534 | #include "xfs_trans_priv.h" |
2535 | #include "xfs_buf_item.h" |
2536 | #include "xfs_log.h" |
2537 | +#include "xfs_error.h" |
2538 | |
2539 | #include <linux/iversion.h> |
2540 | |
2541 | @@ -828,8 +829,10 @@ xfs_inode_item_format_convert( |
2542 | { |
2543 | struct xfs_inode_log_format_32 *in_f32 = buf->i_addr; |
2544 | |
2545 | - if (buf->i_len != sizeof(*in_f32)) |
2546 | + if (buf->i_len != sizeof(*in_f32)) { |
2547 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL); |
2548 | return -EFSCORRUPTED; |
2549 | + } |
2550 | |
2551 | in_f->ilf_type = in_f32->ilf_type; |
2552 | in_f->ilf_size = in_f32->ilf_size; |
2553 | diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c |
2554 | index 239c9548b1568..b6f85e488d5c1 100644 |
2555 | --- a/fs/xfs/xfs_iomap.c |
2556 | +++ b/fs/xfs/xfs_iomap.c |
2557 | @@ -765,6 +765,11 @@ xfs_iomap_write_unwritten( |
2558 | */ |
2559 | resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0) << 1; |
2560 | |
2561 | + /* Attach dquots so that bmbt splits are accounted correctly. */ |
2562 | + error = xfs_qm_dqattach(ip); |
2563 | + if (error) |
2564 | + return error; |
2565 | + |
2566 | do { |
2567 | /* |
2568 | * Set up a transaction to convert the range of extents |
2569 | @@ -783,6 +788,11 @@ xfs_iomap_write_unwritten( |
2570 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
2571 | xfs_trans_ijoin(tp, ip, 0); |
2572 | |
2573 | + error = xfs_trans_reserve_quota_nblks(tp, ip, resblks, 0, |
2574 | + XFS_QMOPT_RES_REGBLKS); |
2575 | + if (error) |
2576 | + goto error_on_bmapi_transaction; |
2577 | + |
2578 | /* |
2579 | * Modify the unwritten extent state of the buffer. |
2580 | */ |
2581 | @@ -1055,6 +1065,13 @@ xfs_file_iomap_begin( |
2582 | trace_xfs_iomap_alloc(ip, offset, length, XFS_DATA_FORK, &imap); |
2583 | |
2584 | out_finish: |
2585 | + /* |
2586 | + * Writes that span EOF might trigger an IO size update on completion, |
2587 | + * so consider them to be dirty for the purposes of O_DSYNC even if |
2588 | + * there is no other metadata changes pending or have been made here. |
2589 | + */ |
2590 | + if ((flags & IOMAP_WRITE) && offset + length > i_size_read(inode)) |
2591 | + iomap->flags |= IOMAP_F_DIRTY; |
2592 | return xfs_bmbt_to_iomap(ip, iomap, &imap, shared); |
2593 | |
2594 | out_found: |
2595 | diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c |
2596 | index ca8c763902b96..80dd05f8f1afc 100644 |
2597 | --- a/fs/xfs/xfs_iops.c |
2598 | +++ b/fs/xfs/xfs_iops.c |
2599 | @@ -20,6 +20,7 @@ |
2600 | #include "xfs_symlink.h" |
2601 | #include "xfs_dir2.h" |
2602 | #include "xfs_iomap.h" |
2603 | +#include "xfs_error.h" |
2604 | |
2605 | #include <linux/xattr.h> |
2606 | #include <linux/posix_acl.h> |
2607 | @@ -470,17 +471,20 @@ xfs_vn_get_link_inline( |
2608 | struct inode *inode, |
2609 | struct delayed_call *done) |
2610 | { |
2611 | + struct xfs_inode *ip = XFS_I(inode); |
2612 | char *link; |
2613 | |
2614 | - ASSERT(XFS_I(inode)->i_df.if_flags & XFS_IFINLINE); |
2615 | + ASSERT(ip->i_df.if_flags & XFS_IFINLINE); |
2616 | |
2617 | /* |
2618 | * The VFS crashes on a NULL pointer, so return -EFSCORRUPTED if |
2619 | * if_data is junk. |
2620 | */ |
2621 | - link = XFS_I(inode)->i_df.if_u1.if_data; |
2622 | - if (!link) |
2623 | + link = ip->i_df.if_u1.if_data; |
2624 | + if (!link) { |
2625 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, ip->i_mount); |
2626 | return ERR_PTR(-EFSCORRUPTED); |
2627 | + } |
2628 | return link; |
2629 | } |
2630 | |
2631 | diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c |
2632 | index c1a514ffff555..248101876e1ec 100644 |
2633 | --- a/fs/xfs/xfs_log_recover.c |
2634 | +++ b/fs/xfs/xfs_log_recover.c |
2635 | @@ -471,7 +471,7 @@ xlog_find_verify_log_record( |
2636 | xfs_warn(log->l_mp, |
2637 | "Log inconsistent (didn't find previous header)"); |
2638 | ASSERT(0); |
2639 | - error = -EIO; |
2640 | + error = -EFSCORRUPTED; |
2641 | goto out; |
2642 | } |
2643 | |
2644 | @@ -1347,10 +1347,11 @@ xlog_find_tail( |
2645 | error = xlog_rseek_logrec_hdr(log, *head_blk, *head_blk, 1, buffer, |
2646 | &rhead_blk, &rhead, &wrapped); |
2647 | if (error < 0) |
2648 | - return error; |
2649 | + goto done; |
2650 | if (!error) { |
2651 | xfs_warn(log->l_mp, "%s: couldn't find sync record", __func__); |
2652 | - return -EIO; |
2653 | + error = -EFSCORRUPTED; |
2654 | + goto done; |
2655 | } |
2656 | *tail_blk = BLOCK_LSN(be64_to_cpu(rhead->h_tail_lsn)); |
2657 | |
2658 | @@ -3166,7 +3167,7 @@ xlog_recover_inode_pass2( |
2659 | default: |
2660 | xfs_warn(log->l_mp, "%s: Invalid flag", __func__); |
2661 | ASSERT(0); |
2662 | - error = -EIO; |
2663 | + error = -EFSCORRUPTED; |
2664 | goto out_release; |
2665 | } |
2666 | } |
2667 | @@ -3247,12 +3248,12 @@ xlog_recover_dquot_pass2( |
2668 | recddq = item->ri_buf[1].i_addr; |
2669 | if (recddq == NULL) { |
2670 | xfs_alert(log->l_mp, "NULL dquot in %s.", __func__); |
2671 | - return -EIO; |
2672 | + return -EFSCORRUPTED; |
2673 | } |
2674 | if (item->ri_buf[1].i_len < sizeof(xfs_disk_dquot_t)) { |
2675 | xfs_alert(log->l_mp, "dquot too small (%d) in %s.", |
2676 | item->ri_buf[1].i_len, __func__); |
2677 | - return -EIO; |
2678 | + return -EFSCORRUPTED; |
2679 | } |
2680 | |
2681 | /* |
2682 | @@ -3279,7 +3280,7 @@ xlog_recover_dquot_pass2( |
2683 | if (fa) { |
2684 | xfs_alert(mp, "corrupt dquot ID 0x%x in log at %pS", |
2685 | dq_f->qlf_id, fa); |
2686 | - return -EIO; |
2687 | + return -EFSCORRUPTED; |
2688 | } |
2689 | ASSERT(dq_f->qlf_len == 1); |
2690 | |
2691 | @@ -3537,6 +3538,7 @@ xfs_cui_copy_format( |
2692 | memcpy(dst_cui_fmt, src_cui_fmt, len); |
2693 | return 0; |
2694 | } |
2695 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL); |
2696 | return -EFSCORRUPTED; |
2697 | } |
2698 | |
2699 | @@ -3601,8 +3603,10 @@ xlog_recover_cud_pass2( |
2700 | struct xfs_ail *ailp = log->l_ailp; |
2701 | |
2702 | cud_formatp = item->ri_buf[0].i_addr; |
2703 | - if (item->ri_buf[0].i_len != sizeof(struct xfs_cud_log_format)) |
2704 | + if (item->ri_buf[0].i_len != sizeof(struct xfs_cud_log_format)) { |
2705 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, log->l_mp); |
2706 | return -EFSCORRUPTED; |
2707 | + } |
2708 | cui_id = cud_formatp->cud_cui_id; |
2709 | |
2710 | /* |
2711 | @@ -3654,6 +3658,7 @@ xfs_bui_copy_format( |
2712 | memcpy(dst_bui_fmt, src_bui_fmt, len); |
2713 | return 0; |
2714 | } |
2715 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL); |
2716 | return -EFSCORRUPTED; |
2717 | } |
2718 | |
2719 | @@ -3677,8 +3682,10 @@ xlog_recover_bui_pass2( |
2720 | |
2721 | bui_formatp = item->ri_buf[0].i_addr; |
2722 | |
2723 | - if (bui_formatp->bui_nextents != XFS_BUI_MAX_FAST_EXTENTS) |
2724 | + if (bui_formatp->bui_nextents != XFS_BUI_MAX_FAST_EXTENTS) { |
2725 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, log->l_mp); |
2726 | return -EFSCORRUPTED; |
2727 | + } |
2728 | buip = xfs_bui_init(mp); |
2729 | error = xfs_bui_copy_format(&item->ri_buf[0], &buip->bui_format); |
2730 | if (error) { |
2731 | @@ -3720,8 +3727,10 @@ xlog_recover_bud_pass2( |
2732 | struct xfs_ail *ailp = log->l_ailp; |
2733 | |
2734 | bud_formatp = item->ri_buf[0].i_addr; |
2735 | - if (item->ri_buf[0].i_len != sizeof(struct xfs_bud_log_format)) |
2736 | + if (item->ri_buf[0].i_len != sizeof(struct xfs_bud_log_format)) { |
2737 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, log->l_mp); |
2738 | return -EFSCORRUPTED; |
2739 | + } |
2740 | bui_id = bud_formatp->bud_bui_id; |
2741 | |
2742 | /* |
2743 | @@ -4018,7 +4027,7 @@ xlog_recover_commit_pass1( |
2744 | xfs_warn(log->l_mp, "%s: invalid item type (%d)", |
2745 | __func__, ITEM_TYPE(item)); |
2746 | ASSERT(0); |
2747 | - return -EIO; |
2748 | + return -EFSCORRUPTED; |
2749 | } |
2750 | } |
2751 | |
2752 | @@ -4066,7 +4075,7 @@ xlog_recover_commit_pass2( |
2753 | xfs_warn(log->l_mp, "%s: invalid item type (%d)", |
2754 | __func__, ITEM_TYPE(item)); |
2755 | ASSERT(0); |
2756 | - return -EIO; |
2757 | + return -EFSCORRUPTED; |
2758 | } |
2759 | } |
2760 | |
2761 | @@ -4187,7 +4196,7 @@ xlog_recover_add_to_cont_trans( |
2762 | ASSERT(len <= sizeof(struct xfs_trans_header)); |
2763 | if (len > sizeof(struct xfs_trans_header)) { |
2764 | xfs_warn(log->l_mp, "%s: bad header length", __func__); |
2765 | - return -EIO; |
2766 | + return -EFSCORRUPTED; |
2767 | } |
2768 | |
2769 | xlog_recover_add_item(&trans->r_itemq); |
2770 | @@ -4243,13 +4252,13 @@ xlog_recover_add_to_trans( |
2771 | xfs_warn(log->l_mp, "%s: bad header magic number", |
2772 | __func__); |
2773 | ASSERT(0); |
2774 | - return -EIO; |
2775 | + return -EFSCORRUPTED; |
2776 | } |
2777 | |
2778 | if (len > sizeof(struct xfs_trans_header)) { |
2779 | xfs_warn(log->l_mp, "%s: bad header length", __func__); |
2780 | ASSERT(0); |
2781 | - return -EIO; |
2782 | + return -EFSCORRUPTED; |
2783 | } |
2784 | |
2785 | /* |
2786 | @@ -4285,7 +4294,7 @@ xlog_recover_add_to_trans( |
2787 | in_f->ilf_size); |
2788 | ASSERT(0); |
2789 | kmem_free(ptr); |
2790 | - return -EIO; |
2791 | + return -EFSCORRUPTED; |
2792 | } |
2793 | |
2794 | item->ri_total = in_f->ilf_size; |
2795 | @@ -4293,7 +4302,16 @@ xlog_recover_add_to_trans( |
2796 | kmem_zalloc(item->ri_total * sizeof(xfs_log_iovec_t), |
2797 | 0); |
2798 | } |
2799 | - ASSERT(item->ri_total > item->ri_cnt); |
2800 | + |
2801 | + if (item->ri_total <= item->ri_cnt) { |
2802 | + xfs_warn(log->l_mp, |
2803 | + "log item region count (%d) overflowed size (%d)", |
2804 | + item->ri_cnt, item->ri_total); |
2805 | + ASSERT(0); |
2806 | + kmem_free(ptr); |
2807 | + return -EFSCORRUPTED; |
2808 | + } |
2809 | + |
2810 | /* Description region is ri_buf[0] */ |
2811 | item->ri_buf[item->ri_cnt].i_addr = ptr; |
2812 | item->ri_buf[item->ri_cnt].i_len = len; |
2813 | @@ -4380,7 +4398,7 @@ xlog_recovery_process_trans( |
2814 | default: |
2815 | xfs_warn(log->l_mp, "%s: bad flag 0x%x", __func__, flags); |
2816 | ASSERT(0); |
2817 | - error = -EIO; |
2818 | + error = -EFSCORRUPTED; |
2819 | break; |
2820 | } |
2821 | if (error || freeit) |
2822 | @@ -4460,7 +4478,7 @@ xlog_recover_process_ophdr( |
2823 | xfs_warn(log->l_mp, "%s: bad clientid 0x%x", |
2824 | __func__, ohead->oh_clientid); |
2825 | ASSERT(0); |
2826 | - return -EIO; |
2827 | + return -EFSCORRUPTED; |
2828 | } |
2829 | |
2830 | /* |
2831 | @@ -4470,7 +4488,7 @@ xlog_recover_process_ophdr( |
2832 | if (dp + len > end) { |
2833 | xfs_warn(log->l_mp, "%s: bad length 0x%x", __func__, len); |
2834 | WARN_ON(1); |
2835 | - return -EIO; |
2836 | + return -EFSCORRUPTED; |
2837 | } |
2838 | |
2839 | trans = xlog_recover_ophdr_to_trans(rhash, rhead, ohead); |
2840 | @@ -5172,8 +5190,10 @@ xlog_recover_process( |
2841 | * If the filesystem is CRC enabled, this mismatch becomes a |
2842 | * fatal log corruption failure. |
2843 | */ |
2844 | - if (xfs_sb_version_hascrc(&log->l_mp->m_sb)) |
2845 | + if (xfs_sb_version_hascrc(&log->l_mp->m_sb)) { |
2846 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, log->l_mp); |
2847 | return -EFSCORRUPTED; |
2848 | + } |
2849 | } |
2850 | |
2851 | xlog_unpack_data(rhead, dp, log); |
2852 | @@ -5200,7 +5220,7 @@ xlog_valid_rec_header( |
2853 | (be32_to_cpu(rhead->h_version) & (~XLOG_VERSION_OKBITS))))) { |
2854 | xfs_warn(log->l_mp, "%s: unrecognised log version (%d).", |
2855 | __func__, be32_to_cpu(rhead->h_version)); |
2856 | - return -EIO; |
2857 | + return -EFSCORRUPTED; |
2858 | } |
2859 | |
2860 | /* LR body must have data or it wouldn't have been written */ |
2861 | @@ -5296,8 +5316,12 @@ xlog_do_recovery_pass( |
2862 | "invalid iclog size (%d bytes), using lsunit (%d bytes)", |
2863 | h_size, log->l_mp->m_logbsize); |
2864 | h_size = log->l_mp->m_logbsize; |
2865 | - } else |
2866 | - return -EFSCORRUPTED; |
2867 | + } else { |
2868 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, |
2869 | + log->l_mp); |
2870 | + error = -EFSCORRUPTED; |
2871 | + goto bread_err1; |
2872 | + } |
2873 | } |
2874 | |
2875 | if ((be32_to_cpu(rhead->h_version) & XLOG_VERSION_2) && |
2876 | diff --git a/fs/xfs/xfs_message.c b/fs/xfs/xfs_message.c |
2877 | index 9804efe525a93..c57e8ad397125 100644 |
2878 | --- a/fs/xfs/xfs_message.c |
2879 | +++ b/fs/xfs/xfs_message.c |
2880 | @@ -105,7 +105,7 @@ assfail(char *expr, char *file, int line) |
2881 | } |
2882 | |
2883 | void |
2884 | -xfs_hex_dump(void *p, int length) |
2885 | +xfs_hex_dump(const void *p, int length) |
2886 | { |
2887 | print_hex_dump(KERN_ALERT, "", DUMP_PREFIX_OFFSET, 16, 1, p, length, 1); |
2888 | } |
2889 | diff --git a/fs/xfs/xfs_message.h b/fs/xfs/xfs_message.h |
2890 | index 34447dca97d13..7f040b04b7393 100644 |
2891 | --- a/fs/xfs/xfs_message.h |
2892 | +++ b/fs/xfs/xfs_message.h |
2893 | @@ -60,6 +60,6 @@ do { \ |
2894 | extern void assfail(char *expr, char *f, int l); |
2895 | extern void asswarn(char *expr, char *f, int l); |
2896 | |
2897 | -extern void xfs_hex_dump(void *p, int length); |
2898 | +extern void xfs_hex_dump(const void *p, int length); |
2899 | |
2900 | #endif /* __XFS_MESSAGE_H */ |
2901 | diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c |
2902 | index 5a0ce0c2c4bbd..bbcf48a625b2a 100644 |
2903 | --- a/fs/xfs/xfs_mount.c |
2904 | +++ b/fs/xfs/xfs_mount.c |
2905 | @@ -31,7 +31,7 @@ |
2906 | #include "xfs_reflink.h" |
2907 | #include "xfs_extent_busy.h" |
2908 | #include "xfs_health.h" |
2909 | - |
2910 | +#include "xfs_trace.h" |
2911 | |
2912 | static DEFINE_MUTEX(xfs_uuid_table_mutex); |
2913 | static int xfs_uuid_table_size; |
2914 | @@ -365,66 +365,119 @@ release_buf: |
2915 | } |
2916 | |
2917 | /* |
2918 | - * Update alignment values based on mount options and sb values |
2919 | + * If the sunit/swidth change would move the precomputed root inode value, we |
2920 | + * must reject the ondisk change because repair will stumble over that. |
2921 | + * However, we allow the mount to proceed because we never rejected this |
2922 | + * combination before. Returns true to update the sb, false otherwise. |
2923 | + */ |
2924 | +static inline int |
2925 | +xfs_check_new_dalign( |
2926 | + struct xfs_mount *mp, |
2927 | + int new_dalign, |
2928 | + bool *update_sb) |
2929 | +{ |
2930 | + struct xfs_sb *sbp = &mp->m_sb; |
2931 | + xfs_ino_t calc_ino; |
2932 | + |
2933 | + calc_ino = xfs_ialloc_calc_rootino(mp, new_dalign); |
2934 | + trace_xfs_check_new_dalign(mp, new_dalign, calc_ino); |
2935 | + |
2936 | + if (sbp->sb_rootino == calc_ino) { |
2937 | + *update_sb = true; |
2938 | + return 0; |
2939 | + } |
2940 | + |
2941 | + xfs_warn(mp, |
2942 | +"Cannot change stripe alignment; would require moving root inode."); |
2943 | + |
2944 | + /* |
2945 | + * XXX: Next time we add a new incompat feature, this should start |
2946 | + * returning -EINVAL to fail the mount. Until then, spit out a warning |
2947 | + * that we're ignoring the administrator's instructions. |
2948 | + */ |
2949 | + xfs_warn(mp, "Skipping superblock stripe alignment update."); |
2950 | + *update_sb = false; |
2951 | + return 0; |
2952 | +} |
2953 | + |
2954 | +/* |
2955 | + * If we were provided with new sunit/swidth values as mount options, make sure |
2956 | + * that they pass basic alignment and superblock feature checks, and convert |
2957 | + * them into the same units (FSB) that everything else expects. This step |
2958 | + * /must/ be done before computing the inode geometry. |
2959 | */ |
2960 | STATIC int |
2961 | -xfs_update_alignment(xfs_mount_t *mp) |
2962 | +xfs_validate_new_dalign( |
2963 | + struct xfs_mount *mp) |
2964 | { |
2965 | - xfs_sb_t *sbp = &(mp->m_sb); |
2966 | + if (mp->m_dalign == 0) |
2967 | + return 0; |
2968 | |
2969 | - if (mp->m_dalign) { |
2970 | + /* |
2971 | + * If stripe unit and stripe width are not multiples |
2972 | + * of the fs blocksize turn off alignment. |
2973 | + */ |
2974 | + if ((BBTOB(mp->m_dalign) & mp->m_blockmask) || |
2975 | + (BBTOB(mp->m_swidth) & mp->m_blockmask)) { |
2976 | + xfs_warn(mp, |
2977 | + "alignment check failed: sunit/swidth vs. blocksize(%d)", |
2978 | + mp->m_sb.sb_blocksize); |
2979 | + return -EINVAL; |
2980 | + } else { |
2981 | /* |
2982 | - * If stripe unit and stripe width are not multiples |
2983 | - * of the fs blocksize turn off alignment. |
2984 | + * Convert the stripe unit and width to FSBs. |
2985 | */ |
2986 | - if ((BBTOB(mp->m_dalign) & mp->m_blockmask) || |
2987 | - (BBTOB(mp->m_swidth) & mp->m_blockmask)) { |
2988 | + mp->m_dalign = XFS_BB_TO_FSBT(mp, mp->m_dalign); |
2989 | + if (mp->m_dalign && (mp->m_sb.sb_agblocks % mp->m_dalign)) { |
2990 | xfs_warn(mp, |
2991 | - "alignment check failed: sunit/swidth vs. blocksize(%d)", |
2992 | - sbp->sb_blocksize); |
2993 | + "alignment check failed: sunit/swidth vs. agsize(%d)", |
2994 | + mp->m_sb.sb_agblocks); |
2995 | return -EINVAL; |
2996 | - } else { |
2997 | - /* |
2998 | - * Convert the stripe unit and width to FSBs. |
2999 | - */ |
3000 | - mp->m_dalign = XFS_BB_TO_FSBT(mp, mp->m_dalign); |
3001 | - if (mp->m_dalign && (sbp->sb_agblocks % mp->m_dalign)) { |
3002 | - xfs_warn(mp, |
3003 | - "alignment check failed: sunit/swidth vs. agsize(%d)", |
3004 | - sbp->sb_agblocks); |
3005 | - return -EINVAL; |
3006 | - } else if (mp->m_dalign) { |
3007 | - mp->m_swidth = XFS_BB_TO_FSBT(mp, mp->m_swidth); |
3008 | - } else { |
3009 | - xfs_warn(mp, |
3010 | - "alignment check failed: sunit(%d) less than bsize(%d)", |
3011 | - mp->m_dalign, sbp->sb_blocksize); |
3012 | - return -EINVAL; |
3013 | - } |
3014 | - } |
3015 | - |
3016 | - /* |
3017 | - * Update superblock with new values |
3018 | - * and log changes |
3019 | - */ |
3020 | - if (xfs_sb_version_hasdalign(sbp)) { |
3021 | - if (sbp->sb_unit != mp->m_dalign) { |
3022 | - sbp->sb_unit = mp->m_dalign; |
3023 | - mp->m_update_sb = true; |
3024 | - } |
3025 | - if (sbp->sb_width != mp->m_swidth) { |
3026 | - sbp->sb_width = mp->m_swidth; |
3027 | - mp->m_update_sb = true; |
3028 | - } |
3029 | + } else if (mp->m_dalign) { |
3030 | + mp->m_swidth = XFS_BB_TO_FSBT(mp, mp->m_swidth); |
3031 | } else { |
3032 | xfs_warn(mp, |
3033 | - "cannot change alignment: superblock does not support data alignment"); |
3034 | + "alignment check failed: sunit(%d) less than bsize(%d)", |
3035 | + mp->m_dalign, mp->m_sb.sb_blocksize); |
3036 | return -EINVAL; |
3037 | } |
3038 | + } |
3039 | + |
3040 | + if (!xfs_sb_version_hasdalign(&mp->m_sb)) { |
3041 | + xfs_warn(mp, |
3042 | +"cannot change alignment: superblock does not support data alignment"); |
3043 | + return -EINVAL; |
3044 | + } |
3045 | + |
3046 | + return 0; |
3047 | +} |
3048 | + |
3049 | +/* Update alignment values based on mount options and sb values. */ |
3050 | +STATIC int |
3051 | +xfs_update_alignment( |
3052 | + struct xfs_mount *mp) |
3053 | +{ |
3054 | + struct xfs_sb *sbp = &mp->m_sb; |
3055 | + |
3056 | + if (mp->m_dalign) { |
3057 | + bool update_sb; |
3058 | + int error; |
3059 | + |
3060 | + if (sbp->sb_unit == mp->m_dalign && |
3061 | + sbp->sb_width == mp->m_swidth) |
3062 | + return 0; |
3063 | + |
3064 | + error = xfs_check_new_dalign(mp, mp->m_dalign, &update_sb); |
3065 | + if (error || !update_sb) |
3066 | + return error; |
3067 | + |
3068 | + sbp->sb_unit = mp->m_dalign; |
3069 | + sbp->sb_width = mp->m_swidth; |
3070 | + mp->m_update_sb = true; |
3071 | } else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN && |
3072 | xfs_sb_version_hasdalign(&mp->m_sb)) { |
3073 | - mp->m_dalign = sbp->sb_unit; |
3074 | - mp->m_swidth = sbp->sb_width; |
3075 | + mp->m_dalign = sbp->sb_unit; |
3076 | + mp->m_swidth = sbp->sb_width; |
3077 | } |
3078 | |
3079 | return 0; |
3080 | @@ -692,12 +745,12 @@ xfs_mountfs( |
3081 | } |
3082 | |
3083 | /* |
3084 | - * Check if sb_agblocks is aligned at stripe boundary |
3085 | - * If sb_agblocks is NOT aligned turn off m_dalign since |
3086 | - * allocator alignment is within an ag, therefore ag has |
3087 | - * to be aligned at stripe boundary. |
3088 | + * If we were given new sunit/swidth options, do some basic validation |
3089 | + * checks and convert the incore dalign and swidth values to the |
3090 | + * same units (FSB) that everything else uses. This /must/ happen |
3091 | + * before computing the inode geometry. |
3092 | */ |
3093 | - error = xfs_update_alignment(mp); |
3094 | + error = xfs_validate_new_dalign(mp); |
3095 | if (error) |
3096 | goto out; |
3097 | |
3098 | @@ -708,6 +761,17 @@ xfs_mountfs( |
3099 | xfs_rmapbt_compute_maxlevels(mp); |
3100 | xfs_refcountbt_compute_maxlevels(mp); |
3101 | |
3102 | + /* |
3103 | + * Check if sb_agblocks is aligned at stripe boundary. If sb_agblocks |
3104 | + * is NOT aligned turn off m_dalign since allocator alignment is within |
3105 | + * an ag, therefore ag has to be aligned at stripe boundary. Note that |
3106 | + * we must compute the free space and rmap btree geometry before doing |
3107 | + * this. |
3108 | + */ |
3109 | + error = xfs_update_alignment(mp); |
3110 | + if (error) |
3111 | + goto out; |
3112 | + |
3113 | /* enable fail_at_unmount as default */ |
3114 | mp->m_fail_unmount = true; |
3115 | |
3116 | diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c |
3117 | index f63fe8d924a36..058af699e046c 100644 |
3118 | --- a/fs/xfs/xfs_pnfs.c |
3119 | +++ b/fs/xfs/xfs_pnfs.c |
3120 | @@ -147,11 +147,11 @@ xfs_fs_map_blocks( |
3121 | if (error) |
3122 | goto out_unlock; |
3123 | |
3124 | + ASSERT(!nimaps || imap.br_startblock != DELAYSTARTBLOCK); |
3125 | + |
3126 | if (write) { |
3127 | enum xfs_prealloc_flags flags = 0; |
3128 | |
3129 | - ASSERT(imap.br_startblock != DELAYSTARTBLOCK); |
3130 | - |
3131 | if (!nimaps || imap.br_startblock == HOLESTARTBLOCK) { |
3132 | /* |
3133 | * xfs_iomap_write_direct() expects to take ownership of |
3134 | diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c |
3135 | index ecd8ce152ab1f..66ea8e4fca86c 100644 |
3136 | --- a/fs/xfs/xfs_qm.c |
3137 | +++ b/fs/xfs/xfs_qm.c |
3138 | @@ -22,6 +22,7 @@ |
3139 | #include "xfs_qm.h" |
3140 | #include "xfs_trace.h" |
3141 | #include "xfs_icache.h" |
3142 | +#include "xfs_error.h" |
3143 | |
3144 | /* |
3145 | * The global quota manager. There is only one of these for the entire |
3146 | @@ -754,11 +755,19 @@ xfs_qm_qino_alloc( |
3147 | if ((flags & XFS_QMOPT_PQUOTA) && |
3148 | (mp->m_sb.sb_gquotino != NULLFSINO)) { |
3149 | ino = mp->m_sb.sb_gquotino; |
3150 | - ASSERT(mp->m_sb.sb_pquotino == NULLFSINO); |
3151 | + if (mp->m_sb.sb_pquotino != NULLFSINO) { |
3152 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, |
3153 | + mp); |
3154 | + return -EFSCORRUPTED; |
3155 | + } |
3156 | } else if ((flags & XFS_QMOPT_GQUOTA) && |
3157 | (mp->m_sb.sb_pquotino != NULLFSINO)) { |
3158 | ino = mp->m_sb.sb_pquotino; |
3159 | - ASSERT(mp->m_sb.sb_gquotino == NULLFSINO); |
3160 | + if (mp->m_sb.sb_gquotino != NULLFSINO) { |
3161 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, |
3162 | + mp); |
3163 | + return -EFSCORRUPTED; |
3164 | + } |
3165 | } |
3166 | if (ino != NULLFSINO) { |
3167 | error = xfs_iget(mp, NULL, ino, 0, 0, ip); |
3168 | diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c |
3169 | index 2328268e62459..d5708d40ad877 100644 |
3170 | --- a/fs/xfs/xfs_refcount_item.c |
3171 | +++ b/fs/xfs/xfs_refcount_item.c |
3172 | @@ -17,7 +17,7 @@ |
3173 | #include "xfs_refcount_item.h" |
3174 | #include "xfs_log.h" |
3175 | #include "xfs_refcount.h" |
3176 | - |
3177 | +#include "xfs_error.h" |
3178 | |
3179 | kmem_zone_t *xfs_cui_zone; |
3180 | kmem_zone_t *xfs_cud_zone; |
3181 | @@ -497,7 +497,7 @@ xfs_cui_recover( |
3182 | */ |
3183 | set_bit(XFS_CUI_RECOVERED, &cuip->cui_flags); |
3184 | xfs_cui_release(cuip); |
3185 | - return -EIO; |
3186 | + return -EFSCORRUPTED; |
3187 | } |
3188 | } |
3189 | |
3190 | @@ -536,6 +536,7 @@ xfs_cui_recover( |
3191 | type = refc_type; |
3192 | break; |
3193 | default: |
3194 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); |
3195 | error = -EFSCORRUPTED; |
3196 | goto abort_error; |
3197 | } |
3198 | diff --git a/fs/xfs/xfs_rmap_item.c b/fs/xfs/xfs_rmap_item.c |
3199 | index 8939e0ea09cd5..02f84d9a511c3 100644 |
3200 | --- a/fs/xfs/xfs_rmap_item.c |
3201 | +++ b/fs/xfs/xfs_rmap_item.c |
3202 | @@ -17,7 +17,7 @@ |
3203 | #include "xfs_rmap_item.h" |
3204 | #include "xfs_log.h" |
3205 | #include "xfs_rmap.h" |
3206 | - |
3207 | +#include "xfs_error.h" |
3208 | |
3209 | kmem_zone_t *xfs_rui_zone; |
3210 | kmem_zone_t *xfs_rud_zone; |
3211 | @@ -171,8 +171,10 @@ xfs_rui_copy_format( |
3212 | src_rui_fmt = buf->i_addr; |
3213 | len = xfs_rui_log_format_sizeof(src_rui_fmt->rui_nextents); |
3214 | |
3215 | - if (buf->i_len != len) |
3216 | + if (buf->i_len != len) { |
3217 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL); |
3218 | return -EFSCORRUPTED; |
3219 | + } |
3220 | |
3221 | memcpy(dst_rui_fmt, src_rui_fmt, len); |
3222 | return 0; |
3223 | @@ -539,7 +541,7 @@ xfs_rui_recover( |
3224 | */ |
3225 | set_bit(XFS_RUI_RECOVERED, &ruip->rui_flags); |
3226 | xfs_rui_release(ruip); |
3227 | - return -EIO; |
3228 | + return -EFSCORRUPTED; |
3229 | } |
3230 | } |
3231 | |
3232 | @@ -581,6 +583,7 @@ xfs_rui_recover( |
3233 | type = XFS_RMAP_FREE; |
3234 | break; |
3235 | default: |
3236 | + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL); |
3237 | error = -EFSCORRUPTED; |
3238 | goto abort_error; |
3239 | } |
3240 | diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h |
3241 | index eaae275ed4308..ffb398c1de698 100644 |
3242 | --- a/fs/xfs/xfs_trace.h |
3243 | +++ b/fs/xfs/xfs_trace.h |
3244 | @@ -3609,6 +3609,27 @@ DEFINE_KMEM_EVENT(kmem_alloc_large); |
3245 | DEFINE_KMEM_EVENT(kmem_realloc); |
3246 | DEFINE_KMEM_EVENT(kmem_zone_alloc); |
3247 | |
3248 | +TRACE_EVENT(xfs_check_new_dalign, |
3249 | + TP_PROTO(struct xfs_mount *mp, int new_dalign, xfs_ino_t calc_rootino), |
3250 | + TP_ARGS(mp, new_dalign, calc_rootino), |
3251 | + TP_STRUCT__entry( |
3252 | + __field(dev_t, dev) |
3253 | + __field(int, new_dalign) |
3254 | + __field(xfs_ino_t, sb_rootino) |
3255 | + __field(xfs_ino_t, calc_rootino) |
3256 | + ), |
3257 | + TP_fast_assign( |
3258 | + __entry->dev = mp->m_super->s_dev; |
3259 | + __entry->new_dalign = new_dalign; |
3260 | + __entry->sb_rootino = mp->m_sb.sb_rootino; |
3261 | + __entry->calc_rootino = calc_rootino; |
3262 | + ), |
3263 | + TP_printk("dev %d:%d new_dalign %d sb_rootino %llu calc_rootino %llu", |
3264 | + MAJOR(__entry->dev), MINOR(__entry->dev), |
3265 | + __entry->new_dalign, __entry->sb_rootino, |
3266 | + __entry->calc_rootino) |
3267 | +) |
3268 | + |
3269 | #endif /* _TRACE_XFS_H */ |
3270 | |
3271 | #undef TRACE_INCLUDE_PATH |
3272 | diff --git a/include/linux/iomap.h b/include/linux/iomap.h |
3273 | index 53b16f104081b..74e05e7b67f50 100644 |
3274 | --- a/include/linux/iomap.h |
3275 | +++ b/include/linux/iomap.h |
3276 | @@ -32,6 +32,8 @@ struct vm_fault; |
3277 | * |
3278 | * IOMAP_F_DIRTY indicates the inode has uncommitted metadata needed to access |
3279 | * written data and requires fdatasync to commit them to persistent storage. |
3280 | + * This needs to take into account metadata changes that *may* be made at IO |
3281 | + * completion, such as file size updates from direct IO. |
3282 | */ |
3283 | #define IOMAP_F_NEW 0x01 /* blocks have been newly allocated */ |
3284 | #define IOMAP_F_DIRTY 0x02 /* uncommitted metadata */ |
3285 | diff --git a/include/linux/sched/task_stack.h b/include/linux/sched/task_stack.h |
3286 | index d10150587d819..1009b6b5ce403 100644 |
3287 | --- a/include/linux/sched/task_stack.h |
3288 | +++ b/include/linux/sched/task_stack.h |
3289 | @@ -16,7 +16,7 @@ |
3290 | * try_get_task_stack() instead. task_stack_page will return a pointer |
3291 | * that could get freed out from under you. |
3292 | */ |
3293 | -static inline void *task_stack_page(const struct task_struct *task) |
3294 | +static __always_inline void *task_stack_page(const struct task_struct *task) |
3295 | { |
3296 | return task->stack; |
3297 | } |
3298 | diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h |
3299 | index 2b78cc734719a..10f209d54f18a 100644 |
3300 | --- a/include/linux/serial_core.h |
3301 | +++ b/include/linux/serial_core.h |
3302 | @@ -297,6 +297,23 @@ struct uart_state { |
3303 | /* number of characters left in xmit buffer before we ask for more */ |
3304 | #define WAKEUP_CHARS 256 |
3305 | |
3306 | +/** |
3307 | + * uart_xmit_advance - Advance xmit buffer and account Tx'ed chars |
3308 | + * @up: uart_port structure describing the port |
3309 | + * @chars: number of characters sent |
3310 | + * |
3311 | + * This function advances the tail of circular xmit buffer by the number of |
3312 | + * @chars transmitted and handles accounting of transmitted bytes (into |
3313 | + * @up's icount.tx). |
3314 | + */ |
3315 | +static inline void uart_xmit_advance(struct uart_port *up, unsigned int chars) |
3316 | +{ |
3317 | + struct circ_buf *xmit = &up->state->xmit; |
3318 | + |
3319 | + xmit->tail = (xmit->tail + chars) & (UART_XMIT_SIZE - 1); |
3320 | + up->icount.tx += chars; |
3321 | +} |
3322 | + |
3323 | struct module; |
3324 | struct tty_driver; |
3325 | |
3326 | diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c |
3327 | index aa7577b189e92..9e847e71ceddf 100644 |
3328 | --- a/kernel/cgroup/cgroup-v1.c |
3329 | +++ b/kernel/cgroup/cgroup-v1.c |
3330 | @@ -15,6 +15,7 @@ |
3331 | #include <linux/pid_namespace.h> |
3332 | #include <linux/cgroupstats.h> |
3333 | #include <linux/fs_parser.h> |
3334 | +#include <linux/cpu.h> |
3335 | |
3336 | #include <trace/events/cgroup.h> |
3337 | |
3338 | @@ -62,6 +63,7 @@ int cgroup_attach_task_all(struct task_struct *from, struct task_struct *tsk) |
3339 | int retval = 0; |
3340 | |
3341 | mutex_lock(&cgroup_mutex); |
3342 | + cpus_read_lock(); |
3343 | percpu_down_write(&cgroup_threadgroup_rwsem); |
3344 | for_each_root(root) { |
3345 | struct cgroup *from_cgrp; |
3346 | @@ -78,6 +80,7 @@ int cgroup_attach_task_all(struct task_struct *from, struct task_struct *tsk) |
3347 | break; |
3348 | } |
3349 | percpu_up_write(&cgroup_threadgroup_rwsem); |
3350 | + cpus_read_unlock(); |
3351 | mutex_unlock(&cgroup_mutex); |
3352 | |
3353 | return retval; |
3354 | diff --git a/kernel/trace/trace_preemptirq.c b/kernel/trace/trace_preemptirq.c |
3355 | index 26b06b09c9f68..e9645f829b94c 100644 |
3356 | --- a/kernel/trace/trace_preemptirq.c |
3357 | +++ b/kernel/trace/trace_preemptirq.c |
3358 | @@ -56,14 +56,14 @@ __visible void trace_hardirqs_on_caller(unsigned long caller_addr) |
3359 | this_cpu_write(tracing_irq_cpu, 0); |
3360 | } |
3361 | |
3362 | - lockdep_hardirqs_on(CALLER_ADDR0); |
3363 | + lockdep_hardirqs_on(caller_addr); |
3364 | } |
3365 | EXPORT_SYMBOL(trace_hardirqs_on_caller); |
3366 | NOKPROBE_SYMBOL(trace_hardirqs_on_caller); |
3367 | |
3368 | __visible void trace_hardirqs_off_caller(unsigned long caller_addr) |
3369 | { |
3370 | - lockdep_hardirqs_off(CALLER_ADDR0); |
3371 | + lockdep_hardirqs_off(caller_addr); |
3372 | |
3373 | if (!this_cpu_read(tracing_irq_cpu)) { |
3374 | this_cpu_write(tracing_irq_cpu, 1); |
3375 | diff --git a/kernel/workqueue.c b/kernel/workqueue.c |
3376 | index e90f37e22202a..dd96391b44de0 100644 |
3377 | --- a/kernel/workqueue.c |
3378 | +++ b/kernel/workqueue.c |
3379 | @@ -3049,10 +3049,8 @@ static bool __flush_work(struct work_struct *work, bool from_cancel) |
3380 | if (WARN_ON(!work->func)) |
3381 | return false; |
3382 | |
3383 | - if (!from_cancel) { |
3384 | - lock_map_acquire(&work->lockdep_map); |
3385 | - lock_map_release(&work->lockdep_map); |
3386 | - } |
3387 | + lock_map_acquire(&work->lockdep_map); |
3388 | + lock_map_release(&work->lockdep_map); |
3389 | |
3390 | if (start_flush_work(work, &barr, from_cancel)) { |
3391 | wait_for_completion(&barr.done); |
3392 | diff --git a/mm/slub.c b/mm/slub.c |
3393 | index 5211496f6d24f..17e663cf38f69 100644 |
3394 | --- a/mm/slub.c |
3395 | +++ b/mm/slub.c |
3396 | @@ -5743,7 +5743,8 @@ static char *create_unique_id(struct kmem_cache *s) |
3397 | char *name = kmalloc(ID_STR_LENGTH, GFP_KERNEL); |
3398 | char *p = name; |
3399 | |
3400 | - BUG_ON(!name); |
3401 | + if (!name) |
3402 | + return ERR_PTR(-ENOMEM); |
3403 | |
3404 | *p++ = ':'; |
3405 | /* |
3406 | @@ -5825,6 +5826,8 @@ static int sysfs_slab_add(struct kmem_cache *s) |
3407 | * for the symlinks. |
3408 | */ |
3409 | name = create_unique_id(s); |
3410 | + if (IS_ERR(name)) |
3411 | + return PTR_ERR(name); |
3412 | } |
3413 | |
3414 | s->kobj.kset = kset; |
3415 | diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c |
3416 | index ddb988c339c17..f6853fc0fcc00 100644 |
3417 | --- a/net/bridge/netfilter/ebtables.c |
3418 | +++ b/net/bridge/netfilter/ebtables.c |
3419 | @@ -999,8 +999,10 @@ static int do_replace_finish(struct net *net, struct ebt_replace *repl, |
3420 | goto free_iterate; |
3421 | } |
3422 | |
3423 | - if (repl->valid_hooks != t->valid_hooks) |
3424 | + if (repl->valid_hooks != t->valid_hooks) { |
3425 | + ret = -EINVAL; |
3426 | goto free_unlock; |
3427 | + } |
3428 | |
3429 | if (repl->num_counters && repl->num_counters != t->private->nentries) { |
3430 | ret = -EINVAL; |
3431 | diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c |
3432 | index 344b2c22e75b5..c353162e81aea 100644 |
3433 | --- a/net/mac80211/scan.c |
3434 | +++ b/net/mac80211/scan.c |
3435 | @@ -431,10 +431,6 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) |
3436 | scan_req = rcu_dereference_protected(local->scan_req, |
3437 | lockdep_is_held(&local->mtx)); |
3438 | |
3439 | - if (scan_req != local->int_scan_req) { |
3440 | - local->scan_info.aborted = aborted; |
3441 | - cfg80211_scan_done(scan_req, &local->scan_info); |
3442 | - } |
3443 | RCU_INIT_POINTER(local->scan_req, NULL); |
3444 | |
3445 | scan_sdata = rcu_dereference_protected(local->scan_sdata, |
3446 | @@ -444,6 +440,13 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) |
3447 | local->scanning = 0; |
3448 | local->scan_chandef.chan = NULL; |
3449 | |
3450 | + synchronize_rcu(); |
3451 | + |
3452 | + if (scan_req != local->int_scan_req) { |
3453 | + local->scan_info.aborted = aborted; |
3454 | + cfg80211_scan_done(scan_req, &local->scan_info); |
3455 | + } |
3456 | + |
3457 | /* Set power back to normal operating levels. */ |
3458 | ieee80211_hw_config(local, 0); |
3459 | |
3460 | diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c |
3461 | index 26245419ef4a9..65b5b05fe38d3 100644 |
3462 | --- a/net/netfilter/nf_conntrack_irc.c |
3463 | +++ b/net/netfilter/nf_conntrack_irc.c |
3464 | @@ -148,15 +148,37 @@ static int help(struct sk_buff *skb, unsigned int protoff, |
3465 | data = ib_ptr; |
3466 | data_limit = ib_ptr + skb->len - dataoff; |
3467 | |
3468 | - /* strlen("\1DCC SENT t AAAAAAAA P\1\n")=24 |
3469 | - * 5+MINMATCHLEN+strlen("t AAAAAAAA P\1\n")=14 */ |
3470 | - while (data < data_limit - (19 + MINMATCHLEN)) { |
3471 | - if (memcmp(data, "\1DCC ", 5)) { |
3472 | + /* Skip any whitespace */ |
3473 | + while (data < data_limit - 10) { |
3474 | + if (*data == ' ' || *data == '\r' || *data == '\n') |
3475 | + data++; |
3476 | + else |
3477 | + break; |
3478 | + } |
3479 | + |
3480 | + /* strlen("PRIVMSG x ")=10 */ |
3481 | + if (data < data_limit - 10) { |
3482 | + if (strncasecmp("PRIVMSG ", data, 8)) |
3483 | + goto out; |
3484 | + data += 8; |
3485 | + } |
3486 | + |
3487 | + /* strlen(" :\1DCC SENT t AAAAAAAA P\1\n")=26 |
3488 | + * 7+MINMATCHLEN+strlen("t AAAAAAAA P\1\n")=26 |
3489 | + */ |
3490 | + while (data < data_limit - (21 + MINMATCHLEN)) { |
3491 | + /* Find first " :", the start of message */ |
3492 | + if (memcmp(data, " :", 2)) { |
3493 | data++; |
3494 | continue; |
3495 | } |
3496 | + data += 2; |
3497 | + |
3498 | + /* then check that place only for the DCC command */ |
3499 | + if (memcmp(data, "\1DCC ", 5)) |
3500 | + goto out; |
3501 | data += 5; |
3502 | - /* we have at least (19+MINMATCHLEN)-5 bytes valid data left */ |
3503 | + /* we have at least (21+MINMATCHLEN)-(2+5) bytes valid data left */ |
3504 | |
3505 | iph = ip_hdr(skb); |
3506 | pr_debug("DCC found in master %pI4:%u %pI4:%u\n", |
3507 | @@ -172,7 +194,7 @@ static int help(struct sk_buff *skb, unsigned int protoff, |
3508 | pr_debug("DCC %s detected\n", dccprotos[i]); |
3509 | |
3510 | /* we have at least |
3511 | - * (19+MINMATCHLEN)-5-dccprotos[i].matchlen bytes valid |
3512 | + * (21+MINMATCHLEN)-7-dccprotos[i].matchlen bytes valid |
3513 | * data left (== 14/13 bytes) */ |
3514 | if (parse_dcc(data, data_limit, &dcc_ip, |
3515 | &dcc_port, &addr_beg_p, &addr_end_p)) { |
3516 | diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c |
3517 | index b83dc9bf0a5dd..78fd9122b70c7 100644 |
3518 | --- a/net/netfilter/nf_conntrack_sip.c |
3519 | +++ b/net/netfilter/nf_conntrack_sip.c |
3520 | @@ -477,7 +477,7 @@ static int ct_sip_walk_headers(const struct nf_conn *ct, const char *dptr, |
3521 | return ret; |
3522 | if (ret == 0) |
3523 | break; |
3524 | - dataoff += *matchoff; |
3525 | + dataoff = *matchoff; |
3526 | } |
3527 | *in_header = 0; |
3528 | } |
3529 | @@ -489,7 +489,7 @@ static int ct_sip_walk_headers(const struct nf_conn *ct, const char *dptr, |
3530 | break; |
3531 | if (ret == 0) |
3532 | return ret; |
3533 | - dataoff += *matchoff; |
3534 | + dataoff = *matchoff; |
3535 | } |
3536 | |
3537 | if (in_header) |
3538 | diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c |
3539 | index 79fbf37291f38..51e3953b414c0 100644 |
3540 | --- a/net/netfilter/nfnetlink_osf.c |
3541 | +++ b/net/netfilter/nfnetlink_osf.c |
3542 | @@ -269,6 +269,7 @@ bool nf_osf_find(const struct sk_buff *skb, |
3543 | struct nf_osf_hdr_ctx ctx; |
3544 | const struct tcphdr *tcp; |
3545 | struct tcphdr _tcph; |
3546 | + bool found = false; |
3547 | |
3548 | memset(&ctx, 0, sizeof(ctx)); |
3549 | |
3550 | @@ -283,10 +284,11 @@ bool nf_osf_find(const struct sk_buff *skb, |
3551 | |
3552 | data->genre = f->genre; |
3553 | data->version = f->version; |
3554 | + found = true; |
3555 | break; |
3556 | } |
3557 | |
3558 | - return true; |
3559 | + return found; |
3560 | } |
3561 | EXPORT_SYMBOL_GPL(nf_osf_find); |
3562 | |
3563 | diff --git a/net/rxrpc/call_event.c b/net/rxrpc/call_event.c |
3564 | index 8574e7066d94c..b5f173960725b 100644 |
3565 | --- a/net/rxrpc/call_event.c |
3566 | +++ b/net/rxrpc/call_event.c |
3567 | @@ -166,7 +166,7 @@ static void rxrpc_resend(struct rxrpc_call *call, unsigned long now_j) |
3568 | _enter("{%d,%d}", call->tx_hard_ack, call->tx_top); |
3569 | |
3570 | now = ktime_get_real(); |
3571 | - max_age = ktime_sub(now, jiffies_to_usecs(call->peer->rto_j)); |
3572 | + max_age = ktime_sub_us(now, jiffies_to_usecs(call->peer->rto_j)); |
3573 | |
3574 | spin_lock_bh(&call->lock); |
3575 | |
3576 | diff --git a/net/rxrpc/local_object.c b/net/rxrpc/local_object.c |
3577 | index 01135e54d95d2..fc784fcc3a947 100644 |
3578 | --- a/net/rxrpc/local_object.c |
3579 | +++ b/net/rxrpc/local_object.c |
3580 | @@ -448,6 +448,9 @@ static void rxrpc_local_processor(struct work_struct *work) |
3581 | container_of(work, struct rxrpc_local, processor); |
3582 | bool again; |
3583 | |
3584 | + if (local->dead) |
3585 | + return; |
3586 | + |
3587 | trace_rxrpc_local(local->debug_id, rxrpc_local_processing, |
3588 | atomic_read(&local->usage), NULL); |
3589 | |
3590 | diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c |
3591 | index 919c7fa5f02d6..48a8c7daa635e 100644 |
3592 | --- a/net/sched/cls_api.c |
3593 | +++ b/net/sched/cls_api.c |
3594 | @@ -2098,6 +2098,7 @@ replay: |
3595 | } |
3596 | |
3597 | if (chain->tmplt_ops && chain->tmplt_ops != tp->ops) { |
3598 | + tfilter_put(tp, fh); |
3599 | NL_SET_ERR_MSG(extack, "Chain template is set to a different filter kind"); |
3600 | err = -EINVAL; |
3601 | goto errout; |
3602 | diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c |
3603 | index 4c26f7fb32b34..506ebae1f72cf 100644 |
3604 | --- a/net/sched/sch_taprio.c |
3605 | +++ b/net/sched/sch_taprio.c |
3606 | @@ -65,6 +65,7 @@ struct taprio_sched { |
3607 | u32 flags; |
3608 | enum tk_offsets tk_offset; |
3609 | int clockid; |
3610 | + bool offloaded; |
3611 | atomic64_t picos_per_byte; /* Using picoseconds because for 10Gbps+ |
3612 | * speeds it's sub-nanoseconds per byte |
3613 | */ |
3614 | @@ -1268,6 +1269,8 @@ static int taprio_enable_offload(struct net_device *dev, |
3615 | goto done; |
3616 | } |
3617 | |
3618 | + q->offloaded = true; |
3619 | + |
3620 | done: |
3621 | taprio_offload_free(offload); |
3622 | |
3623 | @@ -1282,12 +1285,9 @@ static int taprio_disable_offload(struct net_device *dev, |
3624 | struct tc_taprio_qopt_offload *offload; |
3625 | int err; |
3626 | |
3627 | - if (!FULL_OFFLOAD_IS_ENABLED(q->flags)) |
3628 | + if (!q->offloaded) |
3629 | return 0; |
3630 | |
3631 | - if (!ops->ndo_setup_tc) |
3632 | - return -EOPNOTSUPP; |
3633 | - |
3634 | offload = taprio_offload_alloc(0); |
3635 | if (!offload) { |
3636 | NL_SET_ERR_MSG(extack, |
3637 | @@ -1303,6 +1303,8 @@ static int taprio_disable_offload(struct net_device *dev, |
3638 | goto out; |
3639 | } |
3640 | |
3641 | + q->offloaded = false; |
3642 | + |
3643 | out: |
3644 | taprio_offload_free(offload); |
3645 | |
3646 | @@ -1904,12 +1906,14 @@ start_error: |
3647 | |
3648 | static struct Qdisc *taprio_leaf(struct Qdisc *sch, unsigned long cl) |
3649 | { |
3650 | - struct netdev_queue *dev_queue = taprio_queue_get(sch, cl); |
3651 | + struct taprio_sched *q = qdisc_priv(sch); |
3652 | + struct net_device *dev = qdisc_dev(sch); |
3653 | + unsigned int ntx = cl - 1; |
3654 | |
3655 | - if (!dev_queue) |
3656 | + if (ntx >= dev->num_tx_queues) |
3657 | return NULL; |
3658 | |
3659 | - return dev_queue->qdisc_sleeping; |
3660 | + return q->qdiscs[ntx]; |
3661 | } |
3662 | |
3663 | static unsigned long taprio_find(struct Qdisc *sch, u32 classid) |
3664 | diff --git a/scripts/mksysmap b/scripts/mksysmap |
3665 | index 9aa23d15862a0..ad8bbc52267d0 100755 |
3666 | --- a/scripts/mksysmap |
3667 | +++ b/scripts/mksysmap |
3668 | @@ -41,4 +41,4 @@ |
3669 | # so we just ignore them to let readprofile continue to work. |
3670 | # (At least sparc64 has __crc_ in the middle). |
3671 | |
3672 | -$NM -n $1 | grep -v '\( [aNUw] \)\|\(__crc_\)\|\( \$[adt]\)\|\( \.L\)' > $2 |
3673 | +$NM -n $1 | grep -v '\( [aNUw] \)\|\(__crc_\)\|\( \$[adt]\)\|\( \.L\)\|\( L0\)' > $2 |
3674 | diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c |
3675 | index ad4e0af2d0d03..51d2911366e93 100644 |
3676 | --- a/sound/core/oss/pcm_oss.c |
3677 | +++ b/sound/core/oss/pcm_oss.c |
3678 | @@ -1661,13 +1661,14 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file) |
3679 | runtime = substream->runtime; |
3680 | if (atomic_read(&substream->mmap_count)) |
3681 | goto __direct; |
3682 | - if ((err = snd_pcm_oss_make_ready(substream)) < 0) |
3683 | - return err; |
3684 | atomic_inc(&runtime->oss.rw_ref); |
3685 | if (mutex_lock_interruptible(&runtime->oss.params_lock)) { |
3686 | atomic_dec(&runtime->oss.rw_ref); |
3687 | return -ERESTARTSYS; |
3688 | } |
3689 | + err = snd_pcm_oss_make_ready_locked(substream); |
3690 | + if (err < 0) |
3691 | + goto unlock; |
3692 | format = snd_pcm_oss_format_from(runtime->oss.format); |
3693 | width = snd_pcm_format_physical_width(format); |
3694 | if (runtime->oss.buffer_used > 0) { |
3695 | diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c |
3696 | index b8fe0ec5d6247..5b892e7090ddc 100644 |
3697 | --- a/sound/pci/hda/hda_intel.c |
3698 | +++ b/sound/pci/hda/hda_intel.c |
3699 | @@ -2528,6 +2528,8 @@ static const struct pci_device_id azx_ids[] = { |
3700 | /* 5 Series/3400 */ |
3701 | { PCI_DEVICE(0x8086, 0x3b56), |
3702 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM }, |
3703 | + { PCI_DEVICE(0x8086, 0x3b57), |
3704 | + .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM }, |
3705 | /* Poulsbo */ |
3706 | { PCI_DEVICE(0x8086, 0x811b), |
3707 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE }, |
3708 | diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c |
3709 | index 2971b34c87c1a..e235c3ec634db 100644 |
3710 | --- a/sound/pci/hda/hda_tegra.c |
3711 | +++ b/sound/pci/hda/hda_tegra.c |
3712 | @@ -428,7 +428,8 @@ MODULE_DEVICE_TABLE(of, hda_tegra_match); |
3713 | static int hda_tegra_probe(struct platform_device *pdev) |
3714 | { |
3715 | const unsigned int driver_flags = AZX_DCAPS_CORBRP_SELF_CLEAR | |
3716 | - AZX_DCAPS_PM_RUNTIME; |
3717 | + AZX_DCAPS_PM_RUNTIME | |
3718 | + AZX_DCAPS_4K_BDLE_BOUNDARY; |
3719 | struct snd_card *card; |
3720 | struct azx *chip; |
3721 | struct hda_tegra *hda; |
3722 | diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c |
3723 | index 5128a5df16fd3..169e742999873 100644 |
3724 | --- a/sound/pci/hda/patch_hdmi.c |
3725 | +++ b/sound/pci/hda/patch_hdmi.c |
3726 | @@ -3703,6 +3703,7 @@ static int patch_tegra_hdmi(struct hda_codec *codec) |
3727 | if (err) |
3728 | return err; |
3729 | |
3730 | + codec->depop_delay = 10; |
3731 | codec->patch_ops.build_pcms = tegra_hdmi_build_pcms; |
3732 | spec = codec->spec; |
3733 | spec->chmap.ops.chmap_cea_alloc_validate_get_type = |
3734 | diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c |
3735 | index d925ae7f1b027..930bb040b403e 100644 |
3736 | --- a/sound/pci/hda/patch_realtek.c |
3737 | +++ b/sound/pci/hda/patch_realtek.c |
3738 | @@ -6484,6 +6484,8 @@ enum { |
3739 | ALC294_FIXUP_ASUS_GU502_HP, |
3740 | ALC294_FIXUP_ASUS_GU502_PINS, |
3741 | ALC294_FIXUP_ASUS_GU502_VERBS, |
3742 | + ALC294_FIXUP_ASUS_G513_PINS, |
3743 | + ALC285_FIXUP_ASUS_G533Z_PINS, |
3744 | ALC285_FIXUP_HP_GPIO_LED, |
3745 | ALC285_FIXUP_HP_MUTE_LED, |
3746 | ALC236_FIXUP_HP_GPIO_LED, |
3747 | @@ -7760,6 +7762,24 @@ static const struct hda_fixup alc269_fixups[] = { |
3748 | [ALC294_FIXUP_ASUS_GU502_HP] = { |
3749 | .type = HDA_FIXUP_FUNC, |
3750 | .v.func = alc294_fixup_gu502_hp, |
3751 | + }, |
3752 | + [ALC294_FIXUP_ASUS_G513_PINS] = { |
3753 | + .type = HDA_FIXUP_PINS, |
3754 | + .v.pins = (const struct hda_pintbl[]) { |
3755 | + { 0x19, 0x03a11050 }, /* front HP mic */ |
3756 | + { 0x1a, 0x03a11c30 }, /* rear external mic */ |
3757 | + { 0x21, 0x03211420 }, /* front HP out */ |
3758 | + { } |
3759 | + }, |
3760 | + }, |
3761 | + [ALC285_FIXUP_ASUS_G533Z_PINS] = { |
3762 | + .type = HDA_FIXUP_PINS, |
3763 | + .v.pins = (const struct hda_pintbl[]) { |
3764 | + { 0x14, 0x90170120 }, |
3765 | + { } |
3766 | + }, |
3767 | + .chained = true, |
3768 | + .chain_id = ALC294_FIXUP_ASUS_G513_PINS, |
3769 | }, |
3770 | [ALC294_FIXUP_ASUS_COEF_1B] = { |
3771 | .type = HDA_FIXUP_VERBS, |
3772 | @@ -8118,6 +8138,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
3773 | SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC), |
3774 | SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC), |
3775 | SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB), |
3776 | + SND_PCI_QUIRK(0x1028, 0x087d, "Dell Precision 5530", ALC289_FIXUP_DUAL_SPK), |
3777 | SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE), |
3778 | SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE), |
3779 | SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB), |
3780 | @@ -8229,10 +8250,11 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
3781 | SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC), |
3782 | SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), |
3783 | SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), |
3784 | + SND_PCI_QUIRK(0x1043, 0x1662, "ASUS GV301QH", ALC294_FIXUP_ASUS_DUAL_SPK), |
3785 | + SND_PCI_QUIRK(0x1043, 0x16b2, "ASUS GU603", ALC289_FIXUP_ASUS_GA401), |
3786 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), |
3787 | SND_PCI_QUIRK(0x1043, 0x1740, "ASUS UX430UA", ALC295_FIXUP_ASUS_DACS), |
3788 | SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK), |
3789 | - SND_PCI_QUIRK(0x1043, 0x1662, "ASUS GV301QH", ALC294_FIXUP_ASUS_DUAL_SPK), |
3790 | SND_PCI_QUIRK(0x1043, 0x1881, "ASUS Zephyrus S/M", ALC294_FIXUP_ASUS_GX502_PINS), |
3791 | SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC), |
3792 | SND_PCI_QUIRK(0x1043, 0x18f1, "Asus FX505DT", ALC256_FIXUP_ASUS_HEADSET_MIC), |
3793 | @@ -8247,14 +8269,16 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
3794 | SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), |
3795 | SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), |
3796 | SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
3797 | + SND_PCI_QUIRK(0x1043, 0x1c92, "ASUS ROG Strix G15", ALC285_FIXUP_ASUS_G533Z_PINS), |
3798 | SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC), |
3799 | + SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401), |
3800 | SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE), |
3801 | SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502), |
3802 | SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS), |
3803 | + SND_PCI_QUIRK(0x1043, 0x1e5e, "ASUS ROG Strix G513", ALC294_FIXUP_ASUS_G513_PINS), |
3804 | SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401), |
3805 | + SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401), |
3806 | SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401), |
3807 | - SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401), |
3808 | - SND_PCI_QUIRK(0x1043, 0x16b2, "ASUS GU603", ALC289_FIXUP_ASUS_GA401), |
3809 | SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2), |
3810 | SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), |
3811 | SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), |
3812 | @@ -8425,6 +8449,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
3813 | SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), |
3814 | SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), |
3815 | SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS), |
3816 | + SND_PCI_QUIRK(0x19e5, 0x320f, "Huawei WRT-WX9 ", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), |
3817 | SND_PCI_QUIRK(0x1b35, 0x1235, "CZC B20", ALC269_FIXUP_CZC_B20), |
3818 | SND_PCI_QUIRK(0x1b35, 0x1236, "CZC TMI", ALC269_FIXUP_CZC_TMI), |
3819 | SND_PCI_QUIRK(0x1b35, 0x1237, "CZC L101", ALC269_FIXUP_CZC_L101), |
3820 | diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c |
3821 | index bfd3fe5eff31c..04a89171327dc 100644 |
3822 | --- a/sound/pci/hda/patch_sigmatel.c |
3823 | +++ b/sound/pci/hda/patch_sigmatel.c |
3824 | @@ -209,6 +209,7 @@ struct sigmatel_spec { |
3825 | |
3826 | /* beep widgets */ |
3827 | hda_nid_t anabeep_nid; |
3828 | + bool beep_power_on; |
3829 | |
3830 | /* SPDIF-out mux */ |
3831 | const char * const *spdif_labels; |
3832 | @@ -4441,6 +4442,28 @@ static int stac_suspend(struct hda_codec *codec) |
3833 | stac_shutup(codec); |
3834 | return 0; |
3835 | } |
3836 | + |
3837 | +static int stac_check_power_status(struct hda_codec *codec, hda_nid_t nid) |
3838 | +{ |
3839 | +#ifdef CONFIG_SND_HDA_INPUT_BEEP |
3840 | + struct sigmatel_spec *spec = codec->spec; |
3841 | +#endif |
3842 | + int ret = snd_hda_gen_check_power_status(codec, nid); |
3843 | + |
3844 | +#ifdef CONFIG_SND_HDA_INPUT_BEEP |
3845 | + if (nid == spec->gen.beep_nid && codec->beep) { |
3846 | + if (codec->beep->enabled != spec->beep_power_on) { |
3847 | + spec->beep_power_on = codec->beep->enabled; |
3848 | + if (spec->beep_power_on) |
3849 | + snd_hda_power_up_pm(codec); |
3850 | + else |
3851 | + snd_hda_power_down_pm(codec); |
3852 | + } |
3853 | + ret |= spec->beep_power_on; |
3854 | + } |
3855 | +#endif |
3856 | + return ret; |
3857 | +} |
3858 | #else |
3859 | #define stac_suspend NULL |
3860 | #endif /* CONFIG_PM */ |
3861 | @@ -4453,6 +4476,7 @@ static const struct hda_codec_ops stac_patch_ops = { |
3862 | .unsol_event = snd_hda_jack_unsol_event, |
3863 | #ifdef CONFIG_PM |
3864 | .suspend = stac_suspend, |
3865 | + .check_power_status = stac_check_power_status, |
3866 | #endif |
3867 | .reboot_notify = stac_shutup, |
3868 | }; |
3869 | diff --git a/sound/soc/codecs/nau8824.c b/sound/soc/codecs/nau8824.c |
3870 | index c8ccfa2fff848..a95fe3fff1db8 100644 |
3871 | --- a/sound/soc/codecs/nau8824.c |
3872 | +++ b/sound/soc/codecs/nau8824.c |
3873 | @@ -1072,6 +1072,7 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream, |
3874 | struct snd_soc_component *component = dai->component; |
3875 | struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component); |
3876 | unsigned int val_len = 0, osr, ctrl_val, bclk_fs, bclk_div; |
3877 | + int err = -EINVAL; |
3878 | |
3879 | nau8824_sema_acquire(nau8824, HZ); |
3880 | |
3881 | @@ -1088,7 +1089,7 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream, |
3882 | osr &= NAU8824_DAC_OVERSAMPLE_MASK; |
3883 | if (nau8824_clock_check(nau8824, substream->stream, |
3884 | nau8824->fs, osr)) |
3885 | - return -EINVAL; |
3886 | + goto error; |
3887 | regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER, |
3888 | NAU8824_CLK_DAC_SRC_MASK, |
3889 | osr_dac_sel[osr].clk_src << NAU8824_CLK_DAC_SRC_SFT); |
3890 | @@ -1098,7 +1099,7 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream, |
3891 | osr &= NAU8824_ADC_SYNC_DOWN_MASK; |
3892 | if (nau8824_clock_check(nau8824, substream->stream, |
3893 | nau8824->fs, osr)) |
3894 | - return -EINVAL; |
3895 | + goto error; |
3896 | regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER, |
3897 | NAU8824_CLK_ADC_SRC_MASK, |
3898 | osr_adc_sel[osr].clk_src << NAU8824_CLK_ADC_SRC_SFT); |
3899 | @@ -1119,7 +1120,7 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream, |
3900 | else if (bclk_fs <= 256) |
3901 | bclk_div = 0; |
3902 | else |
3903 | - return -EINVAL; |
3904 | + goto error; |
3905 | regmap_update_bits(nau8824->regmap, |
3906 | NAU8824_REG_PORT0_I2S_PCM_CTRL_2, |
3907 | NAU8824_I2S_LRC_DIV_MASK | NAU8824_I2S_BLK_DIV_MASK, |
3908 | @@ -1140,15 +1141,17 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream, |
3909 | val_len |= NAU8824_I2S_DL_32; |
3910 | break; |
3911 | default: |
3912 | - return -EINVAL; |
3913 | + goto error; |
3914 | } |
3915 | |
3916 | regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_1, |
3917 | NAU8824_I2S_DL_MASK, val_len); |
3918 | + err = 0; |
3919 | |
3920 | + error: |
3921 | nau8824_sema_release(nau8824); |
3922 | |
3923 | - return 0; |
3924 | + return err; |
3925 | } |
3926 | |
3927 | static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) |
3928 | @@ -1157,8 +1160,6 @@ static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) |
3929 | struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component); |
3930 | unsigned int ctrl1_val = 0, ctrl2_val = 0; |
3931 | |
3932 | - nau8824_sema_acquire(nau8824, HZ); |
3933 | - |
3934 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
3935 | case SND_SOC_DAIFMT_CBM_CFM: |
3936 | ctrl2_val |= NAU8824_I2S_MS_MASTER; |
3937 | @@ -1200,6 +1201,8 @@ static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) |
3938 | return -EINVAL; |
3939 | } |
3940 | |
3941 | + nau8824_sema_acquire(nau8824, HZ); |
3942 | + |
3943 | regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_1, |
3944 | NAU8824_I2S_DF_MASK | NAU8824_I2S_BP_MASK | |
3945 | NAU8824_I2S_PCMB_EN, ctrl1_val); |
3946 | diff --git a/tools/perf/util/genelf.c b/tools/perf/util/genelf.c |
3947 | index 17b74aba8b9a2..69744fd5db395 100644 |
3948 | --- a/tools/perf/util/genelf.c |
3949 | +++ b/tools/perf/util/genelf.c |
3950 | @@ -256,6 +256,7 @@ jit_write_elf(int fd, uint64_t load_addr, const char *sym, |
3951 | Elf_Data *d; |
3952 | Elf_Scn *scn; |
3953 | Elf_Ehdr *ehdr; |
3954 | + Elf_Phdr *phdr; |
3955 | Elf_Shdr *shdr; |
3956 | uint64_t eh_frame_base_offset; |
3957 | char *strsym = NULL; |
3958 | @@ -290,6 +291,19 @@ jit_write_elf(int fd, uint64_t load_addr, const char *sym, |
3959 | ehdr->e_version = EV_CURRENT; |
3960 | ehdr->e_shstrndx= unwinding ? 4 : 2; /* shdr index for section name */ |
3961 | |
3962 | + /* |
3963 | + * setup program header |
3964 | + */ |
3965 | + phdr = elf_newphdr(e, 1); |
3966 | + phdr[0].p_type = PT_LOAD; |
3967 | + phdr[0].p_offset = 0; |
3968 | + phdr[0].p_vaddr = 0; |
3969 | + phdr[0].p_paddr = 0; |
3970 | + phdr[0].p_filesz = csize; |
3971 | + phdr[0].p_memsz = csize; |
3972 | + phdr[0].p_flags = PF_X | PF_R; |
3973 | + phdr[0].p_align = 8; |
3974 | + |
3975 | /* |
3976 | * setup text section |
3977 | */ |
3978 | diff --git a/tools/perf/util/genelf.h b/tools/perf/util/genelf.h |
3979 | index d4137559be053..ac638945b4cb0 100644 |
3980 | --- a/tools/perf/util/genelf.h |
3981 | +++ b/tools/perf/util/genelf.h |
3982 | @@ -50,8 +50,10 @@ int jit_add_debug_info(Elf *e, uint64_t code_addr, void *debug, int nr_debug_ent |
3983 | |
3984 | #if GEN_ELF_CLASS == ELFCLASS64 |
3985 | #define elf_newehdr elf64_newehdr |
3986 | +#define elf_newphdr elf64_newphdr |
3987 | #define elf_getshdr elf64_getshdr |
3988 | #define Elf_Ehdr Elf64_Ehdr |
3989 | +#define Elf_Phdr Elf64_Phdr |
3990 | #define Elf_Shdr Elf64_Shdr |
3991 | #define Elf_Sym Elf64_Sym |
3992 | #define ELF_ST_TYPE(a) ELF64_ST_TYPE(a) |
3993 | @@ -59,8 +61,10 @@ int jit_add_debug_info(Elf *e, uint64_t code_addr, void *debug, int nr_debug_ent |
3994 | #define ELF_ST_VIS(a) ELF64_ST_VISIBILITY(a) |
3995 | #else |
3996 | #define elf_newehdr elf32_newehdr |
3997 | +#define elf_newphdr elf32_newphdr |
3998 | #define elf_getshdr elf32_getshdr |
3999 | #define Elf_Ehdr Elf32_Ehdr |
4000 | +#define Elf_Phdr Elf32_Phdr |
4001 | #define Elf_Shdr Elf32_Shdr |
4002 | #define Elf_Sym Elf32_Sym |
4003 | #define ELF_ST_TYPE(a) ELF32_ST_TYPE(a) |
4004 | diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c |
4005 | index a04a7dfb8ec09..f15258fbe9dbf 100644 |
4006 | --- a/tools/perf/util/symbol-elf.c |
4007 | +++ b/tools/perf/util/symbol-elf.c |
4008 | @@ -1912,8 +1912,8 @@ static int kcore_copy__compare_file(const char *from_dir, const char *to_dir, |
4009 | * unusual. One significant peculiarity is that the mapping (start -> pgoff) |
4010 | * is not the same for the kernel map and the modules map. That happens because |
4011 | * the data is copied adjacently whereas the original kcore has gaps. Finally, |
4012 | - * kallsyms and modules files are compared with their copies to check that |
4013 | - * modules have not been loaded or unloaded while the copies were taking place. |
4014 | + * kallsyms file is compared with its copy to check that modules have not been |
4015 | + * loaded or unloaded while the copies were taking place. |
4016 | * |
4017 | * Return: %0 on success, %-1 on failure. |
4018 | */ |
4019 | @@ -1976,9 +1976,6 @@ int kcore_copy(const char *from_dir, const char *to_dir) |
4020 | goto out_extract_close; |
4021 | } |
4022 | |
4023 | - if (kcore_copy__compare_file(from_dir, to_dir, "modules")) |
4024 | - goto out_extract_close; |
4025 | - |
4026 | if (kcore_copy__compare_file(from_dir, to_dir, "kallsyms")) |
4027 | goto out_extract_close; |
4028 |