1 /*
2 * linux/fs/file_dev.c
3 *
4 * (C) 1991 Linus Torvalds
5 */
6
7 #include <errno.h> // �����ͷ�ļ�������ϵͳ�и��ֳ����š�
8 #include <fcntl.h> // �ļ�����ͷ�ļ��������ļ������������IJ������Ƴ������ŵĶ��塣
9
10 #include <linux/sched.h> // ���ȳ���ͷ�ļ�������������ṹtask_struct������0�����ݵȡ�
11 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣
12 #include <asm/segment.h> // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����
13
14 #define MIN(a,b) (((a)<(b))?(a):(b)) // ȡa,b�е���Сֵ��
15 #define MAX(a,b) (((a)>(b))?(a):(b)) // ȡa,b�е����ֵ��
16
//// �ļ������� - ����i�ڵ���ļ��ṹ����ȡ�ļ������ݡ�
// ��i�ڵ����ǿ���֪���豸�ţ���filp�ṹ����֪���ļ��е�ǰ��дָ��λ�á�bufָ����
// ���ռ��л�������λ�ã�count����Ҫ��ȡ���ֽ����� ����ֵ��ʵ�ʶ�ȡ���ֽ����������
// �ţ�С��0����
17 int file_read(struct m_inode * inode, struct file * filp, char * buf, int count)
18 {
19 int left,chars,nr;
20 struct buffer_head * bh;
21
// �����жϲ�������Ч�ԡ�����Ҫ��ȡ���ֽڼ���countС�ڵ����㣬��0��������Ҫ��
// ȡ���ֽ���������0����ѭ��ִ�����������ֱ������ȫ���������������⡣�ڶ�ѭ������
// �����У����Ǹ���i�ڵ���ļ����ṹ��Ϣ�������� bmap() �õ������ļ���ǰ��дλ�õ�
// ���ݿ����豸�϶�Ӧ�������nr����nr��Ϊ0�����i�ڵ�ָ�����豸�϶�ȡ�����顣
// ���������ʧ�����˳�ѭ������nrΪ0����ʾָ�������ݿ鲻���ڣ��û����ָ��ΪNULL��
// (filp->f_pos)/BLOCK_SIZE ���ڼ�����ļ���ǰָ���������ݿ�š�
22 if ((left=count)<=0)
23 return 0;
24 while (left) {
25 if (nr = bmap(inode,(filp->f_pos)/BLOCK_SIZE)) { // inode.c��140��
26 if (!(bh=bread(inode->i_dev,nr)))
27 break;
28 } else
29 bh = NULL;
// �������Ǽ����ļ���дָ�������ݿ��е�ƫ��ֵnr�����ڸ����ݿ�������ϣ����ȡ���ֽ���
// Ϊ (BLOCK_SIZE - nr)��Ȼ������ڻ����ȡ���ֽ���left���Ƚϣ�����Сֵ��Ϊ���β���
// ���ȡ���ֽ���chars����� (BLOCK_SIZE - nr) > left����˵���ÿ�����Ҫ��ȡ�����һ
// �����ݣ���֮����Ҫ��ȡ��һ�����ݡ�֮�������д�ļ�ָ�롣 ָ��ǰ�ƴ˴ν���ȡ����
// ����chars��ʣ���ֽڼ���left��Ӧ��ȥchars��
30 nr = filp->f_pos % BLOCK_SIZE;
31 chars = MIN( BLOCK_SIZE-nr , left );
32 filp->f_pos += chars;
33 left -= chars;
// ��������豸�϶��������ݣ���pָ����п�ʼ��ȡ���ݵ�λ�ã����Ҹ���chars�ֽ�
// ���û�������buf�С��������û�������������chars��0ֵ�ֽڡ�
34 if (bh) {
35 char * p = nr + bh->b_data;
36 while (chars-->0)
37 put_fs_byte(*(p++),buf++);
38 brelse(bh);
39 } else {
40 while (chars-->0)
41 put_fs_byte(0,buf++);
42 }
43 }
// �ĸ�i�ڵ�ķ���ʱ��Ϊ��ǰʱ�䡣���ض�ȡ���ֽ���������ȡ�ֽ���Ϊ0���س����š�
// CURRENT_TIME�Ƕ�����include/linux/sched.h��142���ϵĺ꣬���ڼ���UNIXʱ�䡣����
// 1970��1��1��0ʱ0�뿪ʼ������ǰ��ʱ�䡣��λ���롣
44 inode->i_atime = CURRENT_TIME;
45 return (count-left)?(count-left):-ERROR;
46 }
47
//// �ļ�д���� - ����i�ڵ���ļ��ṹ��Ϣ�����û�����д���ļ��С�
// ��i�ڵ����ǿ���֪���豸�ţ�����file�ṹ����֪���ļ��е�ǰ��дָ��λ�á�bufָ��
// �û�̬�л�������λ�ã�countΪ��Ҫд����ֽ����� ����ֵ��ʵ��д����ֽ����������
// �ţ�С��0����
48 int file_write(struct m_inode * inode, struct file * filp, char * buf, int count)
49 {
50 off_t pos;
51 int block,c;
52 struct buffer_head * bh;
53 char * p;
54 int i=0;
55
56 /*
57 * ok, append may not work when many processes are writing at the same time
58 * but so what. That way leads to madness anyway.
59 */
/*
* ok�����������ͬʱдʱ��append�������ܲ��У�����������������������������
* ���»���һ�š�
*/
// ����ȷ������д���ļ���λ�á������Ҫ���ļ����������ݣ����ļ���дָ���Ƶ��ļ�β
// ��������ͽ����ļ���ǰ��дָ�봦д�롣
60 if (filp->f_flags & O_APPEND)
61 pos = inode->i_size;
62 else
63 pos = filp->f_pos;
// Ȼ������д���ֽ���i���տ�ʼʱΪ0��С��ָ��д���ֽ���countʱ��ѭ��ִ�����²�����
// ��ѭ�����������У�������ȡ�ļ����ݿ�� ( pos/BLOCK_SIZE ) ���豸�϶�Ӧ�������
// block�������Ӧ�����鲻���ھʹ���һ�顣����õ�������� = 0�����ʾ����ʧ�ܣ�
// �����˳�ѭ�����������Ǹ��ݸ�����Ŷ�ȡ�豸�ϵ���Ӧ���飬������Ҳ�˳�ѭ����
64 while (i<count) {
65 if (!(block = create_block(inode,pos/BLOCK_SIZE)))
66 break;
67 if (!(bh=bread(inode->i_dev,block)))
68 break;
// ��ʱ�����ָ��bh��ָ��ն�����ļ����ݿ顣����������ļ���ǰ��дָ���ڸ����ݿ���
// ��ƫ��ֵc������ָ��pָ����п�ʼд�����ݵ�λ�ã����øû�������ı�־������
// ���е�ǰָ�룬�ӿ�ʼ��дλ�õ���ĩ����д��c =(BLOCK_SIZE - c)���ֽڡ���c����ʣ��
// ����д����ֽ��� (count - i)����˴�ֻ����д��c = (count - i)���ֽڼ��ɡ�
69 c = pos % BLOCK_SIZE;
70 p = c + bh->b_data;
71 bh->b_dirt = 1;
72 c = BLOCK_SIZE-c;
73 if (c > count-i) c = count-i;
// ��д������֮ǰ��������Ԥ�����ú���һ��ѭ������Ҫ��д�ļ��е�λ�á�������ǰ�pos
// ָ��ǰ�ƴ˴���д����ֽ����������ʱposλ��ֵ�������ļ���ǰ���ȣ�����i�ڵ���
// �ļ������ֶΣ�����i�ڵ����ı�־��Ȼ��Ѵ˴�Ҫд����ֽ���c�ۼӵ���д���ֽڼ�
// ��ֵi�У���ѭ���ж�ʹ�á����Ŵ��û�������buf�и���c���ֽڵ����ٻ������pָ��
// �Ŀ�ʼλ�ô������������ͷŸû���顣
74 pos += c;
75 if (pos > inode->i_size) {
76 inode->i_size = pos;
77 inode->i_dirt = 1;
78 }
79 i += c;
80 while (c-->0)
81 *(p++) = get_fs_byte(buf++);
82 brelse(bh);
83 }
// �������Ѿ�ȫ��д���ļ�������д���������з�������ʱ�ͻ��˳�ѭ������ʱ���Ǹ����ļ�
// ��ʱ��Ϊ��ǰʱ�䣬�������ļ���дָ�롣����˴β����������ļ�β�������ݣ������
// ����дָ���������ǰ��дλ��pos�����������ļ�i�ڵ����ʱ��Ϊ��ǰʱ�䡣���
// ��д����ֽ�������д���ֽ���Ϊ0���س�����-1��
84 inode->i_mtime = CURRENT_TIME;
85 if (!(filp->f_flags & O_APPEND)) {
86 filp->f_pos = pos;
87 inode->i_ctime = CURRENT_TIME;
88 }
89 return (i?i:-1);
90 }
91