linux 1.0 内核注解 linux/fs/read_write.c
时间:2009-05-04 来源:taozhijiangscu
/********************************************
*Created By: 陶治江
*Date: 2009年5月2日0:42:11
********************************************/
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/stat.h>
#include <linux/kernel.h>
#include <linux/sched.h> #include <asm/segment.h> /*这里的代码更加优良了,所有的操作都被封装到了file->f_op->中的
*处理句柄中了,实际是在struct file中插入了结构
*struct file_operations元素了,我很喜欢这样的改变哦 :-)*/ //读取fd指向的目录到struct dirent * dirent中
asmlinkage int sys_readdir(unsigned int fd, struct dirent * dirent, unsigned int count)
{
int error;
struct file * file;
struct inode * inode; //每个进程最多可以打开256个文件,合法性的检测
if (fd >= NR_OPEN || !(file = current->filp[fd]) ||
!(inode = file->f_inode))
return -EBADF;
error = -ENOTDIR;
//struct dirent {
// long d_ino; 节点号
// off_t d_off;
// unsigned short d_reclen; 名字长
// char d_name[NAME_MAX+1];
// }; if (file->f_op && file->f_op->readdir) {
error = verify_area(VERIFY_WRITE, dirent, sizeof (*dirent)); //写验证
if (!error)
error = file->f_op->readdir(inode,file,dirent,count);
}
return error;
} //从新设置文件指针的位置
asmlinkage int sys_lseek(unsigned int fd, off_t offset, unsigned int origin)
{
struct file * file;
int tmp = -1; if (fd >= NR_OPEN || !(file=current->filp[fd]) || !(file->f_inode))
return -EBADF;
if (origin > 2) //只可能是0-2
return -EINVAL;
//如果文件本省封装了这个函数,就调用自己的函数,
//否则使用下面的默认方法进行计算了
if (file->f_op && file->f_op->lseek)
return file->f_op->lseek(file->f_inode,file,offset,origin); //这里的代码是如果结构中的lseek句柄没有,就执行这里的操作
switch (origin) {
case 0: //从头开始
tmp = offset;
break;
case 1: //当前位置算起
tmp = file->f_pos + offset;
break;
case 2: //从尾开始,这里的offset为负值
if (!file->f_inode)
return -EINVAL;
tmp = file->f_inode->i_size + offset;
break;
}
if (tmp < 0)
return -EINVAL;
file->f_pos = tmp;
file->f_reada = 0;
return file->f_pos; /*返回的是设置之后的新文件指针位置*/
} //************************************************************
//这里是读写文件的系统调用,具体的实现是根据文件的类型来进行的
//将count字节读取到buf中
//块设备文件: block_write block_read
//正规文件: file_write file_read
//管道文件: pipe_write pipe_read
//字符设备文件:tty_write tty_read
asmlinkage int sys_read(unsigned int fd,char * buf,unsigned int count)
{
int error;
struct file * file;
struct inode * inode; if (fd>=NR_OPEN || !(file=current->filp[fd]) || !(inode=file->f_inode))
return -EBADF;
if (!(file->f_mode & 1)) //读打开
return -EBADF;
if (!file->f_op || !file->f_op->read)
return -EINVAL;
if (!count)
return 0;
error = verify_area(VERIFY_WRITE,buf,count);
if (error)
return error;
return file->f_op->read(inode,file,buf,count);
} //将buf处的count字节写入到fd中
asmlinkage int sys_write(unsigned int fd,char * buf,unsigned int count)
{
int error;
struct file * file;
struct inode * inode;
if (fd>=NR_OPEN || !(file=current->filp[fd]) || !(inode=file->f_inode))
return -EBADF;
if (!(file->f_mode & 2)) //写打开
return -EBADF;
if (!file->f_op || !file->f_op->write)
return -EINVAL;
if (!count)
return 0;
error = verify_area(VERIFY_READ,buf,count);
if (error)
return error;
return file->f_op->write(inode,file,buf,count);
}
文档地址:http://blogimg.chinaunix.net/blog/upfile2/090503233220.pdf
*Created By: 陶治江
*Date: 2009年5月2日0:42:11
********************************************/
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/stat.h>
#include <linux/kernel.h>
#include <linux/sched.h> #include <asm/segment.h> /*这里的代码更加优良了,所有的操作都被封装到了file->f_op->中的
*处理句柄中了,实际是在struct file中插入了结构
*struct file_operations元素了,我很喜欢这样的改变哦 :-)*/ //读取fd指向的目录到struct dirent * dirent中
asmlinkage int sys_readdir(unsigned int fd, struct dirent * dirent, unsigned int count)
{
int error;
struct file * file;
struct inode * inode; //每个进程最多可以打开256个文件,合法性的检测
if (fd >= NR_OPEN || !(file = current->filp[fd]) ||
!(inode = file->f_inode))
return -EBADF;
error = -ENOTDIR;
//struct dirent {
// long d_ino; 节点号
// off_t d_off;
// unsigned short d_reclen; 名字长
// char d_name[NAME_MAX+1];
// }; if (file->f_op && file->f_op->readdir) {
error = verify_area(VERIFY_WRITE, dirent, sizeof (*dirent)); //写验证
if (!error)
error = file->f_op->readdir(inode,file,dirent,count);
}
return error;
} //从新设置文件指针的位置
asmlinkage int sys_lseek(unsigned int fd, off_t offset, unsigned int origin)
{
struct file * file;
int tmp = -1; if (fd >= NR_OPEN || !(file=current->filp[fd]) || !(file->f_inode))
return -EBADF;
if (origin > 2) //只可能是0-2
return -EINVAL;
//如果文件本省封装了这个函数,就调用自己的函数,
//否则使用下面的默认方法进行计算了
if (file->f_op && file->f_op->lseek)
return file->f_op->lseek(file->f_inode,file,offset,origin); //这里的代码是如果结构中的lseek句柄没有,就执行这里的操作
switch (origin) {
case 0: //从头开始
tmp = offset;
break;
case 1: //当前位置算起
tmp = file->f_pos + offset;
break;
case 2: //从尾开始,这里的offset为负值
if (!file->f_inode)
return -EINVAL;
tmp = file->f_inode->i_size + offset;
break;
}
if (tmp < 0)
return -EINVAL;
file->f_pos = tmp;
file->f_reada = 0;
return file->f_pos; /*返回的是设置之后的新文件指针位置*/
} //************************************************************
//这里是读写文件的系统调用,具体的实现是根据文件的类型来进行的
//将count字节读取到buf中
//块设备文件: block_write block_read
//正规文件: file_write file_read
//管道文件: pipe_write pipe_read
//字符设备文件:tty_write tty_read
asmlinkage int sys_read(unsigned int fd,char * buf,unsigned int count)
{
int error;
struct file * file;
struct inode * inode; if (fd>=NR_OPEN || !(file=current->filp[fd]) || !(inode=file->f_inode))
return -EBADF;
if (!(file->f_mode & 1)) //读打开
return -EBADF;
if (!file->f_op || !file->f_op->read)
return -EINVAL;
if (!count)
return 0;
error = verify_area(VERIFY_WRITE,buf,count);
if (error)
return error;
return file->f_op->read(inode,file,buf,count);
} //将buf处的count字节写入到fd中
asmlinkage int sys_write(unsigned int fd,char * buf,unsigned int count)
{
int error;
struct file * file;
struct inode * inode;
if (fd>=NR_OPEN || !(file=current->filp[fd]) || !(inode=file->f_inode))
return -EBADF;
if (!(file->f_mode & 2)) //写打开
return -EBADF;
if (!file->f_op || !file->f_op->write)
return -EINVAL;
if (!count)
return 0;
error = verify_area(VERIFY_READ,buf,count);
if (error)
return error;
return file->f_op->write(inode,file,buf,count);
}
文档地址:http://blogimg.chinaunix.net/blog/upfile2/090503233220.pdf
相关阅读 更多 +