����12-12 linux/fs/read_write.c


  1 /*

  2  *  linux/fs/read_write.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #include <sys/stat.h>     // �ļ�״̬ͷ�ļ��������ļ����ļ�ϵͳ״̬�ṹstat{}�ͳ�����

  8 #include <errno.h>        // �����ͷ�ļ�������ϵͳ�и��ֳ����š�

  9 #include <sys/types.h>    // ����ͷ�ļ��������˻�����ϵͳ�������͡�

 10

 11 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 12 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�����������ṹtask_struct������0���ݵȡ�

 13 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 14

    // �ַ��豸��д������fs/char_dev.c����95�С�

 15 extern int rw_char(int rw,int dev, char * buf, int count, off_t * pos);

    // ���ܵ�����������fs/pipe.c����13�С�

 16 extern int read_pipe(struct m_inode * inode, char * buf, int count);

    // д�ܵ�����������fs/pipe.c����41�С�

 17 extern int write_pipe(struct m_inode * inode, char * buf, int count);

    // ���豸������������fs/block_dev.c����47�С�

 18 extern int block_read(int dev, off_t * pos, char * buf, int count);

    // ���豸д����������fs/block_dev.c����14�С�

 19 extern int block_write(int dev, off_t * pos, char * buf, int count);

    // ���ļ�����������fs/file_dev.c����17�С�

 20 extern int file_read(struct m_inode * inode, struct file * filp,

 21                 char * buf, int count);

    // д�ļ�����������fs/file_dev.c����48�С�

 22 extern int file_write(struct m_inode * inode, struct file * filp,

 23                 char * buf, int count);

 24

    //// �ض�λ�ļ���дָ��ϵͳ���á�

    // ����fd���ļ������offset���µ��ļ���дָ��ƫ��ֵ��origin��ƫ�Ƶ���ʼλ�ã�����

    // ����ѡ��SEEK_SET��0�����ļ���ʼ������SEEK_CUR��1���ӵ�ǰ��дλ�ã���SEEK_END��

    // 2�����ļ�β������

 25 int sys_lseek(unsigned int fd,off_t offset, int origin)

 26 {

 27         struct file * file;

 28         int tmp;

 29

    // �����жϺ����ṩ�IJ�����Ч�ԡ�����ļ����ֵ���ڳ��������ļ���NR_OPEN(20)��

    // ���߸þ�����ļ��ṹָ��Ϊ�գ����߶�Ӧ�ļ��ṹ��i�ڵ��ֶ�Ϊ�գ�����ָ���豸�ļ�

    // ָ���Dz��ɶ�λ�ģ��򷵻س����벢�˳�������ļ���Ӧ��i�ڵ��ǹܵ��ڵ㣬�򷵻س���

    // ���˳�����Ϊ�ܵ�ͷβָ�벻�������ƶ���

 30         if (fd >= NR_OPEN || !(file=current->filp[fd]) || !(file->f_inode)

 31            || !IS_SEEKABLE(MAJOR(file->f_inode->i_dev)))

 32                 return -EBADF;

 33         if (file->f_inode->i_pipe)

 34                 return -ESPIPE;

    // Ȼ��������õĶ�λ��־���ֱ����¶�λ�ļ���дָ�롣

 35         switch (origin) {

    // origin = SEEK_SET��Ҫ�����ļ���ʼ����Ϊԭ�������ļ���дָ�롣��ƫ��ֵС���㣬���

    // �����ش����롣���������ļ���дָ�����offset��

 36                 case 0:

 37                         if (offset<0) return -EINVAL;

 38                         file->f_pos=offset;

 39                         break;

    // origin = SEEK_CUR��Ҫ�����ļ���ǰ��дָ�봦��Ϊԭ���ض�λ��дָ�롣����ļ���ǰָ

    // �����ƫ��ֵС��0���򷵻س������˳��������ڵ�ǰ��дָ���ϼ���ƫ��ֵ��

 40                 case 1:

 41                         if (file->f_pos+offset<0) return -EINVAL;

 42                         file->f_pos += offset;

 43                         break;

    // origin = SEEK_END��Ҫ�����ļ�ĩβ��Ϊԭ���ض�λ��дָ�롣��ʱ���ļ���С����ƫ��ֵ

    // С�����򷵻س������˳��������ض�λ��дָ��Ϊ�ļ����ȼ���ƫ��ֵ��

 44                 case 2:

 45                         if ((tmp=file->f_inode->i_size+offset) < 0)

 46                                 return -EINVAL;

 47                         file->f_pos = tmp;

 48                         break;

    // ��origin ������Ч�����س������˳���

 49                 default:

 50                         return -EINVAL;

 51         }

 52         return file->f_pos;                 // ��󷵻��ض�λ����ļ���дָ��ֵ��

 53 }

 54

    //// ���ļ�ϵͳ���á�

    // ����fd���ļ������buf�ǻ�������count�������ֽ�����

 55 int sys_read(unsigned int fd,char * buf,int count)

 56 {

 57         struct file * file;

 58         struct m_inode * inode;

 59

    // �������ȶԲ�����Ч�Խ����жϡ�����ļ����ֵ���ڳ��������ļ���NR_OPEN������

    // ��Ҫ��ȡ���ֽڼ���ֵС��0�����߸þ�����ļ��ṹָ��Ϊ�գ��򷵻س����벢�˳�����

    // ���ȡ���ֽ���count����0���򷵻�0�˳�

 60         if (fd>=NR_OPEN || count<0 || !(file=current->filp[fd]))

 61                 return -EINVAL;

 62         if (!count)

 63                 return 0;

    // Ȼ����֤������ݵĻ������ڴ����ơ���ȡ�ļ���i�ڵ㡣���ڸ��ݸ�i�ڵ�����ԣ��ֱ�

    // ������Ӧ�Ķ��������������ǹܵ��ļ��������Ƕ��ܵ��ļ�ģʽ������ж��ܵ�����������

    // ���򷵻ض�ȡ���ֽ��������򷵻س����룬�˳���������ַ����ļ�������ж��ַ��豸��

    // ���������ض�ȡ���ַ���������ǿ��豸�ļ�����ִ�п��豸�������������ض�ȡ���ֽ�����

 64         verify_area(buf,count);

 65         inode = file->f_inode;

 66         if (inode->i_pipe)

 67                 return (file->f_mode&1)?read_pipe(inode,buf,count):-EIO;

 68         if (S_ISCHR(inode->i_mode))

 69                 return rw_char(READ,inode->i_zone[0],buf,count,&file->f_pos);

 70         if (S_ISBLK(inode->i_mode))

 71                 return block_read(inode->i_zone[0],&file->f_pos,buf,count);

    // �����Ŀ¼�ļ������dz����ļ�����������֤��ȡ�ֽ���count����Ч�Բ����е���������

    // ȡ�ֽ��������ļ���ǰ��дָ��ֵ�����ļ����ȣ����������ö�ȡ�ֽ���Ϊ �ļ�����-��ǰ

    // ��дָ��ֵ������ȡ������0���򷵻�0�˳�����Ȼ��ִ���ļ������������ض�ȡ���ֽ���

    // ���˳���

 72         if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode)) {

 73                 if (count+file->f_pos > inode->i_size)

 74                         count = inode->i_size - file->f_pos;

 75                 if (count<=0)

 76                         return 0;

 77                 return file_read(inode,file,buf,count);

 78         }

    // ִ�е����˵�������޷��ж��ļ������ԡ����ӡ�ڵ��ļ����ԣ������س������˳���

 79         printk("(Read)inode->i_mode=%06o\n\r",inode->i_mode);

 80         return -EINVAL;

 81 }

 82

    //// д�ļ�ϵͳ���á�

    // ����fd���ļ������buf���û���������count����д�ֽ�����

 83 int sys_write(unsigned int fd,char * buf,int count)

 84 {

 85         struct file * file;

 86         struct m_inode * inode;

 87        

    // ͬ���أ����������жϺ�����������Ч�ԡ���������ļ����ֵ���ڳ��������ļ���

    // NR_OPEN��������Ҫд����ֽڼ���С��0�����߸þ�����ļ��ṹָ��Ϊ�գ��򷵻س���

    // �벢�˳���������ȡ���ֽ���count����0���򷵻�0�˳�

 88         if (fd>=NR_OPEN || count <0 || !(file=current->filp[fd]))

 89                 return -EINVAL;

 90         if (!count)

 91                 return 0;

    // Ȼ����֤������ݵĻ������ڴ����ơ���ȡ�ļ���i�ڵ㡣���ڸ��ݸ�i�ڵ�����ԣ��ֱ�

    // ������Ӧ�Ķ��������������ǹܵ��ļ���������д�ܵ��ļ�ģʽ�������д�ܵ�����������

    // ���򷵻�д����ֽ��������򷵻س������˳���������ַ��豸�ļ��������д�ַ��豸��

    // ��������д����ַ����˳�������ǿ��豸�ļ�������п��豸д������������д����ֽ�

    // ���˳������dz����ļ�����ִ���ļ�д������������д����ֽ������˳���

 92         inode=file->f_inode;

 93         if (inode->i_pipe)

 94                 return (file->f_mode&2)?write_pipe(inode,buf,count):-EIO;

 95         if (S_ISCHR(inode->i_mode))

 96                 return rw_char(WRITE,inode->i_zone[0],buf,count,&file->f_pos);

 97         if (S_ISBLK(inode->i_mode))

 98                 return block_write(inode->i_zone[0],&file->f_pos,buf,count);

 99         if (S_ISREG(inode->i_mode))

100                 return file_write(inode,file,buf,count);

    // ִ�е����˵�������޷��ж��ļ������ԡ����ӡ�ڵ��ļ����ԣ������س������˳���

101         printk("(Write)inode->i_mode=%06o\n\r",inode->i_mode);

102         return -EINVAL;

103 }

104