[文件系统]read系统调用剖析(一)

时间:2021-10-31 13:15:34

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