mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 18:41:58 +09:00
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:
2
Makefile
2
Makefile
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 =
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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 *
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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)) {
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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(>p->list, &gn->gtp_dev_list);
|
list_add(>p->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, >p->tid_hash[i], hlist_tid)
|
hlist_for_each_entry_safe(pctx, next, >p->tid_hash[i], hlist_tid)
|
||||||
pdp_context_delete(pctx);
|
pdp_context_delete(pctx);
|
||||||
|
|
||||||
list_del_rcu(>p->list);
|
list_del(>p->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 != >p_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 == >p_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 = >p_net_id,
|
.id = >p_net_id,
|
||||||
.size = sizeof(struct gtp_net),
|
.size = sizeof(struct gtp_net),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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[] = {
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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("");
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
135
fs/erofs/zmap.c
135
fs/erofs/zmap.c
@@ -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",
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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 = {
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
Reference in New Issue
Block a user