����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