文件操作接口的系统调用分析—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;
}

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注