Linux那些事儿之我是Sysfs(11)sysfs 创建普通文件

来源:互联网 发布:python socket 修改ttl 编辑:程序博客网 时间:2024/05/17 05:58
sysfs文件系统中,普通文件对应于kobject中的属性。用sysfs_create_file(),参数如下:

sysfs_create_file(struct kobject * kobj, const struct attribute * attr)

传给它的参数是kobj和attr,其中,kobject对应的是文件夹,attribute对应的是该文件夹下的文件。

include/linux/sysfs.h

static inline int __must_check sysfs_create_file(struct kobject *kobj, const struct attribute *attr){return sysfs_create_file_ns(kobj, attr, NULL);}


它直接调用sysfs_create_file_ns()

fs/sysfs/file.c


int sysfs_create_file_ns(struct kobject *kobj, const struct attribute *attr, const void *ns){BUG_ON(!kobj || !kobj->sd || !attr);return sysfs_add_file_mode_ns(kobj->sd, attr, false, attr->mode, ns);}

fs/sysfs/file.c
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;elseops = &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;elseops = &sysfs_file_kfops_empty;size = battr->size;}#ifdef CONFIG_DEBUG_LOCK_ALLOCif (!attr->ignore_lockdep)key = attr->key ?: (struct lock_class_key *)&attr->skey;#endifkn = __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;}

fs/kernfs/file.c

struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, const char *name, umode_t mode, loff_t size, const struct kernfs_ops *ops, void *priv, const void *ns, bool name_is_static, struct lock_class_key *key){struct kernfs_node *kn;unsigned flags;int rc;flags = KERNFS_FILE;if (name_is_static)flags |= KERNFS_STATIC_NAME;kn = kernfs_new_node(parent, name, (mode & S_IALLUGO) | S_IFREG, flags);if (!kn)return ERR_PTR(-ENOMEM);kn->attr.ops = ops;kn->attr.size = size;kn->ns = ns;kn->priv = priv;#ifdef CONFIG_DEBUG_LOCK_ALLOCif (key) {lockdep_init_map(&kn->dep_map, "s_active", key, 0);kn->flags |= KERNFS_LOCKDEP;}#endif/* * kn->attr.ops is accesible only while holding active ref.  We * need to know whether some ops are implemented outside active * ref.  Cache their existence in flags. */if (ops->seq_show)kn->flags |= KERNFS_HAS_SEQ_SHOW;if (ops->mmap)kn->flags |= KERNFS_HAS_MMAP;rc = kernfs_add_one(kn);if (rc) {kernfs_put(kn);return ERR_PTR(rc);}return kn;}



sysfs_create_file()仅仅是调用了kernfs_new_node()创建了一个kernfs_node结构。
0 0
原创粉丝点击