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,
};
@@ -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;
@@ -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
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,