求linux注释 发表于 2014-12-15 10:49

求大牛帮忙解释一下 ext2_find_shared() 这个函数。。

本帖最后由 求linux注释 于 2014-12-15 13:46 编辑

这函数真是头疼死了,又没有相关的书籍可以参考,网上关于这段代码的资料也少到几乎没有。
我把对这段代码的疑问全写在注释里了,所幸的是这段代码很短,求懂这东西的大牛帮忙。。{:3_200:}static Indirect *ext2_find_shared(struct inode *inode,
                                int depth,
                                int offsets,
                                Indirect chain,
                                __le32 *top)
{
        Indirect *partial, *p;
        int k, err;
        *top = 0;
   
        for (k = depth; k > 1 && !offsets; k--);
      //这里是要重新计算深度?

        partial = ext2_get_branch(inode, k, offsets, chain, &err);
      //使用 offsets 数组初始化 chain 数组
   
        if (!partial)
      //如果 ext2_get_branch() 返回空,就说明成功
              partial = chain + k-1;

      /* partial在上面应该已指向了 chain 数组内最后一个间接块对应的对象,他的 key 应该存放着数据块的块号 */

        write_lock(&EXT2_I(inode)->i_meta_lock);
   
        if (!partial->key && //partial->key保存的应该是数据块的块号,那么这里应该就是如果没有映射的数据块
      *partial->p) {   //这里感到很奇怪,*p保存的应该也是数据块的块号,那为什么上面判断的 key 是 0 而这里又要判断为真呢?
      
                write_unlock(&EXT2_I(inode)->i_meta_lock);      
                goto no_top;
        }
   
        for (p=partial; p>chain && all_zeroes((__le32*)p->bh->b_data,p->p); p--);
      //这个循环是什么意思?或者说为什么要找出 b_data ~ p 不全为空的块?

        if (p == chain + k - 1 && p > chain) {
      //???由于不知道上面那个循环是什么意思,这里也看不懂
      
                p->p--;
                //递减?为什么要递减??
      } else {
      //???
      
              *top = *p->p;
              //取出下一级间接块的块号并作为返回值返回给上级函数
              *p->p = 0;
      }
      
        write_unlock(&EXT2_I(inode)->i_meta_lock);

        while(partial > p)
      //遍历释放 partial ~ p 所有块缓冲区
       {
                brelse(partial->bh);
                partial--;
       }
no_top:
        return partial;
}

hnwyllmm 发表于 2014-12-16 13:45

if (!partial->key && //partial->key保存的应该是数据块的块号,那么这里应该就是如果没有映射的数据块
      *partial->p) {   //这里感到很奇怪,*p保存的应该也是数据块的块号,那为什么上面判断的 key 是 0 而这里又要判断为真呢?

我说下关于这个问题的个人观点:
源代码中ext2_get_branch中读取块号到Indirect后,会调用verify_chain来验证这块数据是否改变过:
static inline int verify_chain(Indirect *from, Indirect *to)
{
        while (from <= to && from->key == *from->p) // 这里就是比较key和p是否相等
                from++;
        return (from > to);
}

求linux注释 发表于 2014-12-16 17:27

本帖最后由 求linux注释 于 2014-12-16 17:27 编辑

回复 2# hnwyllmm


verify_chain() 和这个判断条件不同啊。
verify_chain() 只要 key 和 *p 不相等就会立刻退出并返回一个 0 值,而这里是要求 key == 0 且 *p != 0 才会退出。

hnwyllmm 发表于 2014-12-17 13:29

add_chain(++p, bh, (__le32*)bh->b_data + *++offsets);
partial->p是在这个函数里面赋值的,就是partial->p指向了buffer_head的内容,buffer_header可以由程序改写的
如果partial->key是0,表示没有有效的block,partial->p是磁盘数据在内存中的缓存,程序修改时先修改这个缓存,如果说key是0,*p是有效值,应该是在操作的过程中有程序修改了这个文件的block
描述的比较混乱,也没有百分百把握,楼主权当参考吧,如果有更好的解释,希望可以共享一下,共同学习

求linux注释 发表于 2014-12-17 21:43

回复 4# hnwyllmm

很有道理,我现在也觉得他是之后又被某个进程修改了。
页: [1]
查看完整版本: 求大牛帮忙解释一下 ext2_find_shared() 这个函数。。