����9-3 linux/kernel/blk_drv/ll_rw_blk.c
1 /*
2 * linux/kernel/blk_dev/ll_rw.c
3 *
4 * (C) 1991 Linus Torvalds
5 */
6
7 /*
8 * This handles all read/write requests to block devices
9 */
10 #include <errno.h> // �����ͷ�ļ�������ϵͳ�и��ֳ����š�
11 #include <linux/sched.h> // ���ȳ���ͷ�ļ�������������ṹtask_struct������0���ݵȡ�
12 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣
13 #include <asm/system.h> // ϵͳͷ�ļ������������û���������/�ж��ŵȵ�Ƕ��ʽ���ꡣ
14
15 #include "blk.h" // ���豸ͷ�ļ��������������ݽṹ�����豸���ݽṹ�ͺ����Ϣ��
16
17 /*
18 * The request-struct contains all necessary data
19 * to load a nr of sectors into memory
20 */
/*
* ����ṹ�к��м���nr���������ݵ��ڴ���ȥ�����б������Ϣ��
*/
// �����������������NR_REQUEST = 32�������
21 struct request request[NR_REQUEST];
22
23 /*
24 * used to wait on when there are no free requests
25 */
/*
* ����������������û�п�����ʱ���̵���ʱ�ȴ�����
*/
26 struct task_struct * wait_for_request = NULL;
27
28 /* blk_dev_struct is:
29 * do_request-address
30 * next-request
31 */
/* blk_dev_struct���豸�ṹ�ǣ����μ��ļ�kernel/blk_drv/blk.h����45�У�
* do_request-address // ��Ӧ���豸�ŵ�����������ָ�롣
* current-request // ���豸����һ������
*/
// ���豸���顣������ʹ�����豸����Ϊ������ʵ�����ݽ��ڸ����豸���������ʼ��ʱ���롣
// ���磬Ӳ�����������ʼ��ʱ��hd.c��343�У�����һ����伴��������blk_dev[3]�����ݡ�
32 struct blk_dev_struct blk_dev[NR_BLK_DEV] = {
33 { NULL, NULL }, /* no_dev */ // 0 - ���豸��
34 { NULL, NULL }, /* dev mem */ // 1 - �ڴ档
35 { NULL, NULL }, /* dev fd */ // 2 - �����豸��
36 { NULL, NULL }, /* dev hd */ // 3 - Ӳ���豸��
37 { NULL, NULL }, /* dev ttyx */ // 4 - ttyx�豸��
38 { NULL, NULL }, /* dev tty */ // 5 - tty�豸��
39 { NULL, NULL } /* dev lp */ // 6 - lp��ӡ���豸��
40 };
41
42 /*
43 * blk_size contains the size of all block-devices:
44 *
45 * blk_size[MAJOR][MINOR]
46 *
47 * if (!blk_size[MAJOR]) then no minor size checking is done.
48 */
/*
* blk_size���麬�����п��豸�Ĵ�С������������
* blk_size[MAJOR][MINOR]
* ��� (!blk_size[MAJOR])���ؼ�����豸�Ŀ�������
*/
// �豸���ݿ�����ָ�����顣ÿ��ָ����ָ��ָ�����豸�ŵ��ܿ������顣���ܿ�������ÿһ
// ���Ӧ���豸��ȷ����һ�����豸����ӵ�е����ݿ�������1���С = 1KB����
49 int * blk_size[NR_BLK_DEV] = { NULL, NULL, };
50
// ����ָ������顣
// ���ָ���Ļ�����Ѿ�������������������ʹ�Լ�˯�ߣ������жϵصȴ�����ֱ����ִ�н�
// ��������������ȷ�ػ��ѡ�
51 static inline void lock_buffer(struct buffer_head * bh)
52 {
53 cli(); // ���ж����ɡ�
54 while (bh->b_lock) // ����������ѱ�������˯�ߣ�ֱ��������������
55 sleep_on(&bh->b_wait);
56 bh->b_lock=1; // ���������û�������
57 sti(); // ���жϡ�
58 }
59
// �ͷţ������������Ļ�������
// �ú�����blk.h�ļ��е�ͬ��������ȫһ����
60 static inline void unlock_buffer(struct buffer_head * bh)
61 {
62 if (!bh->b_lock) // ����û�����û�б����������ӡ������Ϣ��
63 printk("ll_rw_block.c: buffer not locked\n\r");
64 bh->b_lock = 0; // ��������־��
65 wake_up(&bh->b_wait); // ���ѵȴ��û�����������
66 }
67
68 /*
69 * add-request adds a request to the linked list.
70 * It disables interrupts so that it can muck with the
71 * request-lists in peace.
72 *
73 * Note that swapping requests always go before other requests,
74 * and are done in the order they appear.
75 */
/*
* add-request()�������м���һ�����������ر��жϣ�
* �������ܰ�ȫ�ش������������ˡ�
*
* ע�⣬����������������������֮ǰ���������������dz�
* �ֵ�˳����ɡ�
*/
//// ��������������
// ����dev��ָ�����豸�ṹָ�룬�ýṹ���д����������ָ��͵�ǰ����������ָ�룻
// req�������ú����ݵ�������ṹָ�롣
// ���������Ѿ����úõ�������req���ӵ�ָ���豸�������������С�������豸�ĵ�ǰ����
// ������ָ��Ϊ�գ����������reqΪ��ǰ��������̵����豸�����������������Ͱ�
// req��������뵽�������������С�
76 static void add_request(struct blk_dev_struct * dev, struct request * req)
77 {
78 struct request * tmp;
79
// �����ٽ�һ���Բ����ṩ���������ָ��ͱ�־����ʼ���á��ÿ��������е���һ������ָ
// �룬���жϲ������������ػ��������־��
80 req->next = NULL;
81 cli(); // ���жϡ�
82 if (req->bh)
83 req->bh->b_dirt = 0; // �建�������ࡱ��־��
// Ȼ��鿴ָ���豸�Ƿ��е�ǰ��������鿴�豸�Ƿ���æ�����ָ���豸dev��ǰ������
// ��current_request���Ӷ�Ϊ�գ����ʾĿǰ���豸û������������ǵ�1�������Ҳ��
// Ψһ��һ������˿ɽ����豸��ǰ����ָ��ֱ��ָ��������������ִ����Ӧ�豸������
// ������
84 if (!(tmp = dev->current_request)) {
85 dev->current_request = req;
86 sti(); // ���жϡ�
87 (dev->request_fn)(); // ִ��������������Ӳ����do_hd_request()��
88 return;
89 }
// ���Ŀǰ���豸�Ѿ��е�ǰ�������ڴ��������������õ����㷨������Ѳ���λ�ã�Ȼ��
// ��ǰ��������뵽���������С������������У�����жϳ�������������Ļ����ͷָ��գ�
// ��û�л���飬��ô����Ҫ��һ������Ѿ��п��õĻ���顣�������ǰ����λ�ã�tmp
// ֮���Ŀ�������ͷָ�벻�գ���ѡ�����λ�á������˳�ѭ���������������˴���
// ����жϲ��˳������������㷨���������ô��̴�ͷ���ƶ�������С���Ӷ����ƣ����٣�
// Ӳ�̷���ʱ�䡣
// ����forѭ����if������ڰ�req��ָ��������������У������������е����������Ƚϣ�
// �ҳ�req����ö��е���ȷλ��˳��Ȼ���ж�ѭ��������req���뵽�ö�����ȷλ�ô���
90 for ( ; tmp->next ; tmp=tmp->next) {
91 if (!req->bh)
92 if (tmp->next->bh)
93 break;
94 else
95 continue;
96 if ((IN_ORDER(tmp,req) ||
97 !IN_ORDER(tmp,tmp->next)) &&
98 IN_ORDER(req,tmp->next))
99 break;
100 }
101 req->next=tmp->next;
102 tmp->next=req;
103 sti();
104 }
105
//// ����������������������
// ����major�����豸�ţ�rw��ָ�����bh�Ǵ�����ݵĻ�����ͷָ�롣
106 static void make_request(int major,int rw, struct buffer_head * bh)
107 {
108 struct request * req;
109 int rw_ahead;
110
111 /* WRITEA/READA is special case - it is not really needed, so if the */
112 /* buffer is locked, we just forget about it, else it's a normal read */
/* WRITEA/READA��һ��������� - ���Dz��DZ�Ҫ����������������Ѿ�������*/
/* ���ǾͲ��ù���������Ļ���ֻ��һ��һ��Ķ������� */
// ����'READ'��'WRITE'�����'A'�ַ�����Ӣ�ĵ���Ahead����ʾ��ǰԤ��/д���ݿ����˼��
// �ú������ȶ�����READA/WRITEA���������һЩ���������������������ָ���Ļ�����
// ����ʹ�ö��ѱ�����ʱ���ͷ���Ԥ��/д���������Ϊ��ͨ��READ/WRITE������в�����
// ���⣬�����������������Ȳ��� READҲ���� WRITE�����ʾ�ں˳����д�����ʾ������
// Ϣ��ͣ����ע�⣬��������֮ǰ������Ϊ�����Ƿ���Ԥ��/д���������˱�־rw_ahead��
113 if (rw_ahead = (rw == READA || rw == WRITEA)) {
114 if (bh->b_lock)
115 return;
116 if (rw == READA)
117 rw = READ;
118 else
119 rw = WRITE;
120 }
121 if (rw!=READ && rw!=WRITE)
122 panic("Bad block dev command, must be R/W/RA/WA");
123 lock_buffer(bh);
124 if ((rw == WRITE && !bh->b_dirt) || (rw == READ && bh->b_uptodate)) {
125 unlock_buffer(bh);
126 return;
127 }
128 repeat:
129 /* we don't allow the write-requests to fill up the queue completely:
130 * we want some room for reads: they take precedence. The last third
131 * of the requests are only for reads.
132 */
/* ���Dz����ö�����ȫ����д�����������ҪΪ��������һЩ�ռ䣺������
* �����ȵġ�������еĺ�����֮һ�ռ�����ڶ������
*/
// �ã��������DZ���Ϊ���������ɲ����Ӷ�/д�������ˡ�����������Ҫ������������Ѱ�ҵ�
// һ��������ۣ��������������������̴���������ĩ�˿�ʼ����������Ҫ���ڶ�
// ������������ֱ�ӴӶ���ĩβ��ʼ������������д�����ֻ�ܴӶ���2/3�������ͷ����
// ���������롣�������ǿ�ʼ�Ӻ���ǰ������������ṹrequest���豸�ֶ�devֵ = -1ʱ��
// ��ʾ����δ��ռ�ã����У������û��һ���ǿ��еģ���ʱ����������ָ���Ѿ�����Խ��ͷ
// ��������鿴�˴������Ƿ�����ǰ��/д��READA��WRITEA���������������˴����������
// �����ñ������������˯�ߣ��Եȴ���������ڳ��������һ����������������С�
133 if (rw == READ)
134 req = request+NR_REQUEST; // ���ڶ�����ָ��ָ�����β����
135 else
136 req = request+((NR_REQUEST*2)/3); // ����д����ָ��ָ�����2/3����
137 /* find an empty request */ /* ����һ���������� */
138 while (--req >= request)
139 if (req->dev<0)
140 break;
141 /* if none found, sleep on new requests: check for rw_ahead */
/* ���û���ҵ���������øô����������˯�ߣ������Ƿ���ǰ��/д */
142 if (req < request) { // �����������ͷ�����������
143 if (rw_ahead) { // ��������ǰ��/д�������˳���
144 unlock_buffer(bh);
145 return;
146 }
147 sleep_on(&wait_for_request); // �����˯�ߣ������ٲ鿴������С�
148 goto repeat; // ��ת110�С�
149 }
150 /* fill up the request-info, and add it to the queue */
/* ���������������д������Ϣ���������������� */
// OK������ִ�е������ʾ���ҵ�һ����������� �������������úõ����������͵���
// add_request()�������ӵ���������У������˳�������ṹ��μ�blk_drv/blk.h��23�С�
// req->sector�Ƕ�д��������ʼ�����ţ�req->buffer�������������ݵĻ�������
151 req->dev = bh->b_dev; // �豸�š�
152 req->cmd = rw; // ����(READ/WRITE)��
153 req->errors=0; // ����ʱ�����Ĵ��������
154 req->sector = bh->b_blocknr<<1; // ��ʼ���������ת����������(1��=2����)��
155 req->nr_sectors = 2; // ����������Ҫ��д����������
156 req->buffer = bh->b_data; // ���������ָ��ָ�����д�����ݻ�������
157 req->waiting = NULL; // ����ȴ�����ִ����ɵĵط���
158 req->bh = bh; // �����ͷָ�롣
159 req->next = NULL; // ָ����һ�����
160 add_request(major+blk_dev,req); // ����������������(blk_dev[major],req)��
161 }
162
//// �ͼ�ҳ���д������Low Level Read Write Page����
// ��ҳ�棨4K��Ϊ��λ���ʿ��豸���ݣ���ÿ�ζ�/д8���������μ�����ll_rw_blk()������
163 void ll_rw_page(int rw, int dev, int page, char * buffer)
164 {
165 struct request * req;
166 unsigned int major = MAJOR(dev);
167
// ���ȶԺ��������ĺϷ��Խ��м�⡣����豸���豸�Ų����ڻ��߸��豸���������������
// ���ڣ�����ʾ������Ϣ�������ء������������������Ȳ��� READҲ���� WRITE�����ʾ
// �ں˳����д�����ʾ������Ϣ��ͣ����
168 if (major >= NR_BLK_DEV || !(blk_dev[major].request_fn)) {
169 printk("Trying to read nonexistent block-device\n\r");
170 return;
171 }
172 if (rw!=READ && rw!=WRITE)
173 panic("Bad block dev command, must be R/W");
// �ڲ�����������ɺ�����������ҪΪ���β����������������������Ҫ������������
// Ѱ�ҵ�һ��������ۣ��������������������̴���������ĩ�˿�ʼ���������ǿ�ʼ��
// ����ǰ������������ṹrequest���豸�ֶ�devֵ <0 ʱ����ʾ����δ��ռ�ã����У���
// ���û��һ���ǿ��еģ���ʱ����������ָ���Ѿ�����Խ��ͷ���������ñ������������˯
// �ߣ��Եȴ���������ڳ��������һ����������������С�
174 repeat:
175 req = request+NR_REQUEST; // ��ָ��ָ�����β����
176 while (--req >= request)
177 if (req->dev<0)
178 break;
179 if (req < request) {
180 sleep_on(&wait_for_request); // ˯�ߣ������ٲ鿴������С�
181 goto repeat; // ��ת��174��ȥ����������
182 }
183 /* fill up the request-info, and add it to the queue */
/* ���������������д������Ϣ���������������� */
// OK������ִ�е������ʾ���ҵ�һ����������� �����������ú���������ѵ�ǰ����
// ��Ϊ�����ж�˯���жϺ�ȥ����add_request()�������ӵ���������У�Ȼ��ֱ�ӵ���
// ���Ⱥ����õ�ǰ����˯�ߵȴ�ҳ��ӽ����豸�ж��롣���ﲻ��make_request()��������
// ֱ���˳�������������schedule()������Ϊmake_request()��������2���������ݡ�����
// ����Ҫ�Խ����豸��/д8����������Ҫ���ϳ���ʱ�䡣��˵�ǰ���̿϶���Ҫ�ȴ���˯�ߡ�
// �������ֱ�Ӿ��ý���ȥ˯���ˣ�ʡ���ڳ��������ط���Ҫ������Щ�жϲ�����
184 req->dev = dev; // �豸�š�
185 req->cmd = rw; // ����(READ/WRITE)��
186 req->errors = 0; // ��������������
187 req->sector = page<<3; // ��ʼ��д������
188 req->nr_sectors = 8; // ���������
189 req->buffer = buffer; // ���ݻ�������
190 req->waiting = current; // ��ǰ���̽��������ȴ����С�
191 req->bh = NULL; // �����ͷָ�루���ø��ٻ��壩��
192 req->next = NULL; // ��һ��������ָ�롣
193 current->state = TASK_UNINTERRUPTIBLE; // ��Ϊ�����ж�״̬��
194 add_request(major+blk_dev,req); // ����������������
195 schedule();
196 }
197
//// �ͼ����ݿ��д������Low Level Read Write Block����
// �ú����ǿ��豸����������ϵͳ�������ֵĽӿں�����ͨ����fs/buffer.c�����б����á�
// ��Ҫ�����Ǵ������豸��д��������뵽ָ�����豸��������С�ʵ�ʵĶ�д��������
// ���豸��request_fn()������ɡ�����Ӳ�̲������ú�����do_hd_request()����������
// �����ú�����do_fd_request()����������������do_rd_request()�� ���⣬�ڵ��øú�
// ��֮ǰ����������Ҫ���ȰѶ�/д���豸����Ϣ�����ڻ����ͷ�ṹ�У����豸�š���š�
// ������rw �C READ��READA��WRITE��WRITEA�����bh �C ���ݻ����ͷָ�롣
198 void ll_rw_block(int rw, struct buffer_head * bh)
199 {
200 unsigned int major; // ���豸�ţ�����Ӳ����3����
201
// ����豸���豸�Ų����ڻ��߸��豸������������������ڣ�����ʾ������Ϣ�������ء�
// ��������������������
202 if ((major=MAJOR(bh->b_dev)) >= NR_BLK_DEV ||
203 !(blk_dev[major].request_fn)) {
204 printk("Trying to read nonexistent block-device\n\r");
205 return;
206 }
207 make_request(major,rw,bh);
208 }
209
//// ���豸��ʼ���������ɳ�ʼ������main.c���á�
// ��ʼ���������飬��������������Ϊ������(dev = -1)����32��(NR_REQUEST = 32)��
210 void blk_dev_init(void)
211 {
212 int i;
213
214 for (i=0 ; i<NR_REQUEST ; i++) {
215 request[i].dev = -1;
216 request[i].next = NULL;
217 }
218 }
219