This series hunts the problems discovered after manual enabling of
ARCH_WANT_LD_ORPHAN_WARN. Notably:
- adds the missing PAGE_ALIGNED_DATA() section affecting VDSO
placement (marked for stable);
- properly stops .eh_frame section generation.
Compile and runtime tested on MIPS32R2 CPS board with no issues
using two different toolkits:
- Binutils 2.35.1, GCC 10.2.0;
- LLVM stack 11.0.0.
Since v3 [2]:
- fix the third patch as GNU stack emits .rel.dyn into VDSO for
some reason if .cfi_sections is specified.
Since v2 [1]:
- stop discarding .eh_frame and just prevent it from generating
(Kees);
- drop redundant sections assertions (Fangrui);
- place GOT table in .text instead of asserting as it's not empty
when building with LLVM (Nathan);
- catch compound literals in generic definitions when building with
LD_DEAD_CODE_DATA_ELIMINATION (Kees);
- collect two Reviewed-bys (Kees).
Since v1 [0]:
- catch .got entries too as LLD may produce it (Nathan);
- check for unwanted sections to be zero-sized instead of
discarding (Fangrui).
[0] https://lore.kernel.org/linux-mips/20210104121729.46981-1-alobakin@pm.me
[1] https://lore.kernel.org/linux-mips/20210106200713.31840-1-alobakin@pm.me
[2] https://lore.kernel.org/linux-mips/20210107115120.281008-1-alobakin@pm.me
Alexander Lobakin (7):
MIPS: vmlinux.lds.S: add missing PAGE_ALIGNED_DATA() section
MIPS: vmlinux.lds.S: add ".gnu.attributes" to DISCARDS
MIPS: properly stop .eh_frame generation
MIPS: vmlinux.lds.S: catch bad .rel.dyn at link time
MIPS: vmlinux.lds.S: explicitly declare .got table
vmlinux.lds.h: catch compound literals into data and BSS
MIPS: select ARCH_WANT_LD_ORPHAN_WARN
arch/mips/Kconfig | 1 +
arch/mips/include/asm/asm.h | 18 ++++++++++++++++++
arch/mips/kernel/vmlinux.lds.S | 15 ++++++++++++++-
include/asm-generic/vmlinux.lds.h | 6 +++---
4 files changed, 36 insertions(+), 4 deletions(-)
--
2.30.0
From: Eric Biggers <ebiggers(a)google.com>
When lazytime is enabled and an inode with dirty timestamps is being
expired, either due to dirtytime_expire_interval being exceeded or due
to a sync or syncfs system call, we need to inform the filesystem that
the inode is dirty so that the inode's timestamps can be copied out to
the on-disk data structures. That's because if the filesystem supports
lazytime, it will have ignored the ->dirty_inode(inode, I_DIRTY_TIME)
notification when the timestamp was modified in memory.
Currently this is accomplished by calling mark_inode_dirty_sync() from
__writeback_single_inode(). However, this has the unfortunate side
effect of also putting the inode the writeback list. That's not
appropriate in this case, since the inode is already being written.
That causes the inode to remain dirty after a sync. Normally that's
just wasteful, as it causes the inode to be written twice. But when
fscrypt is used this bug also partially breaks the
FS_IOC_REMOVE_ENCRYPTION_KEY ioctl, as the ioctl reports that files are
still in-use when they aren't. For more details, see the original
report at https://lore.kernel.org/r/20200306004555.GB225345@gmail.com
Fix this by calling ->dirty_inode(inode, I_DIRTY_SYNC) directly instead
of mark_inode_dirty_sync().
This fixes xfstest generic/580 when lazytime is enabled.
A later patch will introduce a ->lazytime_expired method to cleanly
separate out the lazytime expiration case, in particular for XFS which
uses the VFS-level dirtiness tracking only for lazytime. But that's
separate from fixing this bug. Also, note that XFS will incorrectly
ignore the I_DIRTY_SYNC notification from __writeback_single_inode()
both before and after this patch, as I_DIRTY_TIME was already cleared in
i_state. Later patches will fix this separate bug.
Fixes: 0ae45f63d4ef ("vfs: add support for a lazytime mount option")
Cc: stable(a)vger.kernel.org
Signed-off-by: Eric Biggers <ebiggers(a)google.com>
---
fs/fs-writeback.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index acfb55834af23..081e335cdee47 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -1509,11 +1509,22 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
spin_unlock(&inode->i_lock);
- if (dirty & I_DIRTY_TIME)
- mark_inode_dirty_sync(inode);
/* Don't write the inode if only I_DIRTY_PAGES was set */
if (dirty & ~I_DIRTY_PAGES) {
- int err = write_inode(inode, wbc);
+ int err;
+
+ /*
+ * If the inode is being written due to a lazytime timestamp
+ * expiration, then the filesystem needs to be notified about it
+ * so that e.g. the filesystem can update on-disk fields and
+ * journal the timestamp update. Just calling write_inode()
+ * isn't enough. Don't call mark_inode_dirty_sync(), as that
+ * would put the inode back on the dirty list.
+ */
+ if ((dirty & I_DIRTY_TIME) && inode->i_sb->s_op->dirty_inode)
+ inode->i_sb->s_op->dirty_inode(inode, I_DIRTY_SYNC);
+
+ err = write_inode(inode, wbc);
if (ret == 0)
ret = err;
}
base-commit: e71ba9452f0b5b2e8dc8aa5445198cd9214a6a62
--
2.30.0
The device link device's name was of the form:
<supplier-dev-name>--<consumer-dev-name>
This can cause name collision as reported here [1] as device names are
not globally unique. Since device names have to be unique within the
bus/class, add the bus/class name as a prefix to the device names used to
construct the device link device name.
So the devuce link device's name will be of the form:
<supplier-bus-name>:<supplier-dev-name>--<consumer-bus-name>:<consumer-dev-name>
[1] - https://lore.kernel.org/lkml/20201229033440.32142-1-michael@walle.cc/
Cc: stable(a)vger.kernel.org
Fixes: 287905e68dd2 ("driver core: Expose device link details in sysfs")
Reported-by: Michael Walle <michael(a)walle.cc>
Signed-off-by: Saravana Kannan <saravanak(a)google.com>
---
Documentation/ABI/testing/sysfs-class-devlink | 4 ++--
.../ABI/testing/sysfs-devices-consumer | 5 +++--
.../ABI/testing/sysfs-devices-supplier | 5 +++--
drivers/base/core.c | 17 +++++++++--------
include/linux/device.h | 12 ++++++++++++
5 files changed, 29 insertions(+), 14 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-class-devlink b/Documentation/ABI/testing/sysfs-class-devlink
index b662f747c83e..8a21ce515f61 100644
--- a/Documentation/ABI/testing/sysfs-class-devlink
+++ b/Documentation/ABI/testing/sysfs-class-devlink
@@ -5,8 +5,8 @@ Description:
Provide a place in sysfs for the device link objects in the
kernel at any given time. The name of a device link directory,
denoted as ... above, is of the form <supplier>--<consumer>
- where <supplier> is the supplier device name and <consumer> is
- the consumer device name.
+ where <supplier> is the supplier bus:device name and <consumer>
+ is the consumer bus:device name.
What: /sys/class/devlink/.../auto_remove_on
Date: May 2020
diff --git a/Documentation/ABI/testing/sysfs-devices-consumer b/Documentation/ABI/testing/sysfs-devices-consumer
index 1f06d74d1c3c..0809fda092e6 100644
--- a/Documentation/ABI/testing/sysfs-devices-consumer
+++ b/Documentation/ABI/testing/sysfs-devices-consumer
@@ -4,5 +4,6 @@ Contact: Saravana Kannan <saravanak(a)google.com>
Description:
The /sys/devices/.../consumer:<consumer> are symlinks to device
links where this device is the supplier. <consumer> denotes the
- name of the consumer in that device link. There can be zero or
- more of these symlinks for a given device.
+ name of the consumer in that device link and is of the form
+ bus:device name. There can be zero or more of these symlinks
+ for a given device.
diff --git a/Documentation/ABI/testing/sysfs-devices-supplier b/Documentation/ABI/testing/sysfs-devices-supplier
index a919e0db5e90..207f5972e98d 100644
--- a/Documentation/ABI/testing/sysfs-devices-supplier
+++ b/Documentation/ABI/testing/sysfs-devices-supplier
@@ -4,5 +4,6 @@ Contact: Saravana Kannan <saravanak(a)google.com>
Description:
The /sys/devices/.../supplier:<supplier> are symlinks to device
links where this device is the consumer. <supplier> denotes the
- name of the supplier in that device link. There can be zero or
- more of these symlinks for a given device.
+ name of the supplier in that device link and is of the form
+ bus:device name. There can be zero or more of these symlinks
+ for a given device.
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 25e08e5f40bd..4140a69dfe18 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -456,7 +456,9 @@ static int devlink_add_symlinks(struct device *dev,
struct device *con = link->consumer;
char *buf;
- len = max(strlen(dev_name(sup)), strlen(dev_name(con)));
+ len = max(strlen(dev_bus_name(sup)) + strlen(dev_name(sup)),
+ strlen(dev_bus_name(con)) + strlen(dev_name(con)));
+ len += strlen(":");
len += strlen("supplier:") + 1;
buf = kzalloc(len, GFP_KERNEL);
if (!buf)
@@ -470,12 +472,12 @@ static int devlink_add_symlinks(struct device *dev,
if (ret)
goto err_con;
- snprintf(buf, len, "consumer:%s", dev_name(con));
+ snprintf(buf, len, "consumer:%s:%s", dev_bus_name(con), dev_name(con));
ret = sysfs_create_link(&sup->kobj, &link->link_dev.kobj, buf);
if (ret)
goto err_con_dev;
- snprintf(buf, len, "supplier:%s", dev_name(sup));
+ snprintf(buf, len, "supplier:%s:%s", dev_bus_name(sup), dev_name(sup));
ret = sysfs_create_link(&con->kobj, &link->link_dev.kobj, buf);
if (ret)
goto err_sup_dev;
@@ -737,8 +739,9 @@ struct device_link *device_link_add(struct device *consumer,
link->link_dev.class = &devlink_class;
device_set_pm_not_required(&link->link_dev);
- dev_set_name(&link->link_dev, "%s--%s",
- dev_name(supplier), dev_name(consumer));
+ dev_set_name(&link->link_dev, "%s:%s--%s:%s",
+ dev_bus_name(supplier), dev_name(supplier),
+ dev_bus_name(consumer), dev_name(consumer));
if (device_register(&link->link_dev)) {
put_device(consumer);
put_device(supplier);
@@ -1808,9 +1811,7 @@ const char *dev_driver_string(const struct device *dev)
* never change once they are set, so they don't need special care.
*/
drv = READ_ONCE(dev->driver);
- return drv ? drv->name :
- (dev->bus ? dev->bus->name :
- (dev->class ? dev->class->name : ""));
+ return drv ? drv->name : dev_bus_name(dev);
}
EXPORT_SYMBOL(dev_driver_string);
diff --git a/include/linux/device.h b/include/linux/device.h
index 89bb8b84173e..1779f90eeb4c 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -609,6 +609,18 @@ static inline const char *dev_name(const struct device *dev)
return kobject_name(&dev->kobj);
}
+/**
+ * dev_bus_name - Return a device's bus/class name, if at all possible
+ * @dev: struct device to get the bus/class name of
+ *
+ * Will return the name of the bus/class the device is attached to. If it is
+ * not attached to a bus/class, an empty string will be returned.
+ */
+static inline const char *dev_bus_name(const struct device *dev)
+{
+ return dev->bus ? dev->bus->name : (dev->class ? dev->class->name : "");
+}
+
__printf(2, 3) int dev_set_name(struct device *dev, const char *name, ...);
#ifdef CONFIG_NUMA
--
2.29.2.729.g45daf8777d-goog