Merge 6.1.127 into android14-6.1-lts

Changes in 6.1.127
	net: ethernet: ti: cpsw_ale: Fix cpsw_ale_get_field()
	bpf: Fix bpf_sk_select_reuseport() memory leak
	openvswitch: fix lockup on tx to unregistering netdev with carrier
	pktgen: Avoid out-of-bounds access in get_imix_entries
	net: add exit_batch_rtnl() method
	gtp: use exit_batch_rtnl() method
	gtp: Use for_each_netdev_rcu() in gtp_genl_dump_pdp().
	gtp: Destroy device along with udp socket's netns dismantle.
	nfp: bpf: prevent integer overflow in nfp_bpf_event_output()
	net: xilinx: axienet: Fix IRQ coalescing packet count overflow
	net/mlx5: Fix RDMA TX steering prio
	net/mlx5: Clear port select structure when fail to create
	drm/v3d: Ensure job pointer is set to NULL after job completion
	hwmon: (tmp513) Fix division of negative numbers
	Revert "mtd: spi-nor: core: replace dummy buswidth from addr to data"
	i2c: mux: demux-pinctrl: check initial mux selection, too
	i2c: rcar: fix NACK handling when being a target
	nvmet: propagate npwg topology
	mac802154: check local interfaces before deleting sdata list
	hfs: Sanity check the root record
	fs: fix missing declaration of init_files
	kheaders: Ignore silly-rename files
	cachefiles: Parse the "secctx" immediately
	scsi: ufs: core: Honor runtime/system PM levels if set by host controller drivers
	selftests: tc-testing: reduce rshift value
	ACPI: resource: acpi_dev_irq_override(): Check DMI match last
	iomap: avoid avoid truncating 64-bit offset to 32 bits
	poll_wait: add mb() to fix theoretical race between waitqueue_active() and .poll()
	x86/asm: Make serialize() always_inline
	ALSA: hda/realtek: Add support for Ayaneo System using CS35L41 HDA
	zram: fix potential UAF of zram table
	mptcp: be sure to send ack when mptcp-level window re-opens
	selftests: mptcp: avoid spurious errors on disconnect
	net: ethernet: xgbe: re-add aneg to supported features in PHY quirks
	vsock/virtio: discard packets if the transport changes
	vsock/virtio: cancel close work in the destructor
	vsock: reset socket state when de-assigning the transport
	vsock: prevent null-ptr-deref in vsock_*[has_data|has_space]
	filemap: avoid truncating 64-bit offset to 32 bits
	fs/proc: fix softlockup in __read_vmcore (part 2)
	gpiolib: cdev: Fix use after free in lineinfo_changed_notify
	pmdomain: imx8mp-blk-ctrl: add missing loop break condition
	irqchip: Plug a OF node reference leak in platform_irqchip_probe()
	irqchip/gic-v3: Handle CPU_PM_ENTER_FAILED correctly
	irqchip/gic-v3-its: Don't enable interrupts in its_irq_set_vcpu_affinity()
	hrtimers: Handle CPU state correctly on hotplug
	drm/i915/fb: Relax clear color alignment to 64 bytes
	Revert "PCI: Use preserve_config in place of pci_flags"
	iio: imu: inv_icm42600: fix spi burst write not supported
	iio: imu: inv_icm42600: fix timestamps after suspend if sensor is on
	iio: adc: rockchip_saradc: fix information leak in triggered buffer
	drm/amd/display: Fix out-of-bounds access in 'dcn21_link_encoder_create'
	drm/amdgpu: fix usage slab after free
	block: fix uaf for flush rq while iterating tags
	Revert "drm/amdgpu: rework resume handling for display (v2)"
	RDMA/rxe: Fix the qp flush warnings in req
	scsi: sg: Fix slab-use-after-free read in sg_release()
	Revert "regmap: detach regmap from dev on regmap_exit"
	wifi: ath10k: avoid NULL pointer error during sdio remove
	erofs: tidy up EROFS on-disk naming
	erofs: handle NONHEAD !delta[1] lclusters gracefully
	nfsd: add list_head nf_gc to struct nfsd_file
	x86/xen: fix SLS mitigation in xen_hypercall_iret()
	net: fix data-races around sk->sk_forward_alloc
	Linux 6.1.127

Change-Id: I5621f4287b21d7fbcc2f19d46e02d97afe5f0451
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman
2025-02-06 09:44:41 +00:00
68 changed files with 461 additions and 369 deletions

View File

@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
VERSION = 6 VERSION = 6
PATCHLEVEL = 1 PATCHLEVEL = 1
SUBLEVEL = 126 SUBLEVEL = 127
EXTRAVERSION = EXTRAVERSION =
NAME = Curry Ramen NAME = Curry Ramen

View File

@@ -225,7 +225,7 @@ static inline void clwb(volatile void *__p)
#define nop() asm volatile ("nop") #define nop() asm volatile ("nop")
static inline void serialize(void) static __always_inline void serialize(void)
{ {
/* Instruction opcode for SERIALIZE; supported in binutils >= 2.35. */ /* Instruction opcode for SERIALIZE; supported in binutils >= 2.35. */
asm volatile(".byte 0xf, 0x1, 0xe8" ::: "memory"); asm volatile(".byte 0xf, 0x1, 0xe8" ::: "memory");

View File

@@ -221,7 +221,7 @@ SYM_CODE_END(xen_early_idt_handler_array)
push %rax push %rax
mov $__HYPERVISOR_iret, %eax mov $__HYPERVISOR_iret, %eax
syscall /* Do the IRET. */ syscall /* Do the IRET. */
#ifdef CONFIG_MITIGATION_SLS #ifdef CONFIG_SLS
int3 int3
#endif #endif
.endm .endm

View File

@@ -860,10 +860,8 @@ unlock:
* faster to shut down and is made fully functional here as * faster to shut down and is made fully functional here as
* request_queues for non-existent devices never get registered. * request_queues for non-existent devices never get registered.
*/ */
if (!blk_queue_init_done(q)) { blk_queue_flag_set(QUEUE_FLAG_INIT_DONE, q);
blk_queue_flag_set(QUEUE_FLAG_INIT_DONE, q); percpu_ref_switch_to_percpu(&q->q_usage_counter);
percpu_ref_switch_to_percpu(&q->q_usage_counter);
}
return ret; return ret;

View File

@@ -687,13 +687,10 @@ void del_gendisk(struct gendisk *disk)
* If the disk does not own the queue, allow using passthrough requests * If the disk does not own the queue, allow using passthrough requests
* again. Else leave the queue frozen to fail all I/O. * again. Else leave the queue frozen to fail all I/O.
*/ */
if (!test_bit(GD_OWNS_QUEUE, &disk->state)) { if (!test_bit(GD_OWNS_QUEUE, &disk->state))
blk_queue_flag_clear(QUEUE_FLAG_INIT_DONE, q);
__blk_mq_unfreeze_queue(q, true); __blk_mq_unfreeze_queue(q, true);
} else { else if (queue_is_mq(q))
if (queue_is_mq(q)) blk_mq_exit_queue(q);
blk_mq_exit_queue(q);
}
} }
EXPORT_SYMBOL(del_gendisk); EXPORT_SYMBOL(del_gendisk);

View File

@@ -663,11 +663,11 @@ static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity,
for (i = 0; i < ARRAY_SIZE(override_table); i++) { for (i = 0; i < ARRAY_SIZE(override_table); i++) {
const struct irq_override_cmp *entry = &override_table[i]; const struct irq_override_cmp *entry = &override_table[i];
if (dmi_check_system(entry->system) && if (entry->irq == gsi &&
entry->irq == gsi &&
entry->triggering == triggering && entry->triggering == triggering &&
entry->polarity == polarity && entry->polarity == polarity &&
entry->shareable == shareable) entry->shareable == shareable &&
dmi_check_system(entry->system))
return entry->override; return entry->override;
} }

View File

@@ -652,17 +652,6 @@ int regmap_attach_dev(struct device *dev, struct regmap *map,
} }
EXPORT_SYMBOL_GPL(regmap_attach_dev); EXPORT_SYMBOL_GPL(regmap_attach_dev);
static int dev_get_regmap_match(struct device *dev, void *res, void *data);
static int regmap_detach_dev(struct device *dev, struct regmap *map)
{
if (!dev)
return 0;
return devres_release(dev, dev_get_regmap_release,
dev_get_regmap_match, (void *)map->name);
}
static enum regmap_endian regmap_get_reg_endian(const struct regmap_bus *bus, static enum regmap_endian regmap_get_reg_endian(const struct regmap_bus *bus,
const struct regmap_config *config) const struct regmap_config *config)
{ {
@@ -1513,7 +1502,6 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
{ {
int ret; int ret;
regmap_detach_dev(map->dev, map);
regcache_exit(map); regcache_exit(map);
regmap_debugfs_exit(map); regmap_debugfs_exit(map);

View File

@@ -1192,6 +1192,7 @@ static bool zram_meta_alloc(struct zram *zram, u64 disksize)
zram->mem_pool = zs_create_pool(zram->disk->disk_name); zram->mem_pool = zs_create_pool(zram->disk->disk_name);
if (!zram->mem_pool) { if (!zram->mem_pool) {
vfree(zram->table); vfree(zram->table);
zram->table = NULL;
return false; return false;
} }

View File

@@ -2860,9 +2860,9 @@ static int gpio_chrdev_release(struct inode *inode, struct file *file)
struct gpio_chardev_data *cdev = file->private_data; struct gpio_chardev_data *cdev = file->private_data;
struct gpio_device *gdev = cdev->gdev; struct gpio_device *gdev = cdev->gdev;
bitmap_free(cdev->watched_lines);
blocking_notifier_chain_unregister(&gdev->notifier, blocking_notifier_chain_unregister(&gdev->notifier,
&cdev->lineinfo_changed_nb); &cdev->lineinfo_changed_nb);
bitmap_free(cdev->watched_lines);
put_device(&gdev->dev); put_device(&gdev->dev);
kfree(cdev); kfree(cdev);

View File

@@ -3242,7 +3242,7 @@ static int amdgpu_device_ip_resume_phase1(struct amdgpu_device *adev)
* *
* @adev: amdgpu_device pointer * @adev: amdgpu_device pointer
* *
* Second resume function for hardware IPs. The list of all the hardware * First resume function for hardware IPs. The list of all the hardware
* IPs that make up the asic is walked and the resume callbacks are run for * IPs that make up the asic is walked and the resume callbacks are run for
* all blocks except COMMON, GMC, and IH. resume puts the hardware into a * all blocks except COMMON, GMC, and IH. resume puts the hardware into a
* functional state after a suspend and updates the software state as * functional state after a suspend and updates the software state as
@@ -3260,7 +3260,6 @@ static int amdgpu_device_ip_resume_phase2(struct amdgpu_device *adev)
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON || if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON ||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC || adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC ||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH || adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH ||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_DCE ||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP) adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP)
continue; continue;
r = adev->ip_blocks[i].version->funcs->resume(adev); r = adev->ip_blocks[i].version->funcs->resume(adev);
@@ -3284,36 +3283,6 @@ static int amdgpu_device_ip_resume_phase2(struct amdgpu_device *adev)
return 0; return 0;
} }
/**
* amdgpu_device_ip_resume_phase3 - run resume for hardware IPs
*
* @adev: amdgpu_device pointer
*
* Third resume function for hardware IPs. The list of all the hardware
* IPs that make up the asic is walked and the resume callbacks are run for
* all DCE. resume puts the hardware into a functional state after a suspend
* and updates the software state as necessary. This function is also used
* for restoring the GPU after a GPU reset.
*
* Returns 0 on success, negative error code on failure.
*/
static int amdgpu_device_ip_resume_phase3(struct amdgpu_device *adev)
{
int i, r;
for (i = 0; i < adev->num_ip_blocks; i++) {
if (!adev->ip_blocks[i].status.valid || adev->ip_blocks[i].status.hw)
continue;
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_DCE) {
r = adev->ip_blocks[i].version->funcs->resume(adev);
if (r)
return r;
}
}
return 0;
}
/** /**
* amdgpu_device_ip_resume - run resume for hardware IPs * amdgpu_device_ip_resume - run resume for hardware IPs
* *
@@ -3344,13 +3313,6 @@ static int amdgpu_device_ip_resume(struct amdgpu_device *adev)
r = amdgpu_device_ip_resume_phase2(adev); r = amdgpu_device_ip_resume_phase2(adev);
if (r)
return r;
amdgpu_fence_driver_hw_init(adev);
r = amdgpu_device_ip_resume_phase3(adev);
return r; return r;
} }
@@ -4131,8 +4093,8 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev)
int idx; int idx;
bool px; bool px;
amdgpu_fence_driver_sw_fini(adev);
amdgpu_device_ip_fini(adev); amdgpu_device_ip_fini(adev);
amdgpu_fence_driver_sw_fini(adev);
release_firmware(adev->firmware.gpu_info_fw); release_firmware(adev->firmware.gpu_info_fw);
adev->firmware.gpu_info_fw = NULL; adev->firmware.gpu_info_fw = NULL;
adev->accel_working = false; adev->accel_working = false;
@@ -4349,6 +4311,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
dev_err(adev->dev, "amdgpu_device_ip_resume failed (%d).\n", r); dev_err(adev->dev, "amdgpu_device_ip_resume failed (%d).\n", r);
return r; return r;
} }
amdgpu_fence_driver_hw_init(adev);
r = amdgpu_device_ip_late_init(adev); r = amdgpu_device_ip_late_init(adev);
if (r) if (r)
@@ -5102,10 +5065,6 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
if (r) if (r)
goto out; goto out;
r = amdgpu_device_ip_resume_phase3(tmp_adev);
if (r)
goto out;
if (vram_lost) if (vram_lost)
amdgpu_device_fill_reset_magic(tmp_adev); amdgpu_device_fill_reset_magic(tmp_adev);

View File

@@ -220,15 +220,15 @@ int amdgpu_vce_sw_fini(struct amdgpu_device *adev)
drm_sched_entity_destroy(&adev->vce.entity); drm_sched_entity_destroy(&adev->vce.entity);
amdgpu_bo_free_kernel(&adev->vce.vcpu_bo, &adev->vce.gpu_addr,
(void **)&adev->vce.cpu_addr);
for (i = 0; i < adev->vce.num_rings; i++) for (i = 0; i < adev->vce.num_rings; i++)
amdgpu_ring_fini(&adev->vce.ring[i]); amdgpu_ring_fini(&adev->vce.ring[i]);
release_firmware(adev->vce.fw); release_firmware(adev->vce.fw);
mutex_destroy(&adev->vce.idle_mutex); mutex_destroy(&adev->vce.idle_mutex);
amdgpu_bo_free_kernel(&adev->vce.vcpu_bo, &adev->vce.gpu_addr,
(void **)&adev->vce.cpu_addr);
return 0; return 0;
} }

View File

@@ -1340,7 +1340,7 @@ static struct link_encoder *dcn21_link_encoder_create(
kzalloc(sizeof(struct dcn21_link_encoder), GFP_KERNEL); kzalloc(sizeof(struct dcn21_link_encoder), GFP_KERNEL);
int link_regs_id; int link_regs_id;
if (!enc21) if (!enc21 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs))
return NULL; return NULL;
link_regs_id = link_regs_id =

View File

@@ -1571,7 +1571,7 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *
* arithmetic related to alignment and offset calculation. * arithmetic related to alignment and offset calculation.
*/ */
if (is_gen12_ccs_cc_plane(&fb->base, i)) { if (is_gen12_ccs_cc_plane(&fb->base, i)) {
if (IS_ALIGNED(fb->base.offsets[i], PAGE_SIZE)) if (IS_ALIGNED(fb->base.offsets[i], 64))
continue; continue;
else else
return -EINVAL; return -EINVAL;

View File

@@ -103,6 +103,7 @@ v3d_irq(int irq, void *arg)
trace_v3d_bcl_irq(&v3d->drm, fence->seqno); trace_v3d_bcl_irq(&v3d->drm, fence->seqno);
dma_fence_signal(&fence->base); dma_fence_signal(&fence->base);
v3d->bin_job = NULL;
status = IRQ_HANDLED; status = IRQ_HANDLED;
} }
@@ -112,6 +113,7 @@ v3d_irq(int irq, void *arg)
trace_v3d_rcl_irq(&v3d->drm, fence->seqno); trace_v3d_rcl_irq(&v3d->drm, fence->seqno);
dma_fence_signal(&fence->base); dma_fence_signal(&fence->base);
v3d->render_job = NULL;
status = IRQ_HANDLED; status = IRQ_HANDLED;
} }
@@ -121,6 +123,7 @@ v3d_irq(int irq, void *arg)
trace_v3d_csd_irq(&v3d->drm, fence->seqno); trace_v3d_csd_irq(&v3d->drm, fence->seqno);
dma_fence_signal(&fence->base); dma_fence_signal(&fence->base);
v3d->csd_job = NULL;
status = IRQ_HANDLED; status = IRQ_HANDLED;
} }
@@ -157,6 +160,7 @@ v3d_hub_irq(int irq, void *arg)
trace_v3d_tfu_irq(&v3d->drm, fence->seqno); trace_v3d_tfu_irq(&v3d->drm, fence->seqno);
dma_fence_signal(&fence->base); dma_fence_signal(&fence->base);
v3d->tfu_job = NULL;
status = IRQ_HANDLED; status = IRQ_HANDLED;
} }

View File

@@ -203,7 +203,8 @@ static int tmp51x_get_value(struct tmp51x_data *data, u8 reg, u8 pos,
*val = sign_extend32(regval, *val = sign_extend32(regval,
reg == TMP51X_SHUNT_CURRENT_RESULT ? reg == TMP51X_SHUNT_CURRENT_RESULT ?
16 - tmp51x_get_pga_shift(data) : 15); 16 - tmp51x_get_pga_shift(data) : 15);
*val = DIV_ROUND_CLOSEST(*val * 10 * MILLI, data->shunt_uohms); *val = DIV_ROUND_CLOSEST(*val * 10 * (long)MILLI, (long)data->shunt_uohms);
break; break;
case TMP51X_BUS_VOLTAGE_RESULT: case TMP51X_BUS_VOLTAGE_RESULT:
case TMP51X_BUS_VOLTAGE_H_LIMIT: case TMP51X_BUS_VOLTAGE_H_LIMIT:
@@ -219,7 +220,7 @@ static int tmp51x_get_value(struct tmp51x_data *data, u8 reg, u8 pos,
case TMP51X_BUS_CURRENT_RESULT: case TMP51X_BUS_CURRENT_RESULT:
// Current = (ShuntVoltage * CalibrationRegister) / 4096 // Current = (ShuntVoltage * CalibrationRegister) / 4096
*val = sign_extend32(regval, 15) * (long)data->curr_lsb_ua; *val = sign_extend32(regval, 15) * (long)data->curr_lsb_ua;
*val = DIV_ROUND_CLOSEST(*val, MILLI); *val = DIV_ROUND_CLOSEST(*val, (long)MILLI);
break; break;
case TMP51X_LOCAL_TEMP_RESULT: case TMP51X_LOCAL_TEMP_RESULT:
case TMP51X_REMOTE_TEMP_RESULT_1: case TMP51X_REMOTE_TEMP_RESULT_1:
@@ -259,7 +260,7 @@ static int tmp51x_set_value(struct tmp51x_data *data, u8 reg, long val)
* The user enter current value and we convert it to * The user enter current value and we convert it to
* voltage. 1lsb = 10uV * voltage. 1lsb = 10uV
*/ */
val = DIV_ROUND_CLOSEST(val * data->shunt_uohms, 10 * MILLI); val = DIV_ROUND_CLOSEST(val * (long)data->shunt_uohms, 10 * (long)MILLI);
max_val = U16_MAX >> tmp51x_get_pga_shift(data); max_val = U16_MAX >> tmp51x_get_pga_shift(data);
regval = clamp_val(val, -max_val, max_val); regval = clamp_val(val, -max_val, max_val);
break; break;

View File

@@ -110,6 +110,8 @@
#define ID_P_PM_BLOCKED BIT(31) #define ID_P_PM_BLOCKED BIT(31)
#define ID_P_MASK GENMASK(31, 28) #define ID_P_MASK GENMASK(31, 28)
#define ID_SLAVE_NACK BIT(0)
enum rcar_i2c_type { enum rcar_i2c_type {
I2C_RCAR_GEN1, I2C_RCAR_GEN1,
I2C_RCAR_GEN2, I2C_RCAR_GEN2,
@@ -143,6 +145,7 @@ struct rcar_i2c_priv {
int irq; int irq;
struct i2c_client *host_notify_client; struct i2c_client *host_notify_client;
u8 slave_flags;
}; };
#define rcar_i2c_priv_to_dev(p) ((p)->adap.dev.parent) #define rcar_i2c_priv_to_dev(p) ((p)->adap.dev.parent)
@@ -597,6 +600,7 @@ static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv)
{ {
u32 ssr_raw, ssr_filtered; u32 ssr_raw, ssr_filtered;
u8 value; u8 value;
int ret;
ssr_raw = rcar_i2c_read(priv, ICSSR) & 0xff; ssr_raw = rcar_i2c_read(priv, ICSSR) & 0xff;
ssr_filtered = ssr_raw & rcar_i2c_read(priv, ICSIER); ssr_filtered = ssr_raw & rcar_i2c_read(priv, ICSIER);
@@ -612,7 +616,10 @@ static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv)
rcar_i2c_write(priv, ICRXTX, value); rcar_i2c_write(priv, ICRXTX, value);
rcar_i2c_write(priv, ICSIER, SDE | SSR | SAR); rcar_i2c_write(priv, ICSIER, SDE | SSR | SAR);
} else { } else {
i2c_slave_event(priv->slave, I2C_SLAVE_WRITE_REQUESTED, &value); ret = i2c_slave_event(priv->slave, I2C_SLAVE_WRITE_REQUESTED, &value);
if (ret)
priv->slave_flags |= ID_SLAVE_NACK;
rcar_i2c_read(priv, ICRXTX); /* dummy read */ rcar_i2c_read(priv, ICRXTX); /* dummy read */
rcar_i2c_write(priv, ICSIER, SDR | SSR | SAR); rcar_i2c_write(priv, ICSIER, SDR | SSR | SAR);
} }
@@ -625,18 +632,21 @@ static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv)
if (ssr_filtered & SSR) { if (ssr_filtered & SSR) {
i2c_slave_event(priv->slave, I2C_SLAVE_STOP, &value); i2c_slave_event(priv->slave, I2C_SLAVE_STOP, &value);
rcar_i2c_write(priv, ICSCR, SIE | SDBS); /* clear our NACK */ rcar_i2c_write(priv, ICSCR, SIE | SDBS); /* clear our NACK */
priv->slave_flags &= ~ID_SLAVE_NACK;
rcar_i2c_write(priv, ICSIER, SAR); rcar_i2c_write(priv, ICSIER, SAR);
rcar_i2c_write(priv, ICSSR, ~SSR & 0xff); rcar_i2c_write(priv, ICSSR, ~SSR & 0xff);
} }
/* master wants to write to us */ /* master wants to write to us */
if (ssr_filtered & SDR) { if (ssr_filtered & SDR) {
int ret;
value = rcar_i2c_read(priv, ICRXTX); value = rcar_i2c_read(priv, ICRXTX);
ret = i2c_slave_event(priv->slave, I2C_SLAVE_WRITE_RECEIVED, &value); ret = i2c_slave_event(priv->slave, I2C_SLAVE_WRITE_RECEIVED, &value);
/* Send NACK in case of error */ if (ret)
rcar_i2c_write(priv, ICSCR, SIE | SDBS | (ret < 0 ? FNA : 0)); priv->slave_flags |= ID_SLAVE_NACK;
/* Send NACK in case of error, but it will come 1 byte late :( */
rcar_i2c_write(priv, ICSCR, SIE | SDBS |
(priv->slave_flags & ID_SLAVE_NACK ? FNA : 0));
rcar_i2c_write(priv, ICSSR, ~SDR & 0xff); rcar_i2c_write(priv, ICSSR, ~SDR & 0xff);
} }

View File

@@ -261,7 +261,9 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev)
pm_runtime_no_callbacks(&pdev->dev); pm_runtime_no_callbacks(&pdev->dev);
/* switch to first parent as active master */ /* switch to first parent as active master */
i2c_demux_activate_master(priv, 0); err = i2c_demux_activate_master(priv, 0);
if (err)
goto err_rollback;
err = device_create_file(&pdev->dev, &dev_attr_available_masters); err = device_create_file(&pdev->dev, &dev_attr_available_masters);
if (err) if (err)

View File

@@ -270,6 +270,8 @@ static irqreturn_t rockchip_saradc_trigger_handler(int irq, void *p)
int ret; int ret;
int i, j = 0; int i, j = 0;
memset(&data, 0, sizeof(data));
mutex_lock(&i_dev->mlock); mutex_lock(&i_dev->mlock);
for_each_set_bit(i, i_dev->active_scan_mask, i_dev->masklength) { for_each_set_bit(i, i_dev->active_scan_mask, i_dev->masklength) {

View File

@@ -360,6 +360,7 @@ struct inv_icm42600_state {
typedef int (*inv_icm42600_bus_setup)(struct inv_icm42600_state *); typedef int (*inv_icm42600_bus_setup)(struct inv_icm42600_state *);
extern const struct regmap_config inv_icm42600_regmap_config; extern const struct regmap_config inv_icm42600_regmap_config;
extern const struct regmap_config inv_icm42600_spi_regmap_config;
extern const struct dev_pm_ops inv_icm42600_pm_ops; extern const struct dev_pm_ops inv_icm42600_pm_ops;
const struct iio_mount_matrix * const struct iio_mount_matrix *

View File

@@ -43,6 +43,17 @@ const struct regmap_config inv_icm42600_regmap_config = {
}; };
EXPORT_SYMBOL_GPL(inv_icm42600_regmap_config); EXPORT_SYMBOL_GPL(inv_icm42600_regmap_config);
/* define specific regmap for SPI not supporting burst write */
const struct regmap_config inv_icm42600_spi_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 0x4FFF,
.ranges = inv_icm42600_regmap_ranges,
.num_ranges = ARRAY_SIZE(inv_icm42600_regmap_ranges),
.use_single_write = true,
};
EXPORT_SYMBOL_GPL(inv_icm42600_spi_regmap_config);
struct inv_icm42600_hw { struct inv_icm42600_hw {
uint8_t whoami; uint8_t whoami;
const char *name; const char *name;
@@ -709,6 +720,8 @@ out_unlock:
static int __maybe_unused inv_icm42600_resume(struct device *dev) static int __maybe_unused inv_icm42600_resume(struct device *dev)
{ {
struct inv_icm42600_state *st = dev_get_drvdata(dev); struct inv_icm42600_state *st = dev_get_drvdata(dev);
struct inv_icm42600_timestamp *gyro_ts = iio_priv(st->indio_gyro);
struct inv_icm42600_timestamp *accel_ts = iio_priv(st->indio_accel);
int ret; int ret;
mutex_lock(&st->lock); mutex_lock(&st->lock);
@@ -729,9 +742,12 @@ static int __maybe_unused inv_icm42600_resume(struct device *dev)
goto out_unlock; goto out_unlock;
/* restore FIFO data streaming */ /* restore FIFO data streaming */
if (st->fifo.on) if (st->fifo.on) {
inv_icm42600_timestamp_reset(gyro_ts);
inv_icm42600_timestamp_reset(accel_ts);
ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG, ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG,
INV_ICM42600_FIFO_CONFIG_STREAM); INV_ICM42600_FIFO_CONFIG_STREAM);
}
out_unlock: out_unlock:
mutex_unlock(&st->lock); mutex_unlock(&st->lock);

View File

@@ -59,7 +59,8 @@ static int inv_icm42600_probe(struct spi_device *spi)
return -EINVAL; return -EINVAL;
chip = (uintptr_t)match; chip = (uintptr_t)match;
regmap = devm_regmap_init_spi(spi, &inv_icm42600_regmap_config); /* use SPI specific regmap */
regmap = devm_regmap_init_spi(spi, &inv_icm42600_spi_regmap_config);
if (IS_ERR(regmap)) if (IS_ERR(regmap))
return PTR_ERR(regmap); return PTR_ERR(regmap);

View File

@@ -643,13 +643,15 @@ int rxe_requester(void *arg)
if (unlikely(qp->req.state == QP_STATE_ERROR)) { if (unlikely(qp->req.state == QP_STATE_ERROR)) {
wqe = req_next_wqe(qp); wqe = req_next_wqe(qp);
if (wqe) if (wqe) {
/* /*
* Generate an error completion for error qp state * Generate an error completion for error qp state
*/ */
wqe->status = IB_WC_WR_FLUSH_ERR;
goto err; goto err;
else } else {
goto exit; goto exit;
}
} }
if (unlikely(qp->req.state == QP_STATE_RESET)) { if (unlikely(qp->req.state == QP_STATE_RESET)) {

View File

@@ -1967,7 +1967,7 @@ static int its_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
if (!is_v4(its_dev->its)) if (!is_v4(its_dev->its))
return -EINVAL; return -EINVAL;
guard(raw_spinlock_irq)(&its_dev->event_map.vlpi_lock); guard(raw_spinlock)(&its_dev->event_map.vlpi_lock);
/* Unmap request? */ /* Unmap request? */
if (!info) if (!info)

View File

@@ -1428,7 +1428,7 @@ static int gic_retrigger(struct irq_data *data)
static int gic_cpu_pm_notifier(struct notifier_block *self, static int gic_cpu_pm_notifier(struct notifier_block *self,
unsigned long cmd, void *v) unsigned long cmd, void *v)
{ {
if (cmd == CPU_PM_EXIT) { if (cmd == CPU_PM_EXIT || cmd == CPU_PM_ENTER_FAILED) {
if (gic_dist_security_disabled()) if (gic_dist_security_disabled())
gic_enable_redist(true); gic_enable_redist(true);
gic_cpu_sys_reg_init(); gic_cpu_sys_reg_init();

View File

@@ -35,11 +35,10 @@ void __init irqchip_init(void)
int platform_irqchip_probe(struct platform_device *pdev) int platform_irqchip_probe(struct platform_device *pdev)
{ {
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
struct device_node *par_np = of_irq_find_parent(np); struct device_node *par_np __free(device_node) = of_irq_find_parent(np);
of_irq_init_cb_t irq_init_cb = of_device_get_match_data(&pdev->dev); of_irq_init_cb_t irq_init_cb = of_device_get_match_data(&pdev->dev);
if (!irq_init_cb) { if (!irq_init_cb) {
of_node_put(par_np);
return -EINVAL; return -EINVAL;
} }
@@ -55,7 +54,6 @@ int platform_irqchip_probe(struct platform_device *pdev)
* interrupt controller can check for specific domains as necessary. * interrupt controller can check for specific domains as necessary.
*/ */
if (par_np && !irq_find_matching_host(par_np, DOMAIN_BUS_ANY)) { if (par_np && !irq_find_matching_host(par_np, DOMAIN_BUS_ANY)) {
of_node_put(par_np);
return -EPROBE_DEFER; return -EPROBE_DEFER;
} }

View File

@@ -90,7 +90,7 @@ void spi_nor_spimem_setup_op(const struct spi_nor *nor,
op->addr.buswidth = spi_nor_get_protocol_addr_nbits(proto); op->addr.buswidth = spi_nor_get_protocol_addr_nbits(proto);
if (op->dummy.nbytes) if (op->dummy.nbytes)
op->dummy.buswidth = spi_nor_get_protocol_data_nbits(proto); op->dummy.buswidth = spi_nor_get_protocol_addr_nbits(proto);
if (op->data.nbytes) if (op->data.nbytes)
op->data.buswidth = spi_nor_get_protocol_data_nbits(proto); op->data.buswidth = spi_nor_get_protocol_data_nbits(proto);

View File

@@ -856,7 +856,6 @@ static void xgbe_phy_free_phy_device(struct xgbe_prv_data *pdata)
static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata) static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata)
{ {
__ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, };
struct xgbe_phy_data *phy_data = pdata->phy_data; struct xgbe_phy_data *phy_data = pdata->phy_data;
unsigned int phy_id = phy_data->phydev->phy_id; unsigned int phy_id = phy_data->phydev->phy_id;
@@ -878,14 +877,7 @@ static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata)
phy_write(phy_data->phydev, 0x04, 0x0d01); phy_write(phy_data->phydev, 0x04, 0x0d01);
phy_write(phy_data->phydev, 0x00, 0x9140); phy_write(phy_data->phydev, 0x00, 0x9140);
linkmode_set_bit_array(phy_10_100_features_array, linkmode_copy(phy_data->phydev->supported, PHY_GBIT_FEATURES);
ARRAY_SIZE(phy_10_100_features_array),
supported);
linkmode_set_bit_array(phy_gbit_features_array,
ARRAY_SIZE(phy_gbit_features_array),
supported);
linkmode_copy(phy_data->phydev->supported, supported);
phy_support_asym_pause(phy_data->phydev); phy_support_asym_pause(phy_data->phydev);
@@ -897,7 +889,6 @@ static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata)
static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata) static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata)
{ {
__ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, };
struct xgbe_phy_data *phy_data = pdata->phy_data; struct xgbe_phy_data *phy_data = pdata->phy_data;
struct xgbe_sfp_eeprom *sfp_eeprom = &phy_data->sfp_eeprom; struct xgbe_sfp_eeprom *sfp_eeprom = &phy_data->sfp_eeprom;
unsigned int phy_id = phy_data->phydev->phy_id; unsigned int phy_id = phy_data->phydev->phy_id;
@@ -961,13 +952,7 @@ static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata)
reg = phy_read(phy_data->phydev, 0x00); reg = phy_read(phy_data->phydev, 0x00);
phy_write(phy_data->phydev, 0x00, reg & ~0x00800); phy_write(phy_data->phydev, 0x00, reg & ~0x00800);
linkmode_set_bit_array(phy_10_100_features_array, linkmode_copy(phy_data->phydev->supported, PHY_GBIT_FEATURES);
ARRAY_SIZE(phy_10_100_features_array),
supported);
linkmode_set_bit_array(phy_gbit_features_array,
ARRAY_SIZE(phy_gbit_features_array),
supported);
linkmode_copy(phy_data->phydev->supported, supported);
phy_support_asym_pause(phy_data->phydev); phy_support_asym_pause(phy_data->phydev);
netif_dbg(pdata, drv, pdata->netdev, netif_dbg(pdata, drv, pdata->netdev,

View File

@@ -2421,6 +2421,7 @@ struct mlx5_flow_namespace *mlx5_get_flow_namespace(struct mlx5_core_dev *dev,
break; break;
case MLX5_FLOW_NAMESPACE_RDMA_TX: case MLX5_FLOW_NAMESPACE_RDMA_TX:
root_ns = steering->rdma_tx_root_ns; root_ns = steering->rdma_tx_root_ns;
prio = RDMA_TX_BYPASS_PRIO;
break; break;
case MLX5_FLOW_NAMESPACE_RDMA_RX_COUNTERS: case MLX5_FLOW_NAMESPACE_RDMA_RX_COUNTERS:
root_ns = steering->rdma_rx_root_ns; root_ns = steering->rdma_rx_root_ns;

View File

@@ -540,7 +540,7 @@ int mlx5_lag_port_sel_create(struct mlx5_lag *ldev,
set_tt_map(port_sel, hash_type); set_tt_map(port_sel, hash_type);
err = mlx5_lag_create_definers(ldev, hash_type, ports); err = mlx5_lag_create_definers(ldev, hash_type, ports);
if (err) if (err)
return err; goto clear_port_sel;
if (port_sel->tunnel) { if (port_sel->tunnel) {
err = mlx5_lag_create_inner_ttc_table(ldev); err = mlx5_lag_create_inner_ttc_table(ldev);
@@ -559,6 +559,8 @@ destroy_inner:
mlx5_destroy_ttc_table(port_sel->inner.ttc); mlx5_destroy_ttc_table(port_sel->inner.ttc);
destroy_definers: destroy_definers:
mlx5_lag_destroy_definers(ldev); mlx5_lag_destroy_definers(ldev);
clear_port_sel:
memset(port_sel, 0, sizeof(*port_sel));
return err; return err;
} }

View File

@@ -458,7 +458,8 @@ int nfp_bpf_event_output(struct nfp_app_bpf *bpf, const void *data,
map_id_full = be64_to_cpu(cbe->map_ptr); map_id_full = be64_to_cpu(cbe->map_ptr);
map_id = map_id_full; map_id = map_id_full;
if (len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size) if (size_add(pkt_size, data_size) > INT_MAX ||
len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size)
return -EINVAL; return -EINVAL;
if (cbe->hdr.ver != NFP_CCM_ABI_VERSION) if (cbe->hdr.ver != NFP_CCM_ABI_VERSION)
return -EINVAL; return -EINVAL;

View File

@@ -106,15 +106,15 @@ struct cpsw_ale_dev_id {
static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits) static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
{ {
int idx, idx2; int idx, idx2, index;
u32 hi_val = 0; u32 hi_val = 0;
idx = start / 32; idx = start / 32;
idx2 = (start + bits - 1) / 32; idx2 = (start + bits - 1) / 32;
/* Check if bits to be fetched exceed a word */ /* Check if bits to be fetched exceed a word */
if (idx != idx2) { if (idx != idx2) {
idx2 = 2 - idx2; /* flip */ index = 2 - idx2; /* flip */
hi_val = ale_entry[idx2] << ((idx2 * 32) - start); hi_val = ale_entry[index] << ((idx2 * 32) - start);
} }
start -= idx * 32; start -= idx * 32;
idx = 2 - idx; /* flip */ idx = 2 - idx; /* flip */
@@ -124,16 +124,16 @@ static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits, static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits,
u32 value) u32 value)
{ {
int idx, idx2; int idx, idx2, index;
value &= BITMASK(bits); value &= BITMASK(bits);
idx = start / 32; idx = start / 32;
idx2 = (start + bits - 1) / 32; idx2 = (start + bits - 1) / 32;
/* Check if bits to be set exceed a word */ /* Check if bits to be set exceed a word */
if (idx != idx2) { if (idx != idx2) {
idx2 = 2 - idx2; /* flip */ index = 2 - idx2; /* flip */
ale_entry[idx2] &= ~(BITMASK(bits + start - (idx2 * 32))); ale_entry[index] &= ~(BITMASK(bits + start - (idx2 * 32)));
ale_entry[idx2] |= (value >> ((idx2 * 32) - start)); ale_entry[index] |= (value >> ((idx2 * 32) - start));
} }
start -= idx * 32; start -= idx * 32;
idx = 2 - idx; /* flip */ idx = 2 - idx; /* flip */

View File

@@ -1570,6 +1570,12 @@ axienet_ethtools_set_coalesce(struct net_device *ndev,
return -EFAULT; return -EFAULT;
} }
if (ecoalesce->rx_max_coalesced_frames > 255 ||
ecoalesce->tx_max_coalesced_frames > 255) {
NL_SET_ERR_MSG(extack, "frames must be less than 256");
return -EINVAL;
}
if (ecoalesce->rx_max_coalesced_frames) if (ecoalesce->rx_max_coalesced_frames)
lp->coalesce_count_rx = ecoalesce->rx_max_coalesced_frames; lp->coalesce_count_rx = ecoalesce->rx_max_coalesced_frames;
if (ecoalesce->rx_coalesce_usecs) if (ecoalesce->rx_coalesce_usecs)

View File

@@ -1094,8 +1094,8 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev,
goto out_encap; goto out_encap;
} }
gn = net_generic(dev_net(dev), gtp_net_id); gn = net_generic(src_net, gtp_net_id);
list_add_rcu(&gtp->list, &gn->gtp_dev_list); list_add(&gtp->list, &gn->gtp_dev_list);
dev->priv_destructor = gtp_destructor; dev->priv_destructor = gtp_destructor;
netdev_dbg(dev, "registered new GTP interface\n"); netdev_dbg(dev, "registered new GTP interface\n");
@@ -1121,7 +1121,7 @@ static void gtp_dellink(struct net_device *dev, struct list_head *head)
hlist_for_each_entry_safe(pctx, next, &gtp->tid_hash[i], hlist_tid) hlist_for_each_entry_safe(pctx, next, &gtp->tid_hash[i], hlist_tid)
pdp_context_delete(pctx); pdp_context_delete(pctx);
list_del_rcu(&gtp->list); list_del(&gtp->list);
unregister_netdevice_queue(dev, head); unregister_netdevice_queue(dev, head);
} }
@@ -1689,16 +1689,19 @@ static int gtp_genl_dump_pdp(struct sk_buff *skb,
struct gtp_dev *last_gtp = (struct gtp_dev *)cb->args[2], *gtp; struct gtp_dev *last_gtp = (struct gtp_dev *)cb->args[2], *gtp;
int i, j, bucket = cb->args[0], skip = cb->args[1]; int i, j, bucket = cb->args[0], skip = cb->args[1];
struct net *net = sock_net(skb->sk); struct net *net = sock_net(skb->sk);
struct net_device *dev;
struct pdp_ctx *pctx; struct pdp_ctx *pctx;
struct gtp_net *gn;
gn = net_generic(net, gtp_net_id);
if (cb->args[4]) if (cb->args[4])
return 0; return 0;
rcu_read_lock(); rcu_read_lock();
list_for_each_entry_rcu(gtp, &gn->gtp_dev_list, list) { for_each_netdev_rcu(net, dev) {
if (dev->rtnl_link_ops != &gtp_link_ops)
continue;
gtp = netdev_priv(dev);
if (last_gtp && last_gtp != gtp) if (last_gtp && last_gtp != gtp)
continue; continue;
else else
@@ -1883,23 +1886,28 @@ static int __net_init gtp_net_init(struct net *net)
return 0; return 0;
} }
static void __net_exit gtp_net_exit(struct net *net) static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list,
struct list_head *dev_to_kill)
{ {
struct gtp_net *gn = net_generic(net, gtp_net_id); struct net *net;
struct gtp_dev *gtp;
LIST_HEAD(list);
rtnl_lock(); list_for_each_entry(net, net_list, exit_list) {
list_for_each_entry(gtp, &gn->gtp_dev_list, list) struct gtp_net *gn = net_generic(net, gtp_net_id);
gtp_dellink(gtp->dev, &list); struct gtp_dev *gtp, *gtp_next;
struct net_device *dev;
unregister_netdevice_many(&list); for_each_netdev(net, dev)
rtnl_unlock(); if (dev->rtnl_link_ops == &gtp_link_ops)
gtp_dellink(dev, dev_to_kill);
list_for_each_entry_safe(gtp, gtp_next, &gn->gtp_dev_list, list)
gtp_dellink(gtp->dev, dev_to_kill);
}
} }
static struct pernet_operations gtp_net_ops = { static struct pernet_operations gtp_net_ops = {
.init = gtp_net_init, .init = gtp_net_init,
.exit = gtp_net_exit, .exit_batch_rtnl = gtp_net_exit_batch_rtnl,
.id = &gtp_net_id, .id = &gtp_net_id,
.size = sizeof(struct gtp_net), .size = sizeof(struct gtp_net),
}; };

View File

@@ -2647,9 +2647,9 @@ static void ath10k_sdio_remove(struct sdio_func *func)
netif_napi_del(&ar->napi); netif_napi_del(&ar->napi);
ath10k_core_destroy(ar);
destroy_workqueue(ar_sdio->workqueue); destroy_workqueue(ar_sdio->workqueue);
ath10k_core_destroy(ar);
} }
static const struct sdio_device_id ath10k_sdio_devices[] = { static const struct sdio_device_id ath10k_sdio_devices[] = {

View File

@@ -36,7 +36,7 @@ void nvmet_bdev_set_limits(struct block_device *bdev, struct nvme_id_ns *id)
*/ */
id->nsfeat |= 1 << 4; id->nsfeat |= 1 << 4;
/* NPWG = Namespace Preferred Write Granularity. 0's based */ /* NPWG = Namespace Preferred Write Granularity. 0's based */
id->npwg = lpp0b; id->npwg = to0based(bdev_io_min(bdev) / bdev_logical_block_size(bdev));
/* NPWA = Namespace Preferred Write Alignment. 0's based */ /* NPWA = Namespace Preferred Write Alignment. 0's based */
id->npwa = id->npwg; id->npwa = id->npwg;
/* NPDG = Namespace Preferred Deallocate Granularity. 0's based */ /* NPDG = Namespace Preferred Deallocate Granularity. 0's based */

View File

@@ -390,7 +390,6 @@ sg_release(struct inode *inode, struct file *filp)
mutex_lock(&sdp->open_rel_lock); mutex_lock(&sdp->open_rel_lock);
scsi_autopm_put_device(sdp->device); scsi_autopm_put_device(sdp->device);
kref_put(&sfp->f_ref, sg_remove_sfp);
sdp->open_cnt--; sdp->open_cnt--;
/* possibly many open()s waiting on exlude clearing, start many; /* possibly many open()s waiting on exlude clearing, start many;
@@ -402,6 +401,7 @@ sg_release(struct inode *inode, struct file *filp)
wake_up_interruptible(&sdp->open_wait); wake_up_interruptible(&sdp->open_wait);
} }
mutex_unlock(&sdp->open_rel_lock); mutex_unlock(&sdp->open_rel_lock);
kref_put(&sfp->f_ref, sg_remove_sfp);
return 0; return 0;
} }

View File

@@ -659,7 +659,7 @@ static int imx8mp_blk_ctrl_remove(struct platform_device *pdev)
of_genpd_del_provider(pdev->dev.of_node); of_genpd_del_provider(pdev->dev.of_node);
for (i = 0; bc->onecell_data.num_domains; i++) { for (i = 0; i < bc->onecell_data.num_domains; i++) {
struct imx8mp_blk_ctrl_domain *domain = &bc->domains[i]; struct imx8mp_blk_ctrl_domain *domain = &bc->domains[i];
pm_genpd_remove(&domain->genpd); pm_genpd_remove(&domain->genpd);

View File

@@ -10547,14 +10547,17 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
} }
/* /*
* Set the default power management level for runtime and system PM. * Set the default power management level for runtime and system PM if
* not set by the host controller drivers.
* Default power saving mode is to keep UFS link in Hibern8 state * Default power saving mode is to keep UFS link in Hibern8 state
* and UFS device in sleep state. * and UFS device in sleep state.
*/ */
hba->rpm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state( if (!hba->rpm_lvl)
hba->rpm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state(
UFS_SLEEP_PWR_MODE, UFS_SLEEP_PWR_MODE,
UIC_LINK_HIBERN8_STATE); UIC_LINK_HIBERN8_STATE);
hba->spm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state( if (!hba->spm_lvl)
hba->spm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state(
UFS_SLEEP_PWR_MODE, UFS_SLEEP_PWR_MODE,
UIC_LINK_HIBERN8_STATE); UIC_LINK_HIBERN8_STATE);

View File

@@ -15,6 +15,7 @@
#include <linux/namei.h> #include <linux/namei.h>
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/security.h>
#include <linux/statfs.h> #include <linux/statfs.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/string.h> #include <linux/string.h>
@@ -576,7 +577,7 @@ static int cachefiles_daemon_dir(struct cachefiles_cache *cache, char *args)
*/ */
static int cachefiles_daemon_secctx(struct cachefiles_cache *cache, char *args) static int cachefiles_daemon_secctx(struct cachefiles_cache *cache, char *args)
{ {
char *secctx; int err;
_enter(",%s", args); _enter(",%s", args);
@@ -585,16 +586,16 @@ static int cachefiles_daemon_secctx(struct cachefiles_cache *cache, char *args)
return -EINVAL; return -EINVAL;
} }
if (cache->secctx) { if (cache->have_secid) {
pr_err("Second security context specified\n"); pr_err("Second security context specified\n");
return -EINVAL; return -EINVAL;
} }
secctx = kstrdup(args, GFP_KERNEL); err = security_secctx_to_secid(args, strlen(args), &cache->secid);
if (!secctx) if (err)
return -ENOMEM; return err;
cache->secctx = secctx; cache->have_secid = true;
return 0; return 0;
} }
@@ -820,7 +821,6 @@ static void cachefiles_daemon_unbind(struct cachefiles_cache *cache)
put_cred(cache->cache_cred); put_cred(cache->cache_cred);
kfree(cache->rootdirname); kfree(cache->rootdirname);
kfree(cache->secctx);
kfree(cache->tag); kfree(cache->tag);
_leave(""); _leave("");

View File

@@ -122,7 +122,6 @@ struct cachefiles_cache {
#define CACHEFILES_STATE_CHANGED 3 /* T if state changed (poll trigger) */ #define CACHEFILES_STATE_CHANGED 3 /* T if state changed (poll trigger) */
#define CACHEFILES_ONDEMAND_MODE 4 /* T if in on-demand read mode */ #define CACHEFILES_ONDEMAND_MODE 4 /* T if in on-demand read mode */
char *rootdirname; /* name of cache root directory */ char *rootdirname; /* name of cache root directory */
char *secctx; /* LSM security context */
char *tag; /* cache binding tag */ char *tag; /* cache binding tag */
refcount_t unbind_pincount;/* refcount to do daemon unbind */ refcount_t unbind_pincount;/* refcount to do daemon unbind */
struct xarray reqs; /* xarray of pending on-demand requests */ struct xarray reqs; /* xarray of pending on-demand requests */
@@ -130,6 +129,8 @@ struct cachefiles_cache {
struct xarray ondemand_ids; /* xarray for ondemand_id allocation */ struct xarray ondemand_ids; /* xarray for ondemand_id allocation */
u32 ondemand_id_next; u32 ondemand_id_next;
u32 msg_id_next; u32 msg_id_next;
u32 secid; /* LSM security id */
bool have_secid; /* whether "secid" was set */
}; };
static inline bool cachefiles_in_ondemand_mode(struct cachefiles_cache *cache) static inline bool cachefiles_in_ondemand_mode(struct cachefiles_cache *cache)

View File

@@ -18,7 +18,7 @@ int cachefiles_get_security_ID(struct cachefiles_cache *cache)
struct cred *new; struct cred *new;
int ret; int ret;
_enter("{%s}", cache->secctx); _enter("{%u}", cache->have_secid ? cache->secid : 0);
new = prepare_kernel_cred(current); new = prepare_kernel_cred(current);
if (!new) { if (!new) {
@@ -26,8 +26,8 @@ int cachefiles_get_security_ID(struct cachefiles_cache *cache)
goto error; goto error;
} }
if (cache->secctx) { if (cache->have_secid) {
ret = set_security_override_from_ctx(new, cache->secctx); ret = set_security_override(new, cache->secid);
if (ret < 0) { if (ret < 0) {
put_cred(new); put_cred(new);
pr_err("Security denies permission to nominate security context: error %d\n", pr_err("Security denies permission to nominate security context: error %d\n",

View File

@@ -82,32 +82,27 @@ struct erofs_super_block {
}; };
/* /*
* erofs inode datalayout (i_format in on-disk inode): * EROFS inode datalayout (i_format in on-disk inode):
* 0 - uncompressed flat inode without tail-packing inline data: * 0 - uncompressed flat inode without tail-packing inline data:
* inode, [xattrs], ... | ... | no-holed data
* 1 - compressed inode with non-compact indexes: * 1 - compressed inode with non-compact indexes:
* inode, [xattrs], [map_header], extents ... | ...
* 2 - uncompressed flat inode with tail-packing inline data: * 2 - uncompressed flat inode with tail-packing inline data:
* inode, [xattrs], tailpacking data, ... | ... | no-holed data
* 3 - compressed inode with compact indexes: * 3 - compressed inode with compact indexes:
* inode, [xattrs], map_header, extents ... | ...
* 4 - chunk-based inode with (optional) multi-device support: * 4 - chunk-based inode with (optional) multi-device support:
* inode, [xattrs], chunk indexes ... | ...
* 5~7 - reserved * 5~7 - reserved
*/ */
enum { enum {
EROFS_INODE_FLAT_PLAIN = 0, EROFS_INODE_FLAT_PLAIN = 0,
EROFS_INODE_FLAT_COMPRESSION_LEGACY = 1, EROFS_INODE_COMPRESSED_FULL = 1,
EROFS_INODE_FLAT_INLINE = 2, EROFS_INODE_FLAT_INLINE = 2,
EROFS_INODE_FLAT_COMPRESSION = 3, EROFS_INODE_COMPRESSED_COMPACT = 3,
EROFS_INODE_CHUNK_BASED = 4, EROFS_INODE_CHUNK_BASED = 4,
EROFS_INODE_DATALAYOUT_MAX EROFS_INODE_DATALAYOUT_MAX
}; };
static inline bool erofs_inode_is_data_compressed(unsigned int datamode) static inline bool erofs_inode_is_data_compressed(unsigned int datamode)
{ {
return datamode == EROFS_INODE_FLAT_COMPRESSION || return datamode == EROFS_INODE_COMPRESSED_COMPACT ||
datamode == EROFS_INODE_FLAT_COMPRESSION_LEGACY; datamode == EROFS_INODE_COMPRESSED_FULL;
} }
/* bit definitions of inode i_format */ /* bit definitions of inode i_format */
@@ -128,11 +123,30 @@ static inline bool erofs_inode_is_data_compressed(unsigned int datamode)
#define EROFS_CHUNK_FORMAT_ALL \ #define EROFS_CHUNK_FORMAT_ALL \
(EROFS_CHUNK_FORMAT_BLKBITS_MASK | EROFS_CHUNK_FORMAT_INDEXES) (EROFS_CHUNK_FORMAT_BLKBITS_MASK | EROFS_CHUNK_FORMAT_INDEXES)
/* 32-byte on-disk inode */
#define EROFS_INODE_LAYOUT_COMPACT 0
/* 64-byte on-disk inode */
#define EROFS_INODE_LAYOUT_EXTENDED 1
struct erofs_inode_chunk_info { struct erofs_inode_chunk_info {
__le16 format; /* chunk blkbits, etc. */ __le16 format; /* chunk blkbits, etc. */
__le16 reserved; __le16 reserved;
}; };
union erofs_inode_i_u {
/* total compressed blocks for compressed inodes */
__le32 compressed_blocks;
/* block address for uncompressed flat inodes */
__le32 raw_blkaddr;
/* for device files, used to indicate old/new device # */
__le32 rdev;
/* for chunk-based files, it contains the summary info */
struct erofs_inode_chunk_info c;
};
/* 32-byte reduced form of an ondisk inode */ /* 32-byte reduced form of an ondisk inode */
struct erofs_inode_compact { struct erofs_inode_compact {
__le16 i_format; /* inode format hints */ __le16 i_format; /* inode format hints */
@@ -143,29 +157,14 @@ struct erofs_inode_compact {
__le16 i_nlink; __le16 i_nlink;
__le32 i_size; __le32 i_size;
__le32 i_reserved; __le32 i_reserved;
union { union erofs_inode_i_u i_u;
/* total compressed blocks for compressed inodes */
__le32 compressed_blocks;
/* block address for uncompressed flat inodes */
__le32 raw_blkaddr;
/* for device files, used to indicate old/new device # */ __le32 i_ino; /* only used for 32-bit stat compatibility */
__le32 rdev;
/* for chunk-based files, it contains the summary info */
struct erofs_inode_chunk_info c;
} i_u;
__le32 i_ino; /* only used for 32-bit stat compatibility */
__le16 i_uid; __le16 i_uid;
__le16 i_gid; __le16 i_gid;
__le32 i_reserved2; __le32 i_reserved2;
}; };
/* 32-byte on-disk inode */
#define EROFS_INODE_LAYOUT_COMPACT 0
/* 64-byte on-disk inode */
#define EROFS_INODE_LAYOUT_EXTENDED 1
/* 64-byte complete form of an ondisk inode */ /* 64-byte complete form of an ondisk inode */
struct erofs_inode_extended { struct erofs_inode_extended {
__le16 i_format; /* inode format hints */ __le16 i_format; /* inode format hints */
@@ -175,22 +174,9 @@ struct erofs_inode_extended {
__le16 i_mode; __le16 i_mode;
__le16 i_reserved; __le16 i_reserved;
__le64 i_size; __le64 i_size;
union { union erofs_inode_i_u i_u;
/* total compressed blocks for compressed inodes */
__le32 compressed_blocks;
/* block address for uncompressed flat inodes */
__le32 raw_blkaddr;
/* for device files, used to indicate old/new device # */
__le32 rdev;
/* for chunk-based files, it contains the summary info */
struct erofs_inode_chunk_info c;
} i_u;
/* only used for 32-bit stat compatibility */
__le32 i_ino;
__le32 i_ino; /* only used for 32-bit stat compatibility */
__le32 i_uid; __le32 i_uid;
__le32 i_gid; __le32 i_gid;
__le64 i_mtime; __le64 i_mtime;
@@ -199,10 +185,6 @@ struct erofs_inode_extended {
__u8 i_reserved2[16]; __u8 i_reserved2[16];
}; };
#define EROFS_MAX_SHARED_XATTRS (128)
/* h_shared_count between 129 ... 255 are special # */
#define EROFS_SHARED_XATTR_EXTENT (255)
/* /*
* inline xattrs (n == i_xattr_icount): * inline xattrs (n == i_xattr_icount):
* erofs_xattr_ibody_header(1) + (n - 1) * 4 bytes * erofs_xattr_ibody_header(1) + (n - 1) * 4 bytes
@@ -268,6 +250,22 @@ struct erofs_inode_chunk_index {
__le32 blkaddr; /* start block address of this inode chunk */ __le32 blkaddr; /* start block address of this inode chunk */
}; };
/* dirent sorts in alphabet order, thus we can do binary search */
struct erofs_dirent {
__le64 nid; /* node number */
__le16 nameoff; /* start offset of file name */
__u8 file_type; /* file type */
__u8 reserved; /* reserved */
} __packed;
/*
* EROFS file types should match generic FT_* types and
* it seems no need to add BUILD_BUG_ONs since potential
* unmatchness will break other fses as well...
*/
#define EROFS_NAME_LEN 255
/* maximum supported size of a physical compression cluster */ /* maximum supported size of a physical compression cluster */
#define Z_EROFS_PCLUSTER_MAX_SIZE (1024 * 1024) #define Z_EROFS_PCLUSTER_MAX_SIZE (1024 * 1024)
@@ -337,10 +335,8 @@ struct z_erofs_map_header {
__u8 h_clusterbits; __u8 h_clusterbits;
}; };
#define Z_EROFS_VLE_LEGACY_HEADER_PADDING 8
/* /*
* Fixed-sized output compression on-disk logical cluster type: * On-disk logical cluster type:
* 0 - literal (uncompressed) lcluster * 0 - literal (uncompressed) lcluster
* 1,3 - compressed lcluster (for HEAD lclusters) * 1,3 - compressed lcluster (for HEAD lclusters)
* 2 - compressed lcluster (for NONHEAD lclusters) * 2 - compressed lcluster (for NONHEAD lclusters)
@@ -364,27 +360,27 @@ struct z_erofs_map_header {
* di_u.delta[1] = distance to the next HEAD lcluster * di_u.delta[1] = distance to the next HEAD lcluster
*/ */
enum { enum {
Z_EROFS_VLE_CLUSTER_TYPE_PLAIN = 0, Z_EROFS_LCLUSTER_TYPE_PLAIN = 0,
Z_EROFS_VLE_CLUSTER_TYPE_HEAD1 = 1, Z_EROFS_LCLUSTER_TYPE_HEAD1 = 1,
Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD = 2, Z_EROFS_LCLUSTER_TYPE_NONHEAD = 2,
Z_EROFS_VLE_CLUSTER_TYPE_HEAD2 = 3, Z_EROFS_LCLUSTER_TYPE_HEAD2 = 3,
Z_EROFS_VLE_CLUSTER_TYPE_MAX Z_EROFS_LCLUSTER_TYPE_MAX
}; };
#define Z_EROFS_VLE_DI_CLUSTER_TYPE_BITS 2 #define Z_EROFS_LI_LCLUSTER_TYPE_BITS 2
#define Z_EROFS_VLE_DI_CLUSTER_TYPE_BIT 0 #define Z_EROFS_LI_LCLUSTER_TYPE_BIT 0
/* (noncompact only, HEAD) This pcluster refers to partial decompressed data */ /* (noncompact only, HEAD) This pcluster refers to partial decompressed data */
#define Z_EROFS_VLE_DI_PARTIAL_REF (1 << 15) #define Z_EROFS_LI_PARTIAL_REF (1 << 15)
/* /*
* D0_CBLKCNT will be marked _only_ at the 1st non-head lcluster to store the * D0_CBLKCNT will be marked _only_ at the 1st non-head lcluster to store the
* compressed block count of a compressed extent (in logical clusters, aka. * compressed block count of a compressed extent (in logical clusters, aka.
* block count of a pcluster). * block count of a pcluster).
*/ */
#define Z_EROFS_VLE_DI_D0_CBLKCNT (1 << 11) #define Z_EROFS_LI_D0_CBLKCNT (1 << 11)
struct z_erofs_vle_decompressed_index { struct z_erofs_lcluster_index {
__le16 di_advise; __le16 di_advise;
/* where to decompress in the head lcluster */ /* where to decompress in the head lcluster */
__le16 di_clusterofs; __le16 di_clusterofs;
@@ -401,25 +397,8 @@ struct z_erofs_vle_decompressed_index {
} di_u; } di_u;
}; };
#define Z_EROFS_VLE_LEGACY_INDEX_ALIGN(size) \ #define Z_EROFS_FULL_INDEX_ALIGN(end) \
(round_up(size, sizeof(struct z_erofs_vle_decompressed_index)) + \ (ALIGN(end, 8) + sizeof(struct z_erofs_map_header) + 8)
sizeof(struct z_erofs_map_header) + Z_EROFS_VLE_LEGACY_HEADER_PADDING)
/* dirent sorts in alphabet order, thus we can do binary search */
struct erofs_dirent {
__le64 nid; /* node number */
__le16 nameoff; /* start offset of file name */
__u8 file_type; /* file type */
__u8 reserved; /* reserved */
} __packed;
/*
* EROFS file types should match generic FT_* types and
* it seems no need to add BUILD_BUG_ONs since potential
* unmatchness will break other fses as well...
*/
#define EROFS_NAME_LEN 255
/* check the EROFS on-disk layout strictly at compile time */ /* check the EROFS on-disk layout strictly at compile time */
static inline void erofs_check_ondisk_layout_definitions(void) static inline void erofs_check_ondisk_layout_definitions(void)
@@ -436,15 +415,15 @@ static inline void erofs_check_ondisk_layout_definitions(void)
BUILD_BUG_ON(sizeof(struct erofs_inode_chunk_info) != 4); BUILD_BUG_ON(sizeof(struct erofs_inode_chunk_info) != 4);
BUILD_BUG_ON(sizeof(struct erofs_inode_chunk_index) != 8); BUILD_BUG_ON(sizeof(struct erofs_inode_chunk_index) != 8);
BUILD_BUG_ON(sizeof(struct z_erofs_map_header) != 8); BUILD_BUG_ON(sizeof(struct z_erofs_map_header) != 8);
BUILD_BUG_ON(sizeof(struct z_erofs_vle_decompressed_index) != 8); BUILD_BUG_ON(sizeof(struct z_erofs_lcluster_index) != 8);
BUILD_BUG_ON(sizeof(struct erofs_dirent) != 12); BUILD_BUG_ON(sizeof(struct erofs_dirent) != 12);
/* keep in sync between 2 index structures for better extendibility */ /* keep in sync between 2 index structures for better extendibility */
BUILD_BUG_ON(sizeof(struct erofs_inode_chunk_index) != BUILD_BUG_ON(sizeof(struct erofs_inode_chunk_index) !=
sizeof(struct z_erofs_vle_decompressed_index)); sizeof(struct z_erofs_lcluster_index));
BUILD_BUG_ON(sizeof(struct erofs_deviceslot) != 128); BUILD_BUG_ON(sizeof(struct erofs_deviceslot) != 128);
BUILD_BUG_ON(BIT(Z_EROFS_VLE_DI_CLUSTER_TYPE_BITS) < BUILD_BUG_ON(BIT(Z_EROFS_LI_LCLUSTER_TYPE_BITS) <
Z_EROFS_VLE_CLUSTER_TYPE_MAX - 1); Z_EROFS_LCLUSTER_TYPE_MAX - 1);
/* exclude old compiler versions like gcc 7.5.0 */ /* exclude old compiler versions like gcc 7.5.0 */
BUILD_BUG_ON(__builtin_constant_p(fmh) ? BUILD_BUG_ON(__builtin_constant_p(fmh) ?
fmh != cpu_to_le64(1ULL << 63) : 0); fmh != cpu_to_le64(1ULL << 63) : 0);

View File

@@ -14,7 +14,7 @@ int z_erofs_fill_inode(struct inode *inode)
if (!erofs_sb_has_big_pcluster(sbi) && if (!erofs_sb_has_big_pcluster(sbi) &&
!erofs_sb_has_ztailpacking(sbi) && !erofs_sb_has_fragments(sbi) && !erofs_sb_has_ztailpacking(sbi) && !erofs_sb_has_fragments(sbi) &&
vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY) { vi->datalayout == EROFS_INODE_COMPRESSED_FULL) {
vi->z_advise = 0; vi->z_advise = 0;
vi->z_algorithmtype[0] = 0; vi->z_algorithmtype[0] = 0;
vi->z_algorithmtype[1] = 0; vi->z_algorithmtype[1] = 0;
@@ -45,11 +45,10 @@ static int legacy_load_cluster_from_disk(struct z_erofs_maprecorder *m,
{ {
struct inode *const inode = m->inode; struct inode *const inode = m->inode;
struct erofs_inode *const vi = EROFS_I(inode); struct erofs_inode *const vi = EROFS_I(inode);
const erofs_off_t pos = const erofs_off_t pos = Z_EROFS_FULL_INDEX_ALIGN(erofs_iloc(inode) +
Z_EROFS_VLE_LEGACY_INDEX_ALIGN(erofs_iloc(inode) + vi->inode_isize + vi->xattr_isize) +
vi->inode_isize + vi->xattr_isize) + lcn * sizeof(struct z_erofs_lcluster_index);
lcn * sizeof(struct z_erofs_vle_decompressed_index); struct z_erofs_lcluster_index *di;
struct z_erofs_vle_decompressed_index *di;
unsigned int advise, type; unsigned int advise, type;
m->kaddr = erofs_read_metabuf(&m->map->buf, inode->i_sb, m->kaddr = erofs_read_metabuf(&m->map->buf, inode->i_sb,
@@ -57,33 +56,33 @@ static int legacy_load_cluster_from_disk(struct z_erofs_maprecorder *m,
if (IS_ERR(m->kaddr)) if (IS_ERR(m->kaddr))
return PTR_ERR(m->kaddr); return PTR_ERR(m->kaddr);
m->nextpackoff = pos + sizeof(struct z_erofs_vle_decompressed_index); m->nextpackoff = pos + sizeof(struct z_erofs_lcluster_index);
m->lcn = lcn; m->lcn = lcn;
di = m->kaddr + erofs_blkoff(inode->i_sb, pos); di = m->kaddr + erofs_blkoff(inode->i_sb, pos);
advise = le16_to_cpu(di->di_advise); advise = le16_to_cpu(di->di_advise);
type = (advise >> Z_EROFS_VLE_DI_CLUSTER_TYPE_BIT) & type = (advise >> Z_EROFS_LI_LCLUSTER_TYPE_BIT) &
((1 << Z_EROFS_VLE_DI_CLUSTER_TYPE_BITS) - 1); ((1 << Z_EROFS_LI_LCLUSTER_TYPE_BITS) - 1);
switch (type) { switch (type) {
case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD: case Z_EROFS_LCLUSTER_TYPE_NONHEAD:
m->clusterofs = 1 << vi->z_logical_clusterbits; m->clusterofs = 1 << vi->z_logical_clusterbits;
m->delta[0] = le16_to_cpu(di->di_u.delta[0]); m->delta[0] = le16_to_cpu(di->di_u.delta[0]);
if (m->delta[0] & Z_EROFS_VLE_DI_D0_CBLKCNT) { if (m->delta[0] & Z_EROFS_LI_D0_CBLKCNT) {
if (!(vi->z_advise & (Z_EROFS_ADVISE_BIG_PCLUSTER_1 | if (!(vi->z_advise & (Z_EROFS_ADVISE_BIG_PCLUSTER_1 |
Z_EROFS_ADVISE_BIG_PCLUSTER_2))) { Z_EROFS_ADVISE_BIG_PCLUSTER_2))) {
DBG_BUGON(1); DBG_BUGON(1);
return -EFSCORRUPTED; return -EFSCORRUPTED;
} }
m->compressedblks = m->delta[0] & m->compressedblks = m->delta[0] &
~Z_EROFS_VLE_DI_D0_CBLKCNT; ~Z_EROFS_LI_D0_CBLKCNT;
m->delta[0] = 1; m->delta[0] = 1;
} }
m->delta[1] = le16_to_cpu(di->di_u.delta[1]); m->delta[1] = le16_to_cpu(di->di_u.delta[1]);
break; break;
case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN: case Z_EROFS_LCLUSTER_TYPE_PLAIN:
case Z_EROFS_VLE_CLUSTER_TYPE_HEAD1: case Z_EROFS_LCLUSTER_TYPE_HEAD1:
case Z_EROFS_VLE_CLUSTER_TYPE_HEAD2: case Z_EROFS_LCLUSTER_TYPE_HEAD2:
if (advise & Z_EROFS_VLE_DI_PARTIAL_REF) if (advise & Z_EROFS_LI_PARTIAL_REF)
m->partialref = true; m->partialref = true;
m->clusterofs = le16_to_cpu(di->di_clusterofs); m->clusterofs = le16_to_cpu(di->di_clusterofs);
if (m->clusterofs >= 1 << vi->z_logical_clusterbits) { if (m->clusterofs >= 1 << vi->z_logical_clusterbits) {
@@ -122,13 +121,13 @@ static int get_compacted_la_distance(unsigned int lobits,
do { do {
lo = decode_compactedbits(lobits, in, encodebits * i, &type); lo = decode_compactedbits(lobits, in, encodebits * i, &type);
if (type != Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) if (type != Z_EROFS_LCLUSTER_TYPE_NONHEAD)
return d1; return d1;
++d1; ++d1;
} while (++i < vcnt); } while (++i < vcnt);
/* vcnt - 1 (Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) item */ /* vcnt - 1 (Z_EROFS_LCLUSTER_TYPE_NONHEAD) item */
if (!(lo & Z_EROFS_VLE_DI_D0_CBLKCNT)) if (!(lo & Z_EROFS_LI_D0_CBLKCNT))
d1 += lo - 1; d1 += lo - 1;
return d1; return d1;
} }
@@ -155,7 +154,7 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
m->nextpackoff = round_down(pos, vcnt << amortizedshift) + m->nextpackoff = round_down(pos, vcnt << amortizedshift) +
(vcnt << amortizedshift); (vcnt << amortizedshift);
big_pcluster = vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1; big_pcluster = vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1;
lobits = max(lclusterbits, ilog2(Z_EROFS_VLE_DI_D0_CBLKCNT) + 1U); lobits = max(lclusterbits, ilog2(Z_EROFS_LI_D0_CBLKCNT) + 1U);
encodebits = ((vcnt << amortizedshift) - sizeof(__le32)) * 8 / vcnt; encodebits = ((vcnt << amortizedshift) - sizeof(__le32)) * 8 / vcnt;
eofs = erofs_blkoff(m->inode->i_sb, pos); eofs = erofs_blkoff(m->inode->i_sb, pos);
base = round_down(eofs, vcnt << amortizedshift); base = round_down(eofs, vcnt << amortizedshift);
@@ -165,19 +164,19 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
lo = decode_compactedbits(lobits, in, encodebits * i, &type); lo = decode_compactedbits(lobits, in, encodebits * i, &type);
m->type = type; m->type = type;
if (type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) { if (type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
m->clusterofs = 1 << lclusterbits; m->clusterofs = 1 << lclusterbits;
/* figure out lookahead_distance: delta[1] if needed */ /* figure out lookahead_distance: delta[1] if needed */
if (lookahead) if (lookahead)
m->delta[1] = get_compacted_la_distance(lobits, m->delta[1] = get_compacted_la_distance(lobits,
encodebits, vcnt, in, i); encodebits, vcnt, in, i);
if (lo & Z_EROFS_VLE_DI_D0_CBLKCNT) { if (lo & Z_EROFS_LI_D0_CBLKCNT) {
if (!big_pcluster) { if (!big_pcluster) {
DBG_BUGON(1); DBG_BUGON(1);
return -EFSCORRUPTED; return -EFSCORRUPTED;
} }
m->compressedblks = lo & ~Z_EROFS_VLE_DI_D0_CBLKCNT; m->compressedblks = lo & ~Z_EROFS_LI_D0_CBLKCNT;
m->delta[0] = 1; m->delta[0] = 1;
return 0; return 0;
} else if (i + 1 != (int)vcnt) { } else if (i + 1 != (int)vcnt) {
@@ -191,9 +190,9 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
*/ */
lo = decode_compactedbits(lobits, in, lo = decode_compactedbits(lobits, in,
encodebits * (i - 1), &type); encodebits * (i - 1), &type);
if (type != Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) if (type != Z_EROFS_LCLUSTER_TYPE_NONHEAD)
lo = 0; lo = 0;
else if (lo & Z_EROFS_VLE_DI_D0_CBLKCNT) else if (lo & Z_EROFS_LI_D0_CBLKCNT)
lo = 1; lo = 1;
m->delta[0] = lo + 1; m->delta[0] = lo + 1;
return 0; return 0;
@@ -207,7 +206,7 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
--i; --i;
lo = decode_compactedbits(lobits, in, lo = decode_compactedbits(lobits, in,
encodebits * i, &type); encodebits * i, &type);
if (type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) if (type == Z_EROFS_LCLUSTER_TYPE_NONHEAD)
i -= lo; i -= lo;
if (i >= 0) if (i >= 0)
@@ -219,10 +218,10 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
--i; --i;
lo = decode_compactedbits(lobits, in, lo = decode_compactedbits(lobits, in,
encodebits * i, &type); encodebits * i, &type);
if (type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) { if (type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
if (lo & Z_EROFS_VLE_DI_D0_CBLKCNT) { if (lo & Z_EROFS_LI_D0_CBLKCNT) {
--i; --i;
nblk += lo & ~Z_EROFS_VLE_DI_D0_CBLKCNT; nblk += lo & ~Z_EROFS_LI_D0_CBLKCNT;
continue; continue;
} }
/* bigpcluster shouldn't have plain d0 == 1 */ /* bigpcluster shouldn't have plain d0 == 1 */
@@ -253,7 +252,7 @@ static int compacted_load_cluster_from_disk(struct z_erofs_maprecorder *m,
unsigned int amortizedshift; unsigned int amortizedshift;
erofs_off_t pos; erofs_off_t pos;
if (lcn >= totalidx) if (lcn >= totalidx || vi->z_logical_clusterbits > 14)
return -EINVAL; return -EINVAL;
m->lcn = lcn; m->lcn = lcn;
@@ -297,10 +296,10 @@ static int z_erofs_load_cluster_from_disk(struct z_erofs_maprecorder *m,
{ {
const unsigned int datamode = EROFS_I(m->inode)->datalayout; const unsigned int datamode = EROFS_I(m->inode)->datalayout;
if (datamode == EROFS_INODE_FLAT_COMPRESSION_LEGACY) if (datamode == EROFS_INODE_COMPRESSED_FULL)
return legacy_load_cluster_from_disk(m, lcn); return legacy_load_cluster_from_disk(m, lcn);
if (datamode == EROFS_INODE_FLAT_COMPRESSION) if (datamode == EROFS_INODE_COMPRESSED_COMPACT)
return compacted_load_cluster_from_disk(m, lcn, lookahead); return compacted_load_cluster_from_disk(m, lcn, lookahead);
return -EINVAL; return -EINVAL;
@@ -322,7 +321,7 @@ static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m,
return err; return err;
switch (m->type) { switch (m->type) {
case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD: case Z_EROFS_LCLUSTER_TYPE_NONHEAD:
if (!m->delta[0]) { if (!m->delta[0]) {
erofs_err(m->inode->i_sb, erofs_err(m->inode->i_sb,
"invalid lookback distance 0 @ nid %llu", "invalid lookback distance 0 @ nid %llu",
@@ -332,9 +331,9 @@ static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m,
} }
lookback_distance = m->delta[0]; lookback_distance = m->delta[0];
continue; continue;
case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN: case Z_EROFS_LCLUSTER_TYPE_PLAIN:
case Z_EROFS_VLE_CLUSTER_TYPE_HEAD1: case Z_EROFS_LCLUSTER_TYPE_HEAD1:
case Z_EROFS_VLE_CLUSTER_TYPE_HEAD2: case Z_EROFS_LCLUSTER_TYPE_HEAD2:
m->headtype = m->type; m->headtype = m->type;
m->map->m_la = (lcn << lclusterbits) | m->clusterofs; m->map->m_la = (lcn << lclusterbits) | m->clusterofs;
return 0; return 0;
@@ -363,15 +362,15 @@ static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m,
unsigned long lcn; unsigned long lcn;
int err; int err;
DBG_BUGON(m->type != Z_EROFS_VLE_CLUSTER_TYPE_PLAIN && DBG_BUGON(m->type != Z_EROFS_LCLUSTER_TYPE_PLAIN &&
m->type != Z_EROFS_VLE_CLUSTER_TYPE_HEAD1 && m->type != Z_EROFS_LCLUSTER_TYPE_HEAD1 &&
m->type != Z_EROFS_VLE_CLUSTER_TYPE_HEAD2); m->type != Z_EROFS_LCLUSTER_TYPE_HEAD2);
DBG_BUGON(m->type != m->headtype); DBG_BUGON(m->type != m->headtype);
if (m->headtype == Z_EROFS_VLE_CLUSTER_TYPE_PLAIN || if (m->headtype == Z_EROFS_LCLUSTER_TYPE_PLAIN ||
((m->headtype == Z_EROFS_VLE_CLUSTER_TYPE_HEAD1) && ((m->headtype == Z_EROFS_LCLUSTER_TYPE_HEAD1) &&
!(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1)) || !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1)) ||
((m->headtype == Z_EROFS_VLE_CLUSTER_TYPE_HEAD2) && ((m->headtype == Z_EROFS_LCLUSTER_TYPE_HEAD2) &&
!(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_2))) { !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_2))) {
map->m_plen = 1ULL << lclusterbits; map->m_plen = 1ULL << lclusterbits;
return 0; return 0;
@@ -393,19 +392,19 @@ static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m,
* BUG_ON in the debugging mode only for developers to notice that. * BUG_ON in the debugging mode only for developers to notice that.
*/ */
DBG_BUGON(lcn == initial_lcn && DBG_BUGON(lcn == initial_lcn &&
m->type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD); m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD);
switch (m->type) { switch (m->type) {
case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN: case Z_EROFS_LCLUSTER_TYPE_PLAIN:
case Z_EROFS_VLE_CLUSTER_TYPE_HEAD1: case Z_EROFS_LCLUSTER_TYPE_HEAD1:
case Z_EROFS_VLE_CLUSTER_TYPE_HEAD2: case Z_EROFS_LCLUSTER_TYPE_HEAD2:
/* /*
* if the 1st NONHEAD lcluster is actually PLAIN or HEAD type * if the 1st NONHEAD lcluster is actually PLAIN or HEAD type
* rather than CBLKCNT, it's a 1 lcluster-sized pcluster. * rather than CBLKCNT, it's a 1 lcluster-sized pcluster.
*/ */
m->compressedblks = 1 << (lclusterbits - sb->s_blocksize_bits); m->compressedblks = 1 << (lclusterbits - sb->s_blocksize_bits);
break; break;
case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD: case Z_EROFS_LCLUSTER_TYPE_NONHEAD:
if (m->delta[0] != 1) if (m->delta[0] != 1)
goto err_bonus_cblkcnt; goto err_bonus_cblkcnt;
if (m->compressedblks) if (m->compressedblks)
@@ -438,7 +437,7 @@ static int z_erofs_get_extent_decompressedlen(struct z_erofs_maprecorder *m)
u64 lcn = m->lcn, headlcn = map->m_la >> lclusterbits; u64 lcn = m->lcn, headlcn = map->m_la >> lclusterbits;
int err; int err;
do { while (1) {
/* handle the last EOF pcluster (no next HEAD lcluster) */ /* handle the last EOF pcluster (no next HEAD lcluster) */
if ((lcn << lclusterbits) >= inode->i_size) { if ((lcn << lclusterbits) >= inode->i_size) {
map->m_llen = inode->i_size - map->m_la; map->m_llen = inode->i_size - map->m_la;
@@ -449,15 +448,17 @@ static int z_erofs_get_extent_decompressedlen(struct z_erofs_maprecorder *m)
if (err) if (err)
return err; return err;
if (m->type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) { if (m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
DBG_BUGON(!m->delta[1] && /* work around invalid d1 generated by pre-1.0 mkfs */
m->clusterofs != 1 << lclusterbits); if (unlikely(!m->delta[1])) {
} else if (m->type == Z_EROFS_VLE_CLUSTER_TYPE_PLAIN || m->delta[1] = 1;
m->type == Z_EROFS_VLE_CLUSTER_TYPE_HEAD1 || DBG_BUGON(1);
m->type == Z_EROFS_VLE_CLUSTER_TYPE_HEAD2) { }
/* go on until the next HEAD lcluster */ } else if (m->type == Z_EROFS_LCLUSTER_TYPE_PLAIN ||
m->type == Z_EROFS_LCLUSTER_TYPE_HEAD1 ||
m->type == Z_EROFS_LCLUSTER_TYPE_HEAD2) {
if (lcn != headlcn) if (lcn != headlcn)
break; break; /* ends at the next HEAD lcluster */
m->delta[1] = 1; m->delta[1] = 1;
} else { } else {
erofs_err(inode->i_sb, "unknown type %u @ lcn %llu of nid %llu", erofs_err(inode->i_sb, "unknown type %u @ lcn %llu of nid %llu",
@@ -466,15 +467,13 @@ static int z_erofs_get_extent_decompressedlen(struct z_erofs_maprecorder *m)
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
lcn += m->delta[1]; lcn += m->delta[1];
} while (m->delta[1]); }
map->m_llen = (lcn << lclusterbits) + m->clusterofs - map->m_la; map->m_llen = (lcn << lclusterbits) + m->clusterofs - map->m_la;
return 0; return 0;
} }
static int z_erofs_do_map_blocks(struct inode *inode, static int z_erofs_do_map_blocks(struct inode *inode,
struct erofs_map_blocks *map, struct erofs_map_blocks *map, int flags)
int flags)
{ {
struct erofs_inode *const vi = EROFS_I(inode); struct erofs_inode *const vi = EROFS_I(inode);
bool ztailpacking = vi->z_advise & Z_EROFS_ADVISE_INLINE_PCLUSTER; bool ztailpacking = vi->z_advise & Z_EROFS_ADVISE_INLINE_PCLUSTER;
@@ -504,9 +503,9 @@ static int z_erofs_do_map_blocks(struct inode *inode,
end = (m.lcn + 1ULL) << lclusterbits; end = (m.lcn + 1ULL) << lclusterbits;
switch (m.type) { switch (m.type) {
case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN: case Z_EROFS_LCLUSTER_TYPE_PLAIN:
case Z_EROFS_VLE_CLUSTER_TYPE_HEAD1: case Z_EROFS_LCLUSTER_TYPE_HEAD1:
case Z_EROFS_VLE_CLUSTER_TYPE_HEAD2: case Z_EROFS_LCLUSTER_TYPE_HEAD2:
if (endoff >= m.clusterofs) { if (endoff >= m.clusterofs) {
m.headtype = m.type; m.headtype = m.type;
map->m_la = (m.lcn << lclusterbits) | m.clusterofs; map->m_la = (m.lcn << lclusterbits) | m.clusterofs;
@@ -531,7 +530,7 @@ static int z_erofs_do_map_blocks(struct inode *inode,
map->m_flags |= EROFS_MAP_FULL_MAPPED; map->m_flags |= EROFS_MAP_FULL_MAPPED;
m.delta[0] = 1; m.delta[0] = 1;
fallthrough; fallthrough;
case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD: case Z_EROFS_LCLUSTER_TYPE_NONHEAD:
/* get the corresponding first chunk */ /* get the corresponding first chunk */
err = z_erofs_extent_lookback(&m, m.delta[0]); err = z_erofs_extent_lookback(&m, m.delta[0]);
if (err) if (err)
@@ -552,7 +551,7 @@ static int z_erofs_do_map_blocks(struct inode *inode,
vi->z_tailextent_headlcn = m.lcn; vi->z_tailextent_headlcn = m.lcn;
/* for non-compact indexes, fragmentoff is 64 bits */ /* for non-compact indexes, fragmentoff is 64 bits */
if (fragment && if (fragment &&
vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY) vi->datalayout == EROFS_INODE_COMPRESSED_FULL)
vi->z_fragmentoff |= (u64)m.pblk << 32; vi->z_fragmentoff |= (u64)m.pblk << 32;
} }
if (ztailpacking && m.lcn == vi->z_tailextent_headlcn) { if (ztailpacking && m.lcn == vi->z_tailextent_headlcn) {
@@ -568,7 +567,7 @@ static int z_erofs_do_map_blocks(struct inode *inode,
goto unmap_out; goto unmap_out;
} }
if (m.headtype == Z_EROFS_VLE_CLUSTER_TYPE_PLAIN) { if (m.headtype == Z_EROFS_LCLUSTER_TYPE_PLAIN) {
if (map->m_llen > map->m_plen) { if (map->m_llen > map->m_plen) {
DBG_BUGON(1); DBG_BUGON(1);
err = -EFSCORRUPTED; err = -EFSCORRUPTED;
@@ -578,7 +577,7 @@ static int z_erofs_do_map_blocks(struct inode *inode,
Z_EROFS_COMPRESSION_INTERLACED : Z_EROFS_COMPRESSION_INTERLACED :
Z_EROFS_COMPRESSION_SHIFTED; Z_EROFS_COMPRESSION_SHIFTED;
} else { } else {
afmt = m.headtype == Z_EROFS_VLE_CLUSTER_TYPE_HEAD2 ? afmt = m.headtype == Z_EROFS_LCLUSTER_TYPE_HEAD2 ?
vi->z_algorithmtype[1] : vi->z_algorithmtype[0]; vi->z_algorithmtype[1] : vi->z_algorithmtype[0];
if (!(EROFS_I_SB(inode)->available_compr_algs & (1 << afmt))) { if (!(EROFS_I_SB(inode)->available_compr_algs & (1 << afmt))) {
erofs_err(inode->i_sb, "inconsistent algorithmtype %u for nid %llu", erofs_err(inode->i_sb, "inconsistent algorithmtype %u for nid %llu",
@@ -672,7 +671,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
err = -EFSCORRUPTED; err = -EFSCORRUPTED;
goto out_put_metabuf; goto out_put_metabuf;
} }
if (vi->datalayout == EROFS_INODE_FLAT_COMPRESSION && if (vi->datalayout == EROFS_INODE_COMPRESSED_COMPACT &&
!(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1) ^ !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1) ^
!(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_2)) { !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_2)) {
erofs_err(sb, "big pcluster head1/2 of compact indexes should be consistent for nid %llu", erofs_err(sb, "big pcluster head1/2 of compact indexes should be consistent for nid %llu",

View File

@@ -21,6 +21,7 @@
#include <linux/rcupdate.h> #include <linux/rcupdate.h>
#include <linux/close_range.h> #include <linux/close_range.h>
#include <net/sock.h> #include <net/sock.h>
#include <linux/init_task.h>
#include "internal.h" #include "internal.h"

View File

@@ -418,11 +418,13 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent)
goto bail_no_root; goto bail_no_root;
res = hfs_cat_find_brec(sb, HFS_ROOT_CNID, &fd); res = hfs_cat_find_brec(sb, HFS_ROOT_CNID, &fd);
if (!res) { if (!res) {
if (fd.entrylength > sizeof(rec) || fd.entrylength < 0) { if (fd.entrylength != sizeof(rec.dir)) {
res = -EIO; res = -EIO;
goto bail_hfs_find; goto bail_hfs_find;
} }
hfs_bnode_read(fd.bnode, &rec, fd.entryoffset, fd.entrylength); hfs_bnode_read(fd.bnode, &rec, fd.entryoffset, fd.entrylength);
if (rec.type != HFS_CDR_DIR)
res = -EIO;
} }
if (res) if (res)
goto bail_hfs_find; goto bail_hfs_find;

View File

@@ -884,7 +884,7 @@ static int iomap_write_delalloc_scan(struct inode *inode,
} }
/* move offset to start of next folio in range */ /* move offset to start of next folio in range */
start_byte = folio_next_index(folio) << PAGE_SHIFT; start_byte = folio_pos(folio) + folio_size(folio);
folio_unlock(folio); folio_unlock(folio);
folio_put(folio); folio_put(folio);
} }

View File

@@ -219,6 +219,7 @@ nfsd_file_alloc(struct net *net, struct inode *inode, unsigned char need,
return NULL; return NULL;
INIT_LIST_HEAD(&nf->nf_lru); INIT_LIST_HEAD(&nf->nf_lru);
INIT_LIST_HEAD(&nf->nf_gc);
nf->nf_birthtime = ktime_get(); nf->nf_birthtime = ktime_get();
nf->nf_file = NULL; nf->nf_file = NULL;
nf->nf_cred = get_current_cred(); nf->nf_cred = get_current_cred();
@@ -396,8 +397,8 @@ nfsd_file_dispose_list(struct list_head *dispose)
struct nfsd_file *nf; struct nfsd_file *nf;
while (!list_empty(dispose)) { while (!list_empty(dispose)) {
nf = list_first_entry(dispose, struct nfsd_file, nf_lru); nf = list_first_entry(dispose, struct nfsd_file, nf_gc);
list_del_init(&nf->nf_lru); list_del_init(&nf->nf_gc);
nfsd_file_free(nf); nfsd_file_free(nf);
} }
} }
@@ -414,12 +415,12 @@ nfsd_file_dispose_list_delayed(struct list_head *dispose)
{ {
while(!list_empty(dispose)) { while(!list_empty(dispose)) {
struct nfsd_file *nf = list_first_entry(dispose, struct nfsd_file *nf = list_first_entry(dispose,
struct nfsd_file, nf_lru); struct nfsd_file, nf_gc);
struct nfsd_net *nn = net_generic(nf->nf_net, nfsd_net_id); struct nfsd_net *nn = net_generic(nf->nf_net, nfsd_net_id);
struct nfsd_fcache_disposal *l = nn->fcache_disposal; struct nfsd_fcache_disposal *l = nn->fcache_disposal;
spin_lock(&l->lock); spin_lock(&l->lock);
list_move_tail(&nf->nf_lru, &l->freeme); list_move_tail(&nf->nf_gc, &l->freeme);
spin_unlock(&l->lock); spin_unlock(&l->lock);
queue_work(nfsd_filecache_wq, &l->work); queue_work(nfsd_filecache_wq, &l->work);
} }
@@ -476,7 +477,8 @@ nfsd_file_lru_cb(struct list_head *item, struct list_lru_one *lru,
/* Refcount went to zero. Unhash it and queue it to the dispose list */ /* Refcount went to zero. Unhash it and queue it to the dispose list */
nfsd_file_unhash(nf); nfsd_file_unhash(nf);
list_lru_isolate_move(lru, &nf->nf_lru, head); list_lru_isolate(lru, &nf->nf_lru);
list_add(&nf->nf_gc, head);
this_cpu_inc(nfsd_file_evictions); this_cpu_inc(nfsd_file_evictions);
trace_nfsd_file_gc_disposed(nf); trace_nfsd_file_gc_disposed(nf);
return LRU_REMOVED; return LRU_REMOVED;
@@ -555,7 +557,7 @@ nfsd_file_cond_queue(struct nfsd_file *nf, struct list_head *dispose)
/* If refcount goes to 0, then put on the dispose list */ /* If refcount goes to 0, then put on the dispose list */
if (refcount_sub_and_test(decrement, &nf->nf_ref)) { if (refcount_sub_and_test(decrement, &nf->nf_ref)) {
list_add(&nf->nf_lru, dispose); list_add(&nf->nf_gc, dispose);
trace_nfsd_file_closing(nf); trace_nfsd_file_closing(nf);
} }
} }
@@ -631,8 +633,8 @@ nfsd_file_close_inode_sync(struct inode *inode)
nfsd_file_queue_for_close(inode, &dispose); nfsd_file_queue_for_close(inode, &dispose);
while (!list_empty(&dispose)) { while (!list_empty(&dispose)) {
nf = list_first_entry(&dispose, struct nfsd_file, nf_lru); nf = list_first_entry(&dispose, struct nfsd_file, nf_gc);
list_del_init(&nf->nf_lru); list_del_init(&nf->nf_gc);
nfsd_file_free(nf); nfsd_file_free(nf);
} }
flush_delayed_fput(); flush_delayed_fput();

View File

@@ -44,6 +44,7 @@ struct nfsd_file {
struct nfsd_file_mark *nf_mark; struct nfsd_file_mark *nf_mark;
struct list_head nf_lru; struct list_head nf_lru;
struct list_head nf_gc;
struct rcu_head nf_rcu; struct rcu_head nf_rcu;
ktime_t nf_birthtime; ktime_t nf_birthtime;
}; };

View File

@@ -404,6 +404,8 @@ static ssize_t __read_vmcore(struct iov_iter *iter, loff_t *fpos)
if (!iov_iter_count(iter)) if (!iov_iter_count(iter))
return acc; return acc;
} }
cond_resched();
} }
return acc; return acc;

View File

@@ -533,6 +533,7 @@ extern void __init hrtimers_init(void);
extern void sysrq_timer_list_show(void); extern void sysrq_timer_list_show(void);
int hrtimers_prepare_cpu(unsigned int cpu); int hrtimers_prepare_cpu(unsigned int cpu);
int hrtimers_cpu_starting(unsigned int cpu);
#ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_HOTPLUG_CPU
int hrtimers_dead_cpu(unsigned int cpu); int hrtimers_dead_cpu(unsigned int cpu);
#else #else

View File

@@ -41,8 +41,16 @@ typedef struct poll_table_struct {
static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p) static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p)
{ {
if (p && p->_qproc && wait_address) if (p && p->_qproc && wait_address) {
p->_qproc(filp, wait_address, p); p->_qproc(filp, wait_address, p);
/*
* This memory barrier is paired in the wq_has_sleeper().
* See the comment above prepare_to_wait(), we need to
* ensure that subsequent tests in this thread can't be
* reordered with __add_wait_queue() in _qproc() paths.
*/
smp_mb();
}
} }
/* /*

View File

@@ -455,6 +455,9 @@ struct pernet_operations {
void (*pre_exit)(struct net *net); void (*pre_exit)(struct net *net);
void (*exit)(struct net *net); void (*exit)(struct net *net);
void (*exit_batch)(struct list_head *net_exit_list); void (*exit_batch)(struct list_head *net_exit_list);
/* Following method is called with RTNL held. */
void (*exit_batch_rtnl)(struct list_head *net_exit_list,
struct list_head *dev_kill_list);
unsigned int *id; unsigned int *id;
size_t size; size_t size;
}; };

View File

@@ -85,6 +85,7 @@ find $cpio_dir -type f -print0 |
# pre-sorted, as --sort=name might not be available. # pre-sorted, as --sort=name might not be available.
find $cpio_dir -printf "./%P\n" | LC_ALL=C sort | \ find $cpio_dir -printf "./%P\n" | LC_ALL=C sort | \
tar "${KBUILD_BUILD_TIMESTAMP:+--mtime=$KBUILD_BUILD_TIMESTAMP}" \ tar "${KBUILD_BUILD_TIMESTAMP:+--mtime=$KBUILD_BUILD_TIMESTAMP}" \
--exclude=".__afs*" --exclude=".nfs*" \
--owner=0 --group=0 --numeric-owner --no-recursion --mode=u=rw,go=r,a+X \ --owner=0 --group=0 --numeric-owner --no-recursion --mode=u=rw,go=r,a+X \
-I $XZ -cf $tarfile -C $cpio_dir/ -T - > /dev/null -I $XZ -cf $tarfile -C $cpio_dir/ -T - > /dev/null

View File

@@ -2176,6 +2176,15 @@ int hrtimers_prepare_cpu(unsigned int cpu)
} }
cpu_base->cpu = cpu; cpu_base->cpu = cpu;
hrtimer_cpu_base_init_expiry_lock(cpu_base);
return 0;
}
int hrtimers_cpu_starting(unsigned int cpu)
{
struct hrtimer_cpu_base *cpu_base = this_cpu_ptr(&hrtimer_bases);
/* Clear out any left over state from a CPU down operation */
cpu_base->active_bases = 0; cpu_base->active_bases = 0;
cpu_base->hres_active = 0; cpu_base->hres_active = 0;
cpu_base->hang_detected = 0; cpu_base->hang_detected = 0;
@@ -2183,7 +2192,6 @@ int hrtimers_prepare_cpu(unsigned int cpu)
cpu_base->softirq_next_timer = NULL; cpu_base->softirq_next_timer = NULL;
cpu_base->expires_next = KTIME_MAX; cpu_base->expires_next = KTIME_MAX;
cpu_base->softirq_expires_next = KTIME_MAX; cpu_base->softirq_expires_next = KTIME_MAX;
hrtimer_cpu_base_init_expiry_lock(cpu_base);
return 0; return 0;
} }
@@ -2269,6 +2277,7 @@ int hrtimers_dead_cpu(unsigned int scpu)
void __init hrtimers_init(void) void __init hrtimers_init(void)
{ {
hrtimers_prepare_cpu(smp_processor_id()); hrtimers_prepare_cpu(smp_processor_id());
hrtimers_cpu_starting(smp_processor_id());
open_softirq(HRTIMER_SOFTIRQ, hrtimer_run_softirq); open_softirq(HRTIMER_SOFTIRQ, hrtimer_run_softirq);
} }

View File

@@ -2963,7 +2963,7 @@ static inline loff_t folio_seek_hole_data(struct xa_state *xas,
if (ops->is_partially_uptodate(folio, offset, bsz) == if (ops->is_partially_uptodate(folio, offset, bsz) ==
seek_data) seek_data)
break; break;
start = (start + bsz) & ~(bsz - 1); start = (start + bsz) & ~((u64)bsz - 1);
offset += bsz; offset += bsz;
} while (offset < folio_size(folio)); } while (offset < folio_size(folio));
unlock: unlock:

View File

@@ -11106,6 +11106,7 @@ BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern,
bool is_sockarray = map->map_type == BPF_MAP_TYPE_REUSEPORT_SOCKARRAY; bool is_sockarray = map->map_type == BPF_MAP_TYPE_REUSEPORT_SOCKARRAY;
struct sock_reuseport *reuse; struct sock_reuseport *reuse;
struct sock *selected_sk; struct sock *selected_sk;
int err;
selected_sk = map->ops->map_lookup_elem(map, key); selected_sk = map->ops->map_lookup_elem(map, key);
if (!selected_sk) if (!selected_sk)
@@ -11113,10 +11114,6 @@ BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern,
reuse = rcu_dereference(selected_sk->sk_reuseport_cb); reuse = rcu_dereference(selected_sk->sk_reuseport_cb);
if (!reuse) { if (!reuse) {
/* Lookup in sock_map can return TCP ESTABLISHED sockets. */
if (sk_is_refcounted(selected_sk))
sock_put(selected_sk);
/* reuseport_array has only sk with non NULL sk_reuseport_cb. /* reuseport_array has only sk with non NULL sk_reuseport_cb.
* The only (!reuse) case here is - the sk has already been * The only (!reuse) case here is - the sk has already been
* unhashed (e.g. by close()), so treat it as -ENOENT. * unhashed (e.g. by close()), so treat it as -ENOENT.
@@ -11124,24 +11121,33 @@ BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern,
* Other maps (e.g. sock_map) do not provide this guarantee and * Other maps (e.g. sock_map) do not provide this guarantee and
* the sk may never be in the reuseport group to begin with. * the sk may never be in the reuseport group to begin with.
*/ */
return is_sockarray ? -ENOENT : -EINVAL; err = is_sockarray ? -ENOENT : -EINVAL;
goto error;
} }
if (unlikely(reuse->reuseport_id != reuse_kern->reuseport_id)) { if (unlikely(reuse->reuseport_id != reuse_kern->reuseport_id)) {
struct sock *sk = reuse_kern->sk; struct sock *sk = reuse_kern->sk;
if (sk->sk_protocol != selected_sk->sk_protocol) if (sk->sk_protocol != selected_sk->sk_protocol) {
return -EPROTOTYPE; err = -EPROTOTYPE;
else if (sk->sk_family != selected_sk->sk_family) } else if (sk->sk_family != selected_sk->sk_family) {
return -EAFNOSUPPORT; err = -EAFNOSUPPORT;
} else {
/* Catch all. Likely bound to a different sockaddr. */ /* Catch all. Likely bound to a different sockaddr. */
return -EBADFD; err = -EBADFD;
}
goto error;
} }
reuse_kern->selected_sk = selected_sk; reuse_kern->selected_sk = selected_sk;
return 0; return 0;
error:
/* Lookup in sock_map can return TCP ESTABLISHED sockets. */
if (sk_is_refcounted(selected_sk))
sock_put(selected_sk);
return err;
} }
static const struct bpf_func_proto sk_select_reuseport_proto = { static const struct bpf_func_proto sk_select_reuseport_proto = {

View File

@@ -314,8 +314,9 @@ static __net_init int setup_net(struct net *net, struct user_namespace *user_ns)
{ {
/* Must be called with pernet_ops_rwsem held */ /* Must be called with pernet_ops_rwsem held */
const struct pernet_operations *ops, *saved_ops; const struct pernet_operations *ops, *saved_ops;
int error = 0;
LIST_HEAD(net_exit_list); LIST_HEAD(net_exit_list);
LIST_HEAD(dev_kill_list);
int error = 0;
refcount_set(&net->ns.count, 1); refcount_set(&net->ns.count, 1);
ref_tracker_dir_init(&net->refcnt_tracker, 128); ref_tracker_dir_init(&net->refcnt_tracker, 128);
@@ -353,6 +354,15 @@ out_undo:
synchronize_rcu(); synchronize_rcu();
ops = saved_ops;
rtnl_lock();
list_for_each_entry_continue_reverse(ops, &pernet_list, list) {
if (ops->exit_batch_rtnl)
ops->exit_batch_rtnl(&net_exit_list, &dev_kill_list);
}
unregister_netdevice_many(&dev_kill_list);
rtnl_unlock();
ops = saved_ops; ops = saved_ops;
list_for_each_entry_continue_reverse(ops, &pernet_list, list) list_for_each_entry_continue_reverse(ops, &pernet_list, list)
ops_exit_list(ops, &net_exit_list); ops_exit_list(ops, &net_exit_list);
@@ -559,6 +569,7 @@ static void cleanup_net(struct work_struct *work)
struct net *net, *tmp, *last; struct net *net, *tmp, *last;
struct llist_node *net_kill_list; struct llist_node *net_kill_list;
LIST_HEAD(net_exit_list); LIST_HEAD(net_exit_list);
LIST_HEAD(dev_kill_list);
/* Atomically snapshot the list of namespaces to cleanup */ /* Atomically snapshot the list of namespaces to cleanup */
net_kill_list = llist_del_all(&cleanup_list); net_kill_list = llist_del_all(&cleanup_list);
@@ -599,6 +610,14 @@ static void cleanup_net(struct work_struct *work)
*/ */
synchronize_rcu(); synchronize_rcu();
rtnl_lock();
list_for_each_entry_reverse(ops, &pernet_list, list) {
if (ops->exit_batch_rtnl)
ops->exit_batch_rtnl(&net_exit_list, &dev_kill_list);
}
unregister_netdevice_many(&dev_kill_list);
rtnl_unlock();
/* Run all of the network namespace exit methods */ /* Run all of the network namespace exit methods */
list_for_each_entry_reverse(ops, &pernet_list, list) list_for_each_entry_reverse(ops, &pernet_list, list)
ops_exit_list(ops, &net_exit_list); ops_exit_list(ops, &net_exit_list);
@@ -1144,7 +1163,17 @@ static void free_exit_list(struct pernet_operations *ops, struct list_head *net_
{ {
ops_pre_exit_list(ops, net_exit_list); ops_pre_exit_list(ops, net_exit_list);
synchronize_rcu(); synchronize_rcu();
if (ops->exit_batch_rtnl) {
LIST_HEAD(dev_kill_list);
rtnl_lock();
ops->exit_batch_rtnl(net_exit_list, &dev_kill_list);
unregister_netdevice_many(&dev_kill_list);
rtnl_unlock();
}
ops_exit_list(ops, net_exit_list); ops_exit_list(ops, net_exit_list);
ops_free_list(ops, net_exit_list); ops_free_list(ops, net_exit_list);
} }

View File

@@ -850,6 +850,9 @@ static ssize_t get_imix_entries(const char __user *buffer,
unsigned long weight; unsigned long weight;
unsigned long size; unsigned long size;
if (pkt_dev->n_imix_entries >= MAX_IMIX_ENTRIES)
return -E2BIG;
len = num_arg(&buffer[i], max_digits, &size); len = num_arg(&buffer[i], max_digits, &size);
if (len < 0) if (len < 0)
return len; return len;
@@ -879,9 +882,6 @@ static ssize_t get_imix_entries(const char __user *buffer,
i++; i++;
pkt_dev->n_imix_entries++; pkt_dev->n_imix_entries++;
if (pkt_dev->n_imix_entries > MAX_IMIX_ENTRIES)
return -E2BIG;
} while (c == ' '); } while (c == ' ');
return i; return i;

View File

@@ -615,7 +615,7 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
by tcp. Feel free to propose better solution. by tcp. Feel free to propose better solution.
--ANK (980728) --ANK (980728)
*/ */
if (np->rxopt.all) if (np->rxopt.all && sk->sk_state != DCCP_LISTEN)
opt_skb = skb_clone_and_charge_r(skb, sk); opt_skb = skb_clone_and_charge_r(skb, sk);
if (sk->sk_state == DCCP_OPEN) { /* Fast path */ if (sk->sk_state == DCCP_OPEN) { /* Fast path */

View File

@@ -1463,7 +1463,7 @@ int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
by tcp. Feel free to propose better solution. by tcp. Feel free to propose better solution.
--ANK (980728) --ANK (980728)
*/ */
if (np->rxopt.all) if (np->rxopt.all && sk->sk_state != TCP_LISTEN)
opt_skb = skb_clone_and_charge_r(skb, sk); opt_skb = skb_clone_and_charge_r(skb, sk);
reason = SKB_DROP_REASON_NOT_SPECIFIED; reason = SKB_DROP_REASON_NOT_SPECIFIED;
@@ -1502,8 +1502,6 @@ int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
if (nsk != sk) { if (nsk != sk) {
if (tcp_child_process(sk, nsk, skb)) if (tcp_child_process(sk, nsk, skb))
goto reset; goto reset;
if (opt_skb)
__kfree_skb(opt_skb);
return 0; return 0;
} }
} else } else

View File

@@ -689,6 +689,10 @@ void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata)
ASSERT_RTNL(); ASSERT_RTNL();
mutex_lock(&sdata->local->iflist_mtx); mutex_lock(&sdata->local->iflist_mtx);
if (list_empty(&sdata->local->interfaces)) {
mutex_unlock(&sdata->local->iflist_mtx);
return;
}
list_del_rcu(&sdata->list); list_del_rcu(&sdata->list);
mutex_unlock(&sdata->local->iflist_mtx); mutex_unlock(&sdata->local->iflist_mtx);

View File

@@ -605,7 +605,6 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb,
} }
opts->ext_copy.use_ack = 1; opts->ext_copy.use_ack = 1;
opts->suboptions = OPTION_MPTCP_DSS; opts->suboptions = OPTION_MPTCP_DSS;
WRITE_ONCE(msk->old_wspace, __mptcp_space((struct sock *)msk));
/* Add kind/length/subtype/flag overhead if mapping is not populated */ /* Add kind/length/subtype/flag overhead if mapping is not populated */
if (dss_size == 0) if (dss_size == 0)
@@ -1265,7 +1264,7 @@ static void mptcp_set_rwin(struct tcp_sock *tp, struct tcphdr *th)
} }
MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_RCVWNDCONFLICT); MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_RCVWNDCONFLICT);
} }
return; goto update_wspace;
} }
if (rcv_wnd_new != rcv_wnd_old) { if (rcv_wnd_new != rcv_wnd_old) {
@@ -1290,6 +1289,9 @@ raise_win:
th->window = htons(new_win); th->window = htons(new_win);
MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_RCVWNDSHARED); MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_RCVWNDSHARED);
} }
update_wspace:
WRITE_ONCE(msk->old_wspace, tp->rcv_wnd);
} }
__sum16 __mptcp_make_csum(u64 data_seq, u32 subflow_seq, u16 data_len, __wsum sum) __sum16 __mptcp_make_csum(u64 data_seq, u32 subflow_seq, u16 data_len, __wsum sum)

View File

@@ -913,7 +913,9 @@ static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port,
{ {
struct vport *vport = ovs_vport_rcu(dp, out_port); struct vport *vport = ovs_vport_rcu(dp, out_port);
if (likely(vport && netif_carrier_ok(vport->dev))) { if (likely(vport &&
netif_running(vport->dev) &&
netif_carrier_ok(vport->dev))) {
u16 mru = OVS_CB(skb)->mru; u16 mru = OVS_CB(skb)->mru;
u32 cutlen = OVS_CB(skb)->cutlen; u32 cutlen = OVS_CB(skb)->cutlen;

View File

@@ -487,6 +487,15 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk)
*/ */
vsk->transport->release(vsk); vsk->transport->release(vsk);
vsock_deassign_transport(vsk); vsock_deassign_transport(vsk);
/* transport's release() and destruct() can touch some socket
* state, since we are reassigning the socket to a new transport
* during vsock_connect(), let's reset these fields to have a
* clean state.
*/
sock_reset_flag(sk, SOCK_DONE);
sk->sk_state = TCP_CLOSE;
vsk->peer_shutdown = 0;
} }
/* We increase the module refcnt to prevent the transport unloading /* We increase the module refcnt to prevent the transport unloading
@@ -866,6 +875,9 @@ EXPORT_SYMBOL_GPL(vsock_create_connected);
s64 vsock_stream_has_data(struct vsock_sock *vsk) s64 vsock_stream_has_data(struct vsock_sock *vsk)
{ {
if (WARN_ON(!vsk->transport))
return 0;
return vsk->transport->stream_has_data(vsk); return vsk->transport->stream_has_data(vsk);
} }
EXPORT_SYMBOL_GPL(vsock_stream_has_data); EXPORT_SYMBOL_GPL(vsock_stream_has_data);
@@ -874,6 +886,9 @@ static s64 vsock_connectible_has_data(struct vsock_sock *vsk)
{ {
struct sock *sk = sk_vsock(vsk); struct sock *sk = sk_vsock(vsk);
if (WARN_ON(!vsk->transport))
return 0;
if (sk->sk_type == SOCK_SEQPACKET) if (sk->sk_type == SOCK_SEQPACKET)
return vsk->transport->seqpacket_has_data(vsk); return vsk->transport->seqpacket_has_data(vsk);
else else
@@ -882,6 +897,9 @@ static s64 vsock_connectible_has_data(struct vsock_sock *vsk)
s64 vsock_stream_has_space(struct vsock_sock *vsk) s64 vsock_stream_has_space(struct vsock_sock *vsk)
{ {
if (WARN_ON(!vsk->transport))
return 0;
return vsk->transport->stream_has_space(vsk); return vsk->transport->stream_has_space(vsk);
} }
EXPORT_SYMBOL_GPL(vsock_stream_has_space); EXPORT_SYMBOL_GPL(vsock_stream_has_space);

View File

@@ -26,6 +26,9 @@
/* Threshold for detecting small packets to copy */ /* Threshold for detecting small packets to copy */
#define GOOD_COPY_LEN 128 #define GOOD_COPY_LEN 128
static void virtio_transport_cancel_close_work(struct vsock_sock *vsk,
bool cancel_timeout);
uint virtio_transport_max_vsock_pkt_buf_size = 64 * 1024; uint virtio_transport_max_vsock_pkt_buf_size = 64 * 1024;
module_param(virtio_transport_max_vsock_pkt_buf_size, uint, 0444); module_param(virtio_transport_max_vsock_pkt_buf_size, uint, 0444);
EXPORT_SYMBOL_GPL(virtio_transport_max_vsock_pkt_buf_size); EXPORT_SYMBOL_GPL(virtio_transport_max_vsock_pkt_buf_size);
@@ -812,6 +815,8 @@ void virtio_transport_destruct(struct vsock_sock *vsk)
{ {
struct virtio_vsock_sock *vvs = vsk->trans; struct virtio_vsock_sock *vvs = vsk->trans;
virtio_transport_cancel_close_work(vsk, true);
kfree(vvs); kfree(vvs);
vsk->trans = NULL; vsk->trans = NULL;
} }
@@ -900,6 +905,22 @@ static void virtio_transport_wait_close(struct sock *sk, long timeout)
} }
} }
static void virtio_transport_cancel_close_work(struct vsock_sock *vsk,
bool cancel_timeout)
{
struct sock *sk = sk_vsock(vsk);
if (vsk->close_work_scheduled &&
(!cancel_timeout || cancel_delayed_work(&vsk->close_work))) {
vsk->close_work_scheduled = false;
virtio_transport_remove_sock(vsk);
/* Release refcnt obtained when we scheduled the timeout */
sock_put(sk);
}
}
static void virtio_transport_do_close(struct vsock_sock *vsk, static void virtio_transport_do_close(struct vsock_sock *vsk,
bool cancel_timeout) bool cancel_timeout)
{ {
@@ -911,15 +932,7 @@ static void virtio_transport_do_close(struct vsock_sock *vsk,
sk->sk_state = TCP_CLOSING; sk->sk_state = TCP_CLOSING;
sk->sk_state_change(sk); sk->sk_state_change(sk);
if (vsk->close_work_scheduled && virtio_transport_cancel_close_work(vsk, cancel_timeout);
(!cancel_timeout || cancel_delayed_work(&vsk->close_work))) {
vsk->close_work_scheduled = false;
virtio_transport_remove_sock(vsk);
/* Release refcnt obtained when we scheduled the timeout */
sock_put(sk);
}
} }
static void virtio_transport_close_timeout(struct work_struct *work) static void virtio_transport_close_timeout(struct work_struct *work)
@@ -1305,8 +1318,11 @@ void virtio_transport_recv_pkt(struct virtio_transport *t,
lock_sock(sk); lock_sock(sk);
/* Check if sk has been closed before lock_sock */ /* Check if sk has been closed or assigned to another transport before
if (sock_flag(sk, SOCK_DONE)) { * lock_sock (note: listener sockets are not assigned to any transport)
*/
if (sock_flag(sk, SOCK_DONE) ||
(sk->sk_state != TCP_LISTEN && vsk->transport != &t->transport)) {
(void)virtio_transport_reset_no_sock(t, pkt); (void)virtio_transport_reset_no_sock(t, pkt);
release_sock(sk); release_sock(sk);
sock_put(sk); sock_put(sk);

View File

@@ -10242,6 +10242,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC), SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC),
SND_PCI_QUIRK(0x1d72, 0x1945, "Redmi G", ALC256_FIXUP_ASUS_HEADSET_MIC), SND_PCI_QUIRK(0x1d72, 0x1945, "Redmi G", ALC256_FIXUP_ASUS_HEADSET_MIC),
SND_PCI_QUIRK(0x1d72, 0x1947, "RedmiBook Air", ALC255_FIXUP_XIAOMI_HEADSET_MIC), SND_PCI_QUIRK(0x1d72, 0x1947, "RedmiBook Air", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
SND_PCI_QUIRK(0x1f66, 0x0105, "Ayaneo Portable Game Player", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x2782, 0x0214, "VAIO VJFE-CL", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x2782, 0x0214, "VAIO VJFE-CL", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
SND_PCI_QUIRK(0x2782, 0x0228, "Infinix ZERO BOOK 13", ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13), SND_PCI_QUIRK(0x2782, 0x0228, "Infinix ZERO BOOK 13", ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13),
SND_PCI_QUIRK(0x2782, 0x0232, "CHUWI CoreBook XPro", ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO), SND_PCI_QUIRK(0x2782, 0x0232, "CHUWI CoreBook XPro", ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO),

View File

@@ -25,6 +25,8 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <arpa/inet.h>
#include <netdb.h> #include <netdb.h>
#include <netinet/in.h> #include <netinet/in.h>
@@ -1131,23 +1133,42 @@ static void parse_setsock_options(const char *name)
exit(1); exit(1);
} }
void xdisconnect(int fd, int addrlen) void xdisconnect(int fd)
{ {
struct sockaddr_storage empty; socklen_t addrlen = sizeof(struct sockaddr_storage);
struct sockaddr_storage addr, empty;
int msec_sleep = 10; int msec_sleep = 10;
int queued = 1; void *raw_addr;
int i; int i, cmdlen;
char cmd[128];
/* get the local address and convert it to string */
if (getsockname(fd, (struct sockaddr *)&addr, &addrlen) < 0)
xerror("getsockname");
if (addr.ss_family == AF_INET)
raw_addr = &(((struct sockaddr_in *)&addr)->sin_addr);
else if (addr.ss_family == AF_INET6)
raw_addr = &(((struct sockaddr_in6 *)&addr)->sin6_addr);
else
xerror("bad family");
strcpy(cmd, "ss -M | grep -q ");
cmdlen = strlen(cmd);
if (!inet_ntop(addr.ss_family, raw_addr, &cmd[cmdlen],
sizeof(cmd) - cmdlen))
xerror("inet_ntop");
shutdown(fd, SHUT_WR); shutdown(fd, SHUT_WR);
/* while until the pending data is completely flushed, the later /*
* wait until the pending data is completely flushed and all
* the MPTCP sockets reached the closed status.
* disconnect will bypass/ignore/drop any pending data. * disconnect will bypass/ignore/drop any pending data.
*/ */
for (i = 0; ; i += msec_sleep) { for (i = 0; ; i += msec_sleep) {
if (ioctl(fd, SIOCOUTQ, &queued) < 0) /* closed socket are not listed by 'ss' */
xerror("can't query out socket queue: %d", errno); if (system(cmd) != 0)
if (!queued)
break; break;
if (i > poll_timeout) if (i > poll_timeout)
@@ -1195,9 +1216,9 @@ again:
return ret; return ret;
if (cfg_truncate > 0) { if (cfg_truncate > 0) {
xdisconnect(fd, peer->ai_addrlen); xdisconnect(fd);
} else if (--cfg_repeat > 0) { } else if (--cfg_repeat > 0) {
xdisconnect(fd, peer->ai_addrlen); xdisconnect(fd);
/* the socket could be unblocking at this point, we need the /* the socket could be unblocking at this point, we need the
* connect to be blocking * connect to be blocking

View File

@@ -78,10 +78,10 @@
"setup": [ "setup": [
"$TC qdisc add dev $DEV1 ingress" "$TC qdisc add dev $DEV1 ingress"
], ],
"cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 protocol ip flow map key dst rshift 0xff", "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 protocol ip flow map key dst rshift 0x1f",
"expExitCode": "0", "expExitCode": "0",
"verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 protocol ip prio 1 flow", "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 protocol ip prio 1 flow",
"matchPattern": "filter parent ffff: protocol ip pref 1 flow chain [0-9]+ handle 0x1 map keys dst rshift 255 baseclass", "matchPattern": "filter parent ffff: protocol ip pref 1 flow chain [0-9]+ handle 0x1 map keys dst rshift 31 baseclass",
"matchCount": "1", "matchCount": "1",
"teardown": [ "teardown": [
"$TC qdisc del dev $DEV1 ingress" "$TC qdisc del dev $DEV1 ingress"