PAGE / NUMPAGES
首先分析一下sys_read系统调用(内核版本为2.6.19.4)。
源代码如下(摘自fs/read_write.c)
[c-sharp]? \o "view plain" view plain \o "copy" copy文档收集自网络,仅用于个人学习
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);??
????if?(file)?{??
????????loff_t?pos?=?file_pos_read(file);??
????????ret?=?vfs_read(file,?buf,?count,?&pos);??
????????file_pos_write(file,?pos);??
????????fput_light(file,?fput_needed);??
????}??
????return?ret;??
}??
这里用到了fget_light(),file_pos_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在当前进程的struct files_struct中根据所谓的用户空间文件描述符fd来获取文件描述符。另外,根据当前fs_struct是否被多各进程共享来判断是否需要对文件描述符进行加锁,并将加锁结果存到一个int中返回,?fput_light则根据该结果来判断是否需要对文件描述符解锁文档收集自网络,仅用于个人学习
vfs_read()(位于fs/read_write.c)调用具体文件系统的read函数来完成读操作,代码如下:文档收集自网络,仅用于个人学习
[cpp]? \o "view plain" view plain \o "copy" copy文档收集自网络,仅用于个人学习
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))??文档收集自网络,仅用于个人学习
????????return?-EINVAL;??
????if?(unlikely(!access_ok(VERIFY_WRITE,?buf,?count)))??文档收集自网络,仅用于个人学习
????????return?-EFAULT;??
????ret?=?rw_verify_area(READ,?file,?pos,?count);??
????if?(ret?>=?0)?{??
????????count?=?ret;??
????????if?(file->f_op->read)??
????????????ret?=?file->f_op->read(file,?buf,?count,?pos);??
????????else??
????????????ret?=?do_sync_read(file,?buf,?count,?pos);??
????????if?(ret?>?0)?{??
????????????fsnotify_access(file->f_path.dentry);??
????????????add_rchar(current,?ret);??
????????}??
????????inc_syscr(current);??
????}??
????return?ret;??
}??
?
通过源码可以