xref: /csrg-svn/sys/kern/vfs_cluster.c (revision 2325)
1 /*	vfs_cluster.c	4.6	01/31/81	*/
2 
3 #include "../h/param.h"
4 #include "../h/systm.h"
5 #include "../h/dir.h"
6 #include "../h/user.h"
7 #include "../h/buf.h"
8 #include "../h/conf.h"
9 #include "../h/proc.h"
10 #include "../h/seg.h"
11 #include "../h/pte.h"
12 #include "../h/vm.h"
13 #include "../h/trace.h"
14 
15 /*
16  * The following several routines allocate and free
17  * buffers with various side effects.  In general the
18  * arguments to an allocate routine are a device and
19  * a block number, and the value is a pointer to
20  * to the buffer header; the buffer is marked "busy"
21  * so that no one else can touch it.  If the block was
22  * already in core, no I/O need be done; if it is
23  * already busy, the process waits until it becomes free.
24  * The following routines allocate a buffer:
25  *	getblk
26  *	bread
27  *	breada
28  *	baddr	(if it is incore)
29  * Eventually the buffer must be released, possibly with the
30  * side effect of writing it out, by using one of
31  *	bwrite
32  *	bdwrite
33  *	bawrite
34  *	brelse
35  */
36 
37 #define	BUFHSZ	63
38 struct	bufhd bufhash[BUFHSZ];
39 #define	BUFHASH(dev,blkno)	\
40 		((struct buf *)&bufhash[((int)dev+(int)blkno) % BUFHSZ])
41 
42 /*
43  * Initialize hash links for buffers.
44  */
45 bhinit()
46 {
47 	register int i;
48 	register struct bufhd *bp;
49 
50 	for (bp = bufhash, i = 0; i < BUFHSZ; i++, bp++)
51 		bp->b_forw = bp->b_back = (struct buf *)bp;
52 }
53 
54 /* #define	DISKMON	1 */
55 
56 #ifdef	DISKMON
57 struct {
58 	int	nbuf;
59 	long	nread;
60 	long	nreada;
61 	long	ncache;
62 	long	nwrite;
63 	long	bufcount[NBUF];
64 } io_info;
65 #endif
66 
67 /*
68  * Swap IO headers -
69  * They contain the necessary information for the swap I/O.
70  * At any given time, a swap header can be in three
71  * different lists. When free it is in the free list,
72  * when allocated and the I/O queued, it is on the swap
73  * device list, and finally, if the operation was a dirty
74  * page push, when the I/O completes, it is inserted
75  * in a list of cleaned pages to be processed by the pageout daemon.
76  */
77 struct	buf swbuf[NSWBUF];
78 short	swsize[NSWBUF];		/* CAN WE JUST USE B_BCOUNT? */
79 int	swpf[NSWBUF];
80 
81 
82 #ifdef	FASTVAX
83 #define	notavail(bp) \
84 { \
85 	int s = spl6(); \
86 	(bp)->av_back->av_forw = (bp)->av_forw; \
87 	(bp)->av_forw->av_back = (bp)->av_back; \
88 	(bp)->b_flags |= B_BUSY; \
89 	splx(s); \
90 }
91 #endif
92 
93 /*
94  * Read in (if necessary) the block and return a buffer pointer.
95  */
96 struct buf *
97 bread(dev, blkno)
98 dev_t dev;
99 daddr_t blkno;
100 {
101 	register struct buf *bp;
102 
103 	bp = getblk(dev, blkno);
104 	if (bp->b_flags&B_DONE) {
105 #ifdef	EPAWNJ
106 		trace(TR_BREAD|TR_HIT, dev, blkno);
107 #endif
108 #ifdef	DISKMON
109 		io_info.ncache++;
110 #endif
111 		return(bp);
112 	}
113 	bp->b_flags |= B_READ;
114 	bp->b_bcount = BSIZE;
115 	(*bdevsw[major(dev)].d_strategy)(bp);
116 #ifdef	EPAWNJ
117 	trace(TR_BREAD|TR_MISS, dev, blkno);
118 #endif
119 #ifdef	DISKMON
120 	io_info.nread++;
121 #endif
122 	u.u_vm.vm_inblk++;		/* pay for read */
123 	iowait(bp);
124 	return(bp);
125 }
126 
127 /*
128  * Read in the block, like bread, but also start I/O on the
129  * read-ahead block (which is not allocated to the caller)
130  */
131 struct buf *
132 breada(dev, blkno, rablkno)
133 dev_t dev;
134 daddr_t blkno, rablkno;
135 {
136 	register struct buf *bp, *rabp;
137 
138 	bp = NULL;
139 	if (!incore(dev, blkno)) {
140 		bp = getblk(dev, blkno);
141 		if ((bp->b_flags&B_DONE) == 0) {
142 			bp->b_flags |= B_READ;
143 			bp->b_bcount = BSIZE;
144 			(*bdevsw[major(dev)].d_strategy)(bp);
145 #ifdef	EPAWNJ
146 			trace(TR_BREAD|TR_MISS, dev, blkno);
147 #endif
148 #ifdef	DISKMON
149 			io_info.nread++;
150 #endif
151 			u.u_vm.vm_inblk++;		/* pay for read */
152 		}
153 #ifdef	EPAWNJ
154 		else
155 			trace(TR_BREAD|TR_HIT, dev, blkno);
156 #endif
157 	}
158 	if (rablkno && !incore(dev, rablkno)) {
159 		rabp = getblk(dev, rablkno);
160 		if (rabp->b_flags & B_DONE) {
161 			brelse(rabp);
162 #ifdef	EPAWNJ
163 			trace(TR_BREAD|TR_HIT|TR_RA, dev, blkno);
164 #endif
165 		} else {
166 			rabp->b_flags |= B_READ|B_ASYNC;
167 			rabp->b_bcount = BSIZE;
168 			(*bdevsw[major(dev)].d_strategy)(rabp);
169 #ifdef	EPAWNJ
170 			trace(TR_BREAD|TR_MISS|TR_RA, dev, rablock);
171 #endif
172 #ifdef	DISKMON
173 			io_info.nreada++;
174 #endif
175 			u.u_vm.vm_inblk++;		/* pay in advance */
176 		}
177 	}
178 	if(bp == NULL)
179 		return(bread(dev, blkno));
180 	iowait(bp);
181 	return(bp);
182 }
183 
184 /*
185  * Write the buffer, waiting for completion.
186  * Then release the buffer.
187  */
188 bwrite(bp)
189 register struct buf *bp;
190 {
191 	register flag;
192 
193 	flag = bp->b_flags;
194 	bp->b_flags &= ~(B_READ | B_DONE | B_ERROR | B_DELWRI | B_AGE);
195 	bp->b_bcount = BSIZE;
196 #ifdef	DISKMON
197 	io_info.nwrite++;
198 #endif
199 	if ((flag&B_DELWRI) == 0)
200 		u.u_vm.vm_oublk++;		/* noone paid yet */
201 #ifdef	EPAWNJ
202 	trace(TR_BWRITE, bp->b_dev, dbtofsb(bp->b_blkno));
203 #endif
204 	(*bdevsw[major(bp->b_dev)].d_strategy)(bp);
205 	if ((flag&B_ASYNC) == 0) {
206 		iowait(bp);
207 		brelse(bp);
208 	} else if (flag & B_DELWRI)
209 		bp->b_flags |= B_AGE;
210 	else
211 		geterror(bp);
212 }
213 
214 /*
215  * Release the buffer, marking it so that if it is grabbed
216  * for another purpose it will be written out before being
217  * given up (e.g. when writing a partial block where it is
218  * assumed that another write for the same block will soon follow).
219  * This can't be done for magtape, since writes must be done
220  * in the same order as requested.
221  */
222 bdwrite(bp)
223 register struct buf *bp;
224 {
225 	register struct buf *dp;
226 
227 	if ((bp->b_flags&B_DELWRI) == 0)
228 		u.u_vm.vm_oublk++;		/* noone paid yet */
229 	dp = bdevsw[major(bp->b_dev)].d_tab;
230 	if(dp->b_flags & B_TAPE)
231 		bawrite(bp);
232 	else {
233 		bp->b_flags |= B_DELWRI | B_DONE;
234 		brelse(bp);
235 	}
236 }
237 
238 /*
239  * Release the buffer, start I/O on it, but don't wait for completion.
240  */
241 bawrite(bp)
242 register struct buf *bp;
243 {
244 
245 	bp->b_flags |= B_ASYNC;
246 	bwrite(bp);
247 }
248 
249 /*
250  * release the buffer, with no I/O implied.
251  */
252 brelse(bp)
253 register struct buf *bp;
254 {
255 	register struct buf *flist;
256 	register s;
257 
258 	if (bp->b_flags&B_WANTED)
259 		wakeup((caddr_t)bp);
260 	if (bfreelist[0].b_flags&B_WANTED) {
261 		bfreelist[0].b_flags &= ~B_WANTED;
262 		wakeup((caddr_t)bfreelist);
263 	}
264 	if ((bp->b_flags&B_ERROR) && bp->b_dev != NODEV)
265 		bp->b_dev = NODEV;  /* no assoc. on error */
266 	s = spl6();
267 	if (bp->b_flags & (B_ERROR|B_INVAL)) {
268 		/* block has no info ... put at front of most free list */
269 		flist = &bfreelist[BQUEUES-1];
270 		flist->av_forw->av_back = bp;
271 		bp->av_forw = flist->av_forw;
272 		flist->av_forw = bp;
273 		bp->av_back = flist;
274 	} else {
275 		if (bp->b_flags & B_LOCKED)
276 			flist = &bfreelist[BQ_LOCKED];
277 		else if (bp->b_flags & B_AGE)
278 			flist = &bfreelist[BQ_AGE];
279 		else
280 			flist = &bfreelist[BQ_LRU];
281 		flist->av_back->av_forw = bp;
282 		bp->av_back = flist->av_back;
283 		flist->av_back = bp;
284 		bp->av_forw = flist;
285 	}
286 	bp->b_flags &= ~(B_WANTED|B_BUSY|B_ASYNC|B_AGE);
287 	splx(s);
288 }
289 
290 /*
291  * See if the block is associated with some buffer
292  * (mainly to avoid getting hung up on a wait in breada)
293  */
294 incore(dev, blkno)
295 dev_t dev;
296 daddr_t blkno;
297 {
298 	register struct buf *bp;
299 	register struct buf *dp;
300 	register int dblkno = fsbtodb(blkno);
301 
302 	dp = BUFHASH(dev, blkno);
303 	for (bp = dp->b_forw; bp != dp; bp = bp->b_forw)
304 		if (bp->b_blkno == dblkno && bp->b_dev == dev &&
305 		    !(bp->b_flags & B_INVAL))
306 			return (1);
307 	return (0);
308 }
309 
310 struct buf *
311 baddr(dev, blkno)
312 dev_t dev;
313 daddr_t blkno;
314 {
315 
316 	if (incore(dev, blkno))
317 		return (bread(dev, blkno));
318 	return (0);
319 }
320 
321 /*
322  * Assign a buffer for the given block.  If the appropriate
323  * block is already associated, return it; otherwise search
324  * for the oldest non-busy buffer and reassign it.
325  */
326 struct buf *
327 getblk(dev, blkno)
328 dev_t dev;
329 daddr_t blkno;
330 {
331 	register struct buf *bp, *dp, *ep;
332 	register int i, x;
333 	register int dblkno = fsbtodb(blkno);
334 
335 	if ((unsigned)blkno >= 1 << (sizeof(int)*NBBY-PGSHIFT))
336 		blkno = 1 << ((sizeof(int)*NBBY-PGSHIFT) + 1);
337 	dblkno = fsbtodb(blkno);
338 	dp = BUFHASH(dev, dblkno);
339     loop:
340 	(void) spl0();
341 	for (bp = dp->b_forw; bp != dp; bp = bp->b_forw) {
342 		if (bp->b_blkno != dblkno || bp->b_dev != dev ||
343 		    bp->b_flags&B_INVAL)
344 			continue;
345 		(void) spl6();
346 		if (bp->b_flags&B_BUSY) {
347 			bp->b_flags |= B_WANTED;
348 			sleep((caddr_t)bp, PRIBIO+1);
349 			goto loop;
350 		}
351 		(void) spl0();
352 #ifdef	DISKMON
353 		i = 0;
354 		dp = bp->av_forw;
355 		while ((dp->b_flags & B_HEAD) == 0) {
356 			i++;
357 			dp = dp->av_forw;
358 		}
359 		if (i<NBUF)
360 			io_info.bufcount[i]++;
361 #endif
362 		notavail(bp);
363 		bp->b_flags |= B_CACHE;
364 		return(bp);
365 	}
366 	if (major(dev) >= nblkdev)
367 		panic("blkdev");
368 	(void) spl6();
369 	for (ep = &bfreelist[BQUEUES-1]; ep > bfreelist; ep--)
370 		if (ep->av_forw != ep)
371 			break;
372 	if (ep == bfreelist) {		/* no free blocks at all */
373 		ep->b_flags |= B_WANTED;
374 		sleep((caddr_t)ep, PRIBIO+1);
375 		goto loop;
376 	}
377 	(void) spl0();
378 	bp = ep->av_forw;
379 	notavail(bp);
380 	if (bp->b_flags & B_DELWRI) {
381 		bp->b_flags |= B_ASYNC;
382 		bwrite(bp);
383 		goto loop;
384 	}
385 #ifdef EPAWNJ
386 	trace(TR_BRELSE, bp->b_dev, dbtofsb(bp->b_blkno));
387 #endif
388 	bp->b_flags = B_BUSY;
389 	bp->b_back->b_forw = bp->b_forw;
390 	bp->b_forw->b_back = bp->b_back;
391 	bp->b_forw = dp->b_forw;
392 	bp->b_back = dp;
393 	dp->b_forw->b_back = bp;
394 	dp->b_forw = bp;
395 	bp->b_dev = dev;
396 	bp->b_blkno = dblkno;
397 	return(bp);
398 }
399 
400 /*
401  * get an empty block,
402  * not assigned to any particular device
403  */
404 struct buf *
405 geteblk()
406 {
407 	register struct buf *bp, *dp;
408 
409 loop:
410 	(void) spl6();
411 	for (dp = &bfreelist[BQUEUES-1]; dp > bfreelist; dp--)
412 		if (dp->av_forw != dp)
413 			break;
414 	if (dp == bfreelist) {		/* no free blocks */
415 		dp->b_flags |= B_WANTED;
416 		sleep((caddr_t)dp, PRIBIO+1);
417 		goto loop;
418 	}
419 	(void) spl0();
420 	bp = dp->av_forw;
421 	notavail(bp);
422 	if (bp->b_flags & B_DELWRI) {
423 		bp->b_flags |= B_ASYNC;
424 		bwrite(bp);
425 		goto loop;
426 	}
427 #ifdef EPAWNJ
428 	trace(TR_BRELSE, bp->b_dev, dbtofsb(bp->b_blkno));
429 #endif
430 	bp->b_flags = B_BUSY|B_INVAL;
431 	bp->b_back->b_forw = bp->b_forw;
432 	bp->b_forw->b_back = bp->b_back;
433 	bp->b_forw = dp->b_forw;
434 	bp->b_back = dp;
435 	dp->b_forw->b_back = bp;
436 	dp->b_forw = bp;
437 	bp->b_dev = (dev_t)NODEV;
438 	bp->b_hlink = -1;
439 	return(bp);
440 }
441 
442 /*
443  * Wait for I/O completion on the buffer; return errors
444  * to the user.
445  */
446 iowait(bp)
447 register struct buf *bp;
448 {
449 
450 	(void) spl6();
451 	while ((bp->b_flags&B_DONE)==0)
452 		sleep((caddr_t)bp, PRIBIO);
453 	(void) spl0();
454 	geterror(bp);
455 }
456 
457 #ifndef FASTVAX
458 /*
459  * Unlink a buffer from the available list and mark it busy.
460  * (internal interface)
461  */
462 notavail(bp)
463 register struct buf *bp;
464 {
465 	register s;
466 
467 	s = spl6();
468 	bp->av_back->av_forw = bp->av_forw;
469 	bp->av_forw->av_back = bp->av_back;
470 	bp->b_flags |= B_BUSY;
471 	splx(s);
472 }
473 #endif
474 
475 /*
476  * Mark I/O complete on a buffer. If the header
477  * indicates a dirty page push completion, the
478  * header is inserted into the ``cleaned'' list
479  * to be processed by the pageout daemon. Otherwise
480  * release it if I/O is asynchronous, and wake
481  * up anyone waiting for it.
482  */
483 iodone(bp)
484 register struct buf *bp;
485 {
486 	register int s;
487 
488 	if (bp->b_flags & B_DONE)
489 		panic("dup iodone");
490 	bp->b_flags |= B_DONE;
491 	if (bp->b_flags & B_DIRTY) {
492 		if (bp->b_flags & B_ERROR)
493 			panic("IO err in push");
494 		s = spl6();
495 		cnt.v_pgout++;
496 		bp->av_forw = bclnlist;
497 		bp->b_bcount = swsize[bp - swbuf];
498 		bp->b_pfcent = swpf[bp - swbuf];
499 		bclnlist = bp;
500 		if (bswlist.b_flags & B_WANTED)
501 			wakeup((caddr_t)&proc[2]);
502 		splx(s);
503 		return;
504 	}
505 	if (bp->b_flags&B_ASYNC)
506 		brelse(bp);
507 	else {
508 		bp->b_flags &= ~B_WANTED;
509 		wakeup((caddr_t)bp);
510 	}
511 }
512 
513 /*
514  * Zero the core associated with a buffer.
515  */
516 clrbuf(bp)
517 struct buf *bp;
518 {
519 	register *p;
520 	register c;
521 
522 	p = bp->b_un.b_words;
523 	c = BSIZE/sizeof(int);
524 	do
525 		*p++ = 0;
526 	while (--c);
527 	bp->b_resid = 0;
528 }
529 
530 /*
531  * swap I/O -
532  *
533  * If the flag indicates a dirty page push initiated
534  * by the pageout daemon, we map the page into the i th
535  * virtual page of process 2 (the daemon itself) where i is
536  * the index of the swap header that has been allocated.
537  * We simply initialize the header and queue the I/O but
538  * do not wait for completion. When the I/O completes,
539  * iodone() will link the header to a list of cleaned
540  * pages to be processed by the pageout daemon.
541  */
542 swap(p, dblkno, addr, nbytes, rdflg, flag, dev, pfcent)
543 	struct proc *p;
544 	swblk_t dblkno;
545 	caddr_t addr;
546 	int flag, nbytes;
547 	dev_t dev;
548 	unsigned pfcent;
549 {
550 	register struct buf *bp;
551 	register int c;
552 	int p2dp;
553 	register struct pte *dpte, *vpte;
554 
555 	(void) spl6();
556 	while (bswlist.av_forw == NULL) {
557 		bswlist.b_flags |= B_WANTED;
558 		sleep((caddr_t)&bswlist, PSWP+1);
559 	}
560 	bp = bswlist.av_forw;
561 	bswlist.av_forw = bp->av_forw;
562 	(void) spl0();
563 
564 	bp->b_flags = B_BUSY | B_PHYS | rdflg | flag;
565 	if ((bp->b_flags & (B_DIRTY|B_PGIN)) == 0)
566 		if (rdflg == B_READ)
567 			sum.v_pswpin += btoc(nbytes);
568 		else
569 			sum.v_pswpout += btoc(nbytes);
570 	bp->b_proc = p;
571 	if (flag & B_DIRTY) {
572 		p2dp = ((bp - swbuf) * CLSIZE) * KLMAX;
573 		dpte = dptopte(&proc[2], p2dp);
574 		vpte = vtopte(p, btop(addr));
575 		for (c = 0; c < nbytes; c += NBPG) {
576 			if (vpte->pg_pfnum == 0 || vpte->pg_fod)
577 				panic("swap bad pte");
578 			*dpte++ = *vpte++;
579 		}
580 		bp->b_un.b_addr = (caddr_t)ctob(p2dp);
581 	} else
582 		bp->b_un.b_addr = addr;
583 	while (nbytes > 0) {
584 		c = imin(ctob(120), nbytes);
585 		bp->b_bcount = c;
586 		bp->b_blkno = dblkno;
587 		bp->b_dev = dev;
588 		if (flag & B_DIRTY) {
589 			swpf[bp - swbuf] = pfcent;
590 			swsize[bp - swbuf] = nbytes;
591 		}
592 		(*bdevsw[major(dev)].d_strategy)(bp);
593 		if (flag & B_DIRTY) {
594 			if (c < nbytes)
595 				panic("big push");
596 			return;
597 		}
598 		(void) spl6();
599 		while((bp->b_flags&B_DONE)==0)
600 			sleep((caddr_t)bp, PSWP);
601 		(void) spl0();
602 		bp->b_un.b_addr += c;
603 		bp->b_flags &= ~B_DONE;
604 		if (bp->b_flags & B_ERROR) {
605 			if ((flag & (B_UAREA|B_PAGET)) || rdflg == B_WRITE)
606 				panic("hard IO err in swap");
607 			swkill(p, (char *)0);
608 		}
609 		nbytes -= c;
610 		dblkno += btoc(c);
611 	}
612 	(void) spl6();
613 	bp->b_flags &= ~(B_BUSY|B_WANTED|B_PHYS|B_PAGET|B_UAREA|B_DIRTY);
614 	bp->av_forw = bswlist.av_forw;
615 	bswlist.av_forw = bp;
616 	if (bswlist.b_flags & B_WANTED) {
617 		bswlist.b_flags &= ~B_WANTED;
618 		wakeup((caddr_t)&bswlist);
619 		wakeup((caddr_t)&proc[2]);
620 	}
621 	(void) spl0();
622 }
623 
624 /*
625  * If rout == 0 then killed on swap error, else
626  * rout is the name of the routine where we ran out of
627  * swap space.
628  */
629 swkill(p, rout)
630 	struct proc *p;
631 	char *rout;
632 {
633 
634 	printf("%d: ", p->p_pid);
635 	if (rout)
636 		printf("out of swap space in %s\n", rout);
637 	else
638 		printf("killed on swap error\n");
639 	/*
640 	 * To be sure no looping (e.g. in vmsched trying to
641 	 * swap out) mark process locked in core (as though
642 	 * done by user) after killing it so noone will try
643 	 * to swap it out.
644 	 */
645 	psignal(p, SIGKILL);
646 	p->p_flag |= SULOCK;
647 }
648 
649 /*
650  * make sure all write-behind blocks
651  * on dev (or NODEV for all)
652  * are flushed out.
653  * (from umount and update)
654  */
655 bflush(dev)
656 dev_t dev;
657 {
658 	register struct buf *bp;
659 	register struct buf *flist;
660 
661 loop:
662 	(void) spl6();
663 	for (flist = bfreelist; flist < &bfreelist[BQUEUES]; flist++)
664 	for (bp = flist->av_forw; bp != flist; bp = bp->av_forw) {
665 		if (bp->b_flags&B_DELWRI && (dev == NODEV||dev==bp->b_dev)) {
666 			bp->b_flags |= B_ASYNC;
667 			notavail(bp);
668 			bwrite(bp);
669 			goto loop;
670 		}
671 	}
672 	(void) spl0();
673 }
674 
675 /*
676  * Raw I/O. The arguments are
677  *	The strategy routine for the device
678  *	A buffer, which will always be a special buffer
679  *	  header owned exclusively by the device for this purpose
680  *	The device number
681  *	Read/write flag
682  * Essentially all the work is computing physical addresses and
683  * validating them.
684  * If the user has the proper access privilidges, the process is
685  * marked 'delayed unlock' and the pages involved in the I/O are
686  * faulted and locked. After the completion of the I/O, the above pages
687  * are unlocked.
688  */
689 physio(strat, bp, dev, rw, mincnt)
690 int (*strat)();
691 register struct buf *bp;
692 unsigned (*mincnt)();
693 {
694 	register int c;
695 	char *a;
696 
697 	if (useracc(u.u_base,u.u_count,rw==B_READ?B_WRITE:B_READ) == NULL) {
698 		u.u_error = EFAULT;
699 		return;
700 	}
701 	(void) spl6();
702 	while (bp->b_flags&B_BUSY) {
703 		bp->b_flags |= B_WANTED;
704 		sleep((caddr_t)bp, PRIBIO+1);
705 	}
706 	bp->b_error = 0;
707 	bp->b_proc = u.u_procp;
708 	bp->b_un.b_addr = u.u_base;
709 	while (u.u_count != 0 && bp->b_error==0) {
710 		bp->b_flags = B_BUSY | B_PHYS | rw;
711 		bp->b_dev = dev;
712 		bp->b_blkno = u.u_offset >> PGSHIFT;
713 		bp->b_bcount = u.u_count;
714 		(*mincnt)(bp);
715 		c = bp->b_bcount;
716 		u.u_procp->p_flag |= SPHYSIO;
717 		vslock(a = bp->b_un.b_addr, c);
718 		(*strat)(bp);
719 		(void) spl6();
720 		while ((bp->b_flags&B_DONE) == 0)
721 			sleep((caddr_t)bp, PRIBIO);
722 		vsunlock(a, c, rw);
723 		u.u_procp->p_flag &= ~SPHYSIO;
724 		if (bp->b_flags&B_WANTED)
725 			wakeup((caddr_t)bp);
726 		(void) spl0();
727 		bp->b_un.b_addr += c;
728 		u.u_count -= c;
729 		u.u_offset += c;
730 	}
731 	bp->b_flags &= ~(B_BUSY|B_WANTED|B_PHYS);
732 	u.u_count = bp->b_resid;
733 	geterror(bp);
734 }
735 
736 /*ARGSUSED*/
737 unsigned
738 minphys(bp)
739 struct buf *bp;
740 {
741 
742 	if (bp->b_bcount > 60 * 1024)
743 		bp->b_bcount = 60 * 1024;
744 }
745 
746 /*
747  * Pick up the device's error number and pass it to the user;
748  * if there is an error but the number is 0 set a generalized
749  * code.  Actually the latter is always true because devices
750  * don't yet return specific errors.
751  */
752 geterror(bp)
753 register struct buf *bp;
754 {
755 
756 	if (bp->b_flags&B_ERROR)
757 		if ((u.u_error = bp->b_error)==0)
758 			u.u_error = EIO;
759 }
760 
761 /*
762  * Invalidate in core blocks belonging to closed or umounted filesystem
763  *
764  * This is not nicely done at all - the buffer ought to be removed from the
765  * hash chains & have its dev/blkno fields clobbered, but unfortunately we
766  * can't do that here, as it is quite possible that the block is still
767  * being used for i/o. Eventually, all disc drivers should be forced to
768  * have a close routine, which ought ensure that the queue is empty, then
769  * properly flush the queues. Until that happy day, this suffices for
770  * correctness.						... kre
771  */
772 binval(dev)
773 dev_t dev;
774 {
775 	register struct buf *bp, *dp;
776 
777 	dp = bdevsw[major(dev)].d_tab;
778 	for (bp = dp->b_forw; bp != dp; bp = bp->b_forw)
779 		if (bp->b_dev == dev)
780 			bp->b_flags |= B_INVAL;
781 }
782