📄 ll_rw_blk.c.txt
字号:
1 /*
2 * linux/kernel/blk_dev/ll_rw.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */
6
7 /*
8 * This handles all read/write requests to block devices
9 */
10 #include <linux/sched.h>
11 #include <linux/kernel.h>
12 #include <linux/kernel_stat.h>
13 #include <linux/errno.h>
14 #include <linux/string.h>
15 #include <linux/config.h>
16 #include <linux/locks.h>
17
18 #include <asm/system.h>
19
20 #include "blk.h"
21
22 #ifdef CONFIG_SBPCD
23 extern u_long sbpcd_init(u_long, u_long);
24 #endif CONFIG_SBPCD
25
26 /*
27 * The request-struct contains all necessary data
28 * to load a nr of sectors into memory
29 */
30 static struct request all_requests[NR_REQUEST];
31
32 /*
33 * used to wait on when there are no free requests
34 */
35 struct wait_queue * wait_for_request = NULL;
36
37 /* This specifies how many sectors to read ahead on the disk. */
38
39 int read_ahead[MAX_BLKDEV] = {0, };
40
41 /* blk_dev_struct is:
42 * do_request-address
43 * next-request
44 */
45 struct blk_dev_struct blk_dev[MAX_BLKDEV] = {
46 { NULL, NULL }, /* no_dev */
47 { NULL, NULL }, /* dev mem */
48 { NULL, NULL }, /* dev fd */
49 { NULL, NULL }, /* dev hd */
50 { NULL, NULL }, /* dev ttyx */
51 { NULL, NULL }, /* dev tty */
52 { NULL, NULL }, /* dev lp */
53 { NULL, NULL }, /* dev pipes */
54 { NULL, NULL }, /* dev sd */
55 { NULL, NULL } /* dev st */
56 };
57
58 /*
59 * blk_size contains the size of all block-devices in units of 1024 byte
60 * sectors:
61 *
62 * blk_size[MAJOR][MINOR]
63 *
64 * if (!blk_size[MAJOR]) then no minor size checking is done.
65 */
66 int * blk_size[MAX_BLKDEV] = { NULL, NULL, };
67
68 /*
69 * blksize_size contains the size of all block-devices:
70 *
71 * blksize_size[MAJOR][MINOR]
72 *
73 * if (!blksize_size[MAJOR]) then 1024 bytes is assumed.
74 */
75 int * blksize_size[MAX_BLKDEV] = { NULL, NULL, };
76
77 /*
78 * look for a free request in the first N entries.
79 * NOTE: interrupts must be disabled on the way in, and will still
80 * be disabled on the way out.
81 */
82 static inline struct request * get_request(int n, int dev)
83 {
84 static struct request *prev_found = NULL, *prev_limit = NULL;
85 register struct request *req, *limit;
86
87 if (n <= 0)
88 panic("get_request(%d): impossible!\n", n);
89
90 limit = all_requests + n;
91 if (limit != prev_limit) {
92 prev_limit = limit;
93 prev_found = all_requests;
94 }
95 req = prev_found;
96 for (;;) {
97 req = ((req > all_requests) ? req : limit) - 1;
98 if (req->dev < 0)
99 break;
100 if (req == prev_found)
101 return NULL;
102 }
103 prev_found = req;
104 req->dev = dev;
105 return req;
106 }
107
108 /*
109 * wait until a free request in the first N entries is available.
110 * NOTE: interrupts must be disabled on the way in, and will still
111 * be disabled on the way out.
112 */
113 static inline struct request * get_request_wait(int n, int dev)
114 {
115 register struct request *req;
116
117 while ((req = get_request(n, dev)) == NULL)
118 sleep_on(&wait_for_request);
119 return req;
120 }
121
122 /* RO fail safe mechanism */
123
124 static long ro_bits[MAX_BLKDEV][8];
125
126 int is_read_only(int dev)
127 {
128 int minor,major;
129
130 major = MAJOR(dev);
131 minor = MINOR(dev);
132 if (major < 0 || major >= MAX_BLKDEV) return 0;
133 return ro_bits[major][minor >> 5] & (1 << (minor & 31));
134 }
135
136 void set_device_ro(int dev,int flag)
137 {
138 int minor,major;
139
140 major = MAJOR(dev);
141 minor = MINOR(dev);
142 if (major < 0 || major >= MAX_BLKDEV) return;
143 if (flag) ro_bits[major][minor >> 5] |= 1 << (minor & 31);
144 else ro_bits[major][minor >> 5] &= ~(1 << (minor & 31));
145 }
146
147 /*
148 * add-request adds a request to the linked list.
149 * It disables interrupts so that it can muck with the
150 * request-lists in peace.
151 */
152 static void add_request(struct blk_dev_struct * dev, struct request * req)
153 {
154 struct request * tmp;
155
156 req->next = NULL;
157 cli();
158 if (req->bh)
159 req->bh->b_dirt = 0;
160 if (!(tmp = dev->current_request)) {
161 dev->current_request = req;
162 (dev->request_fn)();
163 sti();
164 return;
165 }
166 for ( ; tmp->next ; tmp = tmp->next) {
167 if ((IN_ORDER(tmp,req) ||
168 !IN_ORDER(tmp,tmp->next)) &&
169 IN_ORDER(req,tmp->next))
170 break;
171 }
172 req->next = tmp->next;
173 tmp->next = req;
174
175 /* for SCSI devices, call request_fn unconditionally */
176 if (scsi_major(MAJOR(req->dev)))
177 (dev->request_fn)();
178
179 sti();
180 }
181
182 static void make_request(int major,int rw, struct buffer_head * bh)
183 {
184 unsigned int sector, count;
185 struct request * req;
186 int rw_ahead, max_req;
187
188 /* WRITEA/READA is special case - it is not really needed, so if the */
189 /* buffer is locked, we just forget about it, else it's a normal read */
190 rw_ahead = (rw == READA || rw == WRITEA);
191 if (rw_ahead) {
192 if (bh->b_lock)
193 return;
194 if (rw == READA)
195 rw = READ;
196 else
197 rw = WRITE;
198 }
199 if (rw!=READ && rw!=WRITE) {
200 printk("Bad block dev command, must be R/W/RA/WA\n");
201 return;
202 }
203 count = bh->b_size >> 9;
204 sector = bh->b_blocknr * count;
205 if (blk_size[major])
206 if (blk_size[major][MINOR(bh->b_dev)] < (sector + count)>>1) {
207 bh->b_dirt = bh->b_uptodate = 0;
208 return;
209 }
210 lock_buffer(bh);
211 if ((rw == WRITE && !bh->b_dirt) || (rw == READ && bh->b_uptodate)) {
212 unlock_buffer(bh);
213 return;
214 }
215
216 /* we don't allow the write-requests to fill up the queue completely:
217 * we want some room for reads: they take precedence. The last third
218 * of the requests are only for reads.
219 */
220 max_req = (rw == READ) ? NR_REQUEST : ((NR_REQUEST*2)/3);
221
222 /* big loop: look for a free request. */
223
224 repeat:
225 cli();
226
227 /* The scsi disk drivers completely remove the request from the queue when
228 * they start processing an entry. For this reason it is safe to continue
229 * to add links to the top entry for scsi devices.
230 */
231 if ((major == HD_MAJOR
232 || major == SCSI_DISK_MAJOR
233 || major == SCSI_CDROM_MAJOR)
234 && (req = blk_dev[major].current_request))
235 {
236 if (major == HD_MAJOR)
237 req = req->next;
238 while (req) {
239 if (req->dev == bh->b_dev &&
240 !req->waiting &&
241 req->cmd == rw &&
242 req->sector + req->nr_sectors == sector &&
243 req->nr_sectors < 254)
244 {
245 req->bhtail->b_reqnext = bh;
246 req->bhtail = bh;
247 req->nr_sectors += count;
248 bh->b_dirt = 0;
249 sti();
250 return;
251 }
252
253 if (req->dev == bh->b_dev &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -