Android文件IO路径小记

1 open创建文件

  • bionic libc.

bionic/libc/bionic/open.cpp

     open("my.txt", O_CREAT, mode) ->  __openat("my.txt", O_CREAT, mode)
  • system call

Arm

 arm:   bionic/libc/arch-arm/syscalls/__openat.S

ENTRY(__openat)
    mov     ip, r7
    ldr     r7, =__NR_openat
    swi     #0
    mov     r7, ip
    cmn     r0, #(MAX_ERRNO + 1)
    bxls    lr
    neg     r0, r0
    b       __set_errno_internal
END(__openat)

X86

x86:  bionic/libc/arch-x86/syscalls/__openat.S

ENTRY(__openat)
    pushl   %ebx
    pushl   %ecx
    pushl   %edx
    pushl   %esi
    mov     20(%esp), %ebx
    mov     24(%esp), %ecx
    mov     28(%esp), %edx
    mov     32(%esp), %esi
    movl    $__NR_openat, %eax
    int     $0x80
    cmpl    $-MAX_ERRNO, %eax
    jb      1f
    negl    %eax
    pushl   %eax
    call    __set_errno_internal
    addl    $4, %esp
1:
    popl    %esi
    popl    %edx
    popl    %ecx
    popl    %ebx
    ret
END(__openat)
  • kernel-3.4.0
fs/open.c
fs/namei.c

   SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)


   sys_open() -> do_sys_open() -> do_filp_open() -> path_openat() -> do_last() 
   
       do_last() {
           	/* Negative dentry, just create the file */
           if (!dentry->d_inode) {
		           umode_t mode = op->mode;
		           if (!IS_POSIXACL(dir->d_inode))
			             mode &= ~current_umask();
			             			         
			         error = vfs_create(dir->d_inode, dentry, mode, nd);
			     }
			     
			     
			     
       }
         

int vfs_create(struct inode* dir, 
                  struct dentry *dentry, 
                  umode_t mode, 
                  struct nameidata *nd)
{
    dir->i_op->create()
    
          fs/ext4/namei.c: ext4_create      
}


fs/ext4/inode.c

{
		inode->i_op = &ext4_dir_inode_operations;
		inode->i_fop = &ext4_dir_operations;

}


fs/ext4/namei.c

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,
	.rename		= ext4_rename,
	.setattr	= ext4_setattr,
#ifdef CONFIG_EXT4_FS_XATTR
	.setxattr	= generic_setxattr,
	.getxattr	= generic_getxattr,
	.listxattr	= ext4_listxattr,
	.removexattr	= generic_removexattr,
#endif
	.get_acl	= ext4_get_acl,
	.fiemap         = ext4_fiemap,
};


fs/ext4/dir.c


const struct file_operations ext4_dir_operations = {
	.llseek		= ext4_dir_llseek,
	.read		= generic_read_dir,
	.readdir	= ext4_readdir,
	.unlocked_ioctl = ext4_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl	= ext4_compat_ioctl,
#endif
	.fsync		= ext4_sync_file,
	.release	= ext4_release_dir,
};