Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Pavol Sakac <sakacpav@amazon.de>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	"Rafael J . Wysocki" <rafael@kernel.org>,
	Danilo Krummrich <dakr@kernel.org>, Tejun Heo <tj@kernel.org>
Cc: <linux-kernel@vger.kernel.org>, <driver-core@lists.linux.dev>,
	"David Woodhouse" <dwmw@amazon.co.uk>,
	Pasha Tatashin <pasha.tatashin@soleen.com>,
	Mike Rapoport <rppt@kernel.org>,
	Pratyush Yadav <pratyush@kernel.org>,
	"David Matlack" <dmatlack@google.com>,
	Samiullah Khawaja <skhawaja@google.com>,
	Alexander Graf <graf@amazon.com>, <linux-mm@kvack.org>,
	<kexec@lists.infradead.org>, <nh-open-source@amazon.com>
Subject: [RFC PATCH 05/14] driver core: add struct device_sysfs_entry and walker
Date: Thu, 2 Jul 2026 19:51:05 +0200	[thread overview]
Message-ID: <20260702175114.24659-1-sakacpav@amazon.de> (raw)
In-Reply-To: <20260702174033.32116-1-sakacpav@amazon.de>

Introduce the primitive for declaring per-device sysfs content as
table rows and a single walker that dispatches across eager,
lazy-populate, and teardown paths.

struct device_sysfs_entry { name, applies_to, create, remove }

  - name == NULL: wildcard row (create() does internal name
    dispatch; used for attribute_group-source rows).
  - applies_to: NULL or a pure, cheap, non-sleeping predicate.
  - create: implements ADD_ONE (name != NULL) and ADD_ALL
    (name == NULL) semantics; absorbs -EEXIST from concurrent
    racers to 0.
  - remove: reverse-order teardown.

device_sysfs_apply(dev, entries, action, name) dispatches
DEV_SYSFS_ADD_ONE / DEV_SYSFS_ADD_ALL / DEV_SYSFS_REMOVE_ALL across
the table. -ENOENT from a wildcard row's create() is treated as
"not my name" and the walker continues; any other error propagates
to the caller on ADD_ONE and is absorbed on ADD_ALL (best-effort).
REMOVE_ALL reverses the table and never aborts. The full contract
is documented in Documentation/driver-api/sysfs-lazy.rst (added
later in this series).

Shape follows cftype + cgroup_addrm_files (kernel/cgroup/cgroup.c)
as the in-tree precedent for table-driven attribute creation.
struct kobj_type grows a trailing .entries pointer; ktypes opt in
by setting it and wiring their populate / populate_all callbacks
to the walker. The field is at end of struct for source-
compatibility with positional initialisers of out-of-tree ktypes.

sysfs_add_file_mode_ns() and sysfs_add_bin_file_mode_ns() are
exported (kerneldoc added) so the walker can absorb -EEXIST from
concurrent create racers without going through sysfs_warn_dup().

Two static helpers - create_attr_in_groups() and
create_all_in_groups() - are added for use by attribute-group
source rows that the migration commit later wires up; they search
@groups by @name and walk every visible attribute respectively.

Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Rafael J. Wysocki <rafael@kernel.org>
Cc: Tejun Heo <tj@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Danilo Krummrich <dakr@kernel.org>
Cc: linux-kernel@vger.kernel.org
Cc: linux-api@vger.kernel.org
Cc: driver-core@lists.linux.dev
Assisted-by: Claude:claude-opus-4.7
Signed-off-by: Pavol Sakac <sakacpav@amazon.de>
---
 drivers/base/core.c     | 319 ++++++++++++++++++++++++++++++++++++++++
 fs/sysfs/file.c         |  41 +++++-
 fs/sysfs/sysfs.h        |   6 -
 include/linux/device.h  |  56 +++++++
 include/linux/kobject.h |   5 +
 include/linux/sysfs.h   |  24 +++
 6 files changed, 443 insertions(+), 8 deletions(-)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index 6d0d917d4b1ff..aeb4985eb8838 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -2574,6 +2574,325 @@ static void device_release(struct kobject *kobj)
 	kfree(p);
 }
 
+/*
+ * device_sysfs_apply() - declarative per-device sysfs dispatch
+ *
+ * Single walker over a sentinel-terminated struct device_sysfs_entry
+ * table. Intended to be invoked on every dispatch path (device_add
+ * eager, lazy populate_one, lazy populate_all, device_del teardown)
+ * so adding a new per-device file is one row, not four open-coded
+ * branches. Shape follows cftype + cgroup_addrm_files
+ * (kernel/cgroup/cgroup.c) and pci_sysfs_entries[]
+ * (drivers/pci/pci-sysfs.c).
+ *
+ * ADD_ONE:  first row whose applies_to passes and whose name matches
+ *	     (or a wildcard row whose create() does not return
+ *	     -ENOENT) terminates the walk. -ENOENT from a wildcard
+ *	     row's create() signals "not my name"; the walker
+ *	     continues. Realize callbacks MUST check existence (via
+ *	     sysfs_*_exists()) before calling sysfs_create_*() and
+ *	     return 0 if the entry already exists. Reaching
+ *	     __kernfs_create_*() for a name that another lazy path
+ *	     just created is forbidden under lock
+ *	     serialization. If sysfs_warn_dup() ever fires from a
+ *	     lazy path, it indicates a lock invariant
+ *	     violation or a non-lazy path creating lazy attrs (bug).
+ * ADD_ALL:  every applicable row's create() fires with name = NULL;
+ *	     per-row errors are best-effort - the walker discards
+ *	     return values and rows log via their own diagnostics.
+ * REMOVE_ALL: reverse row order; remove() fires for every row whose
+ *	     applies_to passes. Teardown never aborts.
+ *
+ * The full walker contract (error-absorption matrix, interaction
+ * with negative-dentry caching, lifecycle caveats) is documented in
+ * Documentation/driver-api/sysfs-lazy.rst, added later in this
+ * series.
+ */
+/*
+ * Create one named attr inside @grp; honours grp->is_visible.
+ * Returns 0 on success/hidden/already-present, -ENOENT on no-match.
+ */
+static int create_attr_in_group(struct device *dev,
+				 const struct attribute_group *grp,
+				 const char *name)
+{
+	struct attribute **a;
+	const struct bin_attribute *const *ba;
+	kuid_t uid;
+	kgid_t gid;
+	umode_t mode;
+	int i;
+
+	if (device_is_sysfs_lazy(dev))
+		lockdep_assert_held(&dev->sysfs_lazy->lock);
+
+	kobject_get_ownership(&dev->kobj, &uid, &gid);
+
+	if (grp->name) {
+		if (!strcmp(grp->name, name)) {
+			if (sysfs_group_exists(&dev->kobj, grp))
+				return 0;
+			return sysfs_create_group(&dev->kobj, grp);
+		}
+		return -ENOENT;
+	}
+
+	if (grp->attrs) {
+		for (i = 0, a = grp->attrs; *a; i++, a++) {
+			if (strcmp((*a)->name, name))
+				continue;
+
+			mode = (*a)->mode;
+			if (grp->is_visible || grp->is_visible_const) {
+				if (grp->is_visible)
+					mode = grp->is_visible(&dev->kobj, *a, i);
+				else
+					mode = grp->is_visible_const(&dev->kobj, *a, i);
+				mode &= ~SYSFS_GROUP_INVISIBLE;
+				if (!mode)
+					return 0;	/* hidden */
+			}
+			mode &= SYSFS_PREALLOC | 0664;
+
+			if (sysfs_kn_exists(&dev->kobj, (*a)->name))
+				return 0;
+
+			return sysfs_add_file_mode_ns(dev->kobj.sd, *a,
+						      mode, uid, gid, NULL);
+		}
+	}
+	if (grp->bin_attrs) {
+		for (i = 0, ba = grp->bin_attrs; *ba; i++, ba++) {
+			if (strcmp((*ba)->attr.name, name))
+				continue;
+			mode = (*ba)->attr.mode;
+			if (grp->is_bin_visible) {
+				mode = grp->is_bin_visible(&dev->kobj, *ba, i);
+				mode &= ~SYSFS_GROUP_INVISIBLE;
+				if (!mode)
+					return 0;
+			}
+			mode &= SYSFS_PREALLOC | 0664;
+
+			if (sysfs_kn_exists(&dev->kobj, (*ba)->attr.name))
+				return 0;
+
+			return sysfs_add_bin_file_mode_ns(dev->kobj.sd,
+							  *ba, mode,
+							  (*ba)->size,
+							  uid, gid, NULL);
+		}
+	}
+	return -ENOENT;
+}
+
+/*
+ * Per-group incremental creation. Tolerates partial state from
+ * concurrent populate_one. Best-effort: absorbs per-attr failures.
+ */
+static int create_group_incremental(struct device *dev,
+				     const struct attribute_group *grp)
+{
+	struct attribute **a;
+	const struct bin_attribute *const *ba;
+	int ret;
+
+	if (device_is_sysfs_lazy(dev))
+		lockdep_assert_held(&dev->sysfs_lazy->lock);
+
+	if (grp->name) {
+		struct kernfs_node *subdir;
+		kuid_t uid;
+		kgid_t gid;
+		umode_t mode;
+		int i;
+
+		subdir = kernfs_find_and_get(dev->kobj.sd, grp->name);
+		if (!subdir)
+			return sysfs_create_group(&dev->kobj, grp);
+
+		kobject_get_ownership(&dev->kobj, &uid, &gid);
+
+		if (grp->attrs) {
+			for (i = 0, a = grp->attrs; *a; i++, a++) {
+				struct kernfs_node *kn;
+
+				mode = (*a)->mode;
+				if (grp->is_visible || grp->is_visible_const) {
+					if (grp->is_visible)
+						mode = grp->is_visible(&dev->kobj,
+								       *a, i);
+					else
+						mode = grp->is_visible_const(&dev->kobj,
+									     *a, i);
+					mode &= ~SYSFS_GROUP_INVISIBLE;
+					if (!mode)
+						continue;
+				}
+				mode &= SYSFS_PREALLOC | 0664;
+
+				/* Existence check inside named @subdir (not a kobject). */
+				kn = kernfs_find_and_get(subdir, (*a)->name);
+				if (kn) {
+					kernfs_put(kn);
+					continue;
+				}
+
+				ret = sysfs_add_file_mode_ns(subdir, *a,
+							     mode, uid,
+							     gid, NULL);
+				if (ret)
+					dev_dbg(dev,
+						"lazy %s/%s: %d\n",
+						grp->name, (*a)->name, ret);
+			}
+		}
+		if (grp->bin_attrs) {
+			for (i = 0, ba = grp->bin_attrs; *ba; i++, ba++) {
+				struct kernfs_node *kn;
+
+				mode = (*ba)->attr.mode;
+				if (grp->is_bin_visible) {
+					mode = grp->is_bin_visible(&dev->kobj,
+								   *ba, i);
+					mode &= ~SYSFS_GROUP_INVISIBLE;
+					if (!mode)
+						continue;
+				}
+				mode &= SYSFS_PREALLOC | 0664;
+
+				kn = kernfs_find_and_get(subdir, (*ba)->attr.name);
+				if (kn) {
+					kernfs_put(kn);
+					continue;
+				}
+
+				ret = sysfs_add_bin_file_mode_ns(subdir,
+								 *ba,
+								 mode,
+								 (*ba)->size,
+								 uid,
+								 gid,
+								 NULL);
+				if (ret)
+					dev_dbg(dev,
+						"lazy %s/%s: %d\n",
+						grp->name,
+						(*ba)->attr.name, ret);
+			}
+		}
+
+		kernfs_put(subdir);
+		return 0;
+	}
+
+	if (grp->attrs) {
+		for (a = grp->attrs; *a; a++)
+			(void)create_attr_in_group(dev, grp, (*a)->name);
+	}
+	if (grp->bin_attrs) {
+		for (ba = grp->bin_attrs; *ba; ba++)
+			(void)create_attr_in_group(dev, grp,
+						    (*ba)->attr.name);
+	}
+	return 0;
+}
+
+/* Search @groups for @name. -ENOENT = not in this source. */
+static int __maybe_unused create_attr_in_groups(struct device *dev,
+				  const struct attribute_group *const *groups,
+				  const char *name)
+{
+	const struct attribute_group *const *g;
+	int ret;
+
+	if (!groups)
+		return -ENOENT;
+
+	for (g = groups; *g; g++) {
+		ret = create_attr_in_group(dev, *g, name);
+		if (ret != -ENOENT)
+			return ret;
+	}
+	return -ENOENT;
+}
+
+/* Walk @groups creating every visible attribute. Best-effort. */
+static int __maybe_unused create_all_in_groups(struct device *dev,
+				 const struct attribute_group *const *groups)
+{
+	const struct attribute_group *const *g;
+
+	if (!groups)
+		return 0;
+
+	for (g = groups; *g; g++)
+		(void)create_group_incremental(dev, *g);
+	return 0;
+}
+
+static const struct device_sysfs_entry *
+device_sysfs_entries_end(const struct device_sysfs_entry *entries)
+{
+	const struct device_sysfs_entry *e = entries;
+
+	while (e->create)
+		e++;
+	return e;
+}
+
+static __maybe_unused int
+device_sysfs_apply(struct device *dev,
+		  const struct device_sysfs_entry *entries,
+		  enum dev_sysfs_action action, const char *name)
+{
+	const struct device_sysfs_entry *e;
+
+	if (!entries)
+		return action == DEV_SYSFS_ADD_ONE ? -ENOENT : 0;
+
+	if (action == DEV_SYSFS_REMOVE_ALL) {
+		for (e = device_sysfs_entries_end(entries) - 1;
+		     e >= entries; e--) {
+			if (e->applies_to && !e->applies_to(dev))
+				continue;
+			if (e->remove)
+				e->remove(dev);
+		}
+		return 0;
+	}
+
+	for (e = entries; e->create; e++) {
+		int ret;
+
+		if (e->applies_to && !e->applies_to(dev))
+			continue;
+		if (action == DEV_SYSFS_ADD_ONE && e->name &&
+		    strcmp(e->name, name))
+			continue;
+
+		ret = e->create(dev, action == DEV_SYSFS_ADD_ONE
+					      ? name : NULL);
+		if (action == DEV_SYSFS_ADD_ONE) {
+			/*
+			 * A named row is the authoritative handler for its
+			 * name: return its result even on -ENOENT. A wildcard
+			 * row (e->name == NULL) may decline with -ENOENT, so
+			 * keep scanning for another handler in that case.
+			 */
+			if (e->name || ret != -ENOENT)
+				return ret;
+		}
+		/*
+		 * FIXME: ADD_ALL is best-effort and never returns the first create() failure to
+		 * the caller, so device_ktype_populate_all() latches populated=true after a
+		 * transient failure - the missing attribute is negative-cached forever (a later
+		 * lookup returns -ENOENT and never retries), contradicting the sysfs-lazy ABI.
+		 */
+	}
+	return action == DEV_SYSFS_ADD_ONE ? -ENOENT : 0;
+}
+
 static const struct ns_common *device_namespace(const struct kobject *kobj)
 {
 	const struct device *dev = kobj_to_dev(kobj);
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 5f3144e52ab72..8d0b8c2c2ee4d 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -270,6 +270,25 @@ static const struct kernfs_ops sysfs_bin_kfops_mmap = {
 	.llseek		= sysfs_kf_bin_llseek,
 };
 
+/**
+ * sysfs_add_file_mode_ns - create a sysfs attribute file under @parent
+ * @parent: kernfs node for the parent directory (typically @kobj->sd)
+ * @attr:   attribute descriptor; @attr->name is the file name
+ * @mode:   file mode (low bits) optionally OR'd with %SYSFS_PREALLOC
+ * @uid: file owner UID
+ * @gid: file owner GID
+ * @ns:  namespace tag (may be %NULL)
+ *
+ * Picks a kernfs_ops dispatch row from (prealloc?, has show, has store)
+ * routing read()/write() through @parent->priv->ktype->sysfs_ops.
+ *
+ * Return: 0 on success, or -errno. -EEXIST means the name already
+ * exists and is treated as a caller error (it triggers sysfs_warn_dup()).
+ * The lazy populate path must not reach this: it checks sysfs_kn_exists()/
+ * sysfs_group_exists() under the populate lock before creating, so a
+ * concurrent ADD_ONE/ADD_ALL race resolves to a no-op rather than a
+ * duplicate create.
+ */
 int sysfs_add_file_mode_ns(struct kernfs_node *parent,
 		const struct attribute *attr, umode_t mode, kuid_t uid,
 		kgid_t gid, const struct ns_common *ns)
@@ -320,6 +339,26 @@ int sysfs_add_file_mode_ns(struct kernfs_node *parent,
 	return 0;
 }
 
+/**
+ * sysfs_add_bin_file_mode_ns - create a sysfs binary-attribute file
+ * @parent: kernfs node for the parent directory
+ * @battr:  binary attribute descriptor
+ * @mode:   file mode (low bits)
+ * @size:   in-core size of the binary attribute (passed to __kernfs_create_file())
+ * @uid: file owner UID
+ * @gid: file owner GID
+ * @ns:  namespace tag (may be %NULL)
+ *
+ * Picks a kernfs_ops dispatch row from a 5-row matrix on @battr's
+ * callbacks (mmap > rw > read > write > empty).
+ *
+ * Return: 0 on success, or -errno. -EEXIST means the name already
+ * exists and is treated as a caller error (it triggers sysfs_warn_dup()).
+ * The lazy populate path must not reach this: it checks sysfs_kn_exists()/
+ * sysfs_group_exists() under the populate lock before creating, so a
+ * concurrent ADD_ONE/ADD_ALL race resolves to a no-op rather than a
+ * duplicate create.
+ */
 int sysfs_add_bin_file_mode_ns(struct kernfs_node *parent,
 		const struct bin_attribute *battr, umode_t mode, size_t size,
 		kuid_t uid, kgid_t gid, const struct ns_common *ns)
@@ -816,5 +855,3 @@ ssize_t sysfs_bin_attr_simple_read(struct file *file, struct kobject *kobj,
 	return count;
 }
 EXPORT_SYMBOL_GPL(sysfs_bin_attr_simple_read);
-
-
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index f4583dcafcd1e..94b8aca20bffc 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -27,12 +27,6 @@ void sysfs_warn_dup(struct kernfs_node *parent, const char *name);
 /*
  * file.c
  */
-int sysfs_add_file_mode_ns(struct kernfs_node *parent,
-		const struct attribute *attr, umode_t amode, kuid_t uid,
-		kgid_t gid, const struct ns_common *ns);
-int sysfs_add_bin_file_mode_ns(struct kernfs_node *parent,
-		const struct bin_attribute *battr, umode_t mode, size_t size,
-		kuid_t uid, kgid_t gid, const struct ns_common *ns);
 
 /*
  * symlink.c
diff --git a/include/linux/device.h b/include/linux/device.h
index 39e08e8c950c6..e5485bfbc6c84 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -88,6 +88,62 @@ int subsys_system_register(const struct bus_type *subsys,
 int subsys_virtual_register(const struct bus_type *subsys,
 			    const struct attribute_group **groups);
 
+/**
+ * enum dev_sysfs_action - verb selector for device_sysfs_apply()
+ * @DEV_SYSFS_ADD_ONE: realize a single named entry (lazy populate_one
+ *		       miss path); walker stops at the first row whose
+ *		       @applies_to passes and whose create() returns
+ *		       anything other than -ENOENT.
+ * @DEV_SYSFS_ADD_ALL: realize every applicable entry (eager device_add
+ *		       or lazy populate_all); best-effort, per-row errors
+ *		       do not abort the walk.
+ * @DEV_SYSFS_REMOVE_ALL: tear down every applicable entry in reverse
+ *		       row order (device_del teardown).
+ */
+enum dev_sysfs_action {
+	DEV_SYSFS_ADD_ONE,
+	DEV_SYSFS_ADD_ALL,
+	DEV_SYSFS_REMOVE_ALL,
+};
+
+/**
+ * struct device_sysfs_entry - declarative per-device sysfs content row
+ * @name:	Attribute or symlink name at the top level of the device's
+ *		sysfs directory, or %NULL for a wildcard row whose
+ *		create() performs internal name dispatch (typically a
+ *		group-source row iterating an attribute_group array).
+ * @applies_to: Optional predicate gating row eligibility for this
+ *		device. Must be cheap, non-sleeping, side-effect-free, and
+ *		monotonic for a given device state. MUST NOT acquire any
+ *		lock the walker's caller may already hold (notably
+ *		device_lock()). %NULL means unconditional.
+ * @create:	Required. Creates the row's sysfs content. For a named
+ *		row (@name != NULL) the @name argument equals @e->name on
+ *		ADD_ONE and %NULL on ADD_ALL. For a wildcard row the @name
+ *		argument is the ADD_ONE target (or %NULL on ADD_ALL) and
+ *		the row's create() matches internally, returning -ENOENT
+ *		to signal "not my name" so the walker continues. Must
+ *		convert -EEXIST from concurrent racers to 0.
+ * @remove:	Optional reverse-of-realize teardown. Called on
+ *		REMOVE_ALL in reverse row order. MUST NOT fail the walk.
+ *
+ * Rows are declared in file-static, sentinel-terminated tables whose
+ * base pointer is published to the walker via struct kobj_type.entries
+ * (device ktype shares a single driver_core table and dispatches to
+ * dev->type->entries as well). The row shape mirrors cftype +
+ * cgroup_addrm_files (kernel/cgroup/cgroup.c) and the
+ * pci_sysfs_entries[] at drivers/pci/pci-sysfs.c (added later in
+ * the series); see Documentation/driver-api/sysfs-lazy.rst (also
+ * added later in the series) for the full walker contract and
+ * error-handling matrix.
+ */
+struct device_sysfs_entry {
+	const char *name;
+	bool (*applies_to)(struct device *dev);
+	int  (*create)(struct device *dev, const char *name);
+	void (*remove)(struct device *dev);
+};
+
 /*
  * The type of device, "struct device" is embedded in. A class
  * or bus can contain devices of different types
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index cec6de1720076..c724d86e1a049 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -61,6 +61,8 @@ enum kobject_action {
 	KOBJ_UNBIND,
 };
 
+struct device_sysfs_entry;
+
 struct kobject {
 	const char		*name;
 	struct list_head	entry;
@@ -130,6 +132,9 @@ struct kobj_type {
 	 */
 	int (*populate)(struct kobject *kobj, const char *name);
 	void (*populate_all)(struct kobject *kobj);
+
+	/* Optional table of per-attribute entries (see device_sysfs_apply()). */
+	const struct device_sysfs_entry *entries;
 };
 
 struct kobj_uevent_env {
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index de211563f3dec..aac2f773d5378 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -415,6 +415,12 @@ int __must_check sysfs_create_files(struct kobject *kobj,
 				   const struct attribute * const *attr);
 int __must_check sysfs_chmod_file(struct kobject *kobj,
 				  const struct attribute *attr, umode_t mode);
+int __must_check sysfs_add_file_mode_ns(struct kernfs_node *parent,
+		const struct attribute *attr, umode_t amode, kuid_t uid,
+		kgid_t gid, const struct ns_common *ns);
+int __must_check sysfs_add_bin_file_mode_ns(struct kernfs_node *parent,
+		const struct bin_attribute *battr, umode_t mode, size_t size,
+		kuid_t uid, kgid_t gid, const struct ns_common *ns);
 struct kernfs_node *sysfs_break_active_protection(struct kobject *kobj,
 						  const struct attribute *attr);
 void sysfs_unbreak_active_protection(struct kernfs_node *kn);
@@ -558,6 +564,24 @@ static inline int sysfs_chmod_file(struct kobject *kobj,
 	return 0;
 }
 
+static inline int sysfs_add_file_mode_ns(struct kernfs_node *parent,
+					 const struct attribute *attr,
+					 umode_t amode, kuid_t uid,
+					 kgid_t gid,
+					 const struct ns_common *ns)
+{
+	return 0;
+}
+
+static inline int sysfs_add_bin_file_mode_ns(struct kernfs_node *parent,
+					     const struct bin_attribute *battr,
+					     umode_t mode, size_t size,
+					     kuid_t uid, kgid_t gid,
+					     const struct ns_common *ns)
+{
+	return 0;
+}
+
 static inline struct kernfs_node *
 sysfs_break_active_protection(struct kobject *kobj,
 			      const struct attribute *attr)
-- 
2.47.3




Amazon Web Services Development Center Germany GmbH
Tamara-Danz-Str. 13
10243 Berlin
Geschaeftsfuehrung: Christof Hellmis, Andreas Stieger
Eingetragen am Amtsgericht Charlottenburg unter HRB 257764 B
Sitz: Berlin
Ust-ID: DE 365 538 597



  parent reply	other threads:[~2026-07-03  0:59 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-02 17:40 [RFC PATCH 00/14] driver core: defer per-VF sysfs creation for fast SR-IOV bring-up Pavol Sakac
2026-07-02 17:40 ` [RFC PATCH 01/14] kernfs: add populate callbacks and KERNFS_LAZY flag for lazy dir population Pavol Sakac
2026-07-02 17:40 ` [RFC PATCH 02/14] sysfs: add existence-check helpers for lazy populate races Pavol Sakac
2026-07-02 17:40 ` [RFC PATCH 03/14] sysfs: introduce sysfs_kf_syscall_ops dispatching to kobj_type Pavol Sakac
2026-07-02 17:40 ` [RFC PATCH 04/14] driver core: add struct sysfs_lazy_state and device_set_sysfs_lazy() Pavol Sakac
2026-07-02 17:51 ` Pavol Sakac [this message]
2026-07-02 17:51   ` [RFC PATCH 06/14] driver core: wire device_ktype populate to walker Pavol Sakac
2026-07-02 17:51   ` [RFC PATCH 07/14] driver core: migrate device sysfs to device_sysfs_entry table Pavol Sakac
2026-07-02 17:51   ` [RFC PATCH 08/14] PCI/sysfs: migrate to device_sysfs_entry, defer physfn symlink Pavol Sakac
2026-07-02 17:51   ` [RFC PATCH 09/14] iommu: lazy-populate iommu_group reserved_regions/type attrs Pavol Sakac
2026-07-10 14:19     ` Greg Kroah-Hartman
2026-07-02 17:51   ` [RFC PATCH 10/14] PCI/IOV: opt SR-IOV VFs into sysfs_lazy Pavol Sakac
2026-07-02 17:51   ` [RFC PATCH 11/14] vfio: opt vfio-dev and VFIO group devices " Pavol Sakac
2026-07-02 17:51   ` [RFC PATCH 12/14] driver core: test: add KUnit tests for device_sysfs_apply Pavol Sakac
2026-07-02 17:51   ` [RFC PATCH 13/14] Documentation: add lazy sysfs initialisation and device_sysfs_entry docs Pavol Sakac
2026-07-02 17:51   ` [RFC PATCH 14/14] selftests: sysfs-lazy: add tests for lazy sysfs initialization Pavol Sakac
2026-07-10 14:16 ` [RFC PATCH 00/14] driver core: defer per-VF sysfs creation for fast SR-IOV bring-up Greg Kroah-Hartman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260702175114.24659-1-sakacpav@amazon.de \
    --to=sakacpav@amazon.de \
    --cc=dakr@kernel.org \
    --cc=dmatlack@google.com \
    --cc=driver-core@lists.linux.dev \
    --cc=dwmw@amazon.co.uk \
    --cc=graf@amazon.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=kexec@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=nh-open-source@amazon.com \
    --cc=pasha.tatashin@soleen.com \
    --cc=pratyush@kernel.org \
    --cc=rafael@kernel.org \
    --cc=rppt@kernel.org \
    --cc=skhawaja@google.com \
    --cc=tj@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox