����12-13 linux/fs/open.c


  1 /*

  2  *  linux/fs/open.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 #include <string.h>       // �ַ���ͷ�ļ�����Ҫ������һЩ�й��ַ���������Ƕ�뺯����

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

  9 #include <fcntl.h>        // �ļ�����ͷ�ļ��������ļ������������������Ƴ������Ŷ��塣

 10 #include <sys/types.h>    // ����ͷ�ļ������������ϵͳ���ļ�ϵͳͳ����Ϣ�ṹ�����͡�

 11 #include <utime.h>        // �û�ʱ��ͷ�ļ���������ʺ��޸�ʱ��ṹ�Լ�utime()ԭ�͡�

 12 #include <sys/stat.h>     // �ļ�״̬ͷ�ļ��������ļ�״̬�ṹstat{}�ͷ��ų����ȡ�

 13

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

 15 #include <linux/tty.h>    // ttyͷ�ļ����������й�tty_io������ͨ�ŷ���IJ�����������

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

 17

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

 19

    //// ȡ�ļ�ϵͳ��Ϣ��

    // ����dev�Ǻ����Ѱ�װ�ļ�ϵͳ���豸�š�ubuf��һ��ustat�ṹ������ָ�룬���ڴ��

    // ϵͳ���ص��ļ�ϵͳ��Ϣ����ϵͳ�������ڷ����Ѱ�װ��mounted���ļ�ϵͳ��ͳ����Ϣ��

    // �ɹ�ʱ����0������ubufָ���ustate�ṹ�������ļ�ϵͳ�ܿ��п����Ϳ���i�ڵ�����

    // ustat�ṹ������include/sys/types.h�С�

 20 int sys_ustat(int dev, struct ustat * ubuf)

 21 {

 22         return -ENOSYS;                // �����룺���ܻ�δʵ�֡�

 23 }

 24

    //// �����ļ����ʺ��޸�ʱ�䡣

    // ����filename���ļ�����times�Ƿ��ʺ��޸�ʱ��ṹָ�롣

    // ���timesָ�벻ΪNULL����ȡutimbuf�ṹ�е�ʱ����Ϣ�������ļ��ķ��ʺ��޸�ʱ�䡣

    // ���timesָ����NULL����ȡϵͳ��ǰʱ��������ָ���ļ��ķ��ʺ��޸�ʱ����

 25 int sys_utime(char * filename, struct utimbuf * times)

 26 {

 27         struct m_inode * inode;

 28         long actime,modtime;

 29

    // �ļ���ʱ����Ϣ��������i�ڵ��ӡ�����������ȸ����ļ���ȡ�ö�Ӧi�ڵ㡣���û����

    // �����򷵻س����롣����ṩ�ķ��ʺ��޸�ʱ��ṹָ��times��ΪNULL����ӽṹ�ж�ȡ

    // �û����õ�ʱ��ֵ���������ϵͳ��ǰʱ���������ļ��ķ��ʺ��޸�ʱ�䡣

 30         if (!(inode=namei(filename)))

 31                 return -ENOENT;

 32         if (times) {

 33                 actime = get_fs_long((unsigned long *) &times->actime);

 34                 modtime = get_fs_long((unsigned long *) &times->modtime);

 35         } else

 36                 actime = modtime = CURRENT_TIME;

    // Ȼ���޸�i�ڵ��еķ���ʱ���ֶκ��޸�ʱ���ֶΡ�������i�ڵ����޸ı�־���Żظ�i��

    // �㣬������0��

 37         inode->i_atime = actime;

 38         inode->i_mtime = modtime;

 39         inode->i_dirt = 1;

 40         iput(inode);

 41         return 0;

 42 }

 43

 44 /*

 45  * XXX should we use the real or effective uid?  BSD uses the real uid,

 46  * so as to make this call useful to setuid programs.

 47  */

    /*

     * XXX ���Ǹ�����ʵ�û�id��ruid��������Ч�û�id��euid����BSDϵͳʹ����

     * ��ʵ�û�id����ʹ�õ��ÿ��Թ�setuid����ʹ�á�

     * ��ע��POSIX��׼����ʹ����ʵ�û�ID����

     * ��ע1��Ӣ��ע�Ϳ�ʼ�� 'XXX' ��ʾ��Ҫ��ʾ����

     */

    //// ����ļ��ķ���Ȩ�ޡ�

    // ����filename���ļ�����mode�Ǽ��ķ������ԣ�����3����Ч����λ��ɣ�R_OK(ֵ4)��

    // W_OK(2)��X_OK(1) ��F_OK(0) ��ɣ��ֱ��ʾ����ļ��Ƿ�ɶ�����д����ִ�к��ļ���

    // ����ڡ�������������Ļ����򷵻�0�����򷵻س����롣

 48 int sys_access(const char * filename,int mode)

 49 {

 50         struct m_inode * inode;

 51         int res, i_mode;

 52

    // �ļ��ķ���Ȩ����ϢҲͬ���������ļ���i�ڵ�ṹ�У��������Ҫ��ȡ�ö�Ӧ�ļ�����i

    // �ڵ㡣���ķ�������mode�ɵ�3λ��ɣ������Ҫ���ϰ˽���0007��������и߱���λ��

    // ����ļ�����Ӧ��i�ڵ㲻���ڣ��򷵻�û������Ȩ�޳����롣��i�ڵ���ڣ���ȡi�ڵ�

    // ���ļ������룬���Żظ�i�ڵ㡣���⣬57������䡰iput(inode);��������61��֮��

 53         mode &= 0007;

 54         if (!(inode=namei(filename)))

 55                 return -EACCES;                    // �����룺�޷���Ȩ�ޡ�

 56         i_mode = res = inode->i_mode & 0777;

 57         iput(inode);

    // �����ǰ�����û��Ǹ��ļ�����������ȡ�ļ��������ԡ����������ǰ�����û�����ļ���

    // ��ͬ��һ�飬��ȡ�ļ������ԡ����򣬴�ʱres���3�����������˷��ʸ��ļ����������ԡ�

    // [[?? ����Ӧres >>3 ??]

 58         if (current->uid == inode->i_uid)

 59                 res >>= 6;

 60         else if (current->gid == inode->i_gid)

 61                 res >>= 6;

    // ��ʱres�����3�����Ǹ��ݵ�ǰ�����û����ļ��Ĺ�ϵѡ������ķ�������λ����������

    // ���ж���3���ء�����ļ����Ծ��в�������ѯ������λmode����������ɣ�����0

 62         if ((res & 0007 & mode) == mode)

 63                 return 0;

 64         /*

 65          * XXX we are doing this test last because we really should be

 66          * swapping the effective with the real user id (temporarily),

 67          * and then calling suser() routine.  If we do call the

 68          * suser() routine, it needs to be called last.

 69          */

            /*

             * XXX ��������������IJ��ԣ���Ϊ����ʵ������Ҫ������Ч�û�ID��

             * ��ʵ�û�ID����ʱ�أ���Ȼ��ŵ���suser()�������������ȷʵҪ����

             * suser()����������Ҫ���ű����á�

             */

    // �����ǰ�û�IDΪ0�������û�������������ִ��λ��0�����ļ����Ա��κ���ִ�С���

    // �����򷵻�0�����򷵻س����롣

 70         if ((!current->uid) &&

 71             (!(mode & 1) || (i_mode & 0111)))

 72                 return 0;

 73         return -EACCES;                           // �����룺�޷���Ȩ�ޡ�

 74 }

 75

    //// �ı䵱ǰ����Ŀ¼ϵͳ���á�

    // ����filename��Ŀ¼����

    // �����ɹ��򷵻�0�����򷵻س����롣

 76 int sys_chdir(const char * filename)

 77 {

 78         struct m_inode * inode;

 79

    // �ı䵱ǰ����Ŀ¼����Ҫ��ѽ�������ṹ�ĵ�ǰ����Ŀ¼�ֶ�ָ�����Ŀ¼����i�ڵ㡣

    // �����������ȡĿ¼����i�ڵ㡣���Ŀ¼����Ӧ��i�ڵ㲻���ڣ��򷵻س����롣�����

    // i�ڵ㲻��һ��Ŀ¼i�ڵ㣬��Żظ�i�ڵ㣬�����س����롣

 80         if (!(inode = namei(filename)))

 81                 return -ENOENT;                    // �����룺�ļ���Ŀ¼�����ڡ�

 82         if (!S_ISDIR(inode->i_mode)) {

 83                 iput(inode);

 84                 return -ENOTDIR;                   // �����룺����Ŀ¼����

 85         }

    // Ȼ���ͷŽ���ԭ����Ŀ¼i�ڵ㣬��ʹ��ָ�������õĹ���Ŀ¼i�ڵ㡣����0��

 86         iput(current->pwd);

 87         current->pwd = inode;

 88         return (0);

 89 }

 90

    //// �ı��Ŀ¼ϵͳ���á�

    // ��ָ����Ŀ¼�����ó�Ϊ��ǰ���̵ĸ�Ŀ¼'/'��

    // ��������ɹ��򷵻�0�����򷵻س����롣

 91 int sys_chroot(const char * filename)

 92 {

 93         struct m_inode * inode;

 94

    // �õ������ڸı䵱ǰ��������ṹ�еĸ�Ŀ¼�ֶ�root������ָ���������Ŀ¼����i�ڵ㡣

    // ���Ŀ¼����Ӧ��i�ڵ㲻���ڣ��򷵻س����롣�����i�ڵ㲻��Ŀ¼i�ڵ㣬��Żظ�

    // i�ڵ㣬Ҳ���س����롣

 95         if (!(inode=namei(filename)))

 96                 return -ENOENT;

 97         if (!S_ISDIR(inode->i_mode)) {

 98                 iput(inode);

 99                 return -ENOTDIR;

100         }

    // Ȼ���ͷŵ�ǰ���̵ĸ�Ŀ¼i�ڵ㣬����������Ϊָ��Ŀ¼����i�ڵ㣬����0��

101         iput(current->root);

102         current->root = inode;

103         return (0);

104 }

105

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

    // ����filename���ļ�����mode���µ��ļ����ԡ�

    // �������ɹ��򷵻�0�����򷵻س����롣

106 int sys_chmod(const char * filename,int mode)

107 {

108         struct m_inode * inode;

109

    // �õ���Ϊָ���ļ������µķ�������mode���ļ��ķ����������ļ�����Ӧ��i�ڵ��У����

    // ��������ȡ�ļ�����Ӧ��i�ڵ㡣���i�ڵ㲻���ڣ��򷵻س����루�ļ���Ŀ¼�����ڣ���

    // �����ǰ���̵���Ч�û�id���ļ�i�ڵ���û�id��ͬ������Ҳ���dz����û�����Żظ�

    // �ļ�i�ڵ㣬���س����루û�з���Ȩ�ޣ���

110         if (!(inode=namei(filename)))

111                 return -ENOENT;

112         if ((current->euid != inode->i_uid) && !suser()) {

113                 iput(inode);

114                 return -EACCES;

115         }

    // ������������ø�i�ڵ���ļ����ԣ����ø�i�ڵ����޸ı�־���Żظ�i�ڵ㣬����0��

116         inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777);

117         inode->i_dirt = 1;

118         iput(inode);

119         return 0;

120 }

121

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

    // ����filename���ļ�����uid���û���ʶ��(�û�ID)��gid����ID��

    // �������ɹ��򷵻�0�����򷵻س����롣

122 int sys_chown(const char * filename,int uid,int gid)

123 {

124         struct m_inode * inode;

125

    // �õ������������ļ�i�ڵ��е��û�����ID���������Ҫȡ�ø����ļ�����i�ڵ㡣�����

    // ������i�ڵ㲻���ڣ��򷵻س����루�ļ���Ŀ¼�����ڣ��������ǰ���̲��dz����û���

    // ��Żظ�i�ڵ㣬�����س����루û�з���Ȩ�ޣ���

126         if (!(inode=namei(filename)))

127                 return -ENOENT;

128         if (!suser()) {

129                 iput(inode);

130                 return -EACCES;

131         }

    // �������Ǿ��ò����ṩ��ֵ�������ļ�i�ڵ���û�ID����ID������i�ڵ��Ѿ��޸ı�־��

    // �Żظ�i�ڵ㣬����0��

132         inode->i_uid=uid;

133         inode->i_gid=gid;

134         inode->i_dirt=1;

135         iput(inode);

136         return 0;

137 }

138

    //// ����ַ��豸���͡�

    // �ú��������������ļ���ϵͳ����sys_open()�����ڼ�����򿪵��ļ���tty�ն��ַ���

    // ��ʱ����Ҫ�Ե�ǰ���̵����úͶ�tty�������á�

    // ����0��⴦���ɹ�������-1��ʾʧ�ܣ���Ӧ�ַ��豸���ܴ򿪡�

139 static int check_char_dev(struct m_inode * inode, int dev, int flag)

140 {

141         struct tty_struct *tty;

142         int min;                                     // ���豸�š�

143

    // ֻ�������豸����4��/dev/ttyxx�ļ�����5��/dev/tty�ļ����������/dev/tty�����豸

    // ����0�����һ�������п����նˣ������ǽ��̿����ն��豸��ͬ��������/dev/tty�豸��

    // һ�������豸������Ӧ������ʵ��ʹ�õ�/dev/ttyxx�豸֮һ������һ��������˵��������

    // �����նˣ���ô��������ṹ�е�tty�ֶν���4���豸��ijһ�����豸�š�

    // ����򿪲������ļ��� /dev/tty����MAJOR(dev) = 5������ô������min = ��������ṹ

    // �е�tty�ֶΣ���ȡ4���豸�����豸�š���������򿪵���ij��4���豸����ֱ��ȡ����

    // �豸�š�����õ��� 4���豸���豸��С��0����ô˵������û�п����նˣ������豸�Ŵ�

    // ���򷵻� -1����ʾ���ڽ���û�п����նˣ����߲��ܴ�����豸��

144         if (MAJOR(dev) == 4 || MAJOR(dev) == 5) {

145                 if (MAJOR(dev) == 5)

146                         min = current->tty;

147                 else

148                         min = MINOR(dev);

149                 if (min < 0)

150                         return -1;

    // ��α�ն��豸�ļ�ֻ�ܱ����̶�ռʹ�á�������豸�ű�����һ����α�նˣ����Ҹô��ļ�

    // i �ڵ����ü������� 1����˵�����豸�ѱ���������ʹ�á���˲����ٴ򿪸��ַ��豸�ļ���

    // ���Ƿ��� -1������������tty�ṹָ��ttyָ��tty���ж�Ӧ�ṹ������ļ�������

    // ־flag�в�����������ն˱�־O_NOCTTY�����ҽ����ǽ��������죬���ҵ�ǰ����û�п���

    // �նˣ�����tty�ṹ��session�ֶ�Ϊ0����ʾ���ն˻������κν�����Ŀ����նˣ�����ô

    // ������Ϊ������������ն��豸 min Ϊ������նˡ��������ý�������ṹ�ն��豸���ֶ�

    // ttyֵ����min���������ö�Ӧtty�ṹ�ĻỰ��session�ͽ������pgrp�ֱ���ڽ��̵Ļ�

    // ���źͽ�����š�

151                 if ((IS_A_PTY_MASTER(min)) && (inode->i_count>1))

152                         return -1;

153                 tty = TTY_TABLE(min);

154                 if (!(flag & O_NOCTTY) &&

155                     current->leader &&

156                     current->tty<0 &&

157                     tty->session==0) {

158                         current->tty = min;

159                         tty->session= current->session;

160                         tty->pgrp = current->pgrp;

161                 }

    // ������ļ�������־flag�к���O_NONBLOCK������������־����������Ҫ�Ը��ַ��ն�

    // �豸����������ã�����Ϊ�����������Ҫ��ȡ�������ַ���Ϊ0�����ó�ʱ��ʱֵΪ0��

    // �����ն��豸���óɷǹ淶ģʽ����������ʽֻ�ܹ����ڷǹ淶ģʽ���ڴ�ģʽ�µ�VMIN

    // ��VTIME������Ϊ0ʱ�������������ж���֧�����̾Ͷ�ȡ�����ַ��������̷��ء��μ�

    // include/termios.h�ļ����˵����

162                 if (flag & O_NONBLOCK) {

163                         TTY_TABLE(min)->termios.c_cc[VMIN] =0;

164                         TTY_TABLE(min)->termios.c_cc[VTIME] =0;

165                         TTY_TABLE(min)->termios.c_lflag &= ~ICANON;

166                 }

167         }

168         return 0;

169 }

170

    //// �򿪣��򴴽����ļ�ϵͳ���á�

    // ����filename���ļ�����flag�Ǵ��ļ���־������ȡֵ��O_RDONLY��ֻ������O_WRONLY

    // ��ֻд����O_RDWR����д�����Լ�O_CREAT����������O_EXCL���������ļ����벻���ڣ���

    // O_APPEND�����ļ�β�������ݣ�������һЩ��־����ϣ���������ô�����һ�����ļ�����

    // mode������ָ���ļ����������ԡ���Щ������S_IRWXU���ļ��������ж���д��ִ��Ȩ�ޣ���

    // S_IRUSR���û����ж��ļ�Ȩ�ޣ���S_IRWXG�����Ա���ж���д��ִ��Ȩ�ޣ��ȵȡ�������

    // �������ļ�����Щ����ֻӦ���ڽ������ļ��ķ��ʣ�������ֻ���ļ��Ĵ򿪵���Ҳ������һ

    // ���ɶ�д���ļ������������ò����ɹ����򷵻��ļ����(�ļ�������)�����򷵻س����롣

    // �μ�sys/stat.h��fcntl.h��

171 int sys_open(const char * filename,int flag,int mode)

172 {

173         struct m_inode * inode;

174         struct file * f;

175         int i,fd;

176

    // ���ȶԲ������д��������û����õ��ļ�ģʽ�ͽ���ģʽ���������룬�������ɵ��ļ�ģʽ��

    // Ϊ��Ϊ���ļ�����һ���ļ��������Ҫ�������̽ṹ���ļ��ṹָ�����飬�Բ���һ����

    // ����������������fd���Ǿ��ֵ�����Ѿ�û�п�����򷵻س����루������Ч����

177         mode &= 0777 & ~current->umask;

178         for(fd=0 ; fd<NR_OPEN ; fd++)

179                 if (!current->filp[fd])                       // �ҵ������

180                         break;

181         if (fd>=NR_OPEN)

182                 return -EINVAL;

    // Ȼ���������õ�ǰ���̵�ִ��ʱ�ر��ļ������close_on_exec��λͼ����λ��Ӧ�ı���λ��

    // close_on_exec ��һ�����������ļ������λͼ��־��ÿ������λ����һ�����ŵ��ļ���

    // ����������ȷ���ڵ���ϵͳ���� execve()ʱ��Ҫ�رյ��ļ������������ʹ�� fork()����

    // ������һ���ӽ���ʱ��ͨ�����ڸ��ӽ����е���execve()��������ִ����һ���³��򡣴�ʱ

    // �ӽ����п�ʼִ���³�����һ���ļ������close_on_exec�еĶ�Ӧ����λ����λ����ô

    // ��ִ��execve()ʱ�ö�Ӧ�ļ���������رգ�������ļ������ʼ�մ��ڴ�״̬������

    // һ���ļ�ʱ��Ĭ��������ļ�������ӽ�����Ҳ���ڴ�״̬���������Ҫ��λ��Ӧ����λ��

    // Ȼ��Ϊ���ļ����ļ�����Ѱ��һ�����нṹ�������fָ���ļ������鿪ʼ����������

    // ���ļ��ṹ����ü���Ϊ0��������Ѿ�û�п����ļ����ṹ��򷵻س����롣���⣬

    // ��184���ϵ�ָ�븳ֵ "0+file_table " ��ͬ�� "file_table" �� "&file_table[0]"��

    // ��������д���ܸ�������һЩ��

183         current->close_on_exec &= ~(1<<fd);

184         f=0+file_table;

185         for (i=0 ; i<NR_FILE ; i++,f++)

186                 if (!f->f_count) break;

187         if (i>=NR_FILE)

188                 return -EINVAL;

    // ��ʱ�����ý��̶�Ӧ�ļ����fd���ļ��ṹָ��ָ�����������ļ��ṹ�������ļ����ü���

    // ����1��Ȼ����ú���open_namei()ִ�д򿪲�����������ֵС��0����˵�������������ͷ�

    // �����뵽���ļ��ṹ�����س�����i�����ļ��򿪲����ɹ�����inode���Ѵ��ļ���i�ڵ�

    // ָ�롣

189         (current->filp[fd]=f)->f_count++;

190         if ((i=open_namei(filename,flag,mode,&inode))<0) {

191                 current->filp[fd]=NULL;

192                 f->f_count=0;

193                 return i;

194         }

    // �����Ѵ��ļ�i�ڵ�������ֶΣ����ǿ���֪���ļ������͡����ڲ�ͬ���͵��ļ�������

    // ��Ҫ��һЩ�ر����� ����򿪵����ַ��豸�ļ�����ô���Ǿ�Ҫ����check_char_dev()

    // ��������鵱ǰ�����Ƿ��ܴ�����ַ��豸�ļ��������������������0������ô��

    // check_char_dev()�л���ݾ����ļ��򿪱�־Ϊ�������ÿ����նˡ� �����������

    // ʹ�ø��ַ��豸�ļ�����ô����ֻ���ͷ�����������ļ���;����Դ�����س����롣

195 /* ttys are somewhat special (ttyxx major==4, tty major==5) */

    /* ttys��Щ���⣨ttyxx�����豸��==4��tty�����豸��==5��*/

196         if (S_ISCHR(inode->i_mode))

197                 if (check_char_dev(inode,inode->i_zone[0],flag)) {

198                         iput(inode);

199                         current->filp[fd]=NULL;

200                         f->f_count=0;

201                         return -EAGAIN;          // �����ţ���Դ��ʱ�����á�

202                 }

    // ����򿪵��ǿ��豸�ļ���������Ƭ�Ƿ��������������������Ҫ�ø��ٻ������и��豸

    // �����л����ʧЧ��

203 /* Likewise with block-devices: check for floppy_change */

    /* ͬ�����ڿ��豸�ļ�����Ҫ�����Ƭ�Ƿ񱻸��� */

204         if (S_ISBLK(inode->i_mode))

205                 check_disk_change(inode->i_zone[0]);

    // �������dz�ʼ�����ļ����ļ��ṹ�������ļ��ṹ���Ժͱ�־���þ�����ü���Ϊ1����

    // ����i�ڵ��ֶ�Ϊ���ļ���i�ڵ㣬��ʼ���ļ���дָ��Ϊ0����󷵻��ļ�����š�

206         f->f_mode = inode->i_mode;

207         f->f_flags = flag;

208         f->f_count = 1;

209         f->f_inode = inode;

210         f->f_pos = 0;

211         return (fd);

212 }

213

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

    // ����pathname��·������mode�������sys_open()������ͬ��

    // �ɹ��򷵻��ļ���������򷵻س����롣

214 int sys_creat(const char * pathname, int mode)

215 {

216         return sys_open(pathname, O_CREAT | O_TRUNC, mode);

217 }

218

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

    // ����fd���ļ������

    // �ɹ��򷵻�0�����򷵻س����롣

219 int sys_close(unsigned int fd)

220 {      

221         struct file * filp;

222

    // ���ȼ�������Ч�ԡ����������ļ����ֵ���ڳ���ͬʱ�ܴ򿪵��ļ���NR_OPEN���򷵻�

    // �����루������Ч����Ȼ��λ���̵�ִ��ʱ�ر��ļ����λͼ��Ӧλ�������ļ������Ӧ

    // ���ļ��ṹָ����NULL���򷵻س����롣

223         if (fd >= NR_OPEN)

224                 return -EINVAL;

225         current->close_on_exec &= ~(1<<fd);

226         if (!(filp = current->filp[fd]))

227                 return -EINVAL;

    // �����ø��ļ�������ļ��ṹָ��ΪNULL�����ڹر��ļ�֮ǰ����Ӧ�ļ��ṹ�еľ������

    // �����Ѿ�Ϊ0����˵���ں˳�����ͣ�������򽫶�Ӧ�ļ��ṹ�����ü�����1����ʱ�������

    // ��Ϊ0����˵����������������ʹ�ø��ļ������Ƿ���0���ɹ�����������ü����ѵ���0��

    // ˵�����ļ��Ѿ�û�н������ã����ļ��ṹ�ѱ�Ϊ���С����ͷŸ��ļ�i�ڵ㣬����0��

228         current->filp[fd] = NULL;

229         if (filp->f_count == 0)

230                 panic("Close: file count is 0");

231         if (--filp->f_count)

232                 return (0);

233         iput(filp->f_inode);

234         return (0);

235 }

236