歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> 關於Linux >> uclinux-2008R1-RC8(bf561)到VDSP5的移植(47):d_alloc引出的問題

uclinux-2008R1-RC8(bf561)到VDSP5的移植(47):d_alloc引出的問題

日期:2017/3/3 16:43:28   编辑:關於Linux

在內核中有一個d_alloc函數,用於分配一個dentry的結構體並進行初始化。

/**
 * d_alloc    -    allocate a dcache entry
 * @parent: parent of entry to allocate
 * @name: qstr of the name
 *
 * Allocates a dentry. It returns %NULL if there is insufficient memory
 * available. On a success the dentry is returned. The name passed in is
 * copied and the copy passed in may be reused after this call.
 */

struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
{
     struct dentry *dentry;
     char *dname;

     dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL);
     if (!dentry)
         return NULL;

     if (name->len > DNAME_INLINE_LEN-1) {
         dname = kmalloc(name->len + 1, GFP_KERNEL);
         if (!dname) {
              kmem_cache_free(dentry_cache, dentry);
              return NULL;
         }
     } else {
         dname = dentry->d_iname;
     }  
     dentry->d_name.name = dname;

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

     dentry->d_count.lock = 0; // 新加的語句
     atomic_set(&dentry->d_count, 1);
     dentry->d_flags = DCACHE_UNHASHED;
     spin_lock_init(&dentry->d_lock);
     dentry->d_inode = NULL;
     dentry->d_parent = NULL;
     dentry->d_sb = NULL;
     dentry->d_op = NULL;
     dentry->d_fsdata = NULL;
     dentry->d_mounted = 0;
#ifdef CONFIG_PROFILING
     dentry->d_cookie = NULL;
#endif
     INIT_HLIST_NODE(&dentry->d_hash);
     INIT_LIST_HEAD(&dentry->d_lru);
     INIT_LIST_HEAD(&dentry->d_subdirs);
     INIT_LIST_HEAD(&dentry->d_alias);

     if (parent) {
         dentry->d_parent = dget(parent);
         dentry->d_sb = parent->d_sb;
     } else {
         INIT_LIST_HEAD(&dentry->d_u.d_child);
     }

     spin_lock(&dcache_lock);
     if (parent)
         list_add(&dentry->d_u.d_child, &parent->d_subdirs);
     dentry_stat.nr_dentry++;
     spin_unlock(&dcache_lock);

     return dentry;
}

在原始文件中,沒有紅色標出的語句。

d_count是dentry結構體中的一個成員,其類型是atomic_t,在原內核中不支持SMP,所以沒有什麼問題,但是為了使用SMP,將atomic_t的定義改為了:

typedef struct {
     int counter;
     testset_t lock;
} atomic_t;

其中lock是為了雙核同步而設置的,要求初始值為0,但是在原始文件中並沒有對它進行初始化,故而很可能造成鎖定的失敗。再深入一點思考,突然發現這種初始化的方法似乎特別愚笨,每次都必須對lock成員進行特別的操作。不過在內核中每次初始化時都會調用atomic_set這個宏,在此修改這個宏,使之成為:

static __inline__ void atomic_set(atomic_t * v, int value)
{
     v->counter = value;
     v->lock = 0;
}

Copyright © Linux教程網 All Rights Reserved