给定如下一定情况:
crash> files PID: 7739 TASK: ffff8817facd2100 CPU: 11 COMMAND: "slabtop" ROOT: / CWD: / FD FILE DENTRY INODE TYPE PATH 0 ffff881810117680 ffff880c115a5cc0 ffff881811fa7a78 CHR /dev/null 1 ffff880af6bf2200 ffff88180c64e440 ffff88180dc02438 REG /dev/shm/zxdfs/moni_sys.log 2 ffff88180ef619c0 ffff881811a263c0 ffff880c0eabf118 CHR /dev/console 3 ffff880c9ddbba80 ffff8818014b1540 ffff88100a8117f8 REG /proc/slabinfo
比如对于fd为3,如何快速获取对应的file* 信息?
对于fd来说,一般会根据 fget_light-->fcheck_files来获取file*,(注意,这里无关fget 还是 fget_light,因为最终都是调用fcheck_files)
结构就是当前进程task中的:
struct files_struct *files = current->files;
然后根据这个files_struct成员,找到fdt指针:
static inline struct file * fcheck_files(struct files_struct *files, unsigned int fd) { struct file * file = NULL; struct fdtable *fdt = files_fdtable(files); if (fd < fdt->max_fds) file = rcu_dereference(fdt->fd[fd]); return file; }
fdt中的fd数组中,就是按照fd下标存放的file*指针,如下:
crash> task PID: 7739 TASK: ffff8817facd2100 CPU: 11 COMMAND: "slabtop" crash> struct task_struct.files ffff8817facd2100 files = 0xffff88130c8bec00 crash> struct fdtable.fd 0xffff88126d2f4900 fd = 0xffff880c976ad000 crash> rd 0xffff880c976ad000 4 ffff880c976ad000: ffff881810117680 ffff880af6bf2200 .v......."...... ffff880c976ad010: ffff88180ef619c0 ffff880c9ddbba80 ................
所以对于fd为3来说,取到的file*指针就是ffff880c9ddbba80 ,我们来验证一下这个file*指针:
crash> struct file.f_path.dentry ffff880c9ddbba80 f_path.dentry = 0xffff8818014b1540 crash> struct dentry.d_iname 0xffff8818014b1540 d_iname = "slabinfo\000_offset\000ndler.py\000m\000\000\000\000"
d_iname就是对应的文件路径最后一段文件名,说明我们取的file*指针是对了,有了file* 指针,我们就可以将对应的vfs的其他结构全部串起来。