diff mbox series

[2/2] configfs: Add mechanism to prevent item/group deletion

Message ID b163d92b-5d5a-42fb-bc49-5e55953db795@bootlin.com (mailing list archive)
State New
Headers show
Series [1/2] configfs: Add mechanism to prevent symlink deletion | expand

Commit Message

Louis Chauvet Feb. 28, 2025, 2:43 p.m. UTC
Introduce a new mechanism in configfs to prevent the deletion of certain 
item/group.
This is particularly useful in scenarios where userspace should not be 
allowed
to modify the configfs structure under some conditions, such as in VKMS.

Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
  drivers/gpu/drm/vkms/vkms_configfs.c | 21 +++++++++++++++++++++
  fs/configfs/dir.c                    |  8 +++++++-
  include/linux/configfs.h             |  1 +
  3 files changed, 29 insertions(+), 1 deletion(-)

*item);
  	void (*drop_item)(struct config_group *group, struct config_item *item);
  	bool (*is_visible)(struct config_item *item, struct 
configfs_attribute *attr, int n);
  	bool (*is_bin_visible)(struct config_item *item, struct 
configfs_bin_attribute *attr,
diff mbox series

Patch

diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c 
b/drivers/gpu/drm/vkms/vkms_configfs.c
index 8a7d954399e9..0a196a28ed4a 100644
--- a/drivers/gpu/drm/vkms/vkms_configfs.c
+++ b/drivers/gpu/drm/vkms/vkms_configfs.c
@@ -393,9 +393,30 @@  static struct configfs_item_operations 
plane_item_operations = {
  	.release	= &plane_release,
  };

+int allow_drop_plane_group(struct config_group *group, struct 
config_item *item)
+{
+	struct vkms_configfs_plane *plane;
+	bool enabled;
+
+	plane = plane_item_to_vkms_configfs_plane(item);
+
+	mutex_lock(&plane->dev->lock);
+	enabled = plane->dev->enabled;
+	mutex_unlock(&plane->dev->lock);
+
+	if (enabled)
+		return -EBUSY;
+	return 0;
+}
+
+static struct configfs_group_operations plane_group_operation ={
+	.allow_drop_item = &allow_drop_plane_group,
+};
+
  static const struct config_item_type plane_item_type = {
  	.ct_attrs	= plane_item_attrs,
  	.ct_item_ops	= &plane_item_operations,
+	.ct_group_ops   = &plane_group_operation,
  	.ct_owner	= THIS_MODULE,
  };

diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
index 7d10278db30d..a103196af0f9 100644
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -1544,7 +1544,13 @@  static int configfs_rmdir(struct inode *dir, 
struct dentry *dentry)

  	/* Drop reference from above, item already holds one. */
  	config_item_put(parent_item);
-
+	if (item->ci_type && item->ci_type->ct_group_ops && 
item->ci_type->ct_group_ops->allow_drop_item) {
+		ret = 
item->ci_type->ct_group_ops->allow_drop_item(to_config_group(parent_item), 
item);
+		if (ret) {
+			config_item_put(item);
+			return ret;
+		}
+	}
  	if (item->ci_type)
  		dead_item_owner = item->ci_type->ct_owner;

diff --git a/include/linux/configfs.h b/include/linux/configfs.h
index 7fc52a78d6cd..92933397590d 100644
--- a/include/linux/configfs.h
+++ b/include/linux/configfs.h
@@ -216,6 +216,7 @@  struct configfs_group_operations {
  	struct config_item *(*make_item)(struct config_group *group, const 
char *name);
  	struct config_group *(*make_group)(struct config_group *group, const 
char *name);
  	void (*disconnect_notify)(struct config_group *group, struct 
config_item *item);
+	int (*allow_drop_item)(struct config_group *group, struct config_item