����12-9 linux/fs/file_dev.c


  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