欢迎访问生活随笔!

生活随笔

您现在的位置是:首页 > 形式科学 > 计算机科学 > IT网络

IT网络

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

发布时间:2022-11-24IT网络 小博士
linux/arch/arm/kernel/call。英语字母表的第19个字母
...
调用(sys_read)
调用(sys_write)
调用(sys_open)
调用(sys_close)
..带r

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)
#defineSYSCALL_DEFINE3(name, ...)SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
#ifdef CONFIG_FTRACE_SYSCALLS
...
#else
#defineSYSCALL_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;
}