int sysfs_add_file_mode_ns(struct kernfs_node *parent, const struct attribute *attr, bool is_bin, umode_t mode, const void *ns) { struct lock_class_key *key = NULL; const struct kernfs_ops *ops; struct kernfs_node *kn; loff_t size; if (!is_bin) { struct kobject *kobj = parent->priv; const struct sysfs_ops *sysfs_ops = kobj->ktype->sysfs_ops; /* every kobject with an attribute needs a ktype assigned */ if (WARN(!sysfs_ops, KERN_ERR "missing sysfs attribute operations for kobject: %s\n", kobject_name(kobj))) return -EINVAL; if (sysfs_ops->show && sysfs_ops->store) ops = &sysfs_file_kfops_rw; else if (sysfs_ops->show) ops = &sysfs_file_kfops_ro; else if (sysfs_ops->store) ops = &sysfs_file_kfops_wo; else ops = &sysfs_file_kfops_empty; size = PAGE_SIZE; } else { struct bin_attribute *battr = (void *)attr; if (battr->mmap) ops = &sysfs_bin_kfops_mmap; else if (battr->read && battr->write) ops = &sysfs_bin_kfops_rw; else if (battr->read) ops = &sysfs_bin_kfops_ro; else if (battr->write) ops = &sysfs_bin_kfops_wo; else ops = &sysfs_file_kfops_empty; size = battr->size; } #ifdef CONFIG_DEBUG_LOCK_ALLOC if (!attr->ignore_lockdep) key = attr->key ?: (struct lock_class_key *)&attr->skey; #endif kn = __kernfs_create_file(parent, attr->name, mode, size, ops, (void *)attr, ns, true, key); if (IS_ERR(kn)) { if (PTR_ERR(kn) == -EEXIST) sysfs_warn_dup(parent, attr->name); return PTR_ERR(kn); } return 0; }
static struct dentry *dslab_mount(struct file_system_type *fs_type, int flags, const char *unused_dev_name, void *data) { struct dentry *dentry = NULL; struct kernfs_root *kf_root; struct kernfs_node *kn; bool new_sb; kf_root = kernfs_create_root(&dslab_kf_syscall_ops, KERNFS_ROOT_CREATE_DEACTIVATED, NULL); if (IS_ERR(kf_root)) goto out; kn = __kernfs_create_file(kf_root->kn, "dslab", FS_MODE, 0, &dslab_kernfs_ops, NULL, NULL, NULL); if (IS_ERR(kn)) goto destroy_root; dentry = kernfs_mount(fs_type, flags, kf_root, FS_MAGIC, &new_sb); if (IS_ERR(dentry) || !new_sb) goto destroy_kn; kernfs_activate(kf_root->kn); goto out; destroy_kn: kernfs_remove_by_name(kf_root->kn, "dslab"); destroy_root: kernfs_destroy_root(kf_root); kf_root = NULL; out: return dentry; }