mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 10:31:46 +09:00
Merge 6.1.128 into android14-6.1-lts
Changes in 6.1.128 ASoC: wm8994: Add depends on MFD core ASoC: samsung: Add missing selects for MFD_WM8994 seccomp: Stub for !CONFIG_SECCOMP scsi: iscsi: Fix redundant response for ISCSI_UEVENT_GET_HOST_STATS request drm/amd/display: Use HW lock mgr for PSR1 irqchip/sunxi-nmi: Add missing SKIP_WAKE flag ASoC: samsung: midas_wm1811: Map missing jack kcontrols ASoC: samsung: Add missing depends on I2C regmap: detach regmap from dev on regmap_exit ipv6: Fix soft lockups in fib6_select_path under high next hop churn softirq: Allow raising SCHED_SOFTIRQ from SMP-call-function on RT kernel xfs: bump max fsgeom struct version xfs: hoist freeing of rt data fork extent mappings xfs: prevent rt growfs when quota is enabled xfs: rt stubs should return negative errnos when rt disabled xfs: fix units conversion error in xfs_bmap_del_extent_delay xfs: make sure maxlen is still congruent with prod when rounding down xfs: introduce protection for drop nlink xfs: handle nimaps=0 from xfs_bmapi_write in xfs_alloc_file_space xfs: allow read IO and FICLONE to run concurrently xfs: factor out xfs_defer_pending_abort xfs: abort intent items when recovery intents fail xfs: only remap the written blocks in xfs_reflink_end_cow_extent xfs: up(ic_sema) if flushing data device fails xfs: fix internal error from AGFL exhaustion xfs: inode recovery does not validate the recovered inode xfs: clean up dqblk extraction xfs: dquot recovery does not validate the recovered dquot xfs: clean up FS_XFLAG_REALTIME handling in xfs_ioctl_setattr_xflags xfs: respect the stable writes flag on the RT device gfs2: Truncate address space when flipping GFS2_DIF_JDATA flag io_uring: fix waiters missing wake ups net: sched: fix ets qdisc OOB Indexing block: fix integer overflow in BLKSECDISCARD Revert "HID: multitouch: Add support for lenovo Y9000P Touchpad" vfio/platform: check the bounds of read/write syscalls ext4: fix access to uninitialised lock in fc replay path ipv4: ip_tunnel: Fix suspicious RCU usage warning in ip_tunnel_find() scsi: storvsc: Ratelimit warning logs to prevent VM denial of service wifi: iwlwifi: add a few rate index validity checks smb: client: fix UAF in async decryption USB: serial: quatech2: fix null-ptr-deref in qt2_process_read_urb() Revert "usb: gadget: u_serial: Disable ep before setting port to null to fix the crash caused by port being null" ALSA: usb-audio: Add delay quirk for USB Audio Device Input: atkbd - map F23 key to support default copilot shortcut Input: xpad - add unofficial Xbox 360 wireless receiver clone Input: xpad - add support for wooting two he (arm) smb: client: fix NULL ptr deref in crypto_aead_setkey() ASoC: samsung: midas_wm1811: Fix 'Headphone Switch' control creation drm/v3d: Assign job pointer to NULL before signaling the fence Linux 6.1.128 Change-Id: Ia1ddc5824b498862a5eb730dd99bd3a76dd16015 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 = 127
|
SUBLEVEL = 128
|
||||||
EXTRAVERSION =
|
EXTRAVERSION =
|
||||||
NAME = Curry Ramen
|
NAME = Curry Ramen
|
||||||
|
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ static int blk_ioctl_discard(struct block_device *bdev, fmode_t mode,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
filemap_invalidate_lock(inode->i_mapping);
|
filemap_invalidate_lock(inode->i_mapping);
|
||||||
err = truncate_bdev_range(bdev, mode, start, start + len - 1);
|
err = truncate_bdev_range(bdev, mode, start, end - 1);
|
||||||
if (err)
|
if (err)
|
||||||
goto fail;
|
goto fail;
|
||||||
err = blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_KERNEL);
|
err = blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_KERNEL);
|
||||||
@@ -127,7 +127,7 @@ fail:
|
|||||||
static int blk_ioctl_secure_erase(struct block_device *bdev, fmode_t mode,
|
static int blk_ioctl_secure_erase(struct block_device *bdev, fmode_t mode,
|
||||||
void __user *argp)
|
void __user *argp)
|
||||||
{
|
{
|
||||||
uint64_t start, len;
|
uint64_t start, len, end;
|
||||||
uint64_t range[2];
|
uint64_t range[2];
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@@ -142,11 +142,12 @@ static int blk_ioctl_secure_erase(struct block_device *bdev, fmode_t mode,
|
|||||||
len = range[1];
|
len = range[1];
|
||||||
if ((start & 511) || (len & 511))
|
if ((start & 511) || (len & 511))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (start + len > bdev_nr_bytes(bdev))
|
if (check_add_overflow(start, len, &end) ||
|
||||||
|
end > bdev_nr_bytes(bdev))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
filemap_invalidate_lock(bdev->bd_inode->i_mapping);
|
filemap_invalidate_lock(bdev->bd_inode->i_mapping);
|
||||||
err = truncate_bdev_range(bdev, mode, start, start + len - 1);
|
err = truncate_bdev_range(bdev, mode, start, end - 1);
|
||||||
if (!err)
|
if (!err)
|
||||||
err = blkdev_issue_secure_erase(bdev, start >> 9, len >> 9,
|
err = blkdev_issue_secure_erase(bdev, start >> 9, len >> 9,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
|
|||||||
@@ -652,6 +652,17 @@ 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)
|
||||||
{
|
{
|
||||||
@@ -1536,6 +1547,7 @@ void regmap_exit(struct regmap *map)
|
|||||||
{
|
{
|
||||||
struct regmap_async *async;
|
struct regmap_async *async;
|
||||||
|
|
||||||
|
regmap_detach_dev(map->dev, map);
|
||||||
regcache_exit(map);
|
regcache_exit(map);
|
||||||
regmap_debugfs_exit(map);
|
regmap_debugfs_exit(map);
|
||||||
regmap_range_exit(map);
|
regmap_range_exit(map);
|
||||||
|
|||||||
@@ -65,7 +65,8 @@ void dmub_hw_lock_mgr_inbox0_cmd(struct dc_dmub_srv *dmub_srv,
|
|||||||
|
|
||||||
bool should_use_dmub_lock(struct dc_link *link)
|
bool should_use_dmub_lock(struct dc_link *link)
|
||||||
{
|
{
|
||||||
if (link->psr_settings.psr_version == DC_PSR_VERSION_SU_1)
|
if (link->psr_settings.psr_version == DC_PSR_VERSION_SU_1 ||
|
||||||
|
link->psr_settings.psr_version == DC_PSR_VERSION_1)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,8 +102,10 @@ v3d_irq(int irq, void *arg)
|
|||||||
to_v3d_fence(v3d->bin_job->base.irq_fence);
|
to_v3d_fence(v3d->bin_job->base.irq_fence);
|
||||||
|
|
||||||
trace_v3d_bcl_irq(&v3d->drm, fence->seqno);
|
trace_v3d_bcl_irq(&v3d->drm, fence->seqno);
|
||||||
dma_fence_signal(&fence->base);
|
|
||||||
v3d->bin_job = NULL;
|
v3d->bin_job = NULL;
|
||||||
|
dma_fence_signal(&fence->base);
|
||||||
|
|
||||||
status = IRQ_HANDLED;
|
status = IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,8 +114,10 @@ v3d_irq(int irq, void *arg)
|
|||||||
to_v3d_fence(v3d->render_job->base.irq_fence);
|
to_v3d_fence(v3d->render_job->base.irq_fence);
|
||||||
|
|
||||||
trace_v3d_rcl_irq(&v3d->drm, fence->seqno);
|
trace_v3d_rcl_irq(&v3d->drm, fence->seqno);
|
||||||
dma_fence_signal(&fence->base);
|
|
||||||
v3d->render_job = NULL;
|
v3d->render_job = NULL;
|
||||||
|
dma_fence_signal(&fence->base);
|
||||||
|
|
||||||
status = IRQ_HANDLED;
|
status = IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,8 +126,10 @@ v3d_irq(int irq, void *arg)
|
|||||||
to_v3d_fence(v3d->csd_job->base.irq_fence);
|
to_v3d_fence(v3d->csd_job->base.irq_fence);
|
||||||
|
|
||||||
trace_v3d_csd_irq(&v3d->drm, fence->seqno);
|
trace_v3d_csd_irq(&v3d->drm, fence->seqno);
|
||||||
dma_fence_signal(&fence->base);
|
|
||||||
v3d->csd_job = NULL;
|
v3d->csd_job = NULL;
|
||||||
|
dma_fence_signal(&fence->base);
|
||||||
|
|
||||||
status = IRQ_HANDLED;
|
status = IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,8 +165,10 @@ v3d_hub_irq(int irq, void *arg)
|
|||||||
to_v3d_fence(v3d->tfu_job->base.irq_fence);
|
to_v3d_fence(v3d->tfu_job->base.irq_fence);
|
||||||
|
|
||||||
trace_v3d_tfu_irq(&v3d->drm, fence->seqno);
|
trace_v3d_tfu_irq(&v3d->drm, fence->seqno);
|
||||||
dma_fence_signal(&fence->base);
|
|
||||||
v3d->tfu_job = NULL;
|
v3d->tfu_job = NULL;
|
||||||
|
dma_fence_signal(&fence->base);
|
||||||
|
|
||||||
status = IRQ_HANDLED;
|
status = IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -507,7 +507,6 @@
|
|||||||
#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_E100 0xe100
|
#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_E100 0xe100
|
||||||
|
|
||||||
#define I2C_VENDOR_ID_GOODIX 0x27c6
|
#define I2C_VENDOR_ID_GOODIX 0x27c6
|
||||||
#define I2C_DEVICE_ID_GOODIX_01E0 0x01e0
|
|
||||||
#define I2C_DEVICE_ID_GOODIX_01E8 0x01e8
|
#define I2C_DEVICE_ID_GOODIX_01E8 0x01e8
|
||||||
#define I2C_DEVICE_ID_GOODIX_01E9 0x01e9
|
#define I2C_DEVICE_ID_GOODIX_01E9 0x01e9
|
||||||
#define I2C_DEVICE_ID_GOODIX_01F0 0x01f0
|
#define I2C_DEVICE_ID_GOODIX_01F0 0x01f0
|
||||||
|
|||||||
@@ -1447,8 +1447,7 @@ static __u8 *mt_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
|||||||
{
|
{
|
||||||
if (hdev->vendor == I2C_VENDOR_ID_GOODIX &&
|
if (hdev->vendor == I2C_VENDOR_ID_GOODIX &&
|
||||||
(hdev->product == I2C_DEVICE_ID_GOODIX_01E8 ||
|
(hdev->product == I2C_DEVICE_ID_GOODIX_01E8 ||
|
||||||
hdev->product == I2C_DEVICE_ID_GOODIX_01E9 ||
|
hdev->product == I2C_DEVICE_ID_GOODIX_01E9)) {
|
||||||
hdev->product == I2C_DEVICE_ID_GOODIX_01E0)) {
|
|
||||||
if (rdesc[607] == 0x15) {
|
if (rdesc[607] == 0x15) {
|
||||||
rdesc[607] = 0x25;
|
rdesc[607] = 0x25;
|
||||||
dev_info(
|
dev_info(
|
||||||
@@ -2073,10 +2072,7 @@ static const struct hid_device_id mt_devices[] = {
|
|||||||
I2C_DEVICE_ID_GOODIX_01E8) },
|
I2C_DEVICE_ID_GOODIX_01E8) },
|
||||||
{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU,
|
{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU,
|
||||||
HID_DEVICE(BUS_I2C, HID_GROUP_ANY, I2C_VENDOR_ID_GOODIX,
|
HID_DEVICE(BUS_I2C, HID_GROUP_ANY, I2C_VENDOR_ID_GOODIX,
|
||||||
I2C_DEVICE_ID_GOODIX_01E9) },
|
I2C_DEVICE_ID_GOODIX_01E8) },
|
||||||
{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU,
|
|
||||||
HID_DEVICE(BUS_I2C, HID_GROUP_ANY, I2C_VENDOR_ID_GOODIX,
|
|
||||||
I2C_DEVICE_ID_GOODIX_01E0) },
|
|
||||||
|
|
||||||
/* GoodTouch panels */
|
/* GoodTouch panels */
|
||||||
{ .driver_data = MT_CLS_NSMU,
|
{ .driver_data = MT_CLS_NSMU,
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ static const struct xpad_device {
|
|||||||
{ 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 },
|
{ 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 },
|
||||||
{ 0x045e, 0x028f, "Microsoft X-Box 360 pad v2", 0, XTYPE_XBOX360 },
|
{ 0x045e, 0x028f, "Microsoft X-Box 360 pad v2", 0, XTYPE_XBOX360 },
|
||||||
{ 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
|
{ 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
|
||||||
|
{ 0x045e, 0x02a9, "Xbox 360 Wireless Receiver (Unofficial)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
|
||||||
{ 0x045e, 0x02d1, "Microsoft X-Box One pad", 0, XTYPE_XBOXONE },
|
{ 0x045e, 0x02d1, "Microsoft X-Box One pad", 0, XTYPE_XBOXONE },
|
||||||
{ 0x045e, 0x02dd, "Microsoft X-Box One pad (Firmware 2015)", 0, XTYPE_XBOXONE },
|
{ 0x045e, 0x02dd, "Microsoft X-Box One pad (Firmware 2015)", 0, XTYPE_XBOXONE },
|
||||||
{ 0x045e, 0x02e3, "Microsoft X-Box One Elite pad", MAP_PADDLES, XTYPE_XBOXONE },
|
{ 0x045e, 0x02e3, "Microsoft X-Box One Elite pad", MAP_PADDLES, XTYPE_XBOXONE },
|
||||||
@@ -366,6 +367,7 @@ static const struct xpad_device {
|
|||||||
{ 0x31e3, 0x1200, "Wooting Two", 0, XTYPE_XBOX360 },
|
{ 0x31e3, 0x1200, "Wooting Two", 0, XTYPE_XBOX360 },
|
||||||
{ 0x31e3, 0x1210, "Wooting Lekker", 0, XTYPE_XBOX360 },
|
{ 0x31e3, 0x1210, "Wooting Lekker", 0, XTYPE_XBOX360 },
|
||||||
{ 0x31e3, 0x1220, "Wooting Two HE", 0, XTYPE_XBOX360 },
|
{ 0x31e3, 0x1220, "Wooting Two HE", 0, XTYPE_XBOX360 },
|
||||||
|
{ 0x31e3, 0x1230, "Wooting Two HE (ARM)", 0, XTYPE_XBOX360 },
|
||||||
{ 0x31e3, 0x1300, "Wooting 60HE (AVR)", 0, XTYPE_XBOX360 },
|
{ 0x31e3, 0x1300, "Wooting 60HE (AVR)", 0, XTYPE_XBOX360 },
|
||||||
{ 0x31e3, 0x1310, "Wooting 60HE (ARM)", 0, XTYPE_XBOX360 },
|
{ 0x31e3, 0x1310, "Wooting 60HE (ARM)", 0, XTYPE_XBOX360 },
|
||||||
{ 0x3285, 0x0607, "Nacon GC-100", 0, XTYPE_XBOX360 },
|
{ 0x3285, 0x0607, "Nacon GC-100", 0, XTYPE_XBOX360 },
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ static const unsigned short atkbd_set2_keycode[ATKBD_KEYMAP_SIZE] = {
|
|||||||
0, 46, 45, 32, 18, 5, 4, 95, 0, 57, 47, 33, 20, 19, 6,183,
|
0, 46, 45, 32, 18, 5, 4, 95, 0, 57, 47, 33, 20, 19, 6,183,
|
||||||
0, 49, 48, 35, 34, 21, 7,184, 0, 0, 50, 36, 22, 8, 9,185,
|
0, 49, 48, 35, 34, 21, 7,184, 0, 0, 50, 36, 22, 8, 9,185,
|
||||||
0, 51, 37, 23, 24, 11, 10, 0, 0, 52, 53, 38, 39, 25, 12, 0,
|
0, 51, 37, 23, 24, 11, 10, 0, 0, 52, 53, 38, 39, 25, 12, 0,
|
||||||
0, 89, 40, 0, 26, 13, 0, 0, 58, 54, 28, 27, 0, 43, 0, 85,
|
0, 89, 40, 0, 26, 13, 0,193, 58, 54, 28, 27, 0, 43, 0, 85,
|
||||||
0, 86, 91, 90, 92, 0, 14, 94, 0, 79,124, 75, 71,121, 0, 0,
|
0, 86, 91, 90, 92, 0, 14, 94, 0, 79,124, 75, 71,121, 0, 0,
|
||||||
82, 83, 80, 76, 77, 72, 1, 69, 87, 78, 81, 74, 55, 73, 70, 99,
|
82, 83, 80, 76, 77, 72, 1, 69, 87, 78, 81, 74, 55, 73, 70, 99,
|
||||||
|
|
||||||
|
|||||||
@@ -187,7 +187,8 @@ static int __init sunxi_sc_nmi_irq_init(struct device_node *node,
|
|||||||
gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
|
gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
|
||||||
gc->chip_types[0].chip.irq_eoi = irq_gc_ack_set_bit;
|
gc->chip_types[0].chip.irq_eoi = irq_gc_ack_set_bit;
|
||||||
gc->chip_types[0].chip.irq_set_type = sunxi_sc_nmi_set_type;
|
gc->chip_types[0].chip.irq_set_type = sunxi_sc_nmi_set_type;
|
||||||
gc->chip_types[0].chip.flags = IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED;
|
gc->chip_types[0].chip.flags = IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED |
|
||||||
|
IRQCHIP_SKIP_SET_WAKE;
|
||||||
gc->chip_types[0].regs.ack = reg_offs->pend;
|
gc->chip_types[0].regs.ack = reg_offs->pend;
|
||||||
gc->chip_types[0].regs.mask = reg_offs->enable;
|
gc->chip_types[0].regs.mask = reg_offs->enable;
|
||||||
gc->chip_types[0].regs.type = reg_offs->ctrl;
|
gc->chip_types[0].regs.type = reg_offs->ctrl;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||||
* Copyright (C) 2019 - 2020, 2022 Intel Corporation
|
* Copyright (C) 2019 - 2020, 2022 - 2023 Intel Corporation
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
@@ -125,7 +125,7 @@ static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
|
|||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return IWL_RATE_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rs_rate_scale_perform(struct iwl_priv *priv,
|
static void rs_rate_scale_perform(struct iwl_priv *priv,
|
||||||
@@ -3146,7 +3146,10 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
|
|||||||
for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
|
for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
|
||||||
index = iwl_hwrate_to_plcp_idx(
|
index = iwl_hwrate_to_plcp_idx(
|
||||||
le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags));
|
le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags));
|
||||||
if (is_legacy(tbl->lq_type)) {
|
if (index == IWL_RATE_INVALID) {
|
||||||
|
desc += sprintf(buff + desc, " rate[%d] 0x%X invalid rate\n",
|
||||||
|
i, le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags));
|
||||||
|
} else if (is_legacy(tbl->lq_type)) {
|
||||||
desc += sprintf(buff+desc, " rate[%d] 0x%X %smbps\n",
|
desc += sprintf(buff+desc, " rate[%d] 0x%X %smbps\n",
|
||||||
i, le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags),
|
i, le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags),
|
||||||
iwl_rate_mcs[index].mbps);
|
iwl_rate_mcs[index].mbps);
|
||||||
|
|||||||
@@ -1072,10 +1072,13 @@ static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta,
|
|||||||
|
|
||||||
rate->bw = RATE_MCS_CHAN_WIDTH_20;
|
rate->bw = RATE_MCS_CHAN_WIDTH_20;
|
||||||
|
|
||||||
WARN_ON_ONCE(rate->index < IWL_RATE_MCS_0_INDEX ||
|
if (WARN_ON_ONCE(rate->index < IWL_RATE_MCS_0_INDEX))
|
||||||
rate->index > IWL_RATE_MCS_9_INDEX);
|
rate->index = rs_ht_to_legacy[IWL_RATE_MCS_0_INDEX];
|
||||||
|
else if (WARN_ON_ONCE(rate->index > IWL_RATE_MCS_9_INDEX))
|
||||||
|
rate->index = rs_ht_to_legacy[IWL_RATE_MCS_9_INDEX];
|
||||||
|
else
|
||||||
|
rate->index = rs_ht_to_legacy[rate->index];
|
||||||
|
|
||||||
rate->index = rs_ht_to_legacy[rate->index];
|
|
||||||
rate->ldpc = false;
|
rate->ldpc = false;
|
||||||
} else {
|
} else {
|
||||||
/* Downgrade to SISO with same MCS if in MIMO */
|
/* Downgrade to SISO with same MCS if in MIMO */
|
||||||
|
|||||||
@@ -4102,7 +4102,7 @@ iscsi_if_rx(struct sk_buff *skb)
|
|||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
/*
|
/*
|
||||||
* special case for GET_STATS:
|
* special case for GET_STATS, GET_CHAP and GET_HOST_STATS:
|
||||||
* on success - sending reply and stats from
|
* on success - sending reply and stats from
|
||||||
* inside of if_recv_msg(),
|
* inside of if_recv_msg(),
|
||||||
* on error - fall through.
|
* on error - fall through.
|
||||||
@@ -4111,6 +4111,8 @@ iscsi_if_rx(struct sk_buff *skb)
|
|||||||
break;
|
break;
|
||||||
if (ev->type == ISCSI_UEVENT_GET_CHAP && !err)
|
if (ev->type == ISCSI_UEVENT_GET_CHAP && !err)
|
||||||
break;
|
break;
|
||||||
|
if (ev->type == ISCSI_UEVENT_GET_HOST_STATS && !err)
|
||||||
|
break;
|
||||||
err = iscsi_if_send_reply(portid, nlh->nlmsg_type,
|
err = iscsi_if_send_reply(portid, nlh->nlmsg_type,
|
||||||
ev, sizeof(*ev));
|
ev, sizeof(*ev));
|
||||||
if (err == -EAGAIN && --retries < 0) {
|
if (err == -EAGAIN && --retries < 0) {
|
||||||
|
|||||||
@@ -171,6 +171,12 @@ do { \
|
|||||||
dev_warn(&(dev)->device, fmt, ##__VA_ARGS__); \
|
dev_warn(&(dev)->device, fmt, ##__VA_ARGS__); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define storvsc_log_ratelimited(dev, level, fmt, ...) \
|
||||||
|
do { \
|
||||||
|
if (do_logging(level)) \
|
||||||
|
dev_warn_ratelimited(&(dev)->device, fmt, ##__VA_ARGS__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
struct vmscsi_request {
|
struct vmscsi_request {
|
||||||
u16 length;
|
u16 length;
|
||||||
u8 srb_status;
|
u8 srb_status;
|
||||||
@@ -1168,7 +1174,7 @@ static void storvsc_on_io_completion(struct storvsc_device *stor_device,
|
|||||||
int loglevel = (stor_pkt->vm_srb.cdb[0] == TEST_UNIT_READY) ?
|
int loglevel = (stor_pkt->vm_srb.cdb[0] == TEST_UNIT_READY) ?
|
||||||
STORVSC_LOGGING_WARN : STORVSC_LOGGING_ERROR;
|
STORVSC_LOGGING_WARN : STORVSC_LOGGING_ERROR;
|
||||||
|
|
||||||
storvsc_log(device, loglevel,
|
storvsc_log_ratelimited(device, loglevel,
|
||||||
"tag#%d cmd 0x%x status: scsi 0x%x srb 0x%x hv 0x%x\n",
|
"tag#%d cmd 0x%x status: scsi 0x%x srb 0x%x hv 0x%x\n",
|
||||||
scsi_cmd_to_rq(request->cmd)->tag,
|
scsi_cmd_to_rq(request->cmd)->tag,
|
||||||
stor_pkt->vm_srb.cdb[0],
|
stor_pkt->vm_srb.cdb[0],
|
||||||
|
|||||||
@@ -1403,10 +1403,6 @@ void gserial_disconnect(struct gserial *gser)
|
|||||||
/* REVISIT as above: how best to track this? */
|
/* REVISIT as above: how best to track this? */
|
||||||
port->port_line_coding = gser->port_line_coding;
|
port->port_line_coding = gser->port_line_coding;
|
||||||
|
|
||||||
/* disable endpoints, aborting down any active I/O */
|
|
||||||
usb_ep_disable(gser->out);
|
|
||||||
usb_ep_disable(gser->in);
|
|
||||||
|
|
||||||
port->port_usb = NULL;
|
port->port_usb = NULL;
|
||||||
gser->ioport = NULL;
|
gser->ioport = NULL;
|
||||||
if (port->port.count > 0) {
|
if (port->port.count > 0) {
|
||||||
@@ -1418,6 +1414,10 @@ void gserial_disconnect(struct gserial *gser)
|
|||||||
spin_unlock(&port->port_lock);
|
spin_unlock(&port->port_lock);
|
||||||
spin_unlock_irqrestore(&serial_port_lock, flags);
|
spin_unlock_irqrestore(&serial_port_lock, flags);
|
||||||
|
|
||||||
|
/* disable endpoints, aborting down any active I/O */
|
||||||
|
usb_ep_disable(gser->out);
|
||||||
|
usb_ep_disable(gser->in);
|
||||||
|
|
||||||
/* finally, free any unused/unusable I/O buffers */
|
/* finally, free any unused/unusable I/O buffers */
|
||||||
spin_lock_irqsave(&port->port_lock, flags);
|
spin_lock_irqsave(&port->port_lock, flags);
|
||||||
if (port->port.count == 0)
|
if (port->port.count == 0)
|
||||||
|
|||||||
@@ -511,7 +511,7 @@ static void qt2_process_read_urb(struct urb *urb)
|
|||||||
|
|
||||||
newport = *(ch + 3);
|
newport = *(ch + 3);
|
||||||
|
|
||||||
if (newport > serial->num_ports) {
|
if (newport >= serial->num_ports) {
|
||||||
dev_err(&port->dev,
|
dev_err(&port->dev,
|
||||||
"%s - port change to invalid port: %i\n",
|
"%s - port change to invalid port: %i\n",
|
||||||
__func__, newport);
|
__func__, newport);
|
||||||
|
|||||||
@@ -391,6 +391,11 @@ static ssize_t vfio_platform_read_mmio(struct vfio_platform_region *reg,
|
|||||||
{
|
{
|
||||||
unsigned int done = 0;
|
unsigned int done = 0;
|
||||||
|
|
||||||
|
if (off >= reg->size)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
count = min_t(size_t, count, reg->size - off);
|
||||||
|
|
||||||
if (!reg->ioaddr) {
|
if (!reg->ioaddr) {
|
||||||
reg->ioaddr =
|
reg->ioaddr =
|
||||||
ioremap(reg->addr, reg->size);
|
ioremap(reg->addr, reg->size);
|
||||||
@@ -470,6 +475,11 @@ static ssize_t vfio_platform_write_mmio(struct vfio_platform_region *reg,
|
|||||||
{
|
{
|
||||||
unsigned int done = 0;
|
unsigned int done = 0;
|
||||||
|
|
||||||
|
if (off >= reg->size)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
count = min_t(size_t, count, reg->size - off);
|
||||||
|
|
||||||
if (!reg->ioaddr) {
|
if (!reg->ioaddr) {
|
||||||
reg->ioaddr =
|
reg->ioaddr =
|
||||||
ioremap(reg->addr, reg->size);
|
ioremap(reg->addr, reg->size);
|
||||||
|
|||||||
@@ -5256,6 +5256,8 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
|
|||||||
INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
|
INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
|
||||||
mutex_init(&sbi->s_orphan_lock);
|
mutex_init(&sbi->s_orphan_lock);
|
||||||
|
|
||||||
|
spin_lock_init(&sbi->s_bdev_wb_lock);
|
||||||
|
|
||||||
ext4_fast_commit_init(sb);
|
ext4_fast_commit_init(sb);
|
||||||
|
|
||||||
sb->s_root = NULL;
|
sb->s_root = NULL;
|
||||||
@@ -5501,7 +5503,6 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
|
|||||||
* Save the original bdev mapping's wb_err value which could be
|
* Save the original bdev mapping's wb_err value which could be
|
||||||
* used to detect the metadata async write error.
|
* used to detect the metadata async write error.
|
||||||
*/
|
*/
|
||||||
spin_lock_init(&sbi->s_bdev_wb_lock);
|
|
||||||
errseq_check_and_advance(&sb->s_bdev->bd_inode->i_mapping->wb_err,
|
errseq_check_and_advance(&sb->s_bdev->bd_inode->i_mapping->wb_err,
|
||||||
&sbi->s_bdev_wb_err);
|
&sbi->s_bdev_wb_err);
|
||||||
sb->s_bdev->bd_super = sb;
|
sb->s_bdev->bd_super = sb;
|
||||||
|
|||||||
@@ -250,6 +250,7 @@ static int do_gfs2_set_flags(struct inode *inode, u32 reqflags, u32 mask)
|
|||||||
error = filemap_fdatawait(inode->i_mapping);
|
error = filemap_fdatawait(inode->i_mapping);
|
||||||
if (error)
|
if (error)
|
||||||
goto out;
|
goto out;
|
||||||
|
truncate_inode_pages(inode->i_mapping, 0);
|
||||||
if (new_flags & GFS2_DIF_JDATA)
|
if (new_flags & GFS2_DIF_JDATA)
|
||||||
gfs2_ordered_del_inode(ip);
|
gfs2_ordered_del_inode(ip);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4488,7 +4488,7 @@ smb2_get_enc_key(struct TCP_Server_Info *server, __u64 ses_id, int enc, u8 *key)
|
|||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
crypt_message(struct TCP_Server_Info *server, int num_rqst,
|
crypt_message(struct TCP_Server_Info *server, int num_rqst,
|
||||||
struct smb_rqst *rqst, int enc)
|
struct smb_rqst *rqst, int enc, struct crypto_aead *tfm)
|
||||||
{
|
{
|
||||||
struct smb2_transform_hdr *tr_hdr =
|
struct smb2_transform_hdr *tr_hdr =
|
||||||
(struct smb2_transform_hdr *)rqst[0].rq_iov[0].iov_base;
|
(struct smb2_transform_hdr *)rqst[0].rq_iov[0].iov_base;
|
||||||
@@ -4499,8 +4499,6 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
|
|||||||
u8 key[SMB3_ENC_DEC_KEY_SIZE];
|
u8 key[SMB3_ENC_DEC_KEY_SIZE];
|
||||||
struct aead_request *req;
|
struct aead_request *req;
|
||||||
u8 *iv;
|
u8 *iv;
|
||||||
DECLARE_CRYPTO_WAIT(wait);
|
|
||||||
struct crypto_aead *tfm;
|
|
||||||
unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
|
unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
|
||||||
void *creq;
|
void *creq;
|
||||||
|
|
||||||
@@ -4511,14 +4509,6 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = smb3_crypto_aead_allocate(server);
|
|
||||||
if (rc) {
|
|
||||||
cifs_server_dbg(VFS, "%s: crypto alloc failed\n", __func__);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
tfm = enc ? server->secmech.enc : server->secmech.dec;
|
|
||||||
|
|
||||||
if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
|
if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
|
||||||
(server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
|
(server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
|
||||||
rc = crypto_aead_setkey(tfm, key, SMB3_GCM256_CRYPTKEY_SIZE);
|
rc = crypto_aead_setkey(tfm, key, SMB3_GCM256_CRYPTKEY_SIZE);
|
||||||
@@ -4557,11 +4547,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
|
|||||||
aead_request_set_crypt(req, sg, sg, crypt_len, iv);
|
aead_request_set_crypt(req, sg, sg, crypt_len, iv);
|
||||||
aead_request_set_ad(req, assoc_data_len);
|
aead_request_set_ad(req, assoc_data_len);
|
||||||
|
|
||||||
aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
|
rc = enc ? crypto_aead_encrypt(req) : crypto_aead_decrypt(req);
|
||||||
crypto_req_done, &wait);
|
|
||||||
|
|
||||||
rc = crypto_wait_req(enc ? crypto_aead_encrypt(req)
|
|
||||||
: crypto_aead_decrypt(req), &wait);
|
|
||||||
|
|
||||||
if (!rc && enc)
|
if (!rc && enc)
|
||||||
memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE);
|
memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE);
|
||||||
@@ -4650,7 +4636,7 @@ smb3_init_transform_rq(struct TCP_Server_Info *server, int num_rqst,
|
|||||||
/* fill the 1st iov with a transform header */
|
/* fill the 1st iov with a transform header */
|
||||||
fill_transform_hdr(tr_hdr, orig_len, old_rq, server->cipher_type);
|
fill_transform_hdr(tr_hdr, orig_len, old_rq, server->cipher_type);
|
||||||
|
|
||||||
rc = crypt_message(server, num_rqst, new_rq, 1);
|
rc = crypt_message(server, num_rqst, new_rq, 1, server->secmech.enc);
|
||||||
cifs_dbg(FYI, "Encrypt message returned %d\n", rc);
|
cifs_dbg(FYI, "Encrypt message returned %d\n", rc);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto err_free;
|
goto err_free;
|
||||||
@@ -4676,8 +4662,9 @@ decrypt_raw_data(struct TCP_Server_Info *server, char *buf,
|
|||||||
unsigned int npages, unsigned int page_data_size,
|
unsigned int npages, unsigned int page_data_size,
|
||||||
bool is_offloaded)
|
bool is_offloaded)
|
||||||
{
|
{
|
||||||
struct kvec iov[2];
|
struct crypto_aead *tfm;
|
||||||
struct smb_rqst rqst = {NULL};
|
struct smb_rqst rqst = {NULL};
|
||||||
|
struct kvec iov[2];
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
iov[0].iov_base = buf;
|
iov[0].iov_base = buf;
|
||||||
@@ -4692,9 +4679,31 @@ decrypt_raw_data(struct TCP_Server_Info *server, char *buf,
|
|||||||
rqst.rq_pagesz = PAGE_SIZE;
|
rqst.rq_pagesz = PAGE_SIZE;
|
||||||
rqst.rq_tailsz = (page_data_size % PAGE_SIZE) ? : PAGE_SIZE;
|
rqst.rq_tailsz = (page_data_size % PAGE_SIZE) ? : PAGE_SIZE;
|
||||||
|
|
||||||
rc = crypt_message(server, 1, &rqst, 0);
|
if (is_offloaded) {
|
||||||
|
if ((server->cipher_type == SMB2_ENCRYPTION_AES128_GCM) ||
|
||||||
|
(server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
|
||||||
|
tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
|
||||||
|
else
|
||||||
|
tfm = crypto_alloc_aead("ccm(aes)", 0, 0);
|
||||||
|
if (IS_ERR(tfm)) {
|
||||||
|
rc = PTR_ERR(tfm);
|
||||||
|
cifs_server_dbg(VFS, "%s: Failed alloc decrypt TFM, rc=%d\n", __func__, rc);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (unlikely(!server->secmech.dec))
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
tfm = server->secmech.dec;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = crypt_message(server, 1, &rqst, 0, tfm);
|
||||||
cifs_dbg(FYI, "Decrypt message returned %d\n", rc);
|
cifs_dbg(FYI, "Decrypt message returned %d\n", rc);
|
||||||
|
|
||||||
|
if (is_offloaded)
|
||||||
|
crypto_free_aead(tfm);
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
|||||||
@@ -1070,7 +1070,9 @@ SMB2_negotiate(const unsigned int xid,
|
|||||||
* SMB3.0 supports only 1 cipher and doesn't have a encryption neg context
|
* SMB3.0 supports only 1 cipher and doesn't have a encryption neg context
|
||||||
* Set the cipher type manually.
|
* Set the cipher type manually.
|
||||||
*/
|
*/
|
||||||
if (server->dialect == SMB30_PROT_ID && (server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION))
|
if ((server->dialect == SMB30_PROT_ID ||
|
||||||
|
server->dialect == SMB302_PROT_ID) &&
|
||||||
|
(server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION))
|
||||||
server->cipher_type = SMB2_ENCRYPTION_AES128_CCM;
|
server->cipher_type = SMB2_ENCRYPTION_AES128_CCM;
|
||||||
|
|
||||||
security_blob = smb2_get_data_area_len(&blob_offset, &blob_length,
|
security_blob = smb2_get_data_area_len(&blob_offset, &blob_length,
|
||||||
@@ -1105,6 +1107,12 @@ SMB2_negotiate(const unsigned int xid,
|
|||||||
else
|
else
|
||||||
cifs_server_dbg(VFS, "Missing expected negotiate contexts\n");
|
cifs_server_dbg(VFS, "Missing expected negotiate contexts\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (server->cipher_type && !rc) {
|
||||||
|
rc = smb3_crypto_aead_allocate(server);
|
||||||
|
if (rc)
|
||||||
|
cifs_server_dbg(VFS, "%s: crypto alloc failed, rc=%d\n", __func__, rc);
|
||||||
|
}
|
||||||
neg_exit:
|
neg_exit:
|
||||||
free_rsp_buf(resp_buftype, rsp);
|
free_rsp_buf(resp_buftype, rsp);
|
||||||
return rc;
|
return rc;
|
||||||
|
|||||||
@@ -2273,16 +2273,37 @@ xfs_alloc_min_freelist(
|
|||||||
|
|
||||||
ASSERT(mp->m_alloc_maxlevels > 0);
|
ASSERT(mp->m_alloc_maxlevels > 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For a btree shorter than the maximum height, the worst case is that
|
||||||
|
* every level gets split and a new level is added, then while inserting
|
||||||
|
* another entry to refill the AGFL, every level under the old root gets
|
||||||
|
* split again. This is:
|
||||||
|
*
|
||||||
|
* (full height split reservation) + (AGFL refill split height)
|
||||||
|
* = (current height + 1) + (current height - 1)
|
||||||
|
* = (new height) + (new height - 2)
|
||||||
|
* = 2 * new height - 2
|
||||||
|
*
|
||||||
|
* For a btree of maximum height, the worst case is that every level
|
||||||
|
* under the root gets split, then while inserting another entry to
|
||||||
|
* refill the AGFL, every level under the root gets split again. This is
|
||||||
|
* also:
|
||||||
|
*
|
||||||
|
* 2 * (current height - 1)
|
||||||
|
* = 2 * (new height - 1)
|
||||||
|
* = 2 * new height - 2
|
||||||
|
*/
|
||||||
|
|
||||||
/* space needed by-bno freespace btree */
|
/* space needed by-bno freespace btree */
|
||||||
min_free = min_t(unsigned int, levels[XFS_BTNUM_BNOi] + 1,
|
min_free = min_t(unsigned int, levels[XFS_BTNUM_BNOi] + 1,
|
||||||
mp->m_alloc_maxlevels);
|
mp->m_alloc_maxlevels) * 2 - 2;
|
||||||
/* space needed by-size freespace btree */
|
/* space needed by-size freespace btree */
|
||||||
min_free += min_t(unsigned int, levels[XFS_BTNUM_CNTi] + 1,
|
min_free += min_t(unsigned int, levels[XFS_BTNUM_CNTi] + 1,
|
||||||
mp->m_alloc_maxlevels);
|
mp->m_alloc_maxlevels) * 2 - 2;
|
||||||
/* space needed reverse mapping used space btree */
|
/* space needed reverse mapping used space btree */
|
||||||
if (xfs_has_rmapbt(mp))
|
if (xfs_has_rmapbt(mp))
|
||||||
min_free += min_t(unsigned int, levels[XFS_BTNUM_RMAPi] + 1,
|
min_free += min_t(unsigned int, levels[XFS_BTNUM_RMAPi] + 1,
|
||||||
mp->m_rmap_maxlevels);
|
mp->m_rmap_maxlevels) * 2 - 2;
|
||||||
|
|
||||||
return min_free;
|
return min_free;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4805,7 +4805,7 @@ xfs_bmap_del_extent_delay(
|
|||||||
ASSERT(got_endoff >= del_endoff);
|
ASSERT(got_endoff >= del_endoff);
|
||||||
|
|
||||||
if (isrt) {
|
if (isrt) {
|
||||||
uint64_t rtexts = XFS_FSB_TO_B(mp, del->br_blockcount);
|
uint64_t rtexts = del->br_blockcount;
|
||||||
|
|
||||||
do_div(rtexts, mp->m_sb.sb_rextsize);
|
do_div(rtexts, mp->m_sb.sb_rextsize);
|
||||||
xfs_mod_frextents(mp, rtexts);
|
xfs_mod_frextents(mp, rtexts);
|
||||||
@@ -5035,33 +5035,20 @@ xfs_bmap_del_extent_real(
|
|||||||
|
|
||||||
flags = XFS_ILOG_CORE;
|
flags = XFS_ILOG_CORE;
|
||||||
if (whichfork == XFS_DATA_FORK && XFS_IS_REALTIME_INODE(ip)) {
|
if (whichfork == XFS_DATA_FORK && XFS_IS_REALTIME_INODE(ip)) {
|
||||||
xfs_filblks_t len;
|
|
||||||
xfs_extlen_t mod;
|
|
||||||
|
|
||||||
len = div_u64_rem(del->br_blockcount, mp->m_sb.sb_rextsize,
|
|
||||||
&mod);
|
|
||||||
ASSERT(mod == 0);
|
|
||||||
|
|
||||||
if (!(bflags & XFS_BMAPI_REMAP)) {
|
if (!(bflags & XFS_BMAPI_REMAP)) {
|
||||||
xfs_fsblock_t bno;
|
error = xfs_rtfree_blocks(tp, del->br_startblock,
|
||||||
|
del->br_blockcount);
|
||||||
bno = div_u64_rem(del->br_startblock,
|
|
||||||
mp->m_sb.sb_rextsize, &mod);
|
|
||||||
ASSERT(mod == 0);
|
|
||||||
|
|
||||||
error = xfs_rtfree_extent(tp, bno, (xfs_extlen_t)len);
|
|
||||||
if (error)
|
if (error)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
do_fx = 0;
|
do_fx = 0;
|
||||||
nblks = len * mp->m_sb.sb_rextsize;
|
|
||||||
qfield = XFS_TRANS_DQ_RTBCOUNT;
|
qfield = XFS_TRANS_DQ_RTBCOUNT;
|
||||||
} else {
|
} else {
|
||||||
do_fx = 1;
|
do_fx = 1;
|
||||||
nblks = del->br_blockcount;
|
|
||||||
qfield = XFS_TRANS_DQ_BCOUNT;
|
qfield = XFS_TRANS_DQ_BCOUNT;
|
||||||
}
|
}
|
||||||
|
nblks = del->br_blockcount;
|
||||||
|
|
||||||
del_endblock = del->br_startblock + del->br_blockcount;
|
del_endblock = del->br_startblock + del->br_blockcount;
|
||||||
if (cur) {
|
if (cur) {
|
||||||
|
|||||||
@@ -245,26 +245,33 @@ xfs_defer_create_intents(
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATIC void
|
||||||
|
xfs_defer_pending_abort(
|
||||||
|
struct xfs_mount *mp,
|
||||||
|
struct list_head *dop_list)
|
||||||
|
{
|
||||||
|
struct xfs_defer_pending *dfp;
|
||||||
|
const struct xfs_defer_op_type *ops;
|
||||||
|
|
||||||
|
/* Abort intent items that don't have a done item. */
|
||||||
|
list_for_each_entry(dfp, dop_list, dfp_list) {
|
||||||
|
ops = defer_op_types[dfp->dfp_type];
|
||||||
|
trace_xfs_defer_pending_abort(mp, dfp);
|
||||||
|
if (dfp->dfp_intent && !dfp->dfp_done) {
|
||||||
|
ops->abort_intent(dfp->dfp_intent);
|
||||||
|
dfp->dfp_intent = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Abort all the intents that were committed. */
|
/* Abort all the intents that were committed. */
|
||||||
STATIC void
|
STATIC void
|
||||||
xfs_defer_trans_abort(
|
xfs_defer_trans_abort(
|
||||||
struct xfs_trans *tp,
|
struct xfs_trans *tp,
|
||||||
struct list_head *dop_pending)
|
struct list_head *dop_pending)
|
||||||
{
|
{
|
||||||
struct xfs_defer_pending *dfp;
|
|
||||||
const struct xfs_defer_op_type *ops;
|
|
||||||
|
|
||||||
trace_xfs_defer_trans_abort(tp, _RET_IP_);
|
trace_xfs_defer_trans_abort(tp, _RET_IP_);
|
||||||
|
xfs_defer_pending_abort(tp->t_mountp, dop_pending);
|
||||||
/* Abort intent items that don't have a done item. */
|
|
||||||
list_for_each_entry(dfp, dop_pending, dfp_list) {
|
|
||||||
ops = defer_op_types[dfp->dfp_type];
|
|
||||||
trace_xfs_defer_pending_abort(tp->t_mountp, dfp);
|
|
||||||
if (dfp->dfp_intent && !dfp->dfp_done) {
|
|
||||||
ops->abort_intent(dfp->dfp_intent);
|
|
||||||
dfp->dfp_intent = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -754,12 +761,13 @@ xfs_defer_ops_capture(
|
|||||||
|
|
||||||
/* Release all resources that we used to capture deferred ops. */
|
/* Release all resources that we used to capture deferred ops. */
|
||||||
void
|
void
|
||||||
xfs_defer_ops_capture_free(
|
xfs_defer_ops_capture_abort(
|
||||||
struct xfs_mount *mp,
|
struct xfs_mount *mp,
|
||||||
struct xfs_defer_capture *dfc)
|
struct xfs_defer_capture *dfc)
|
||||||
{
|
{
|
||||||
unsigned short i;
|
unsigned short i;
|
||||||
|
|
||||||
|
xfs_defer_pending_abort(mp, &dfc->dfc_dfops);
|
||||||
xfs_defer_cancel_list(mp, &dfc->dfc_dfops);
|
xfs_defer_cancel_list(mp, &dfc->dfc_dfops);
|
||||||
|
|
||||||
for (i = 0; i < dfc->dfc_held.dr_bufs; i++)
|
for (i = 0; i < dfc->dfc_held.dr_bufs; i++)
|
||||||
@@ -800,7 +808,7 @@ xfs_defer_ops_capture_and_commit(
|
|||||||
/* Commit the transaction and add the capture structure to the list. */
|
/* Commit the transaction and add the capture structure to the list. */
|
||||||
error = xfs_trans_commit(tp);
|
error = xfs_trans_commit(tp);
|
||||||
if (error) {
|
if (error) {
|
||||||
xfs_defer_ops_capture_free(mp, dfc);
|
xfs_defer_ops_capture_abort(mp, dfc);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ int xfs_defer_ops_capture_and_commit(struct xfs_trans *tp,
|
|||||||
struct list_head *capture_list);
|
struct list_head *capture_list);
|
||||||
void xfs_defer_ops_continue(struct xfs_defer_capture *d, struct xfs_trans *tp,
|
void xfs_defer_ops_continue(struct xfs_defer_capture *d, struct xfs_trans *tp,
|
||||||
struct xfs_defer_resources *dres);
|
struct xfs_defer_resources *dres);
|
||||||
void xfs_defer_ops_capture_free(struct xfs_mount *mp,
|
void xfs_defer_ops_capture_abort(struct xfs_mount *mp,
|
||||||
struct xfs_defer_capture *d);
|
struct xfs_defer_capture *d);
|
||||||
void xfs_defer_resources_rele(struct xfs_defer_resources *dres);
|
void xfs_defer_resources_rele(struct xfs_defer_resources *dres);
|
||||||
|
|
||||||
|
|||||||
@@ -507,6 +507,9 @@ xfs_dinode_verify(
|
|||||||
if (mode && nextents + naextents > nblocks)
|
if (mode && nextents + naextents > nblocks)
|
||||||
return __this_address;
|
return __this_address;
|
||||||
|
|
||||||
|
if (nextents + naextents == 0 && nblocks != 0)
|
||||||
|
return __this_address;
|
||||||
|
|
||||||
if (S_ISDIR(mode) && nextents > mp->m_dir_geo->max_extents)
|
if (S_ISDIR(mode) && nextents > mp->m_dir_geo->max_extents)
|
||||||
return __this_address;
|
return __this_address;
|
||||||
|
|
||||||
|
|||||||
@@ -1005,6 +1005,39 @@ xfs_rtfree_extent(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free some blocks in the realtime subvolume. rtbno and rtlen are in units of
|
||||||
|
* rt blocks, not rt extents; must be aligned to the rt extent size; and rtlen
|
||||||
|
* cannot exceed XFS_MAX_BMBT_EXTLEN.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xfs_rtfree_blocks(
|
||||||
|
struct xfs_trans *tp,
|
||||||
|
xfs_fsblock_t rtbno,
|
||||||
|
xfs_filblks_t rtlen)
|
||||||
|
{
|
||||||
|
struct xfs_mount *mp = tp->t_mountp;
|
||||||
|
xfs_rtblock_t bno;
|
||||||
|
xfs_filblks_t len;
|
||||||
|
xfs_extlen_t mod;
|
||||||
|
|
||||||
|
ASSERT(rtlen <= XFS_MAX_BMBT_EXTLEN);
|
||||||
|
|
||||||
|
len = div_u64_rem(rtlen, mp->m_sb.sb_rextsize, &mod);
|
||||||
|
if (mod) {
|
||||||
|
ASSERT(mod == 0);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
bno = div_u64_rem(rtbno, mp->m_sb.sb_rextsize, &mod);
|
||||||
|
if (mod) {
|
||||||
|
ASSERT(mod == 0);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xfs_rtfree_extent(tp, bno, len);
|
||||||
|
}
|
||||||
|
|
||||||
/* Find all the free records within a given range. */
|
/* Find all the free records within a given range. */
|
||||||
int
|
int
|
||||||
xfs_rtalloc_query_range(
|
xfs_rtalloc_query_range(
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ extern uint64_t xfs_sb_version_to_features(struct xfs_sb *sbp);
|
|||||||
|
|
||||||
extern int xfs_update_secondary_sbs(struct xfs_mount *mp);
|
extern int xfs_update_secondary_sbs(struct xfs_mount *mp);
|
||||||
|
|
||||||
#define XFS_FS_GEOM_MAX_STRUCT_VER (4)
|
#define XFS_FS_GEOM_MAX_STRUCT_VER (5)
|
||||||
extern void xfs_fs_geometry(struct xfs_mount *mp, struct xfs_fsop_geom *geo,
|
extern void xfs_fs_geometry(struct xfs_mount *mp, struct xfs_fsop_geom *geo,
|
||||||
int struct_version);
|
int struct_version);
|
||||||
extern int xfs_sb_read_secondary(struct xfs_mount *mp,
|
extern int xfs_sb_read_secondary(struct xfs_mount *mp,
|
||||||
|
|||||||
@@ -780,12 +780,10 @@ xfs_alloc_file_space(
|
|||||||
{
|
{
|
||||||
xfs_mount_t *mp = ip->i_mount;
|
xfs_mount_t *mp = ip->i_mount;
|
||||||
xfs_off_t count;
|
xfs_off_t count;
|
||||||
xfs_filblks_t allocated_fsb;
|
|
||||||
xfs_filblks_t allocatesize_fsb;
|
xfs_filblks_t allocatesize_fsb;
|
||||||
xfs_extlen_t extsz, temp;
|
xfs_extlen_t extsz, temp;
|
||||||
xfs_fileoff_t startoffset_fsb;
|
xfs_fileoff_t startoffset_fsb;
|
||||||
xfs_fileoff_t endoffset_fsb;
|
xfs_fileoff_t endoffset_fsb;
|
||||||
int nimaps;
|
|
||||||
int rt;
|
int rt;
|
||||||
xfs_trans_t *tp;
|
xfs_trans_t *tp;
|
||||||
xfs_bmbt_irec_t imaps[1], *imapp;
|
xfs_bmbt_irec_t imaps[1], *imapp;
|
||||||
@@ -808,7 +806,6 @@ xfs_alloc_file_space(
|
|||||||
|
|
||||||
count = len;
|
count = len;
|
||||||
imapp = &imaps[0];
|
imapp = &imaps[0];
|
||||||
nimaps = 1;
|
|
||||||
startoffset_fsb = XFS_B_TO_FSBT(mp, offset);
|
startoffset_fsb = XFS_B_TO_FSBT(mp, offset);
|
||||||
endoffset_fsb = XFS_B_TO_FSB(mp, offset + count);
|
endoffset_fsb = XFS_B_TO_FSB(mp, offset + count);
|
||||||
allocatesize_fsb = endoffset_fsb - startoffset_fsb;
|
allocatesize_fsb = endoffset_fsb - startoffset_fsb;
|
||||||
@@ -819,6 +816,7 @@ xfs_alloc_file_space(
|
|||||||
while (allocatesize_fsb && !error) {
|
while (allocatesize_fsb && !error) {
|
||||||
xfs_fileoff_t s, e;
|
xfs_fileoff_t s, e;
|
||||||
unsigned int dblocks, rblocks, resblks;
|
unsigned int dblocks, rblocks, resblks;
|
||||||
|
int nimaps = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine space reservations for data/realtime.
|
* Determine space reservations for data/realtime.
|
||||||
@@ -884,15 +882,19 @@ xfs_alloc_file_space(
|
|||||||
if (error)
|
if (error)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
allocated_fsb = imapp->br_blockcount;
|
/*
|
||||||
|
* If the allocator cannot find a single free extent large
|
||||||
if (nimaps == 0) {
|
* enough to cover the start block of the requested range,
|
||||||
error = -ENOSPC;
|
* xfs_bmapi_write will return 0 but leave *nimaps set to 0.
|
||||||
break;
|
*
|
||||||
|
* In that case we simply need to keep looping with the same
|
||||||
|
* startoffset_fsb so that one of the following allocations
|
||||||
|
* will eventually reach the requested range.
|
||||||
|
*/
|
||||||
|
if (nimaps) {
|
||||||
|
startoffset_fsb += imapp->br_blockcount;
|
||||||
|
allocatesize_fsb -= imapp->br_blockcount;
|
||||||
}
|
}
|
||||||
|
|
||||||
startoffset_fsb += allocated_fsb;
|
|
||||||
allocatesize_fsb -= allocated_fsb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
|
|||||||
@@ -562,7 +562,8 @@ xfs_dquot_from_disk(
|
|||||||
struct xfs_dquot *dqp,
|
struct xfs_dquot *dqp,
|
||||||
struct xfs_buf *bp)
|
struct xfs_buf *bp)
|
||||||
{
|
{
|
||||||
struct xfs_disk_dquot *ddqp = bp->b_addr + dqp->q_bufoffset;
|
struct xfs_dqblk *dqb = xfs_buf_offset(bp, dqp->q_bufoffset);
|
||||||
|
struct xfs_disk_dquot *ddqp = &dqb->dd_diskdq;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ensure that we got the type and ID we were looking for.
|
* Ensure that we got the type and ID we were looking for.
|
||||||
@@ -1250,7 +1251,7 @@ xfs_qm_dqflush(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Flush the incore dquot to the ondisk buffer. */
|
/* Flush the incore dquot to the ondisk buffer. */
|
||||||
dqblk = bp->b_addr + dqp->q_bufoffset;
|
dqblk = xfs_buf_offset(bp, dqp->q_bufoffset);
|
||||||
xfs_dquot_to_disk(&dqblk->dd_diskdq, dqp);
|
xfs_dquot_to_disk(&dqblk->dd_diskdq, dqp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "xfs_log.h"
|
#include "xfs_log.h"
|
||||||
#include "xfs_log_priv.h"
|
#include "xfs_log_priv.h"
|
||||||
#include "xfs_log_recover.h"
|
#include "xfs_log_recover.h"
|
||||||
|
#include "xfs_error.h"
|
||||||
|
|
||||||
STATIC void
|
STATIC void
|
||||||
xlog_recover_dquot_ra_pass2(
|
xlog_recover_dquot_ra_pass2(
|
||||||
@@ -65,6 +66,7 @@ xlog_recover_dquot_commit_pass2(
|
|||||||
{
|
{
|
||||||
struct xfs_mount *mp = log->l_mp;
|
struct xfs_mount *mp = log->l_mp;
|
||||||
struct xfs_buf *bp;
|
struct xfs_buf *bp;
|
||||||
|
struct xfs_dqblk *dqb;
|
||||||
struct xfs_disk_dquot *ddq, *recddq;
|
struct xfs_disk_dquot *ddq, *recddq;
|
||||||
struct xfs_dq_logformat *dq_f;
|
struct xfs_dq_logformat *dq_f;
|
||||||
xfs_failaddr_t fa;
|
xfs_failaddr_t fa;
|
||||||
@@ -130,14 +132,14 @@ xlog_recover_dquot_commit_pass2(
|
|||||||
return error;
|
return error;
|
||||||
|
|
||||||
ASSERT(bp);
|
ASSERT(bp);
|
||||||
ddq = xfs_buf_offset(bp, dq_f->qlf_boffset);
|
dqb = xfs_buf_offset(bp, dq_f->qlf_boffset);
|
||||||
|
ddq = &dqb->dd_diskdq;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the dquot has an LSN in it, recover the dquot only if it's less
|
* If the dquot has an LSN in it, recover the dquot only if it's less
|
||||||
* than the lsn of the transaction we are replaying.
|
* than the lsn of the transaction we are replaying.
|
||||||
*/
|
*/
|
||||||
if (xfs_has_crc(mp)) {
|
if (xfs_has_crc(mp)) {
|
||||||
struct xfs_dqblk *dqb = (struct xfs_dqblk *)ddq;
|
|
||||||
xfs_lsn_t lsn = be64_to_cpu(dqb->dd_lsn);
|
xfs_lsn_t lsn = be64_to_cpu(dqb->dd_lsn);
|
||||||
|
|
||||||
if (lsn && lsn != -1 && XFS_LSN_CMP(lsn, current_lsn) >= 0) {
|
if (lsn && lsn != -1 && XFS_LSN_CMP(lsn, current_lsn) >= 0) {
|
||||||
@@ -147,10 +149,23 @@ xlog_recover_dquot_commit_pass2(
|
|||||||
|
|
||||||
memcpy(ddq, recddq, item->ri_buf[1].i_len);
|
memcpy(ddq, recddq, item->ri_buf[1].i_len);
|
||||||
if (xfs_has_crc(mp)) {
|
if (xfs_has_crc(mp)) {
|
||||||
xfs_update_cksum((char *)ddq, sizeof(struct xfs_dqblk),
|
xfs_update_cksum((char *)dqb, sizeof(struct xfs_dqblk),
|
||||||
XFS_DQUOT_CRC_OFF);
|
XFS_DQUOT_CRC_OFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Validate the recovered dquot. */
|
||||||
|
fa = xfs_dqblk_verify(log->l_mp, dqb, dq_f->qlf_id);
|
||||||
|
if (fa) {
|
||||||
|
XFS_CORRUPTION_ERROR("Bad dquot after recovery",
|
||||||
|
XFS_ERRLEVEL_LOW, mp, dqb,
|
||||||
|
sizeof(struct xfs_dqblk));
|
||||||
|
xfs_alert(mp,
|
||||||
|
"Metadata corruption detected at %pS, dquot 0x%x",
|
||||||
|
fa, dq_f->qlf_id);
|
||||||
|
error = -EFSCORRUPTED;
|
||||||
|
goto out_release;
|
||||||
|
}
|
||||||
|
|
||||||
ASSERT(dq_f->qlf_size == 2);
|
ASSERT(dq_f->qlf_size == 2);
|
||||||
ASSERT(bp->b_mount == mp);
|
ASSERT(bp->b_mount == mp);
|
||||||
bp->b_flags |= _XBF_LOGRECOVERY;
|
bp->b_flags |= _XBF_LOGRECOVERY;
|
||||||
|
|||||||
@@ -214,6 +214,43 @@ xfs_ilock_iocb(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
xfs_ilock_iocb_for_write(
|
||||||
|
struct kiocb *iocb,
|
||||||
|
unsigned int *lock_mode)
|
||||||
|
{
|
||||||
|
ssize_t ret;
|
||||||
|
struct xfs_inode *ip = XFS_I(file_inode(iocb->ki_filp));
|
||||||
|
|
||||||
|
ret = xfs_ilock_iocb(iocb, *lock_mode);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (*lock_mode == XFS_IOLOCK_EXCL)
|
||||||
|
return 0;
|
||||||
|
if (!xfs_iflags_test(ip, XFS_IREMAPPING))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
xfs_iunlock(ip, *lock_mode);
|
||||||
|
*lock_mode = XFS_IOLOCK_EXCL;
|
||||||
|
return xfs_ilock_iocb(iocb, *lock_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
xfs_ilock_for_write_fault(
|
||||||
|
struct xfs_inode *ip)
|
||||||
|
{
|
||||||
|
/* get a shared lock if no remapping in progress */
|
||||||
|
xfs_ilock(ip, XFS_MMAPLOCK_SHARED);
|
||||||
|
if (!xfs_iflags_test(ip, XFS_IREMAPPING))
|
||||||
|
return XFS_MMAPLOCK_SHARED;
|
||||||
|
|
||||||
|
/* wait for remapping to complete */
|
||||||
|
xfs_iunlock(ip, XFS_MMAPLOCK_SHARED);
|
||||||
|
xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
|
||||||
|
return XFS_MMAPLOCK_EXCL;
|
||||||
|
}
|
||||||
|
|
||||||
STATIC ssize_t
|
STATIC ssize_t
|
||||||
xfs_file_dio_read(
|
xfs_file_dio_read(
|
||||||
struct kiocb *iocb,
|
struct kiocb *iocb,
|
||||||
@@ -523,7 +560,7 @@ xfs_file_dio_write_aligned(
|
|||||||
unsigned int iolock = XFS_IOLOCK_SHARED;
|
unsigned int iolock = XFS_IOLOCK_SHARED;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
ret = xfs_ilock_iocb(iocb, iolock);
|
ret = xfs_ilock_iocb_for_write(iocb, &iolock);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
ret = xfs_file_write_checks(iocb, from, &iolock);
|
ret = xfs_file_write_checks(iocb, from, &iolock);
|
||||||
@@ -590,7 +627,7 @@ retry_exclusive:
|
|||||||
flags = IOMAP_DIO_FORCE_WAIT;
|
flags = IOMAP_DIO_FORCE_WAIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = xfs_ilock_iocb(iocb, iolock);
|
ret = xfs_ilock_iocb_for_write(iocb, &iolock);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@@ -1158,7 +1195,7 @@ xfs_file_remap_range(
|
|||||||
if (xfs_file_sync_writes(file_in) || xfs_file_sync_writes(file_out))
|
if (xfs_file_sync_writes(file_in) || xfs_file_sync_writes(file_out))
|
||||||
xfs_log_force_inode(dest);
|
xfs_log_force_inode(dest);
|
||||||
out_unlock:
|
out_unlock:
|
||||||
xfs_iunlock2_io_mmap(src, dest);
|
xfs_iunlock2_remapping(src, dest);
|
||||||
if (ret)
|
if (ret)
|
||||||
trace_xfs_reflink_remap_range_error(dest, ret, _RET_IP_);
|
trace_xfs_reflink_remap_range_error(dest, ret, _RET_IP_);
|
||||||
/*
|
/*
|
||||||
@@ -1313,6 +1350,7 @@ __xfs_filemap_fault(
|
|||||||
struct inode *inode = file_inode(vmf->vma->vm_file);
|
struct inode *inode = file_inode(vmf->vma->vm_file);
|
||||||
struct xfs_inode *ip = XFS_I(inode);
|
struct xfs_inode *ip = XFS_I(inode);
|
||||||
vm_fault_t ret;
|
vm_fault_t ret;
|
||||||
|
unsigned int lock_mode = 0;
|
||||||
|
|
||||||
trace_xfs_filemap_fault(ip, pe_size, write_fault);
|
trace_xfs_filemap_fault(ip, pe_size, write_fault);
|
||||||
|
|
||||||
@@ -1321,25 +1359,24 @@ __xfs_filemap_fault(
|
|||||||
file_update_time(vmf->vma->vm_file);
|
file_update_time(vmf->vma->vm_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IS_DAX(inode) || write_fault)
|
||||||
|
lock_mode = xfs_ilock_for_write_fault(XFS_I(inode));
|
||||||
|
|
||||||
if (IS_DAX(inode)) {
|
if (IS_DAX(inode)) {
|
||||||
pfn_t pfn;
|
pfn_t pfn;
|
||||||
|
|
||||||
xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED);
|
|
||||||
ret = xfs_dax_fault(vmf, pe_size, write_fault, &pfn);
|
ret = xfs_dax_fault(vmf, pe_size, write_fault, &pfn);
|
||||||
if (ret & VM_FAULT_NEEDDSYNC)
|
if (ret & VM_FAULT_NEEDDSYNC)
|
||||||
ret = dax_finish_sync_fault(vmf, pe_size, pfn);
|
ret = dax_finish_sync_fault(vmf, pe_size, pfn);
|
||||||
xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED);
|
} else if (write_fault) {
|
||||||
|
ret = iomap_page_mkwrite(vmf, &xfs_page_mkwrite_iomap_ops);
|
||||||
} else {
|
} else {
|
||||||
if (write_fault) {
|
ret = filemap_fault(vmf);
|
||||||
xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED);
|
|
||||||
ret = iomap_page_mkwrite(vmf,
|
|
||||||
&xfs_page_mkwrite_iomap_ops);
|
|
||||||
xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED);
|
|
||||||
} else {
|
|
||||||
ret = filemap_fault(vmf);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lock_mode)
|
||||||
|
xfs_iunlock(XFS_I(inode), lock_mode);
|
||||||
|
|
||||||
if (write_fault)
|
if (write_fault)
|
||||||
sb_end_pagefault(inode->i_sb);
|
sb_end_pagefault(inode->i_sb);
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -919,6 +919,13 @@ xfs_droplink(
|
|||||||
xfs_trans_t *tp,
|
xfs_trans_t *tp,
|
||||||
xfs_inode_t *ip)
|
xfs_inode_t *ip)
|
||||||
{
|
{
|
||||||
|
if (VFS_I(ip)->i_nlink == 0) {
|
||||||
|
xfs_alert(ip->i_mount,
|
||||||
|
"%s: Attempt to drop inode (%llu) with nlink zero.",
|
||||||
|
__func__, ip->i_ino);
|
||||||
|
return -EFSCORRUPTED;
|
||||||
|
}
|
||||||
|
|
||||||
xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
|
xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
|
||||||
|
|
||||||
drop_nlink(VFS_I(ip));
|
drop_nlink(VFS_I(ip));
|
||||||
@@ -3637,6 +3644,23 @@ xfs_iunlock2_io_mmap(
|
|||||||
inode_unlock(VFS_I(ip1));
|
inode_unlock(VFS_I(ip1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Drop the MMAPLOCK and the IOLOCK after a remap completes. */
|
||||||
|
void
|
||||||
|
xfs_iunlock2_remapping(
|
||||||
|
struct xfs_inode *ip1,
|
||||||
|
struct xfs_inode *ip2)
|
||||||
|
{
|
||||||
|
xfs_iflags_clear(ip1, XFS_IREMAPPING);
|
||||||
|
|
||||||
|
if (ip1 != ip2)
|
||||||
|
xfs_iunlock(ip1, XFS_MMAPLOCK_SHARED);
|
||||||
|
xfs_iunlock(ip2, XFS_MMAPLOCK_EXCL);
|
||||||
|
|
||||||
|
if (ip1 != ip2)
|
||||||
|
inode_unlock_shared(VFS_I(ip1));
|
||||||
|
inode_unlock(VFS_I(ip2));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reload the incore inode list for this inode. Caller should ensure that
|
* Reload the incore inode list for this inode. Caller should ensure that
|
||||||
* the link count cannot change, either by taking ILOCK_SHARED or otherwise
|
* the link count cannot change, either by taking ILOCK_SHARED or otherwise
|
||||||
|
|||||||
@@ -347,6 +347,14 @@ static inline bool xfs_inode_has_large_extent_counts(struct xfs_inode *ip)
|
|||||||
/* Quotacheck is running but inode has not been added to quota counts. */
|
/* Quotacheck is running but inode has not been added to quota counts. */
|
||||||
#define XFS_IQUOTAUNCHECKED (1 << 14)
|
#define XFS_IQUOTAUNCHECKED (1 << 14)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remap in progress. Callers that wish to update file data while
|
||||||
|
* holding a shared IOLOCK or MMAPLOCK must drop the lock and retake
|
||||||
|
* the lock in exclusive mode. Relocking the file will block until
|
||||||
|
* IREMAPPING is cleared.
|
||||||
|
*/
|
||||||
|
#define XFS_IREMAPPING (1U << 15)
|
||||||
|
|
||||||
/* All inode state flags related to inode reclaim. */
|
/* All inode state flags related to inode reclaim. */
|
||||||
#define XFS_ALL_IRECLAIM_FLAGS (XFS_IRECLAIMABLE | \
|
#define XFS_ALL_IRECLAIM_FLAGS (XFS_IRECLAIMABLE | \
|
||||||
XFS_IRECLAIM | \
|
XFS_IRECLAIM | \
|
||||||
@@ -561,6 +569,14 @@ extern void xfs_setup_inode(struct xfs_inode *ip);
|
|||||||
extern void xfs_setup_iops(struct xfs_inode *ip);
|
extern void xfs_setup_iops(struct xfs_inode *ip);
|
||||||
extern void xfs_diflags_to_iflags(struct xfs_inode *ip, bool init);
|
extern void xfs_diflags_to_iflags(struct xfs_inode *ip, bool init);
|
||||||
|
|
||||||
|
static inline void xfs_update_stable_writes(struct xfs_inode *ip)
|
||||||
|
{
|
||||||
|
if (bdev_stable_writes(xfs_inode_buftarg(ip)->bt_bdev))
|
||||||
|
mapping_set_stable_writes(VFS_I(ip)->i_mapping);
|
||||||
|
else
|
||||||
|
mapping_clear_stable_writes(VFS_I(ip)->i_mapping);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When setting up a newly allocated inode, we need to call
|
* When setting up a newly allocated inode, we need to call
|
||||||
* xfs_finish_inode_setup() once the inode is fully instantiated at
|
* xfs_finish_inode_setup() once the inode is fully instantiated at
|
||||||
@@ -595,6 +611,7 @@ void xfs_end_io(struct work_struct *work);
|
|||||||
|
|
||||||
int xfs_ilock2_io_mmap(struct xfs_inode *ip1, struct xfs_inode *ip2);
|
int xfs_ilock2_io_mmap(struct xfs_inode *ip1, struct xfs_inode *ip2);
|
||||||
void xfs_iunlock2_io_mmap(struct xfs_inode *ip1, struct xfs_inode *ip2);
|
void xfs_iunlock2_io_mmap(struct xfs_inode *ip1, struct xfs_inode *ip2);
|
||||||
|
void xfs_iunlock2_remapping(struct xfs_inode *ip1, struct xfs_inode *ip2);
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
xfs_inode_unlinked_incomplete(
|
xfs_inode_unlinked_incomplete(
|
||||||
|
|||||||
@@ -286,6 +286,7 @@ xlog_recover_inode_commit_pass2(
|
|||||||
struct xfs_log_dinode *ldip;
|
struct xfs_log_dinode *ldip;
|
||||||
uint isize;
|
uint isize;
|
||||||
int need_free = 0;
|
int need_free = 0;
|
||||||
|
xfs_failaddr_t fa;
|
||||||
|
|
||||||
if (item->ri_buf[0].i_len == sizeof(struct xfs_inode_log_format)) {
|
if (item->ri_buf[0].i_len == sizeof(struct xfs_inode_log_format)) {
|
||||||
in_f = item->ri_buf[0].i_addr;
|
in_f = item->ri_buf[0].i_addr;
|
||||||
@@ -530,8 +531,19 @@ out_owner_change:
|
|||||||
(dip->di_mode != 0))
|
(dip->di_mode != 0))
|
||||||
error = xfs_recover_inode_owner_change(mp, dip, in_f,
|
error = xfs_recover_inode_owner_change(mp, dip, in_f,
|
||||||
buffer_list);
|
buffer_list);
|
||||||
/* re-generate the checksum. */
|
/* re-generate the checksum and validate the recovered inode. */
|
||||||
xfs_dinode_calc_crc(log->l_mp, dip);
|
xfs_dinode_calc_crc(log->l_mp, dip);
|
||||||
|
fa = xfs_dinode_verify(log->l_mp, in_f->ilf_ino, dip);
|
||||||
|
if (fa) {
|
||||||
|
XFS_CORRUPTION_ERROR(
|
||||||
|
"Bad dinode after recovery",
|
||||||
|
XFS_ERRLEVEL_LOW, mp, dip, sizeof(*dip));
|
||||||
|
xfs_alert(mp,
|
||||||
|
"Metadata corruption detected at %pS, inode 0x%llx",
|
||||||
|
fa, in_f->ilf_ino);
|
||||||
|
error = -EFSCORRUPTED;
|
||||||
|
goto out_release;
|
||||||
|
}
|
||||||
|
|
||||||
ASSERT(bp->b_mount == mp);
|
ASSERT(bp->b_mount == mp);
|
||||||
bp->b_flags |= _XBF_LOGRECOVERY;
|
bp->b_flags |= _XBF_LOGRECOVERY;
|
||||||
|
|||||||
@@ -1120,23 +1120,25 @@ xfs_ioctl_setattr_xflags(
|
|||||||
struct fileattr *fa)
|
struct fileattr *fa)
|
||||||
{
|
{
|
||||||
struct xfs_mount *mp = ip->i_mount;
|
struct xfs_mount *mp = ip->i_mount;
|
||||||
|
bool rtflag = (fa->fsx_xflags & FS_XFLAG_REALTIME);
|
||||||
uint64_t i_flags2;
|
uint64_t i_flags2;
|
||||||
|
|
||||||
/* Can't change realtime flag if any extents are allocated. */
|
if (rtflag != XFS_IS_REALTIME_INODE(ip)) {
|
||||||
if ((ip->i_df.if_nextents || ip->i_delayed_blks) &&
|
/* Can't change realtime flag if any extents are allocated. */
|
||||||
XFS_IS_REALTIME_INODE(ip) != (fa->fsx_xflags & FS_XFLAG_REALTIME))
|
if (ip->i_df.if_nextents || ip->i_delayed_blks)
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
/* If realtime flag is set then must have realtime device */
|
|
||||||
if (fa->fsx_xflags & FS_XFLAG_REALTIME) {
|
|
||||||
if (mp->m_sb.sb_rblocks == 0 || mp->m_sb.sb_rextsize == 0 ||
|
|
||||||
(ip->i_extsize % mp->m_sb.sb_rextsize))
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear reflink if we are actually able to set the rt flag. */
|
if (rtflag) {
|
||||||
if ((fa->fsx_xflags & FS_XFLAG_REALTIME) && xfs_is_reflink_inode(ip))
|
/* If realtime flag is set then must have realtime device */
|
||||||
ip->i_diflags2 &= ~XFS_DIFLAG2_REFLINK;
|
if (mp->m_sb.sb_rblocks == 0 || mp->m_sb.sb_rextsize == 0 ||
|
||||||
|
(ip->i_extsize % mp->m_sb.sb_rextsize))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* Clear reflink if we are actually able to set the rt flag. */
|
||||||
|
if (xfs_is_reflink_inode(ip))
|
||||||
|
ip->i_diflags2 &= ~XFS_DIFLAG2_REFLINK;
|
||||||
|
}
|
||||||
|
|
||||||
/* Don't allow us to set DAX mode for a reflinked file for now. */
|
/* Don't allow us to set DAX mode for a reflinked file for now. */
|
||||||
if ((fa->fsx_xflags & FS_XFLAG_DAX) && xfs_is_reflink_inode(ip))
|
if ((fa->fsx_xflags & FS_XFLAG_DAX) && xfs_is_reflink_inode(ip))
|
||||||
@@ -1151,6 +1153,14 @@ xfs_ioctl_setattr_xflags(
|
|||||||
ip->i_diflags2 = i_flags2;
|
ip->i_diflags2 = i_flags2;
|
||||||
|
|
||||||
xfs_diflags_to_iflags(ip, false);
|
xfs_diflags_to_iflags(ip, false);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make the stable writes flag match that of the device the inode
|
||||||
|
* resides on when flipping the RT flag.
|
||||||
|
*/
|
||||||
|
if (rtflag != XFS_IS_REALTIME_INODE(ip) && S_ISREG(VFS_I(ip)->i_mode))
|
||||||
|
xfs_update_stable_writes(ip);
|
||||||
|
|
||||||
xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
|
xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
|
||||||
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
|
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
|
||||||
XFS_STATS_INC(mp, xs_ig_attrchg);
|
XFS_STATS_INC(mp, xs_ig_attrchg);
|
||||||
|
|||||||
@@ -1291,6 +1291,13 @@ xfs_setup_inode(
|
|||||||
gfp_mask = mapping_gfp_mask(inode->i_mapping);
|
gfp_mask = mapping_gfp_mask(inode->i_mapping);
|
||||||
mapping_set_gfp_mask(inode->i_mapping, (gfp_mask & ~(__GFP_FS)));
|
mapping_set_gfp_mask(inode->i_mapping, (gfp_mask & ~(__GFP_FS)));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For real-time inodes update the stable write flags to that of the RT
|
||||||
|
* device instead of the data device.
|
||||||
|
*/
|
||||||
|
if (S_ISREG(inode->i_mode) && XFS_IS_REALTIME_INODE(ip))
|
||||||
|
xfs_update_stable_writes(ip);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there is no attribute fork no ACL can exist on this inode,
|
* If there is no attribute fork no ACL can exist on this inode,
|
||||||
* and it can't have any file capabilities attached to it either.
|
* and it can't have any file capabilities attached to it either.
|
||||||
|
|||||||
@@ -1891,9 +1891,7 @@ xlog_write_iclog(
|
|||||||
* the buffer manually, the code needs to be kept in sync
|
* the buffer manually, the code needs to be kept in sync
|
||||||
* with the I/O completion path.
|
* with the I/O completion path.
|
||||||
*/
|
*/
|
||||||
xlog_state_done_syncing(iclog);
|
goto sync;
|
||||||
up(&iclog->ic_sema);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1923,20 +1921,17 @@ xlog_write_iclog(
|
|||||||
* avoid shutdown re-entering this path and erroring out again.
|
* avoid shutdown re-entering this path and erroring out again.
|
||||||
*/
|
*/
|
||||||
if (log->l_targ != log->l_mp->m_ddev_targp &&
|
if (log->l_targ != log->l_mp->m_ddev_targp &&
|
||||||
blkdev_issue_flush(log->l_mp->m_ddev_targp->bt_bdev)) {
|
blkdev_issue_flush(log->l_mp->m_ddev_targp->bt_bdev))
|
||||||
xlog_force_shutdown(log, SHUTDOWN_LOG_IO_ERROR);
|
goto shutdown;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (iclog->ic_flags & XLOG_ICL_NEED_FUA)
|
if (iclog->ic_flags & XLOG_ICL_NEED_FUA)
|
||||||
iclog->ic_bio.bi_opf |= REQ_FUA;
|
iclog->ic_bio.bi_opf |= REQ_FUA;
|
||||||
|
|
||||||
iclog->ic_flags &= ~(XLOG_ICL_NEED_FLUSH | XLOG_ICL_NEED_FUA);
|
iclog->ic_flags &= ~(XLOG_ICL_NEED_FLUSH | XLOG_ICL_NEED_FUA);
|
||||||
|
|
||||||
if (xlog_map_iclog_data(&iclog->ic_bio, iclog->ic_data, count)) {
|
if (xlog_map_iclog_data(&iclog->ic_bio, iclog->ic_data, count))
|
||||||
xlog_force_shutdown(log, SHUTDOWN_LOG_IO_ERROR);
|
goto shutdown;
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (is_vmalloc_addr(iclog->ic_data))
|
if (is_vmalloc_addr(iclog->ic_data))
|
||||||
flush_kernel_vmap_range(iclog->ic_data, count);
|
flush_kernel_vmap_range(iclog->ic_data, count);
|
||||||
|
|
||||||
@@ -1957,6 +1952,12 @@ xlog_write_iclog(
|
|||||||
}
|
}
|
||||||
|
|
||||||
submit_bio(&iclog->ic_bio);
|
submit_bio(&iclog->ic_bio);
|
||||||
|
return;
|
||||||
|
shutdown:
|
||||||
|
xlog_force_shutdown(log, SHUTDOWN_LOG_IO_ERROR);
|
||||||
|
sync:
|
||||||
|
xlog_state_done_syncing(iclog);
|
||||||
|
up(&iclog->ic_sema);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -2514,7 +2514,7 @@ xlog_abort_defer_ops(
|
|||||||
|
|
||||||
list_for_each_entry_safe(dfc, next, capture_list, dfc_list) {
|
list_for_each_entry_safe(dfc, next, capture_list, dfc_list) {
|
||||||
list_del_init(&dfc->dfc_list);
|
list_del_init(&dfc->dfc_list);
|
||||||
xfs_defer_ops_capture_free(mp, dfc);
|
xfs_defer_ops_capture_abort(mp, dfc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -783,6 +783,7 @@ xfs_reflink_end_cow_extent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
del = got;
|
del = got;
|
||||||
|
xfs_trim_extent(&del, *offset_fsb, end_fsb - *offset_fsb);
|
||||||
|
|
||||||
/* Grab the corresponding mapping in the data fork. */
|
/* Grab the corresponding mapping in the data fork. */
|
||||||
nmaps = 1;
|
nmaps = 1;
|
||||||
@@ -1539,6 +1540,10 @@ xfs_reflink_remap_prep(
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
|
xfs_iflags_set(src, XFS_IREMAPPING);
|
||||||
|
if (inode_in != inode_out)
|
||||||
|
xfs_ilock_demote(src, XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
out_unlock:
|
out_unlock:
|
||||||
xfs_iunlock2_io_mmap(src, dest);
|
xfs_iunlock2_io_mmap(src, dest);
|
||||||
|
|||||||
@@ -211,6 +211,23 @@ xfs_rtallocate_range(
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure we don't run off the end of the rt volume. Be careful that
|
||||||
|
* adjusting maxlen downwards doesn't cause us to fail the alignment checks.
|
||||||
|
*/
|
||||||
|
static inline xfs_extlen_t
|
||||||
|
xfs_rtallocate_clamp_len(
|
||||||
|
struct xfs_mount *mp,
|
||||||
|
xfs_rtblock_t startrtx,
|
||||||
|
xfs_extlen_t rtxlen,
|
||||||
|
xfs_extlen_t prod)
|
||||||
|
{
|
||||||
|
xfs_extlen_t ret;
|
||||||
|
|
||||||
|
ret = min(mp->m_sb.sb_rextents, startrtx + rtxlen) - startrtx;
|
||||||
|
return rounddown(ret, prod);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Attempt to allocate an extent minlen<=len<=maxlen starting from
|
* Attempt to allocate an extent minlen<=len<=maxlen starting from
|
||||||
* bitmap block bbno. If we don't get maxlen then use prod to trim
|
* bitmap block bbno. If we don't get maxlen then use prod to trim
|
||||||
@@ -248,7 +265,7 @@ xfs_rtallocate_extent_block(
|
|||||||
i <= end;
|
i <= end;
|
||||||
i++) {
|
i++) {
|
||||||
/* Make sure we don't scan off the end of the rt volume. */
|
/* Make sure we don't scan off the end of the rt volume. */
|
||||||
maxlen = min(mp->m_sb.sb_rextents, i + maxlen) - i;
|
maxlen = xfs_rtallocate_clamp_len(mp, i, maxlen, prod);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* See if there's a free extent of maxlen starting at i.
|
* See if there's a free extent of maxlen starting at i.
|
||||||
@@ -355,7 +372,8 @@ xfs_rtallocate_extent_exact(
|
|||||||
int isfree; /* extent is free */
|
int isfree; /* extent is free */
|
||||||
xfs_rtblock_t next; /* next block to try (dummy) */
|
xfs_rtblock_t next; /* next block to try (dummy) */
|
||||||
|
|
||||||
ASSERT(minlen % prod == 0 && maxlen % prod == 0);
|
ASSERT(minlen % prod == 0);
|
||||||
|
ASSERT(maxlen % prod == 0);
|
||||||
/*
|
/*
|
||||||
* Check if the range in question (for maxlen) is free.
|
* Check if the range in question (for maxlen) is free.
|
||||||
*/
|
*/
|
||||||
@@ -438,7 +456,9 @@ xfs_rtallocate_extent_near(
|
|||||||
xfs_rtblock_t n; /* next block to try */
|
xfs_rtblock_t n; /* next block to try */
|
||||||
xfs_rtblock_t r; /* result block */
|
xfs_rtblock_t r; /* result block */
|
||||||
|
|
||||||
ASSERT(minlen % prod == 0 && maxlen % prod == 0);
|
ASSERT(minlen % prod == 0);
|
||||||
|
ASSERT(maxlen % prod == 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the block number given is off the end, silently set it to
|
* If the block number given is off the end, silently set it to
|
||||||
* the last block.
|
* the last block.
|
||||||
@@ -447,7 +467,7 @@ xfs_rtallocate_extent_near(
|
|||||||
bno = mp->m_sb.sb_rextents - 1;
|
bno = mp->m_sb.sb_rextents - 1;
|
||||||
|
|
||||||
/* Make sure we don't run off the end of the rt volume. */
|
/* Make sure we don't run off the end of the rt volume. */
|
||||||
maxlen = min(mp->m_sb.sb_rextents, bno + maxlen) - bno;
|
maxlen = xfs_rtallocate_clamp_len(mp, bno, maxlen, prod);
|
||||||
if (maxlen < minlen) {
|
if (maxlen < minlen) {
|
||||||
*rtblock = NULLRTBLOCK;
|
*rtblock = NULLRTBLOCK;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -638,7 +658,8 @@ xfs_rtallocate_extent_size(
|
|||||||
xfs_rtblock_t r; /* result block number */
|
xfs_rtblock_t r; /* result block number */
|
||||||
xfs_suminfo_t sum; /* summary information for extents */
|
xfs_suminfo_t sum; /* summary information for extents */
|
||||||
|
|
||||||
ASSERT(minlen % prod == 0 && maxlen % prod == 0);
|
ASSERT(minlen % prod == 0);
|
||||||
|
ASSERT(maxlen % prod == 0);
|
||||||
ASSERT(maxlen != 0);
|
ASSERT(maxlen != 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -954,7 +975,7 @@ xfs_growfs_rt(
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* Unsupported realtime features. */
|
/* Unsupported realtime features. */
|
||||||
if (xfs_has_rmapbt(mp) || xfs_has_reflink(mp))
|
if (xfs_has_rmapbt(mp) || xfs_has_reflink(mp) || xfs_has_quota(mp))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
nrblocks = in->newblocks;
|
nrblocks = in->newblocks;
|
||||||
|
|||||||
@@ -58,6 +58,10 @@ xfs_rtfree_extent(
|
|||||||
xfs_rtblock_t bno, /* starting block number to free */
|
xfs_rtblock_t bno, /* starting block number to free */
|
||||||
xfs_extlen_t len); /* length of extent freed */
|
xfs_extlen_t len); /* length of extent freed */
|
||||||
|
|
||||||
|
/* Same as above, but in units of rt blocks. */
|
||||||
|
int xfs_rtfree_blocks(struct xfs_trans *tp, xfs_fsblock_t rtbno,
|
||||||
|
xfs_filblks_t rtlen);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize realtime fields in the mount structure.
|
* Initialize realtime fields in the mount structure.
|
||||||
*/
|
*/
|
||||||
@@ -137,16 +141,17 @@ int xfs_rtalloc_extent_is_free(struct xfs_mount *mp, struct xfs_trans *tp,
|
|||||||
bool *is_free);
|
bool *is_free);
|
||||||
int xfs_rtalloc_reinit_frextents(struct xfs_mount *mp);
|
int xfs_rtalloc_reinit_frextents(struct xfs_mount *mp);
|
||||||
#else
|
#else
|
||||||
# define xfs_rtallocate_extent(t,b,min,max,l,f,p,rb) (ENOSYS)
|
# define xfs_rtallocate_extent(t,b,min,max,l,f,p,rb) (-ENOSYS)
|
||||||
# define xfs_rtfree_extent(t,b,l) (ENOSYS)
|
# define xfs_rtfree_extent(t,b,l) (-ENOSYS)
|
||||||
# define xfs_rtpick_extent(m,t,l,rb) (ENOSYS)
|
# define xfs_rtfree_blocks(t,rb,rl) (-ENOSYS)
|
||||||
# define xfs_growfs_rt(mp,in) (ENOSYS)
|
# define xfs_rtpick_extent(m,t,l,rb) (-ENOSYS)
|
||||||
# define xfs_rtalloc_query_range(t,l,h,f,p) (ENOSYS)
|
# define xfs_growfs_rt(mp,in) (-ENOSYS)
|
||||||
# define xfs_rtalloc_query_all(m,t,f,p) (ENOSYS)
|
# define xfs_rtalloc_query_range(m,t,l,h,f,p) (-ENOSYS)
|
||||||
# define xfs_rtbuf_get(m,t,b,i,p) (ENOSYS)
|
# define xfs_rtalloc_query_all(m,t,f,p) (-ENOSYS)
|
||||||
# define xfs_verify_rtbno(m, r) (false)
|
# define xfs_rtbuf_get(m,t,b,i,p) (-ENOSYS)
|
||||||
# define xfs_rtalloc_extent_is_free(m,t,s,l,i) (ENOSYS)
|
# define xfs_verify_rtbno(m, r) (false)
|
||||||
# define xfs_rtalloc_reinit_frextents(m) (0)
|
# define xfs_rtalloc_extent_is_free(m,t,s,l,i) (-ENOSYS)
|
||||||
|
# define xfs_rtalloc_reinit_frextents(m) (0)
|
||||||
static inline int /* error */
|
static inline int /* error */
|
||||||
xfs_rtmount_init(
|
xfs_rtmount_init(
|
||||||
xfs_mount_t *mp) /* file system mount structure */
|
xfs_mount_t *mp) /* file system mount structure */
|
||||||
@@ -157,7 +162,7 @@ xfs_rtmount_init(
|
|||||||
xfs_warn(mp, "Not built with CONFIG_XFS_RT");
|
xfs_warn(mp, "Not built with CONFIG_XFS_RT");
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
# define xfs_rtmount_inodes(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS))
|
# define xfs_rtmount_inodes(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (-ENOSYS))
|
||||||
# define xfs_rtunmount_inodes(m)
|
# define xfs_rtunmount_inodes(m)
|
||||||
#endif /* CONFIG_XFS_RT */
|
#endif /* CONFIG_XFS_RT */
|
||||||
|
|
||||||
|
|||||||
@@ -69,10 +69,10 @@ struct seccomp_data;
|
|||||||
|
|
||||||
#ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
|
#ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
|
||||||
static inline int secure_computing(void) { return 0; }
|
static inline int secure_computing(void) { return 0; }
|
||||||
static inline int __secure_computing(const struct seccomp_data *sd) { return 0; }
|
|
||||||
#else
|
#else
|
||||||
static inline void secure_computing_strict(int this_syscall) { return; }
|
static inline void secure_computing_strict(int this_syscall) { return; }
|
||||||
#endif
|
#endif
|
||||||
|
static inline int __secure_computing(const struct seccomp_data *sd) { return 0; }
|
||||||
|
|
||||||
static inline long prctl_get_seccomp(void)
|
static inline long prctl_get_seccomp(void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -597,8 +597,10 @@ static inline void __io_cq_unlock_post_flush(struct io_ring_ctx *ctx)
|
|||||||
io_commit_cqring(ctx);
|
io_commit_cqring(ctx);
|
||||||
spin_unlock(&ctx->completion_lock);
|
spin_unlock(&ctx->completion_lock);
|
||||||
io_commit_cqring_flush(ctx);
|
io_commit_cqring_flush(ctx);
|
||||||
if (!(ctx->flags & IORING_SETUP_DEFER_TASKRUN))
|
if (!(ctx->flags & IORING_SETUP_DEFER_TASKRUN)) {
|
||||||
|
smp_mb();
|
||||||
__io_cqring_wake(ctx);
|
__io_cqring_wake(ctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void io_cq_unlock_post(struct io_ring_ctx *ctx)
|
void io_cq_unlock_post(struct io_ring_ctx *ctx)
|
||||||
|
|||||||
@@ -321,17 +321,24 @@ static inline void invoke_softirq(void)
|
|||||||
wakeup_softirqd();
|
wakeup_softirqd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SCHED_SOFTIRQ_MASK BIT(SCHED_SOFTIRQ)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* flush_smp_call_function_queue() can raise a soft interrupt in a function
|
* flush_smp_call_function_queue() can raise a soft interrupt in a function
|
||||||
* call. On RT kernels this is undesired and the only known functionality
|
* call. On RT kernels this is undesired and the only known functionalities
|
||||||
* in the block layer which does this is disabled on RT. If soft interrupts
|
* are in the block layer which is disabled on RT, and in the scheduler for
|
||||||
* get raised which haven't been raised before the flush, warn so it can be
|
* idle load balancing. If soft interrupts get raised which haven't been
|
||||||
|
* raised before the flush, warn if it is not a SCHED_SOFTIRQ so it can be
|
||||||
* investigated.
|
* investigated.
|
||||||
*/
|
*/
|
||||||
void do_softirq_post_smp_call_flush(unsigned int was_pending)
|
void do_softirq_post_smp_call_flush(unsigned int was_pending)
|
||||||
{
|
{
|
||||||
if (WARN_ON_ONCE(was_pending != local_softirq_pending()))
|
unsigned int is_pending = local_softirq_pending();
|
||||||
|
|
||||||
|
if (unlikely(was_pending != is_pending)) {
|
||||||
|
WARN_ON_ONCE(was_pending != (is_pending & ~SCHED_SOFTIRQ_MASK));
|
||||||
invoke_softirq();
|
invoke_softirq();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* CONFIG_PREEMPT_RT */
|
#else /* CONFIG_PREEMPT_RT */
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ static struct ip_tunnel *ip_tunnel_find(struct ip_tunnel_net *itn,
|
|||||||
struct ip_tunnel *t = NULL;
|
struct ip_tunnel *t = NULL;
|
||||||
struct hlist_head *head = ip_bucket(itn, parms);
|
struct hlist_head *head = ip_bucket(itn, parms);
|
||||||
|
|
||||||
hlist_for_each_entry_rcu(t, head, hash_node) {
|
hlist_for_each_entry_rcu(t, head, hash_node, lockdep_rtnl_is_held()) {
|
||||||
if (local == t->parms.iph.saddr &&
|
if (local == t->parms.iph.saddr &&
|
||||||
remote == t->parms.iph.daddr &&
|
remote == t->parms.iph.daddr &&
|
||||||
link == t->parms.link &&
|
link == t->parms.link &&
|
||||||
|
|||||||
@@ -1180,8 +1180,8 @@ next_iter:
|
|||||||
while (sibling) {
|
while (sibling) {
|
||||||
if (sibling->fib6_metric == rt->fib6_metric &&
|
if (sibling->fib6_metric == rt->fib6_metric &&
|
||||||
rt6_qualify_for_ecmp(sibling)) {
|
rt6_qualify_for_ecmp(sibling)) {
|
||||||
list_add_tail(&rt->fib6_siblings,
|
list_add_tail_rcu(&rt->fib6_siblings,
|
||||||
&sibling->fib6_siblings);
|
&sibling->fib6_siblings);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sibling = rcu_dereference_protected(sibling->fib6_next,
|
sibling = rcu_dereference_protected(sibling->fib6_next,
|
||||||
@@ -1242,7 +1242,7 @@ add:
|
|||||||
fib6_siblings)
|
fib6_siblings)
|
||||||
sibling->fib6_nsiblings--;
|
sibling->fib6_nsiblings--;
|
||||||
rt->fib6_nsiblings = 0;
|
rt->fib6_nsiblings = 0;
|
||||||
list_del_init(&rt->fib6_siblings);
|
list_del_rcu(&rt->fib6_siblings);
|
||||||
rt6_multipath_rebalance(next_sibling);
|
rt6_multipath_rebalance(next_sibling);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -1955,7 +1955,7 @@ static void fib6_del_route(struct fib6_table *table, struct fib6_node *fn,
|
|||||||
&rt->fib6_siblings, fib6_siblings)
|
&rt->fib6_siblings, fib6_siblings)
|
||||||
sibling->fib6_nsiblings--;
|
sibling->fib6_nsiblings--;
|
||||||
rt->fib6_nsiblings = 0;
|
rt->fib6_nsiblings = 0;
|
||||||
list_del_init(&rt->fib6_siblings);
|
list_del_rcu(&rt->fib6_siblings);
|
||||||
rt6_multipath_rebalance(next_sibling);
|
rt6_multipath_rebalance(next_sibling);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -417,8 +417,8 @@ void fib6_select_path(const struct net *net, struct fib6_result *res,
|
|||||||
struct flowi6 *fl6, int oif, bool have_oif_match,
|
struct flowi6 *fl6, int oif, bool have_oif_match,
|
||||||
const struct sk_buff *skb, int strict)
|
const struct sk_buff *skb, int strict)
|
||||||
{
|
{
|
||||||
struct fib6_info *sibling, *next_sibling;
|
|
||||||
struct fib6_info *match = res->f6i;
|
struct fib6_info *match = res->f6i;
|
||||||
|
struct fib6_info *sibling;
|
||||||
|
|
||||||
if (!match->nh && (!match->fib6_nsiblings || have_oif_match))
|
if (!match->nh && (!match->fib6_nsiblings || have_oif_match))
|
||||||
goto out;
|
goto out;
|
||||||
@@ -444,8 +444,8 @@ void fib6_select_path(const struct net *net, struct fib6_result *res,
|
|||||||
if (fl6->mp_hash <= atomic_read(&match->fib6_nh->fib_nh_upper_bound))
|
if (fl6->mp_hash <= atomic_read(&match->fib6_nh->fib_nh_upper_bound))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
list_for_each_entry_safe(sibling, next_sibling, &match->fib6_siblings,
|
list_for_each_entry_rcu(sibling, &match->fib6_siblings,
|
||||||
fib6_siblings) {
|
fib6_siblings) {
|
||||||
const struct fib6_nh *nh = sibling->fib6_nh;
|
const struct fib6_nh *nh = sibling->fib6_nh;
|
||||||
int nh_upper_bound;
|
int nh_upper_bound;
|
||||||
|
|
||||||
@@ -5169,14 +5169,18 @@ static void ip6_route_mpath_notify(struct fib6_info *rt,
|
|||||||
* nexthop. Since sibling routes are always added at the end of
|
* nexthop. Since sibling routes are always added at the end of
|
||||||
* the list, find the first sibling of the last route appended
|
* the list, find the first sibling of the last route appended
|
||||||
*/
|
*/
|
||||||
|
rcu_read_lock();
|
||||||
|
|
||||||
if ((nlflags & NLM_F_APPEND) && rt_last && rt_last->fib6_nsiblings) {
|
if ((nlflags & NLM_F_APPEND) && rt_last && rt_last->fib6_nsiblings) {
|
||||||
rt = list_first_entry(&rt_last->fib6_siblings,
|
rt = list_first_or_null_rcu(&rt_last->fib6_siblings,
|
||||||
struct fib6_info,
|
struct fib6_info,
|
||||||
fib6_siblings);
|
fib6_siblings);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rt)
|
if (rt)
|
||||||
inet6_rt_notify(RTM_NEWROUTE, rt, info, nlflags);
|
inet6_rt_notify(RTM_NEWROUTE, rt, info, nlflags);
|
||||||
|
|
||||||
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ip6_route_mpath_should_notify(const struct fib6_info *rt)
|
static bool ip6_route_mpath_should_notify(const struct fib6_info *rt)
|
||||||
@@ -5521,17 +5525,21 @@ static size_t rt6_nlmsg_size(struct fib6_info *f6i)
|
|||||||
nexthop_for_each_fib6_nh(f6i->nh, rt6_nh_nlmsg_size,
|
nexthop_for_each_fib6_nh(f6i->nh, rt6_nh_nlmsg_size,
|
||||||
&nexthop_len);
|
&nexthop_len);
|
||||||
} else {
|
} else {
|
||||||
struct fib6_info *sibling, *next_sibling;
|
|
||||||
struct fib6_nh *nh = f6i->fib6_nh;
|
struct fib6_nh *nh = f6i->fib6_nh;
|
||||||
|
struct fib6_info *sibling;
|
||||||
|
|
||||||
nexthop_len = 0;
|
nexthop_len = 0;
|
||||||
if (f6i->fib6_nsiblings) {
|
if (f6i->fib6_nsiblings) {
|
||||||
rt6_nh_nlmsg_size(nh, &nexthop_len);
|
rt6_nh_nlmsg_size(nh, &nexthop_len);
|
||||||
|
|
||||||
list_for_each_entry_safe(sibling, next_sibling,
|
rcu_read_lock();
|
||||||
&f6i->fib6_siblings, fib6_siblings) {
|
|
||||||
|
list_for_each_entry_rcu(sibling, &f6i->fib6_siblings,
|
||||||
|
fib6_siblings) {
|
||||||
rt6_nh_nlmsg_size(sibling->fib6_nh, &nexthop_len);
|
rt6_nh_nlmsg_size(sibling->fib6_nh, &nexthop_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
nexthop_len += lwtunnel_get_encap_size(nh->fib_nh_lws);
|
nexthop_len += lwtunnel_get_encap_size(nh->fib_nh_lws);
|
||||||
}
|
}
|
||||||
@@ -5695,7 +5703,7 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb,
|
|||||||
lwtunnel_fill_encap(skb, dst->lwtstate, RTA_ENCAP, RTA_ENCAP_TYPE) < 0)
|
lwtunnel_fill_encap(skb, dst->lwtstate, RTA_ENCAP, RTA_ENCAP_TYPE) < 0)
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
} else if (rt->fib6_nsiblings) {
|
} else if (rt->fib6_nsiblings) {
|
||||||
struct fib6_info *sibling, *next_sibling;
|
struct fib6_info *sibling;
|
||||||
struct nlattr *mp;
|
struct nlattr *mp;
|
||||||
|
|
||||||
mp = nla_nest_start_noflag(skb, RTA_MULTIPATH);
|
mp = nla_nest_start_noflag(skb, RTA_MULTIPATH);
|
||||||
@@ -5707,14 +5715,21 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb,
|
|||||||
0) < 0)
|
0) < 0)
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
|
||||||
list_for_each_entry_safe(sibling, next_sibling,
|
rcu_read_lock();
|
||||||
&rt->fib6_siblings, fib6_siblings) {
|
|
||||||
|
list_for_each_entry_rcu(sibling, &rt->fib6_siblings,
|
||||||
|
fib6_siblings) {
|
||||||
if (fib_add_nexthop(skb, &sibling->fib6_nh->nh_common,
|
if (fib_add_nexthop(skb, &sibling->fib6_nh->nh_common,
|
||||||
sibling->fib6_nh->fib_nh_weight,
|
sibling->fib6_nh->fib_nh_weight,
|
||||||
AF_INET6, 0) < 0)
|
AF_INET6, 0) < 0) {
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
nla_nest_end(skb, mp);
|
nla_nest_end(skb, mp);
|
||||||
} else if (rt->nh) {
|
} else if (rt->nh) {
|
||||||
if (nla_put_u32(skb, RTA_NH_ID, rt->nh->id))
|
if (nla_put_u32(skb, RTA_NH_ID, rt->nh->id))
|
||||||
@@ -6151,7 +6166,7 @@ void inet6_rt_notify(int event, struct fib6_info *rt, struct nl_info *info,
|
|||||||
err = -ENOBUFS;
|
err = -ENOBUFS;
|
||||||
seq = info->nlh ? info->nlh->nlmsg_seq : 0;
|
seq = info->nlh ? info->nlh->nlmsg_seq : 0;
|
||||||
|
|
||||||
skb = nlmsg_new(rt6_nlmsg_size(rt), gfp_any());
|
skb = nlmsg_new(rt6_nlmsg_size(rt), GFP_ATOMIC);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
goto errout;
|
goto errout;
|
||||||
|
|
||||||
@@ -6164,7 +6179,7 @@ void inet6_rt_notify(int event, struct fib6_info *rt, struct nl_info *info,
|
|||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
rtnl_notify(skb, net, info->portid, RTNLGRP_IPV6_ROUTE,
|
rtnl_notify(skb, net, info->portid, RTNLGRP_IPV6_ROUTE,
|
||||||
info->nlh, gfp_any());
|
info->nlh, GFP_ATOMIC);
|
||||||
return;
|
return;
|
||||||
errout:
|
errout:
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
|||||||
@@ -91,6 +91,8 @@ ets_class_from_arg(struct Qdisc *sch, unsigned long arg)
|
|||||||
{
|
{
|
||||||
struct ets_sched *q = qdisc_priv(sch);
|
struct ets_sched *q = qdisc_priv(sch);
|
||||||
|
|
||||||
|
if (arg == 0 || arg > q->nbands)
|
||||||
|
return NULL;
|
||||||
return &q->classes[arg - 1];
|
return &q->classes[arg - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1982,6 +1982,7 @@ config SND_SOC_WM8993
|
|||||||
|
|
||||||
config SND_SOC_WM8994
|
config SND_SOC_WM8994
|
||||||
tristate
|
tristate
|
||||||
|
depends on MFD_WM8994
|
||||||
|
|
||||||
config SND_SOC_WM8995
|
config SND_SOC_WM8995
|
||||||
tristate
|
tristate
|
||||||
|
|||||||
@@ -220,8 +220,9 @@ config SND_SOC_SAMSUNG_TM2_WM5110
|
|||||||
|
|
||||||
config SND_SOC_SAMSUNG_ARIES_WM8994
|
config SND_SOC_SAMSUNG_ARIES_WM8994
|
||||||
tristate "SoC I2S Audio support for WM8994 on Aries"
|
tristate "SoC I2S Audio support for WM8994 on Aries"
|
||||||
depends on SND_SOC_SAMSUNG && MFD_WM8994 && IIO && EXTCON
|
depends on SND_SOC_SAMSUNG && I2C && IIO && EXTCON
|
||||||
select SND_SOC_BT_SCO
|
select SND_SOC_BT_SCO
|
||||||
|
select MFD_WM8994
|
||||||
select SND_SOC_WM8994
|
select SND_SOC_WM8994
|
||||||
select SND_SAMSUNG_I2S
|
select SND_SAMSUNG_I2S
|
||||||
help
|
help
|
||||||
@@ -233,8 +234,9 @@ config SND_SOC_SAMSUNG_ARIES_WM8994
|
|||||||
|
|
||||||
config SND_SOC_SAMSUNG_MIDAS_WM1811
|
config SND_SOC_SAMSUNG_MIDAS_WM1811
|
||||||
tristate "SoC I2S Audio support for Midas boards"
|
tristate "SoC I2S Audio support for Midas boards"
|
||||||
depends on SND_SOC_SAMSUNG
|
depends on SND_SOC_SAMSUNG && I2C
|
||||||
select SND_SAMSUNG_I2S
|
select SND_SAMSUNG_I2S
|
||||||
|
select MFD_WM8994
|
||||||
select SND_SOC_WM8994
|
select SND_SOC_WM8994
|
||||||
help
|
help
|
||||||
Say Y if you want to add support for SoC audio on the Midas boards.
|
Say Y if you want to add support for SoC audio on the Midas boards.
|
||||||
|
|||||||
@@ -38,6 +38,17 @@ struct midas_priv {
|
|||||||
struct snd_soc_jack headset_jack;
|
struct snd_soc_jack headset_jack;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct snd_soc_jack_pin headset_jack_pins[] = {
|
||||||
|
{
|
||||||
|
.pin = "Headphone",
|
||||||
|
.mask = SND_JACK_HEADPHONE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.pin = "Headset Mic",
|
||||||
|
.mask = SND_JACK_MICROPHONE,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
static int midas_start_fll1(struct snd_soc_pcm_runtime *rtd, unsigned int rate)
|
static int midas_start_fll1(struct snd_soc_pcm_runtime *rtd, unsigned int rate)
|
||||||
{
|
{
|
||||||
struct snd_soc_card *card = rtd->card;
|
struct snd_soc_card *card = rtd->card;
|
||||||
@@ -261,6 +272,7 @@ static const struct snd_soc_dapm_widget midas_dapm_widgets[] = {
|
|||||||
SND_SOC_DAPM_LINE("HDMI", NULL),
|
SND_SOC_DAPM_LINE("HDMI", NULL),
|
||||||
SND_SOC_DAPM_LINE("FM In", midas_fm_set),
|
SND_SOC_DAPM_LINE("FM In", midas_fm_set),
|
||||||
|
|
||||||
|
SND_SOC_DAPM_HP("Headphone", NULL),
|
||||||
SND_SOC_DAPM_MIC("Headset Mic", NULL),
|
SND_SOC_DAPM_MIC("Headset Mic", NULL),
|
||||||
SND_SOC_DAPM_MIC("Main Mic", midas_mic_bias),
|
SND_SOC_DAPM_MIC("Main Mic", midas_mic_bias),
|
||||||
SND_SOC_DAPM_MIC("Sub Mic", midas_submic_bias),
|
SND_SOC_DAPM_MIC("Sub Mic", midas_submic_bias),
|
||||||
@@ -305,11 +317,13 @@ static int midas_late_probe(struct snd_soc_card *card)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = snd_soc_card_jack_new(card, "Headset",
|
ret = snd_soc_card_jack_new_pins(card, "Headset",
|
||||||
SND_JACK_HEADSET | SND_JACK_MECHANICAL |
|
SND_JACK_HEADSET | SND_JACK_MECHANICAL |
|
||||||
SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 |
|
SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 |
|
||||||
SND_JACK_BTN_3 | SND_JACK_BTN_4 | SND_JACK_BTN_5,
|
SND_JACK_BTN_3 | SND_JACK_BTN_4 | SND_JACK_BTN_5,
|
||||||
&priv->headset_jack);
|
&priv->headset_jack,
|
||||||
|
headset_jack_pins,
|
||||||
|
ARRAY_SIZE(headset_jack_pins));
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
|||||||
@@ -2137,6 +2137,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
|
|||||||
QUIRK_FLAG_CTL_MSG_DELAY_1M),
|
QUIRK_FLAG_CTL_MSG_DELAY_1M),
|
||||||
DEVICE_FLG(0x0c45, 0x6340, /* Sonix HD USB Camera */
|
DEVICE_FLG(0x0c45, 0x6340, /* Sonix HD USB Camera */
|
||||||
QUIRK_FLAG_GET_SAMPLE_RATE),
|
QUIRK_FLAG_GET_SAMPLE_RATE),
|
||||||
|
DEVICE_FLG(0x0d8c, 0x0014, /* USB Audio Device */
|
||||||
|
QUIRK_FLAG_CTL_MSG_DELAY_1M),
|
||||||
DEVICE_FLG(0x0ecb, 0x205c, /* JBL Quantum610 Wireless */
|
DEVICE_FLG(0x0ecb, 0x205c, /* JBL Quantum610 Wireless */
|
||||||
QUIRK_FLAG_FIXED_RATE),
|
QUIRK_FLAG_FIXED_RATE),
|
||||||
DEVICE_FLG(0x0ecb, 0x2069, /* JBL Quantum810 Wireless */
|
DEVICE_FLG(0x0ecb, 0x2069, /* JBL Quantum810 Wireless */
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ TEST_GEN_PROGS += sk_bind_sendto_listen
|
|||||||
TEST_GEN_PROGS += sk_connect_zero_addr
|
TEST_GEN_PROGS += sk_connect_zero_addr
|
||||||
TEST_PROGS += test_ingress_egress_chaining.sh
|
TEST_PROGS += test_ingress_egress_chaining.sh
|
||||||
TEST_GEN_FILES += nat6to4.o
|
TEST_GEN_FILES += nat6to4.o
|
||||||
|
TEST_PROGS += ipv6_route_update_soft_lockup.sh
|
||||||
|
|
||||||
TEST_FILES := settings
|
TEST_FILES := settings
|
||||||
|
|
||||||
|
|||||||
262
tools/testing/selftests/net/ipv6_route_update_soft_lockup.sh
Normal file
262
tools/testing/selftests/net/ipv6_route_update_soft_lockup.sh
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
#
|
||||||
|
# Testing for potential kernel soft lockup during IPv6 routing table
|
||||||
|
# refresh under heavy outgoing IPv6 traffic. If a kernel soft lockup
|
||||||
|
# occurs, a kernel panic will be triggered to prevent associated issues.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Test Environment Layout
|
||||||
|
#
|
||||||
|
# ┌----------------┐ ┌----------------┐
|
||||||
|
# | SOURCE_NS | | SINK_NS |
|
||||||
|
# | NAMESPACE | | NAMESPACE |
|
||||||
|
# |(iperf3 clients)| |(iperf3 servers)|
|
||||||
|
# | | | |
|
||||||
|
# | | | |
|
||||||
|
# | ┌-----------| nexthops |---------┐ |
|
||||||
|
# | |veth_source|<--------------------------------------->|veth_sink|<┐ |
|
||||||
|
# | └-----------|2001:0DB8:1::0:1/96 2001:0DB8:1::1:1/96 |---------┘ | |
|
||||||
|
# | | ^ 2001:0DB8:1::1:2/96 | | |
|
||||||
|
# | | . . | fwd | |
|
||||||
|
# | ┌---------┐ | . . | | |
|
||||||
|
# | | IPv6 | | . . | V |
|
||||||
|
# | | routing | | . 2001:0DB8:1::1:80/96| ┌-----┐ |
|
||||||
|
# | | table | | . | | lo | |
|
||||||
|
# | | nexthop | | . └--------┴-----┴-┘
|
||||||
|
# | | update | | ............................> 2001:0DB8:2::1:1/128
|
||||||
|
# | └-------- ┘ |
|
||||||
|
# └----------------┘
|
||||||
|
#
|
||||||
|
# The test script sets up two network namespaces, source_ns and sink_ns,
|
||||||
|
# connected via a veth link. Within source_ns, it continuously updates the
|
||||||
|
# IPv6 routing table by flushing and inserting IPV6_NEXTHOP_ADDR_COUNT nexthop
|
||||||
|
# IPs destined for SINK_LOOPBACK_IP_ADDR in sink_ns. This refresh occurs at a
|
||||||
|
# rate of 1/ROUTING_TABLE_REFRESH_PERIOD per second for TEST_DURATION seconds.
|
||||||
|
#
|
||||||
|
# Simultaneously, multiple iperf3 clients within source_ns generate heavy
|
||||||
|
# outgoing IPv6 traffic. Each client is assigned a unique port number starting
|
||||||
|
# at 5000 and incrementing sequentially. Each client targets a unique iperf3
|
||||||
|
# server running in sink_ns, connected to the SINK_LOOPBACK_IFACE interface
|
||||||
|
# using the same port number.
|
||||||
|
#
|
||||||
|
# The number of iperf3 servers and clients is set to half of the total
|
||||||
|
# available cores on each machine.
|
||||||
|
#
|
||||||
|
# NOTE: We have tested this script on machines with various CPU specifications,
|
||||||
|
# ranging from lower to higher performance as listed below. The test script
|
||||||
|
# effectively triggered a kernel soft lockup on machines running an unpatched
|
||||||
|
# kernel in under a minute:
|
||||||
|
#
|
||||||
|
# - 1x Intel Xeon E-2278G 8-Core Processor @ 3.40GHz
|
||||||
|
# - 1x Intel Xeon E-2378G Processor 8-Core @ 2.80GHz
|
||||||
|
# - 1x AMD EPYC 7401P 24-Core Processor @ 2.00GHz
|
||||||
|
# - 1x AMD EPYC 7402P 24-Core Processor @ 2.80GHz
|
||||||
|
# - 2x Intel Xeon Gold 5120 14-Core Processor @ 2.20GHz
|
||||||
|
# - 1x Ampere Altra Q80-30 80-Core Processor @ 3.00GHz
|
||||||
|
# - 2x Intel Xeon Gold 5120 14-Core Processor @ 2.20GHz
|
||||||
|
# - 2x Intel Xeon Silver 4214 24-Core Processor @ 2.20GHz
|
||||||
|
# - 1x AMD EPYC 7502P 32-Core @ 2.50GHz
|
||||||
|
# - 1x Intel Xeon Gold 6314U 32-Core Processor @ 2.30GHz
|
||||||
|
# - 2x Intel Xeon Gold 6338 32-Core Processor @ 2.00GHz
|
||||||
|
#
|
||||||
|
# On less performant machines, you may need to increase the TEST_DURATION
|
||||||
|
# parameter to enhance the likelihood of encountering a race condition leading
|
||||||
|
# to a kernel soft lockup and avoid a false negative result.
|
||||||
|
#
|
||||||
|
# NOTE: The test may not produce the expected result in virtualized
|
||||||
|
# environments (e.g., qemu) due to differences in timing and CPU handling,
|
||||||
|
# which can affect the conditions needed to trigger a soft lockup.
|
||||||
|
|
||||||
|
source lib.sh
|
||||||
|
source net_helper.sh
|
||||||
|
|
||||||
|
TEST_DURATION=300
|
||||||
|
ROUTING_TABLE_REFRESH_PERIOD=0.01
|
||||||
|
|
||||||
|
IPERF3_BITRATE="300m"
|
||||||
|
|
||||||
|
|
||||||
|
IPV6_NEXTHOP_ADDR_COUNT="128"
|
||||||
|
IPV6_NEXTHOP_ADDR_MASK="96"
|
||||||
|
IPV6_NEXTHOP_PREFIX="2001:0DB8:1"
|
||||||
|
|
||||||
|
|
||||||
|
SOURCE_TEST_IFACE="veth_source"
|
||||||
|
SOURCE_TEST_IP_ADDR="2001:0DB8:1::0:1/96"
|
||||||
|
|
||||||
|
SINK_TEST_IFACE="veth_sink"
|
||||||
|
# ${SINK_TEST_IFACE} is populated with the following range of IPv6 addresses:
|
||||||
|
# 2001:0DB8:1::1:1 to 2001:0DB8:1::1:${IPV6_NEXTHOP_ADDR_COUNT}
|
||||||
|
SINK_LOOPBACK_IFACE="lo"
|
||||||
|
SINK_LOOPBACK_IP_MASK="128"
|
||||||
|
SINK_LOOPBACK_IP_ADDR="2001:0DB8:2::1:1"
|
||||||
|
|
||||||
|
nexthop_ip_list=""
|
||||||
|
termination_signal=""
|
||||||
|
kernel_softlokup_panic_prev_val=""
|
||||||
|
|
||||||
|
terminate_ns_processes_by_pattern() {
|
||||||
|
local ns=$1
|
||||||
|
local pattern=$2
|
||||||
|
|
||||||
|
for pid in $(ip netns pids ${ns}); do
|
||||||
|
[ -e /proc/$pid/cmdline ] && grep -qe "${pattern}" /proc/$pid/cmdline && kill -9 $pid
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
echo "info: cleaning up namespaces and terminating all processes within them..."
|
||||||
|
|
||||||
|
|
||||||
|
# Terminate iperf3 instances running in the source_ns. To avoid race
|
||||||
|
# conditions, first iterate over the PIDs and terminate those
|
||||||
|
# associated with the bash shells running the
|
||||||
|
# `while true; do iperf3 -c ...; done` loops. In a second iteration,
|
||||||
|
# terminate the individual `iperf3 -c ...` instances.
|
||||||
|
terminate_ns_processes_by_pattern ${source_ns} while
|
||||||
|
terminate_ns_processes_by_pattern ${source_ns} iperf3
|
||||||
|
|
||||||
|
# Repeat the same process for sink_ns
|
||||||
|
terminate_ns_processes_by_pattern ${sink_ns} while
|
||||||
|
terminate_ns_processes_by_pattern ${sink_ns} iperf3
|
||||||
|
|
||||||
|
# Check if any iperf3 instances are still running. This could happen
|
||||||
|
# if a core has entered an infinite loop and the timeout for detecting
|
||||||
|
# the soft lockup has not expired, but either the test interval has
|
||||||
|
# already elapsed or the test was terminated manually (e.g., with ^C)
|
||||||
|
for pid in $(ip netns pids ${source_ns}); do
|
||||||
|
if [ -e /proc/$pid/cmdline ] && grep -qe 'iperf3' /proc/$pid/cmdline; then
|
||||||
|
echo "FAIL: unable to terminate some iperf3 instances. Soft lockup is underway. A kernel panic is on the way!"
|
||||||
|
exit ${ksft_fail}
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$termination_signal" == "SIGINT" ]; then
|
||||||
|
echo "SKIP: Termination due to ^C (SIGINT)"
|
||||||
|
elif [ "$termination_signal" == "SIGALRM" ]; then
|
||||||
|
echo "PASS: No kernel soft lockup occurred during this ${TEST_DURATION} second test"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cleanup_ns ${source_ns} ${sink_ns}
|
||||||
|
|
||||||
|
sysctl -qw kernel.softlockup_panic=${kernel_softlokup_panic_prev_val}
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_prepare() {
|
||||||
|
setup_ns source_ns sink_ns
|
||||||
|
|
||||||
|
ip -n ${source_ns} link add name ${SOURCE_TEST_IFACE} type veth peer name ${SINK_TEST_IFACE} netns ${sink_ns}
|
||||||
|
|
||||||
|
# Setting up the Source namespace
|
||||||
|
ip -n ${source_ns} addr add ${SOURCE_TEST_IP_ADDR} dev ${SOURCE_TEST_IFACE}
|
||||||
|
ip -n ${source_ns} link set dev ${SOURCE_TEST_IFACE} qlen 10000
|
||||||
|
ip -n ${source_ns} link set dev ${SOURCE_TEST_IFACE} up
|
||||||
|
ip netns exec ${source_ns} sysctl -qw net.ipv6.fib_multipath_hash_policy=1
|
||||||
|
|
||||||
|
# Setting up the Sink namespace
|
||||||
|
ip -n ${sink_ns} addr add ${SINK_LOOPBACK_IP_ADDR}/${SINK_LOOPBACK_IP_MASK} dev ${SINK_LOOPBACK_IFACE}
|
||||||
|
ip -n ${sink_ns} link set dev ${SINK_LOOPBACK_IFACE} up
|
||||||
|
ip netns exec ${sink_ns} sysctl -qw net.ipv6.conf.${SINK_LOOPBACK_IFACE}.forwarding=1
|
||||||
|
|
||||||
|
ip -n ${sink_ns} link set ${SINK_TEST_IFACE} up
|
||||||
|
ip netns exec ${sink_ns} sysctl -qw net.ipv6.conf.${SINK_TEST_IFACE}.forwarding=1
|
||||||
|
|
||||||
|
|
||||||
|
# Populate nexthop IPv6 addresses on the test interface in the sink_ns
|
||||||
|
echo "info: populating ${IPV6_NEXTHOP_ADDR_COUNT} IPv6 addresses on the ${SINK_TEST_IFACE} interface ..."
|
||||||
|
for IP in $(seq 1 ${IPV6_NEXTHOP_ADDR_COUNT}); do
|
||||||
|
ip -n ${sink_ns} addr add ${IPV6_NEXTHOP_PREFIX}::$(printf "1:%x" "${IP}")/${IPV6_NEXTHOP_ADDR_MASK} dev ${SINK_TEST_IFACE};
|
||||||
|
done
|
||||||
|
|
||||||
|
# Preparing list of nexthops
|
||||||
|
for IP in $(seq 1 ${IPV6_NEXTHOP_ADDR_COUNT}); do
|
||||||
|
nexthop_ip_list=$nexthop_ip_list" nexthop via ${IPV6_NEXTHOP_PREFIX}::$(printf "1:%x" $IP) dev ${SOURCE_TEST_IFACE} weight 1"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
test_soft_lockup_during_routing_table_refresh() {
|
||||||
|
# Start num_of_iperf_servers iperf3 servers in the sink_ns namespace,
|
||||||
|
# each listening on ports starting at 5001 and incrementing
|
||||||
|
# sequentially. Since iperf3 instances may terminate unexpectedly, a
|
||||||
|
# while loop is used to automatically restart them in such cases.
|
||||||
|
echo "info: starting ${num_of_iperf_servers} iperf3 servers in the sink_ns namespace ..."
|
||||||
|
for i in $(seq 1 ${num_of_iperf_servers}); do
|
||||||
|
cmd="iperf3 --bind ${SINK_LOOPBACK_IP_ADDR} -s -p $(printf '5%03d' ${i}) --rcv-timeout 200 &>/dev/null"
|
||||||
|
ip netns exec ${sink_ns} bash -c "while true; do ${cmd}; done &" &>/dev/null
|
||||||
|
done
|
||||||
|
|
||||||
|
# Wait for the iperf3 servers to be ready
|
||||||
|
for i in $(seq ${num_of_iperf_servers}); do
|
||||||
|
port=$(printf '5%03d' ${i});
|
||||||
|
wait_local_port_listen ${sink_ns} ${port} tcp
|
||||||
|
done
|
||||||
|
|
||||||
|
# Continuously refresh the routing table in the background within
|
||||||
|
# the source_ns namespace
|
||||||
|
ip netns exec ${source_ns} bash -c "
|
||||||
|
while \$(ip netns list | grep -q ${source_ns}); do
|
||||||
|
ip -6 route add ${SINK_LOOPBACK_IP_ADDR}/${SINK_LOOPBACK_IP_MASK} ${nexthop_ip_list};
|
||||||
|
sleep ${ROUTING_TABLE_REFRESH_PERIOD};
|
||||||
|
ip -6 route delete ${SINK_LOOPBACK_IP_ADDR}/${SINK_LOOPBACK_IP_MASK};
|
||||||
|
done &"
|
||||||
|
|
||||||
|
# Start num_of_iperf_servers iperf3 clients in the source_ns namespace,
|
||||||
|
# each sending TCP traffic on sequential ports starting at 5001.
|
||||||
|
# Since iperf3 instances may terminate unexpectedly (e.g., if the route
|
||||||
|
# to the server is deleted in the background during a route refresh), a
|
||||||
|
# while loop is used to automatically restart them in such cases.
|
||||||
|
echo "info: starting ${num_of_iperf_servers} iperf3 clients in the source_ns namespace ..."
|
||||||
|
for i in $(seq 1 ${num_of_iperf_servers}); do
|
||||||
|
cmd="iperf3 -c ${SINK_LOOPBACK_IP_ADDR} -p $(printf '5%03d' ${i}) --length 64 --bitrate ${IPERF3_BITRATE} -t 0 --connect-timeout 150 &>/dev/null"
|
||||||
|
ip netns exec ${source_ns} bash -c "while true; do ${cmd}; done &" &>/dev/null
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "info: IPv6 routing table is being updated at the rate of $(echo "1/${ROUTING_TABLE_REFRESH_PERIOD}" | bc)/s for ${TEST_DURATION} seconds ..."
|
||||||
|
echo "info: A kernel soft lockup, if detected, results in a kernel panic!"
|
||||||
|
|
||||||
|
wait
|
||||||
|
}
|
||||||
|
|
||||||
|
# Make sure 'iperf3' is installed, skip the test otherwise
|
||||||
|
if [ ! -x "$(command -v "iperf3")" ]; then
|
||||||
|
echo "SKIP: 'iperf3' is not installed. Skipping the test."
|
||||||
|
exit ${ksft_skip}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Determine the number of cores on the machine
|
||||||
|
num_of_iperf_servers=$(( $(nproc)/2 ))
|
||||||
|
|
||||||
|
# Check if we are running on a multi-core machine, skip the test otherwise
|
||||||
|
if [ "${num_of_iperf_servers}" -eq 0 ]; then
|
||||||
|
echo "SKIP: This test is not valid on a single core machine!"
|
||||||
|
exit ${ksft_skip}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Since the kernel soft lockup we're testing causes at least one core to enter
|
||||||
|
# an infinite loop, destabilizing the host and likely affecting subsequent
|
||||||
|
# tests, we trigger a kernel panic instead of reporting a failure and
|
||||||
|
# continuing
|
||||||
|
kernel_softlokup_panic_prev_val=$(sysctl -n kernel.softlockup_panic)
|
||||||
|
sysctl -qw kernel.softlockup_panic=1
|
||||||
|
|
||||||
|
handle_sigint() {
|
||||||
|
termination_signal="SIGINT"
|
||||||
|
cleanup
|
||||||
|
exit ${ksft_skip}
|
||||||
|
}
|
||||||
|
|
||||||
|
handle_sigalrm() {
|
||||||
|
termination_signal="SIGALRM"
|
||||||
|
cleanup
|
||||||
|
exit ${ksft_pass}
|
||||||
|
}
|
||||||
|
|
||||||
|
trap handle_sigint SIGINT
|
||||||
|
trap handle_sigalrm SIGALRM
|
||||||
|
|
||||||
|
(sleep ${TEST_DURATION} && kill -s SIGALRM $$)&
|
||||||
|
|
||||||
|
setup_prepare
|
||||||
|
test_soft_lockup_during_routing_table_refresh
|
||||||
Reference in New Issue
Block a user