在內核中有一個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;
}
uclinux-2008R1-RC8(bf561)到VDSP5的移植(55):filemap.c的問題
uclinux-2008R1-RC8(bf561)到VDSP5的移植(54):initramfs的問題
uclinux-2008R1-RC8(bf561)到VDSP5的移植(53):reboot.c的問題
uclinux-2008R1-RC8(bf561)到VDSP5的移植(52):cache.s的問題
uclinux-2008R1-RC8(bf561)到VDSP5的移植(50):jiffies_64的定義問題
uclinux-2008R1-RC8(bf561)到VDSP5的移植(49):kernel_thread_helper的問題