• 文件操作接口的系统调用分析---SYSCALL_DEFINEx


    linux/arch/arm/kernel/call.S

    ...
    CALL(sys_read)
    CALL(sys_write)
    CALL(sys_open)
    CALL(sys_close)
    ...
     
    以read,write接口举栗子:
    linux/fs/read_write.c
     
    SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
    {
         struct file *file;
         ssize_t ret = -EBADF;
         int fput_needed;

         file = fget_light(fd, &fput_needed);     // 获取到  struct file
         if (file) {
              loff_t pos = file_pos_read(file);          //获取文件指针的position
              ret = vfs_read(file, buf, count, &pos);     // read file
              file_pos_write(file, pos);                    //保存文件指针的position
              fput_light(file, fput_needed);          // 写回 struct file
         }

         return ret;
    }
    SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
    #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
    #ifdef CONFIG_FTRACE_SYSCALLS
         ...
    #else
    #define SYSCALL_DEFINEx(x, sname, ...)                   
         __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
    #endif
     
    ===SYSCALL_DEFINEx(3, _read, unsigned int, fd, char __user *, buf, size_t, count)
    ===__SYSCALL_DEFINEx(3,_read, unsigned int, fd, char __user *, buf, size_t, count)
     
    #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
         ......
    #else /* CONFIG_HAVE_SYSCALL_WRAPPERS */

    #define SYSCALL_DEFINE(name) asmlinkage long sys_##name
    #define __SYSCALL_DEFINEx(x, name, ...)                        
         asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__))

    #endif /* CONFIG_HAVE_SYSCALL_WRAPPERS */
     
    ===asmlinkage long sys_read(__SC_DECL3(unsigned int, fd, char __user *, buf, size_t, count))
     
    #define __SC_DECL1(t1, a1)     t1 a1
    #define __SC_DECL2(t2, a2, ...) t2 a2, __SC_DECL1(__VA_ARGS__)
    #define __SC_DECL3(t3, a3, ...) t3 a3, __SC_DECL2(__VA_ARGS__)
    #define __SC_DECL4(t4, a4, ...) t4 a4, __SC_DECL3(__VA_ARGS__)
    #define __SC_DECL5(t5, a5, ...) t5 a5, __SC_DECL4(__VA_ARGS__)
    #define __SC_DECL6(t6, a6, ...) t6 a6, __SC_DECL5(__VA_ARGS__)
     
    ===__SC_DECL3(unsigned int, fd, char __user *, buf, size_t, count)
         ===>unsigned int fd, __SC_DECL2(char __user *, buf, size_t, count)
         ===>unsigned int fd, char __user * buf,  __SC_DECL1(size_t, count)
         ===>unsigned int fd, char __user * buf,  size_t count
     
    ===asmlinkage long sys_read(__SC_DECL3(unsigned int, fd, char __user *, buf, size_t, count))
         ===>asmlinkage long sys_read(unsigned int fd, char __user * buf,  size_t count)
     
    ===============

    ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
    {
         ssize_t ret;

         if (!(file->f_mode & FMODE_READ))     //权限检测
              return -EBADF;
         if (!file->f_op || (!file->f_op->read && !file->f_op->aio_read)) //检测fop是否存在,驱动read接口是否实现
              return -EINVAL;
         if (unlikely(!access_ok(VERIFY_WRITE, buf, count)))     //检测用户空间的buf是否可写
              return -EFAULT;

         ret = rw_verify_area(READ, file, pos, count);     //检测file文件,pos开始的count个字节的区域是否可读
         if (ret >= 0) {
              count = ret;
              if (file->f_op->read)
                   ret = file->f_op->read(file, buf, count, pos);     //调用相应驱动注册的read接口
              else
                   ret = do_sync_read(file, buf, count, pos);
              if (ret > 0) {
                   fsnotify_access(file);
                   add_rchar(current, ret);
              }
              inc_syscr(current);
         }

         return ret;
    }
  • 相关阅读:
    【VS开发】【电子电路技术】VPX技术介绍
    【VS开发】【电子电路技术】VPX技术介绍
    【VS开发】【DSP开发】浅谈Linux PCI设备驱动(二)
    【VS开发】【DSP开发】浅谈Linux PCI设备驱动(二)
    【VS开发】【DSP开发】浅谈Linux PCI设备驱动(一)
    【VS开发】【DSP开发】浅谈Linux PCI设备驱动(一)
    【Linux开发】彻底释放Linux线程的资源
    【Linux开发】彻底释放Linux线程的资源
    【VS开发】C++线程安全
    【VS开发】C++线程安全
  • 原文地址:https://www.cnblogs.com/black-mamba/p/5043971.html
Copyright © 2020-2023  润新知