open调用创建inode的过程

open调用创建inode的过程

Content #

如果创建一个新文件,会调用 open 函数,并且参数会有 O_CREAT。这表示当文件找不到的时候,就需要创建一个。open 是一个系统调用,在内核里面会调用 sys_open,定义如下:

SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
{
  if (force_o_largefile())
    flags |= O_LARGEFILE;

  return do_sys_open(AT_FDCWD, filename, flags, mode);
}

调用链:

do_sys_open-> do_filp_open->path_openat->do_last->lookup_open

这个调用链的逻辑是,要打开一个文件,先要根据路径找到文件夹。如果发现文件夹下面没有这个文件,同时又设置了 O_CREAT,就说明要在这个文件夹下面创建一个文件,那就需要一个新的 inode。

static int lookup_open(struct nameidata *nd, struct path *path,
      struct file *file,
      const struct open_flags *op,
      bool got_write, int *opened)
{
......
  if (!dentry->d_inode && (open_flag & O_CREAT)) {
......
    error = dir_inode->i_op->create(dir_inode, dentry, mode,
            open_flag & O_EXCL);
......
  }
......
}

想要创建新的 inode,就要调用 dir_inode,也就是文件夹的 inode 的 create 函数。它的具体定义是这样的:

const struct inode_operations ext4_dir_inode_operations = {
  .create    = ext4_create,
  .lookup    = ext4_lookup,
  .link    = ext4_link,
  .unlink    = ext4_unlink,
  .symlink  = ext4_symlink,
  .mkdir    = ext4_mkdir,
  .rmdir    = ext4_rmdir,
  .mknod    = ext4_mknod,
  .tmpfile  = ext4_tmpfile,
  .rename    = ext4_rename2,
  .setattr  = ext4_setattr,
  .getattr  = ext4_getattr,
  .listxattr  = ext4_listxattr,
  .get_acl  = ext4_get_acl,
  .set_acl  = ext4_set_acl,
  .fiemap         = ext4_fiemap,
};

create 操作调用的是 ext4_create。

接下来的调用链是这样的:

ext4_create->ext4_new_inode_start_handle->__ext4_new_inode

在 __ext4_new_inode 函数中,会创建新的 inode。

struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
             umode_t mode, const struct qstr *qstr,
             __u32 goal, uid_t *owner, __u32 i_flags,
             int handle_type, unsigned int line_no,
             int nblocks)
{
......
inode_bitmap_bh = ext4_read_inode_bitmap(sb, group);
......
ino = ext4_find_next_zero_bit((unsigned long *)
                inode_bitmap_bh->b_data,
                EXT4_INODES_PER_GROUP(sb), ino);
......
}

从文件系统里面读取 inode 位图,然后找到下一个为 0 的 inode,就是空闲的 inode。

Viewpoints #

From #

28 | 硬盘文件系统:如何最合理地组织档案库的文档?