Chinaunix首页 | 论坛 | 博客
  • 博客访问: 438750
  • 博文数量: 99
  • 博客积分: 65
  • 博客等级: 民兵
  • 技术积分: 1012
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-20 16:30
个人简介

linux kernel 工程师

文章分类

全部博文(99)

文章存档

2018年(5)

2017年(12)

2016年(27)

2015年(10)

2014年(43)

2012年(2)

我的朋友

分类: LINUX

2016-12-25 14:11:28

回顾do_lookup里面的情景:
比如说要查找"/mnt/tmp1"里面的tmp1分量, __d_lookup在内存里面没有查找到。
这时需要分配一个dentry的数据结构。分配的函数就是d_alloc。

函数参数:
struct dentry * parent,指向的是"/mnt”的dentry
qstr *name,保存有"tmp1"分量的hash值,len=3,name=”tmp1".


点击(此处)折叠或打开

  1. /**
  2.  * d_alloc    -    allocate a dcache entry
  3.  * @parent: parent of entry to allocate
  4.  * @name: qstr of the name
  5.  *
  6.  * Allocates a dentry. It returns %NULL if there is insufficient memory
  7.  * available. On a success the dentry is returned. The name passed in is
  8.  * copied and the copy passed in may be reused after this call.
  9.  */
  10.  
  11. struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
  12. {
  13.     struct dentry *dentry;
  14.     char *dname;

    /* 分配一块内存
    dentry结构里面有一个d_iname[DNAME_INLINE_LEN_MIN]
数组 */

  1.     dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL);
  2.     if (!dentry)
  3.         return NULL;

    /* 如果路径分量name->name字符串太长,超过了DNAME_INLINE_LEN_MIN(128字节),那么dentry->d_iname就不能用来保存name->name了。需要另外分配一块内存来 */

  1.     if (name->len > DNAME_INLINE_LEN-1) {
  2.         dname = kmalloc(name->len + 1, GFP_KERNEL);
  3.         if (!dname) {
  4.             kmem_cache_free(dentry_cache, dentry);
  5.             return NULL;
  6.         }
  7.     } else {
  8.         dname = dentry->d_iname;
  9.     }    
  10.     dentry->d_name.name = dname;

    /* 将qstr *name的内容copy过来 */

  1.     dentry->d_name.len = name->len;
  2.     dentry->d_name.hash = name->hash;
  3.     memcpy(dname, name->name, name->len);
  4.     dname[name->len] = 0;

    /* dentry刚刚分配的状态是DCACHE_UNHASHED,因为它还没有链入dentry_hashtable[dentry->d_name.hash]的hash链,等dentry在文件系统的lookup函数中填充完毕后,会将dentry通过d_hash链入hashtdentry_able[dentry->d_name.hash],链入以后才取消DCACHE_UNHASHED标志
比如procfs的lookup函数proc_root_lookup

调用流程:
proc_root_lookup->
    proc_lookup->
        proc_lookup_de

proc_lookup_de函数里面,通过d_add将dentry链入hashtdentry_able[dentry->d_name.hash],并取消dentry的DCACHE_UNHASHED标志
    if (inode) {
        dentry->d_op = &proc_dentry_operations;
        d_add(dentry, inode);
        return NULL;
    }



*/

  1.     atomic_set(&dentry->d_count, 1);
  2.     dentry->d_flags = DCACHE_UNHASHED;
  3.     spin_lock_init(&dentry->d_lock);
  4.     dentry->d_inode = NULL;
  5.     dentry->d_parent = NULL;
  6.     dentry->d_sb = NULL;
  7.     dentry->d_op = NULL;
  8.     dentry->d_fsdata = NULL;
  9.     dentry->d_mounted = 0;
  10.     INIT_HLIST_NODE(&dentry->d_hash);
  11.     INIT_LIST_HEAD(&dentry->d_lru);
  12.     INIT_LIST_HEAD(&dentry->d_subdirs);
  13.     INIT_LIST_HEAD(&dentry->d_alias);

    /* dentry在分配时已经设置其parent entry */

  1.     if (parent) {
  2.         dentry->d_parent = dget(parent);
  3.         dentry->d_sb = parent->d_sb;
  4.     } else {
  5.         INIT_LIST_HEAD(&dentry->d_u.d_child);
  6.     }

  7.     /* dentry在分配时还要通过d_u.d_child链入parent 的d_subdirs中 */
  8.     spin_lock(&dcache_lock);
  9.     if (parent)
  10.         list_add(&dentry->d_u.d_child, &parent->d_subdirs);
  11.     dentry_stat.nr_dentry++;
  12.     spin_unlock(&dcache_lock);

  13.     return dentry;
  14. }

阅读(1015) | 评论(0) | 转发(0) |
0

上一篇:do_lookup

下一篇:link_path_walk

给主人留下些什么吧!~~