linux 文件系统 fd与file*之间的关系

给定如下一定情况:

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的其他结构全部串起来。

猜你喜欢

转载自www.cnblogs.com/10087622blog/p/9540565.html