Linux 内核文件系统dentry 您所在的位置:网站首页 Linux获取进程全路径 Linux 内核文件系统dentry

Linux 内核文件系统dentry

2024-07-15 15:02| 来源: 网络整理| 查看: 265

文章目录 一、简介1.1 __dentry_path1.2 prepend_name1.3 d_path 二、dmeo参考资料

一、简介 // linux-5.4.18/fs/d_path.c char *dentry_path_raw(struct dentry *dentry, char *buf, int buflen) { return __dentry_path(dentry, buf, buflen); } EXPORT_SYMBOL(dentry_path_raw);

该函数根据给定dentry返回其文件的完整路径。使用EXPORT_SYMBOL导出,可以直接调用。 关于dentry介绍请参考:Linux文件系统 struct dentry 结构体解析

1.1 __dentry_path /* * Write full pathname from the root of the filesystem into the buffer. */ static char *__dentry_path(struct dentry *d, char *buf, int buflen) { struct dentry *dentry; char *end, *retval; int len, seq = 0; int error = 0; if (buflen seq = 1; goto restart; } done_seqretry(&rename_lock, seq); if (error) goto Elong; return retval; Elong: return ERR_PTR(-ENAMETOOLONG); }

函数 __dentry_path,用于将文件系统根目录到给定的 dentry 的完整路径名写入缓冲区。

函数的参数包括要获取路径名的 dentry,存储路径名的缓冲区 buf,以及缓冲区的长度 buflen。

static int prepend(char **buffer, int *buflen, const char *str, int namelen) { *buflen -= namelen; if (*buflen d_parent)

在此期间,函数通过调用 prefetch 函数预取父节点,以提高性能。

_dentry_path 函数负责构建文件系统根目录到给定 dentry 对象的完整路径名,并将其存储在提供的缓冲区中。

注意_dentry_path 函数(即dentry_path_raw)对于传入的 buf 缓冲区,是从缓冲区的末尾开始构建dentry 对象的路径名,从buf的末尾往前构建dentry 对象的路径名,因此构建完成后,我们不能使用buf缓冲区来当作路径名,应该使用该函数的返回值来当作路径名,即调用者应该使用返回的指针来使用路径名,而不是传入的缓冲区指针。缓冲区的开头留下 0 字节(如果传入的缓冲区buf初始化为0),而路径名的开始通常会从缓冲区开始的部分字节偏移处开始的。

大概的过程就是,比如目录 /home/user01/c/:

//缓冲区buf末尾添加一个斜杠 (/) 和一个空字符 (\0),形成一个以斜杠结尾的字符串,以确保路径名的正确格式。

/\0 /c/\0 /user01/c/\0 /home/user01/c/\0 buf retval / /c/ /user01/c/ /home/user01/c/ buf retval

应该使用retval作为文件名而不是buf。

这里有一个疑问?如果是获取文件的完整路径,比如文件 /home/user01/c/text.txt,那么需要在text.txt的末尾添加一个斜杠 (/)?

如下图所示: 在这里插入图片描述

1.2 prepend_name /** * prepend_name - prepend a pathname in front of current buffer pointer * @buffer: buffer pointer * @buflen: allocated length of the buffer * @name: name string and length qstr structure * * With RCU path tracing, it may race with d_move(). Use READ_ONCE() to * make sure that either the old or the new name pointer and length are * fetched. However, there may be mismatch between length and pointer. * The length cannot be trusted, we need to copy it byte-by-byte until * the length is reached or a null byte is found. It also prepends "/" at * the beginning of the name. The sequence number check at the caller will * retry it again when a d_move() does happen. So any garbage in the buffer * due to mismatched pointer and length will be discarded. * * Load acquire is needed to make sure that we see that terminating NUL. */ static int prepend_name(char **buffer, int *buflen, const struct qstr *name) { const char *dname = smp_load_acquire(&name->name); /* ^^^ */ u32 dlen = READ_ONCE(name->len); char *p; *buflen -= dlen + 1; if (*buflen char *res = buf + buflen; struct path root; int error; /* * We have various synthetic filesystems that never get mounted. On * these filesystems dentries are never used for lookup purposes, and * thus don't need to be hashed. They also don't need a name until a * user wants to identify the object in /proc/pid/fd/. The little hack * below allows us to generate a name for these objects on demand: * * Some pseudo inodes are mountable. When they are mounted * path->dentry == path->mnt->mnt_root. In that case don't call d_dname * and instead have d_path return the mounted path. */ if (path->dentry->d_op && path->dentry->d_op->d_dname && (!IS_ROOT(path->dentry) || path->dentry != path->mnt->mnt_root)) return path->dentry->d_op->d_dname(path->dentry, buf, buflen); rcu_read_lock(); get_fs_root_rcu(current->fs, &root); error = path_with_deleted(path, &root, &res, &buflen); rcu_read_unlock(); if (error return 0; } printk("path = %s\n", path); free_page((unsigned long)buffer); return 0; } static void __exit hello_exit(void) { } module_init(hello_init); module_exit(hello_exit); MODULE_LICENSE("GPL");

需要注意的是,调用者调用dentry_path_raw应该使用返回的指针来作为路径名,而不是传入的缓冲区指针。路径名通常是从缓冲区的部分字节偏移处开始的,缓冲区的开头部分字节是无意义的。

/usr/bin/kmod buffer path

应当使用返回的指针path来作为路径名,而不是传入的缓冲区指针buffer。

# dmesg -c path = /usr/bin/kmod 参考资料

Linux 5.4.18

https://blog.csdn.net/qq_42931917/article/details/119803534



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有