Annotation of /trunk/kernel-alx/patches-5.4/0314-5.4.215-all-fixes.patch
Parent Directory | Revision Log
Revision 3635 -
(hide annotations)
(download)
Mon Oct 24 12:34:12 2022 UTC (19 months, 2 weeks ago) by niro
File size: 132438 byte(s)
Mon Oct 24 12:34:12 2022 UTC (19 months, 2 weeks ago) by niro
File size: 132438 byte(s)
-sync kernel patches
1 | niro | 3635 | 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 |