����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