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

📄 ll_rw_blk.c

📁 arm平台上的uclinux系统全部源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
				unlock_buffer(bh); /* Hmmph! Already have it */				return;			}			kstat.pgpgin++;			max_req = NR_REQUEST;	/* reads take precedence */			break;		case WRITEA:			rw_ahead = 1;			rw = WRITE;	/* drop into WRITE */		case WRITE:			if (!buffer_dirty(bh)) {#if 0				printk ("make_request(): buffer clean for WRITE\n");#endif				unlock_buffer(bh); /* Hmmph! Nothing to write */				return;			}			/* We don't allow the write-requests to fill up the			 * queue completely:  we want some room for reads,			 * as they take precedence. The last third of the			 * requests are only for reads.			 */			kstat.pgpgout++;			max_req = (NR_REQUEST * 2) / 3;			break;		default:			printk(KERN_ERR "make_request: bad block dev cmd,"                               " must be R/W/RA/WA\n");			unlock_buffer(bh);			return;	}/* look for a free request. */       /* Loop uses two requests, 1 for loop and 1 for the real device.        * Cut max_req in half to avoid running out and deadlocking. */        if (major == LOOP_MAJOR)	     max_req >>= 1;	/*	 * Try to coalesce the new request with old requests	 */	cli();	req = blk_dev[major].current_request;	if (!req) {		/* MD and loop can't handle plugging without deadlocking */		if (major != MD_MAJOR && major != LOOP_MAJOR)			plug_device(blk_dev + major);	} else switch (major) {	     case IDE0_MAJOR:	/* same as HD_MAJOR */	     case IDE1_MAJOR:	     case FLOPPY_MAJOR:	     case IDE2_MAJOR:	     case IDE3_MAJOR:	     case XT_DISK_MAJOR:		/*		 * The scsi disk and cdrom drivers completely remove the request		 * from the queue when they start processing an entry.  For this		 * reason it is safe to continue to add links to the top entry for		 * those devices.		 *		 * All other drivers need to jump over the first entry, as that		 * entry may be busy being processed and we thus can't change it.		 */	        req = req->next;		if (!req)			break;		/* fall through */	     case SCSI_DISK_MAJOR:	     case SCSI_CDROM_MAJOR:		do {			if (req->sem)				continue;			if (req->cmd != rw)				continue;			if (req->nr_sectors >= MAX_SECTORS)				continue;			if (req->rq_dev != bh->b_rdev)				continue;			/* Can we add it to the end of this request? */			if (req->sector + req->nr_sectors == sector) {				req->bhtail->b_reqnext = bh;				req->bhtail = bh;				req->nr_sectors += count;				/* Can we now merge this req with the next? */				attempt_merge(req);			/* or to the beginning? */			} else if (req->sector - count == sector) {			    	bh->b_reqnext = req->bh;			    	req->bh = bh;			    	req->buffer = bh->b_data;			    	req->current_nr_sectors = count;			    	req->sector = sector;			    	req->nr_sectors += count;			} else				continue;			mark_buffer_clean(bh);		    	sti();		    	return;		} while ((req = req->next) != NULL);	}/* find an unused request. */	req = get_request(max_req, bh->b_rdev);	sti();/* if no request available: if rw_ahead, forget it; otherwise try again blocking.. */	if (!req) {		if (rw_ahead) {			unlock_buffer(bh);			return;		}		req = __get_request_wait(max_req, bh->b_rdev);	}/* fill up the request-info, and add it to the queue */	req->cmd = rw;	req->errors = 0;	req->sector = sector;	req->nr_sectors = count;	req->current_nr_sectors = count;	req->buffer = bh->b_data;	req->sem = NULL;	req->bh = bh;	req->bhtail = bh;	req->next = NULL;	add_request(major+blk_dev,req);}/* This function can be used to request a number of buffers from a block   device. Currently the only restriction is that all buffers must belong to   the same device */void ll_rw_block(int rw, int nr, struct buffer_head * bh[]){	unsigned int major;	int correct_size;	struct blk_dev_struct * dev;	int i;	/* Make sure that the first block contains something reasonable */	while (!*bh) {		bh++;		if (--nr <= 0)			return;	}	dev = NULL;	if ((major = MAJOR(bh[0]->b_dev)) < MAX_BLKDEV)		dev = blk_dev + major;	if (!dev || !dev->request_fn) {		printk(KERN_ERR	"ll_rw_block: Trying to read nonexistent block-device %s (%ld)\n",		kdevname(bh[0]->b_dev), bh[0]->b_blocknr);		goto sorry;	}	/* Determine correct block size for this device.  */	correct_size = BLOCK_SIZE;	if (blksize_size[major]) {		i = blksize_size[major][MINOR(bh[0]->b_dev)];		if (i)			correct_size = i;	}	/* Verify requested block sizes.  */	for (i = 0; i < nr; i++) {		if (bh[i] && bh[i]->b_size != correct_size) {			printk(KERN_NOTICE "ll_rw_block: device %s: "			       "only %d-char blocks implemented (%lu)\n",			       kdevname(bh[0]->b_dev),			       correct_size, bh[i]->b_size);			goto sorry;		}		/* Md remaps blocks now */		bh[i]->b_rdev = bh[i]->b_dev;		bh[i]->b_rsector=bh[i]->b_blocknr*(bh[i]->b_size >> 9);#ifdef CONFIG_BLK_DEV_MD		if (major==MD_MAJOR &&		    md_map (MINOR(bh[i]->b_dev), &bh[i]->b_rdev,			    &bh[i]->b_rsector, bh[i]->b_size >> 9)) {		        printk (KERN_ERR				"Bad md_map in ll_rw_block\n");		        goto sorry;		}#endif	}	if ((rw == WRITE || rw == WRITEA) && is_read_only(bh[0]->b_dev)) {		printk(KERN_NOTICE "Can't write to read-only device %s\n",		       kdevname(bh[0]->b_dev));		goto sorry;	}	for (i = 0; i < nr; i++) {		if (bh[i]) {			set_bit(BH_Req, &bh[i]->b_state);#ifdef CONFIG_BLK_DEV_MD			if (MAJOR(bh[i]->b_dev) == MD_MAJOR) {				md_make_request(MINOR (bh[i]->b_dev), rw, bh[i]);				continue;			}#endif			make_request(MAJOR(bh[i]->b_rdev), rw, bh[i]);		}	}	return;      sorry:	for (i = 0; i < nr; i++) {		if (bh[i]) {			clear_bit(BH_Dirty, &bh[i]->b_state);			clear_bit(BH_Uptodate, &bh[i]->b_state);		}	}	return;}void ll_rw_swap_file(int rw, kdev_t dev, unsigned int *b, int nb, char *buf){	int i, j;	int buffersize;	int max_req;	unsigned long rsector;	kdev_t rdev;	struct request * req[8];	unsigned int major = MAJOR(dev);	struct semaphore sem = MUTEX_LOCKED;	if (major >= MAX_BLKDEV || !(blk_dev[major].request_fn)) {		printk(KERN_NOTICE "ll_rw_swap_file: trying to swap to"                                   " nonexistent block-device\n");		return;	}	max_req = NR_REQUEST;	switch (rw) {		case READ:			break;		case WRITE:			max_req = (NR_REQUEST * 2) / 3;			if (is_read_only(dev)) {				printk(KERN_NOTICE                                       "Can't swap to read-only device %s\n",					kdevname(dev));				return;			}			break;		default:			panic("ll_rw_swap: bad block dev cmd, must be R/W");	}	buffersize = PAGE_SIZE / nb;	if (major == LOOP_MAJOR)	     max_req >>= 1;	for (j=0, i=0; i<nb;)	{		for (; j < 8 && i < nb; j++, i++, buf += buffersize)		{		        rdev = dev;			rsector = b[i] * (buffersize >> 9);#ifdef CONFIG_BLK_DEV_MD			if (major==MD_MAJOR &&			    md_map (MINOR(dev), &rdev,				    &rsector, buffersize >> 9)) {			        printk (KERN_ERR                                        "Bad md_map in ll_rw_swap_file\n");				return;			}#endif						if (j == 0) {				req[j] = get_request_wait(max_req, rdev);			} else {				cli();				req[j] = get_request(max_req, rdev);				sti();				if (req[j] == NULL)					break;			}			req[j]->cmd = rw;			req[j]->errors = 0;			req[j]->sector = rsector;			req[j]->nr_sectors = buffersize >> 9;			req[j]->current_nr_sectors = buffersize >> 9;			req[j]->buffer = buf;			req[j]->sem = &sem;			req[j]->bh = NULL;			req[j]->next = NULL;			add_request(MAJOR(rdev)+blk_dev,req[j]);		}		run_task_queue(&tq_disk);		while (j > 0) {			j--;			down(&sem);		}	}}int blk_dev_init(void){	struct request * req;	struct blk_dev_struct *dev;	for (dev = blk_dev + MAX_BLKDEV; dev-- != blk_dev;) {		dev->request_fn      = NULL;		dev->current_request = NULL;		dev->plug.rq_status  = RQ_INACTIVE;		dev->plug.cmd        = -1;		dev->plug.next       = NULL;		dev->plug_tq.routine = &unplug_device;		dev->plug_tq.data    = dev;	}	req = all_requests + NR_REQUEST;	while (--req >= all_requests) {		req->rq_status = RQ_INACTIVE;		req->next = NULL;	}	memset(ro_bits,0,sizeof(ro_bits));#ifdef CONFIG_BLK_DEV_RAM	rd_init();#endif#ifdef CONFIG_BLK_DEV_LOOP	loop_init();#endif#ifdef CONFIG_BLK_DEV_IDE	ide_init();		/* this MUST precede hd_init */#endif#ifdef CONFIG_BLK_DEV_HD	hd_init();#endif#ifdef CONFIG_BLK_DEV_XD	xd_init();#endif#ifdef CONFIG_BLK_DEV_FD	floppy_init();#else#if !defined(CONFIG_ARCH_ARC) && !defined(CONFIG_ARCH_SA110EVAL)	outb_p(0xc, 0x3f2);#endif#endif#ifdef CONFIG_BLK_DEV_MD	md_init();#endif CONFIG_BLK_DEV_MD	return 0;}

⌨️ 快捷键说明

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