⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ll_rw_blk.c.txt

📁 Linux块设备驱动分析与模拟实现
💻 TXT
📖 第 1 页 / 共 2 页
字号:
254                             !req->waiting &&
255                             req->cmd == rw &&
256                             req->sector - count == sector &&
257                             req->nr_sectors < 254)
258                         {
259                                 req->nr_sectors += count;
260                                 bh->b_reqnext = req->bh;
261                                 req->buffer = bh->b_data;
262                                 req->current_nr_sectors = count;
263                                 req->sector = sector;
264                                 bh->b_dirt = 0;
265                                 req->bh = bh;
266                                 sti();
267                                 return;
268                         }    
269 
270                         req = req->next;
271                 }
272         }
273 
274 /* find an unused request. */
275         req = get_request(max_req, bh->b_dev);
276 
277 /* if no request available: if rw_ahead, forget it; otherwise try again. */
278         if (! req) {
279                 if (rw_ahead) {
280                         sti();
281                         unlock_buffer(bh);
282                         return;
283                 }
284                 sleep_on(&wait_for_request);
285                 sti();
286                 goto repeat;
287         }
288 
289 /* we found a request. */
290         sti();
291 
292 /* fill up the request-info, and add it to the queue */
293         req->cmd = rw;
294         req->errors = 0;
295         req->sector = sector;
296         req->nr_sectors = count;
297         req->current_nr_sectors = count;
298         req->buffer = bh->b_data;
299         req->waiting = NULL;
300         req->bh = bh;
301         req->bhtail = bh;
302         req->next = NULL;
303         add_request(major+blk_dev,req);
304 }
305 
306 void ll_rw_page(int rw, int dev, int page, char * buffer)
307 {
308         struct request * req;
309         unsigned int major = MAJOR(dev);
310 
311         if (major >= MAX_BLKDEV || !(blk_dev[major].request_fn)) {
312                 printk("Trying to read nonexistent block-device %04x (%d)\n",dev,page*8);
313                 return;
314         }
315         if (rw!=READ && rw!=WRITE)
316                 panic("Bad block dev command, must be R/W");
317         if (rw == WRITE && is_read_only(dev)) {
318                 printk("Can't page to read-only device 0x%X\n",dev);
319                 return;
320         }
321         cli();
322         req = get_request_wait(NR_REQUEST, dev);
323         sti();
324 /* fill up the request-info, and add it to the queue */
325         req->cmd = rw;
326         req->errors = 0;
327         req->sector = page<<3;
328         req->nr_sectors = 8;
329         req->current_nr_sectors = 8;
330         req->buffer = buffer;
331         req->waiting = current;
332         req->bh = NULL;
333         req->next = NULL;
334         current->state = TASK_SWAPPING;
335         add_request(major+blk_dev,req);
336         schedule();
337 }
338 
339 /* This function can be used to request a number of buffers from a block
340    device. Currently the only restriction is that all buffers must belong to
341    the same device */
342 
343 void ll_rw_block(int rw, int nr, struct buffer_head * bh[])
344 {
345         unsigned int major;
346         struct request plug;
347         int plugged;
348         int correct_size;
349         struct blk_dev_struct * dev;
350         int i;
351 
352         /* Make sure that the first block contains something reasonable */
353         while (!*bh) {
354                 bh++;
355                 if (--nr <= 0)
356                         return;
357         };
358 
359         dev = NULL;
360         if ((major = MAJOR(bh[0]->b_dev)) < MAX_BLKDEV)
361                 dev = blk_dev + major;
362         if (!dev || !dev->request_fn) {
363                 printk(
364         "ll_rw_block: Trying to read nonexistent block-device %04lX (%ld)\n",
365                        (unsigned long) bh[0]->b_dev, bh[0]->b_blocknr);
366                 goto sorry;
367         }
368 
369         /* Determine correct block size for this device.  */
370         correct_size = BLOCK_SIZE;
371         if (blksize_size[major]) {
372                 i = blksize_size[major][MINOR(bh[0]->b_dev)];
373                 if (i)
374                         correct_size = i;
375         }
376 
377         /* Verify requested block sizees.  */
378         for (i = 0; i < nr; i++) {
379                 if (bh[i] && bh[i]->b_size != correct_size) {
380                         printk(
381                         "ll_rw_block: only %d-char blocks implemented (%lu)\n",
382                                correct_size, bh[i]->b_size);
383                         goto sorry;
384                 }
385         }
386 
387         if ((rw == WRITE || rw == WRITEA) && is_read_only(bh[0]->b_dev)) {
388                 printk("Can't write to read-only device 0x%X\n",bh[0]->b_dev);
389                 goto sorry;
390         }
391 
392         /* If there are no pending requests for this device, then we insert
393            a dummy request for that device.  This will prevent the request
394            from starting until we have shoved all of the blocks into the
395            queue, and then we let it rip.  */
396 
397         plugged = 0;
398         cli();
399         if (!dev->current_request && nr > 1) {
400                 dev->current_request = &plug;
401                 plug.dev = -1;
402                 plug.next = NULL;
403                 plugged = 1;
404         }
405         sti();
406         for (i = 0; i < nr; i++) {
407                 if (bh[i]) {
408                         bh[i]->b_req = 1;
409                         make_request(major, rw, bh[i]);
410                         if (rw == READ || rw == READA)
411                                 kstat.pgpgin++;
412                         else
413                                 kstat.pgpgout++;
414                 }
415         }
416         if (plugged) {
417                 cli();
418                 dev->current_request = plug.next;
419                 (dev->request_fn)();
420                 sti();
421         }
422         return;
423 
424       sorry:
425         for (i = 0; i < nr; i++) {
426                 if (bh[i])
427                         bh[i]->b_dirt = bh[i]->b_uptodate = 0;
428         }
429         return;
430 }
431 
432 void ll_rw_swap_file(int rw, int dev, unsigned int *b, int nb, char *buf)
433 {
434         int i;
435         int buffersize;
436         struct request * req;
437         unsigned int major = MAJOR(dev);
438 
439         if (major >= MAX_BLKDEV || !(blk_dev[major].request_fn)) {
440                 printk("ll_rw_swap_file: trying to swap nonexistent block-device\n");
441                 return;
442         }
443 
444         if (rw!=READ && rw!=WRITE) {
445                 printk("ll_rw_swap: bad block dev command, must be R/W");
446                 return;
447         }
448         if (rw == WRITE && is_read_only(dev)) {
449                 printk("Can't swap to read-only device 0x%X\n",dev);
450                 return;
451         }
452         
453         buffersize = PAGE_SIZE / nb;
454 
455         for (i=0; i<nb; i++, buf += buffersize)
456         {
457                 cli();
458                 req = get_request_wait(NR_REQUEST, dev);
459                 sti();
460                 req->cmd = rw;
461                 req->errors = 0;
462                 req->sector = (b[i] * buffersize) >> 9;
463                 req->nr_sectors = buffersize >> 9;
464                 req->current_nr_sectors = buffersize >> 9;
465                 req->buffer = buf;
466                 req->waiting = current;
467                 req->bh = NULL;
468                 req->next = NULL;
469                 current->state = TASK_UNINTERRUPTIBLE;
470                 add_request(major+blk_dev,req);
471                 schedule();
472         }
473 }
474 
475 long blk_dev_init(long mem_start, long mem_end)
476 {
477         struct request * req;
478 
479         req = all_requests + NR_REQUEST;
480         while (--req >= all_requests) {
481                 req->dev = -1;
482                 req->next = NULL;
483         }
484         memset(ro_bits,0,sizeof(ro_bits));
485 #ifdef CONFIG_BLK_DEV_HD
486         mem_start = hd_init(mem_start,mem_end);
487 #endif
488 #ifdef CONFIG_BLK_DEV_XD
489         mem_start = xd_init(mem_start,mem_end);
490 #endif
491 #ifdef CONFIG_CDU31A
492         mem_start = cdu31a_init(mem_start,mem_end);
493 #endif
494 #ifdef CONFIG_MCD
495         mem_start = mcd_init(mem_start,mem_end);
496 #endif
497 #ifdef CONFIG_SBPCD
498         mem_start = sbpcd_init(mem_start, mem_end);
499 #endif CONFIG_SBPCD
500         if (ramdisk_size)
501                 mem_start += rd_init(mem_start, ramdisk_size*1024);
502         return mem_start;
503 }
504 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -