一:read系统调用剖析
1,kernel层的read系统调用的入口函数是在kernel/fs/Read_write.c文件中,如下所示:
372 SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
373 {
374 struct file *file;
375 ssize_t ret = -EBADF;
376 int fput_needed;
378 file = fget_light(fd, &fput_needed);
379 if (file) {
380 loff_t pos = file_pos_read(file);
381 ret = vfs_read(file, buf, count, &pos);
382 file_pos_write(file, pos);
383 fput_light(file, fput_needed);
384 }
386 return ret;
387 }
fget_light(fd, &fput_needed)函数的作用是根据用户层的文件描述符fd根据当前进程的current->files->fdt->fd[fd]中找到内核中的struct file结构体。
file_pos_read(file);的作用是获取到要读写文件的偏移,
最终是调用到了vfs_read()函数去真正的读写。
1. ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
2. {
3. ssize_t ret;
4. /*如果标志中不允许所请求的访问,则返回*/
5. if (!(file->f_mode & FMODE_READ))
. 6. return -EBADF;
07. 7. /*如果没有相关的操作,则返回*/
08. 8. if (!file->f_op || (!file->f_op->read && !file->f_op->aio_read))
09. 9. return -EINVAL;
10.10. /*检查参数*/
11.11. if (unlikely(!access_ok(VERIFY_WRITE, buf, count)))
12.12. return -EFAULT;
13.13. /*对要访问的文件部分检查是否有冲突的强制锁,通过inode结构lock当前要操作的区域,成功返回0*,文件系统是否允许使用
强制锁是在mount的时候指定,如果mount的时候指定了MS_MANDLOCK则允许使用强制锁。文件锁概念请详细见下面网址链接*/
14.14. ret = rw_verify_area(READ, file, pos, count);
15.15. if (ret >= 0) {
16.16. count = ret;
17.17. /*下面的方法返回实际传送的字节数,文件指针被适当的修改*/
18.18. if (file->f_op->read)/*如果定义,则用他来传送数据*/
19.19. ret = file->f_op->read(file, buf, count, pos);
20.20. else
21.21. /*通用读取例程*/
22.22. ret = do_sync_read(file, buf, count, pos);
23.23. if (ret > 0) {
/* 通知目录,当前文件已经被访问*/
24.24. fsnotify_access(file->f_path.dentry);
25.25. add_rchar(current, ret);
26.26. }
27.27. inc_syscr(current);
28.28. }
29.29. /*返回实际传送字节数*/
30.30. return ret;
31.31. }
linux 2.6文件锁的概念