unlink라는 시스템 콜을 따라가면 아래 함수를 볼 수 있다.
여기서 lookup_hash(&nd) 함수를 좀 파고들어가 보자.
static long do_unlinkat(int dfd, const char __user *pathname)
{
int error;
char *name;
struct dentry *dentry;
struct nameidata nd;
struct inode *inode = NULL;
...
nd.flags &= ~LOOKUP_PARENT;
mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
dentry = lookup_hash(&nd);
}
아래와 같은 함수 호출 체인을 볼 수 있는데, 덴트리는 덴트리 캐시에서 덴트리 인스턴스를 찾는 것이다.
static struct dentry *lookup_hash(struct nameidata *nd)
{
return __lookup_hash(&nd->last, nd->path.dentry, nd);
}
static struct dentry *__lookup_hash(struct qstr *name,
struct dentry *base, struct nameidata *nd)
{
bool need_lookup;
struct dentry *dentry;
dentry = lookup_dcache(name, base, nd, &need_lookup);
if (!need_lookup)
return dentry;
return lookup_real(base->d_inode, dentry, nd);
}
d_hash(parent, hash); 라는 함수를 호출해서 해시 테이블 포멧의 덴트리 캐시 리스트를 가져온다.
static struct dentry *lookup_dcache(struct qstr *name, struct dentry *dir,
struct nameidata *nd, bool *need_lookup)
{
struct dentry *dentry;
int error;
*need_lookup = false;
dentry = d_lookup(dir, name);
..
}
struct dentry *d_lookup(struct dentry *parent, struct qstr *name)
{
struct dentry *dentry;
unsigned seq;
do {
seq = read_seqbegin(&rename_lock);
dentry = __d_lookup(parent, name);
if (dentry)
break;
} while (read_seqretry(&rename_lock, seq));
return dentry;
}
struct dentry *__d_lookup(struct dentry *parent, struct qstr *name)
{
unsigned int len = name->len;
unsigned int hash = name->hash;
const unsigned char *str = name->name;
struct hlist_bl_head *b = d_hash(parent, hash);
struct hlist_bl_node *node;
..
}
결국 *d_hash() 함수를 통해 덴트리 캐시를 처리하는 해시 테이블에 접근한다.
dentry_hashtable은 0xC17C8200에 있다.
(static struct hlist_bl_head *) dentry_hashtable = 0xC17C8200 = __bss_stop+0x9117E0 -> (
(struct hlist_bl_node *) first = 0x0 = -> NULL)
static inline struct hlist_bl_head *d_hash(const struct dentry *parent,
unsigned int hash)
{
hash += (unsigned long) parent / L1_CACHE_BYTES;
hash = hash + (hash >> D_HASHBITS);
return dentry_hashtable + (hash & D_HASHMASK);
}
0xC17C8200 란 주소와 이 리스트의 구조체만 가지고 리스트의 내용을 깔 수가 있는데 다음에 찾자.
'Core BSP 분석 > 리눅스 커널 핵심 분석' 카테고리의 다른 글
아이노드 오퍼레이션 - ext4 파일 시스템 (0) | 2023.05.05 |
---|---|
덴트리를 통해 시스템 콜 파일 패스 알아내기 (0) | 2023.05.05 |
슈퍼블록 객체 - ext4 파일시스템 (0) | 2023.05.05 |
GPIO - 리눅스 커널 (0) | 2023.05.05 |
wakelock - 안드로이드 (0) | 2023.05.05 |