文件系统如何管理目录和文件(4)lookup_one_len

装载:http://book.51cto.com/art/201401/427827.htm

然后调用lookup_one_len获得一个dentry结构。lookup_one_len函数首先在父目录下根据名字查找dentry结构,如果存在同名的dentry结构就返回指针,如果不存在就创建一个dentry。lookup_one_len的代码如代码清单2-16所示
代码清单2-16 查找同名dentry的lookup_one_len函数

    struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)  
1272    {  
    ……/*省略参数定义*/  
1277    this.name = name;  
1278    this.len = len;  
1279    if (!len)  
1280        goto access;  
1281   /*这里根据名字计算hasn值,看看是怎么计算的*/  
1282    hash = init_name_hash();  
1283    while (len--) {  
1284        c = *(const unsigned char *)name++;  
1285        if (c == '/' || c == '\0')  
1286            goto access;  
1287        hash = partial_name_hash(c, hash);  
1288    }  
1289    this.hash = end_name_hash(hash);  
1290  
1291    return __lookup_hash(&this, base, NULL); 

第1282~1289行的作用是计算名字的hash值。因为初始hash函数init_name_hash和最终hash函数end_name_hash都不执行任何的计算,所以最终得到的hash值是将名字中的每个字符做固定的数学运算得到的。

__lookup_hash函数是通过hash值查找同名字的dentry结构,它的代码如代码清单2-17所示。

代码清单2-17 在hash链表中查找的__lookup_hash函数

static struct dentry * __lookup_hash(struct qstr *name,  
struct dentry * base, struct nameidata *nd)  
{  
  struct dentry * dentry;  
  struct inode *inode;  
  int err;  
 
  inode = base->d_inode;  
  err = permission(inode, MAY_EXEC, nd);  
  dentry = ERR_PTR(err);  
  if (err)  
      goto out;  
 
  /*  
   * See if the low-level filesystem might want  
   * to use its own hash..  
   */  
  if (base->d_op && base->d_op->d_hash) {  
      err = base->d_op->d_hash(base, name);  
      dentry = ERR_PTR(err);  
      if (err < 0)  
          goto out;  
  } 

_lookup_hash函数第一部分是检查inode的权限,然后检查文件系统是否提供了特有的hash函数,如果有hash函数,则调用重新计算hash值

dentry = cached_lookup(base, name, nd);  
if (!dentry) {  
      /*如果没有找到。说明这个目录不存在,则创建一个dentry*/  
      struct dentry *new = d_alloc(base, name);  
      dentry = ERR_PTR(-ENOMEM);  
      if (!new)  
          goto out;  
      dentry = inode->i_op->lookup(inode, new, nd);  
      if (!dentry)  
          dentry = new;  
      else  
          dput(new);  
  }  
out:  
  return dentry;  
} 

cached_lookup在dentry cache里面查找同名的dentry结构,如果返回为空,说明不存在同名的dentry结构,那么调用d_alloc创建一个新的dentry结构。

创建dentry结构完成后,需要再次调用文件系统的lookup查找是否有同名的dentry存在。这样做为了防止同名的dentry已经被其他用户提前创建了。

cached_lookup函数的代码如代码清单2-18所示。
代码清单2-18 cached_lookup函数

static struct dentry * cached_lookup(struct dentry * parent,  
struct qstr * name, struct nameidata *nd)  
{  
  struct dentry * dentry = __d_lookup(parent, name);  
 
  /* lockess __d_lookup may fail due to concurrent d_move()  
   * in some unrelated directory, so try with d_lookup  
   */  
  /*注意原来的解释,为何再次查找?因为要防止一个并发的move操作*/  
  if (!dentry)  
       dentry = d_lookup(parent, name);  
       ……/*省略校验的代码*/  
} 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值