资源描述:
《linux内核中打开文件.docx》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库。
1、首先分析一下sys_read系统调用(内核版本为2.6.19.4)。源代码如下(摘自fs/read_write.c)[c-sharp] viewplaincopy1.SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) 2.{ 3. struct file *file; 4. ssize_t ret = -EBADF; 5. int fput_needed; 6. file = fget_light(fd, &f
2、put_needed); 7. if (file) { 8. loff_t pos = file_pos_read(file); 9. ret = vfs_read(file, buf, count, &pos); 10. file_pos_write(file, pos); 11. fput_light(file, fput_needed); 12. } 13. return ret; 14.} 这里用到了fget_light(),file_pos
3、_read(),vfs_read(),file_pos_write(),fput_light()。 ·file_pos_read()和file_pos_write()(均位于fs/read_write.c)用来读取当前文件指针(即当前文件操作的位置)·fget_light()和fput_light()(位于fs/file_table.c和include/linux/file.h)必须是成对出现的!fget_light在当前进程的structfiles_struct中根据所谓的用户空间文件描述符fd来获取文件描述符。另外,根据当前fs_str
4、uct是否被多各进程共享来判断是否需要对文件描述符进行加锁,并将加锁结果存到一个int中返回, fput_light则根据该结果来判断是否需要对文件描述符解锁·vfs_read()(位于fs/read_write.c)调用具体文件系统的read函数来完成读操作,代码如下:[cpp] viewplaincopy1.ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) 2.{ 3. ssize_t ret; 1. if
5、(!(file->f_mode & FMODE_READ)) 2. return -EBADF; 3. if (!file->f_op
6、
7、 (!file->f_op->read && !file->f_op->aio_read)) 4. return -EINVAL; 5. if (unlikely(!access_ok(VERIFY_WRITE, buf, count))) 6. return -EFAULT; 7. ret = rw_verify_area(REA
8、D, file, pos, count); 8. if (ret >= 0) { 9. count = ret; 10. if (file->f_op->read) 11. ret = file->f_op->read(file, buf, count, pos); 12. else 13. ret = do_sync_read(file, buf, count, pos); 14. if (ret > 0) { 15.
9、 fsnotify_access(file->f_path.dentry); 16. add_rchar(current, ret); 17. } 18. inc_syscr(current); 19. } 20. return ret; 21.} 通过源码可以看出,内核中无法直接使用sys_read()来进行文件操作,因为sys_read()总会在当前进程的structfiles_struct中查找文件。(除非内核想对当前进程打开的某个文件
10、进行操作,不知道这种情况是否存在)内核可以使用vfs_read()来进行文件操作,一个例子如下[cpp] viewplaincopy1.ssize_t nread; 2.lof