文件/fs/sysfs/dir.c
/**
* sysfs_create_dir_ns - 用命名空间tags为一个object创建directory
* @kobj: 要创建目录的object
* @ns: 要用到的命名空间tag
*/
int sysfs_create_dir_ns(struct kobject *kobj, const void *ns)
{
struct kernfs_node *parent, *kn;
BUG_ON(!kobj);
if (kobj->parent)
parent = kobj->parent->sd;
else
parent = sysfs_root_kn;
if (!parent)
return -ENOENT;
kn = kernfs_create_dir_ns(parent, kobject_name(kobj), S_IRWXU | S_IRUGO | S_IXUGO, kobj, ns);
if (IS_ERR(kn)) {
if (PTR_ERR(kn) == -EEXIST)
sysfs_warn_dup(parent, kobject_name(kobj));
return PTR_ERR(kn);
}
kobj->sd = kn;
return 0;
}
我非常遗憾的发现这里出现了一个kernfs_node,这个在3.13版本的内核中还没有,3.13版本内核中这个结构体叫做sysfs_dirent
看起来所谓的创建一个文件夹就是新建一个kernfs_node
文件/fs/kernfs/dir.c
/**
* kernfs_create_dir_ns - 创建一个目录
* @parent: 要创建目录的父目录
* @name: 新目录的名称
* @mode: 新目录的mode(权限)
* @priv: opaque data associated with the new directory伴随着该目录的半透明数据?
* @ns: 该目录的可选命名空间tag
*
* Returns the created node on success, ERR_PTR() value on failure.
*/
struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent,
const char *name, umode_t mode,
void *priv, const void *ns)
{
struct kernfs_addrm_cxt acxt;
struct kernfs_node *kn;
int rc;
/* allocate */
kn = kernfs_new_node(parent, name, mode | S_IFDIR, KERNFS_DIR);
if (!kn)
return ERR_PTR(-ENOMEM);
kn->dir.root = parent->dir.root;
kn->ns = ns;
kn->priv = priv;
/* link in */
kernfs_addrm_start(&acxt);
rc = kernfs_add_one(&acxt, kn);
kernfs_addrm_finish(&acxt);
if (!rc)
return kn;
kernfs_put(kn);
return ERR_PTR(rc);
}
struct kernfs_node *kernfs_new_node(struct kernfs_node *parent,
const char *name, umode_t mode,
unsigned flags)
{
struct kernfs_node *kn;
kn = __kernfs_new_node(kernfs_root(parent), name, mode, flags);
if (kn) {
kernfs_get(parent);
kn->parent = parent;
}
return kn;
}
文件/fs/kernfs/dir.c
static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
const char *name, umode_t mode,
unsigned flags)
{
char *dup_name = NULL;
struct kernfs_node *kn;
int ret;
if (!(flags & KERNFS_STATIC_NAME)) {
name = dup_name = kstrdup(name, GFP_KERNEL);//字符串复制,把name复制为dup_name
if (!name)
return NULL;
}
kn = kmem_cache_zalloc(kernfs_node_cache, GFP_KERNEL); //高速缓存内存,用于可能频繁分配和释放的地方
if (!kn)
goto err_out1;
ret = ida_simple_get(&root->ino_ida, 1, 0, GFP_KERNEL); //这里是分配一个ID,好吧,先放这里,以后再回来深入研究
if (ret < 0)
goto err_out2;
kn->ino = ret;
atomic_set(&kn->count, 1);
atomic_set(&kn->active, 0);
kn->name = name;
kn->mode = mode;
kn->flags = flags | KERNFS_REMOVED;
return kn;
err_out2:
kmem_cache_free(kernfs_node_cache, kn);
err_out1:
kfree(dup_name);
return NULL;
}