一: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文件锁的概念