1 /*
2 * linux/fs/bitmap.c
3 *
4 * (C) 1991 Linus Torvalds
5 */
6
7 /* bitmap.c contains the code that handles the inode and block bitmaps */
/* bitmap.c�����д���i�ڵ�ʹ��̿�λͼ�Ĵ��� */
8 #include <string.h> // �ַ���ͷ�ļ�����Ҫ������һЩ�й��ַ���������Ƕ�뺯����
9 // ����ʹ�������е�memset()������
10 #include <linux/sched.h> // ���ȳ���ͷ�ļ�����������ṹtask_struct������0���ݡ�
11 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣
12
//// ��ָ����ַ��addr������һ��1024�ֽ��ڴ����㡣
// ���룺eax = 0��ecx = �Գ���Ϊ��λ�����ݿ鳤�ȣ�BLOCK_SIZE/4����edi = ָ����ʼ��
// ַaddr��
13 #define clear_block(addr) \
14 __asm__("cld\n\t" \ // �巽��λ��
15 "rep\n\t" \ // �ظ�ִ�д洢���ݣ�0����
16 "stosl" \
17 ::"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di")
18
//// ��ָ����ַ��ʼ�ĵ�nr��λƫ�ƴ��ı���λ��λ��nr�ɴ���32����������ԭ����λֵ��
// ���룺%0 -eax������ֵ����%1 -eax(0)��%2 -nr��λƫ��ֵ��%3 -(addr)��addr�����ݡ�
// ��20�ж�����һ���ֲ��Ĵ�������res���ñ�������������ָ����eax�Ĵ����У��Ա���
// ��Ч���ʺͲ��������ֶ�������ķ�����Ҫ������Ƕ�������С���ϸ˵���μ�gcc�ֲ�
// ����ָ���Ĵ����еı������������궨����һ��������ʽ���ñ���ʽֵ�����res��ֵ��
// ��21���ϵ�btslָ�����ڲ��Բ����ñ���λ��Bit Test and Set�����ѻ���ַ��%3����
// ����λƫ��ֵ��%2����ָ���ı���λֵ�ȱ��浽��λ��־CF�У�Ȼ�����øñ���λΪ1��
// ָ��setb���ڸ��ݽ�λ��־CF���ò�������%al�������CF=1��%al =1������%al =0��
19 #define set_bit(nr,addr) ({\
20 register int res __asm__("ax"); \
21 __asm__ __volatile__("btsl %2,%3\n\tsetb %%al": \
22 "=a" (res):"" (0),"r" (nr),"m" (*(addr))); \
23 res;})
24
//// ��λָ����ַ��ʼ�ĵ�nrλƫ�ƴ��ı���λ������ԭ����λֵ�ķ��롣
// ���룺%0 -eax������ֵ����%1 -eax(0)��%2 -nr��λƫ��ֵ��%3 -(addr)��addr�����ݡ�
// ��27���ϵ�btrlָ�����ڲ��Բ���λ����λ��Bit Test and Reset�����������������
// btsl���ƣ����Ǹ�λָ������λ��ָ��setnb���ڸ��ݽ�λ��־CF���ò�������%al����
// ���CF = 1��%al = 0������%al = 1��
25 #define clear_bit(nr,addr) ({\
26 register int res __asm__("ax"); \
27 __asm__ __volatile__("btrl %2,%3\n\tsetnb %%al": \
28 "=a" (res):"" (0),"r" (nr),"m" (*(addr))); \
29 res;})
30
//// ��addr��ʼѰ�ҵ�1��0ֵ����λ��
// ���룺%0 - ecx(����ֵ)��%1 - ecx(0)��%2 - esi(addr)��
// ��addrָ����ַ��ʼ��λͼ��Ѱ�ҵ�1����0�ı���λ�����������addr�ı���λƫ��
// ֵ���ء�addr�ǻ�����������ĵ�ַ��ɨ��Ѱ�ҵķ�Χ��1024�ֽڣ�8192����λ����
31 #define find_first_zero(addr) ({ \
32 int __res; \
33 __asm__("cld\n" \ // �巽��λ��
34 "1:\tlodsl\n\t" \ // ȡ[esi]��eax��
35 "notl %%eax\n\t" \ // eax��ÿλȡ����
36 "bsfl %%eax,%%edx\n\t" \ // ��λ0ɨ��eax����1�ĵ�1��λ����ƫ��ֵ��edx��
37 "je 2f\n\t" \ // ���eax��ȫ��0������ǰ��ת�����2��(40��)��
38 "addl %%edx,%%ecx\n\t" \ // ƫ��ֵ����ecx��ecx��λͼ��0ֵλ��ƫ��ֵ����
39 "jmp 3f\n" \ // ��ǰ��ת�����3������������
40 "2:\taddl $32,%%ecx\n\t" \ // δ�ҵ�0ֵλ����ecx��1�����ֵ�λƫ����32��
41 "cmpl $8192,%%ecx\n\t" \ // �Ѿ�ɨ����8192����λ��1024�ֽڣ�����
42 "jl 1b\n" \ // ����û��ɨ����1�����ݣ�����ǰ��ת�����1����
43 "3:" \ // ��������ʱecx����λƫ������
44 :"=c" (__res):"c" (0),"S" (addr):"ax","dx","si"); \
45 __res;})
46
//// �ͷ��豸dev���������е�����block��
// ��λָ������block��Ӧ������λͼ����λ���ɹ���1������0��
// ������dev���豸�ţ�block������ţ��̿�ţ���
47 int free_block(int dev, int block)
48 {
49 struct super_block * sb;
50 struct buffer_head * bh;
51
// ����ȡ�豸dev���ļ�ϵͳ�ij�������Ϣ������������������ʼ����ź��ļ�ϵͳ����
// ��������Ϣ�жϲ���block����Ч�ԡ����ָ���豸�����鲻���ڣ������ͣ����������
// ��С��������������1������Ŀ�Ż��ߴ����豸������������Ҳ����ͣ����
52 if (!(sb = get_super(dev))) // fs/super.c����56��
53 panic("trying to free block on nonexistent device");
54 if (block < sb->s_firstdatazone || block >= sb->s_nzones)
55 panic("trying to free block not in datazone");
56 bh = get_hash_table(dev,block);
// Ȼ��� hash����Ѱ�Ҹÿ����ݡ����ҵ������ж�����Ч�ԣ��������ĺ��±�־���ͷ�
// �����ݿ顣�öδ������Ҫ��;�����������Ŀǰ�����ڸ��ٻ������У����ͷŶ�Ӧ�Ļ�
// ��顣
57 if (bh) {
58 if (bh->b_count > 1) { // �����������1�������brelse()��
59 brelse(bh); // b_count--���˳����ÿ黹�����á�
60 return 0;
61 }
62 bh->b_dirt=0; // ����λ���ĺ��Ѹ��±�־��
63 bh->b_uptodate=0;
64 if (bh->b_count) // ����ʱb_countΪ1�������brelse()�ͷ�֮��
65 brelse(bh);
66 }
// �������Ǹ�λblock������λͼ�еı���λ����0�����ȼ���block����������ʼ�����
// ��������ţ���1��ʼ��������Ȼ�������(����)λͼ���в�������λ��Ӧ�ı���λ��
// �����Ӧ����λԭ������0�������ͣ��������1���������1024�ֽڣ���8192����λ��
// ��� block/8192 ���ɼ����ָ���� block ����λͼ�е��ĸ����ϡ��� block&8191 ��
// �Եõ�block������λͼ��ǰ���еı���ƫ��λ�á�
67 block -= sb->s_firstdatazone - 1 ; // ��block = block - ( s_firstdatazone -1);
68 if (clear_bit(block&8191,sb->s_zmap[block/8192]->b_data)) {
69 printk("block (%04x:%d) ",dev,block+sb->s_firstdatazone-1);
70 printk("free_block: bit already cleared\n");
71 }
// �������Ӧ����λͼ���ڻ��������ı�־��
72 sb->s_zmap[block/8192]->b_dirt = 1;
73 return 1;
74 }
75
////���豸����һ�����飨�̿飬���飩��
// ��������ȡ���豸�ij����飬���ڳ������е�����λͼ��Ѱ�ҵ�һ��0ֵ����λ������
// һ���������飩��Ȼ����λ��Ӧ����������λͼ�еı���λ������Ϊ�������ڻ�
// ������ȡ��һ���Ӧ����顣��û�������㣬���������Ѹ��±�־�����ı�־��
// ����������š�����ִ�гɹ�������ţ��̿�ţ�������0��
76 int new_block(int dev)
77 {
78 struct buffer_head * bh;
79 struct super_block * sb;
80 int i,j;
81
// ���Ȼ�ȡ�豸dev�ij����顣���ָ���豸�ij����鲻���ڣ������ͣ����Ȼ��ɨ���ļ�
// ϵͳ��8������λͼ��Ѱ����0ֵ����λ����Ѱ�ҿ������飬��ȡ���ø������
// ��š� ���ȫ��ɨ����8������λͼ�����б���λ��i >= 8 �� j >= 8192����û�ҵ�
// 0ֵ����λ����λͼ���ڵĻ����ָ����Ч(bh = NULL)�� ����0�˳���û�п������飩��
82 if (!(sb = get_super(dev)))
83 panic("trying to get new block from nonexistant device");
84 j = 8192;
85 for (i=0 ; i<8 ; i++)
86 if (bh=sb->s_zmap[i])
87 if ((j=find_first_zero(bh->b_data))<8192)
88 break;
89 if (i>=8 || !bh || j>=8192)
90 return 0;
// ���������ҵ���������j��Ӧ����λͼ�еı���λ������Ӧ����λ�Ѿ���λ�������
// ͣ���������ô��λͼ�Ķ�Ӧ�����������ı�־����Ϊ����λͼ����ʾ������������
// �����ռ�������������λͼ�б���λƫ��ֵ��ʾ����������ʼ������Ŀ�ţ����
// ������Ҫ������������1������Ŀ�ţ���jת��������š���ʱ������������
// ���豸�ϵ�������������˵��ָ�������ڶ�Ӧ�豸�ϲ����ڡ�����ʧ�ܣ�����0�˳���
91 if (set_bit(j,bh->b_data))
92 panic("new_block: bit already set");
93 bh->b_dirt = 1;
94 j += i*8192 + sb->s_firstdatazone-1;
95 if (j >= sb->s_nzones)
96 return 0;
// Ȼ���ڸ��ٻ�������Ϊ���豸��ָ���������ȡ��һ������飬�����ػ����ͷָ�롣
// ��Ϊ��ȡ�õ����������ô���һ��Ϊ1��getblk()�л����ã����������Ϊ1��ͣ����
// ������������㣬���������Ѹ��±�־�����ı�־��Ȼ���ͷŶ�Ӧ����飬����
// ����š�
97 if (!(bh=getblk(dev,j)))
98 panic("new_block: cannot get block");
99 if (bh->b_count != 1)
100 panic("new block: count is != 1");
101 clear_block(bh->b_data);
102 bh->b_uptodate = 1;
103 bh->b_dirt = 1;
104 brelse(bh);
105 return j;
106 }
107
//// �ͷ�ָ����i�ڵ㡣
// �ú��������жϲ���������i�ڵ�ŵ���Ч�ԺͿ��ͷ��ԡ���i�ڵ���Ȼ��ʹ��������
// ���ͷš�Ȼ�����ó�������Ϣ��i�ڵ�λͼ���в�������λi�ڵ�Ŷ�Ӧ��i�ڵ�λͼ��
// ����λ�������i�ڵ�ṹ��
108 void free_inode(struct m_inode * inode)
109 {
110 struct super_block * sb;
111 struct buffer_head * bh;
112
// �����жϲ�����������Ҫ�ͷŵ�i�ڵ���Ч�Ի�Ϸ��ԡ����i�ڵ�ָ��=NULL�����˳���
// ���i�ڵ��ϵ��豸���ֶ�Ϊ0��˵���ýڵ�û��ʹ�á�������0��ն�Ӧi�ڵ���ռ�ڴ�
// �������ء�memset()������ include/string.h ��395�п�ʼ���������ʾ��0��дinode
// ָ��ָ������������ sizeof(*inode) ���ڴ�顣
113 if (!inode)
114 return;
115 if (!inode->i_dev) {
116 memset(inode,0,sizeof(*inode));
117 return;
118 }
// �����i�ڵ㻹�������������ã������ͷţ�˵���ں������⣬ͣ��������ļ�������
// ��Ϊ0�����ʾ���������ļ�Ŀ¼����ʹ�øýڵ㣬���Ҳ��Ӧ�ͷţ���Ӧ�÷Żصȡ�
119 if (inode->i_count>1) {
120 printk("trying to free inode with count=%d\n",inode->i_count);
121 panic("free_inode");
122 }
123 if (inode->i_nlinks)
124 panic("trying to free inode with links");
// ���ж���i�ڵ�ĺ�����֮�����ǿ�ʼ�����䳬������Ϣ�����е�i�ڵ�λͼ���в�����
// ����ȡi�ڵ������豸�ij����飬�����豸�Ƿ���ڡ�Ȼ���ж�i�ڵ�ŵķ�Χ�Ƿ���ȷ��
// ��� i�ڵ�ŵ���0 �� ���ڸ��豸�� i�ڵ��������������0��i�ڵ㱣��û��ʹ�ã���
// �����i�ڵ��Ӧ�Ľڵ�λͼ�����ڣ����������Ϊһ��������i�ڵ�λͼ�� 8192 ��
// ��λ�����i_num>>13����i_num/8192�����Եõ���ǰi�ڵ�����ڵ�s_imap[]�����
// ���̿顣
125 if (!(sb = get_super(inode->i_dev)))
126 panic("trying to free inode on nonexistent device");
127 if (inode->i_num < 1 || inode->i_num > sb->s_ninodes)
128 panic("trying to free inode 0 or nonexistant inode");
129 if (!(bh=sb->s_imap[inode->i_num>>13]))
130 panic("nonexistent imap in superblock");
// �������Ǹ�λi�ڵ��Ӧ�Ľڵ�λͼ�еı���λ������ñ���λ�Ѿ�����0������ʾ����
// ������Ϣ�������i�ڵ�λͼ���ڻ��������ı�־������ո�i�ڵ�ṹ��ռ�ڴ�����
131 if (clear_bit(inode->i_num&8191,bh->b_data))
132 printk("free_inode: bit already cleared.\n\r");
133 bh->b_dirt = 1;
134 memset(inode,0,sizeof(*inode));
135 }
136
//// Ϊ�豸dev����һ����i�ڵ㡣��ʼ�������ظ���i�ڵ��ָ�롣
// ���ڴ�i�ڵ���л�ȡһ������i�ڵ�������i�ڵ�λͼ����һ������i�ڵ㡣
137 struct m_inode * new_inode(int dev)
138 {
139 struct m_inode * inode;
140 struct super_block * sb;
141 struct buffer_head * bh;
142 int i,j;
143
// ���ȴ��ڴ�i�ڵ����inode_table���л�ȡһ������i�ڵ������ȡָ���豸�ij�����
// �ṹ�� Ȼ��ɨ�賬������8��i�ڵ�λͼ��Ѱ����0����λ��Ѱ�ҿ��нڵ㣬��ȡ����
// ��i�ڵ�Ľڵ�š����ȫ��ɨ���껹û�ҵ�������λͼ���ڵĻ������Ч��bh = NULL����
// ��Ż���ǰ�����i�ڵ���е�i�ڵ㣬�����ؿ�ָ���˳���û�п���i�ڵ㣩��
144 if (!(inode=get_empty_inode())) // fs/inode.c����197��
145 return NULL;
146 if (!(sb = get_super(dev))) // fs/super.c����56��
147 panic("new_inode with unknown device");
148 j = 8192;
149 for (i=0 ; i<8 ; i++)
150 if (bh=sb->s_imap[i])
151 if ((j=find_first_zero(bh->b_data))<8192)
152 break;
153 if (!bh || j >= 8192 || j+i*8192 > sb->s_ninodes) {
154 iput(inode);
155 return NULL;
156 }
// ���������Ѿ��ҵ��˻�δʹ�õ�i�ڵ��j��������λi�ڵ�j��Ӧ��i�ڵ�λͼ��Ӧ��
// ��λ������Ѿ���λ�����������Ȼ����i�ڵ�λͼ���ڻ�������ı�־������ʼ��
// ��i�ڵ�ṹ��i_ctime��i�ڵ����ݸı�ʱ�䣩��
157 if (set_bit(j,bh->b_data))
158 panic("new_inode: bit already set");
159 bh->b_dirt = 1;
160 inode->i_count=1; // ���ü�����
161 inode->i_nlinks=1; // �ļ�Ŀ¼����������
162 inode->i_dev=dev; // i�ڵ����ڵ��豸�š�
163 inode->i_uid=current->euid; // i�ڵ������û�id��
164 inode->i_gid=current->egid; // ��id��
165 inode->i_dirt=1; // ���ı�־��λ��
166 inode->i_num = j + i*8192; // ��Ӧ�豸�е�i�ڵ�š�
167 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; // ����ʱ�䡣
168 return inode; // ���ظ�i�ڵ�ָ�롣
169 }
170