|
|
1.1 root 1: /*
1.1.1.2 root 2: * linux/fs/buffer.c
3: *
1.1.1.10 root 4: * Copyright (C) 1991, 1992 Linus Torvalds
1.1.1.2 root 5: */
6:
7: /*
1.1 root 8: * 'buffer.c' implements the buffer-cache functions. Race-conditions have
9: * been avoided by NEVER letting a interrupt change a buffer (except for the
10: * data, of course), but instead letting the caller do it. NOTE! As interrupts
11: * can wake up a caller, some cli-sti sequences are needed to check for
12: * sleep-on-calls. These should be extremely quick, though (I hope).
13: */
14:
1.1.1.2 root 15: /*
16: * NOTE! There is one discordant note here: checking floppies for
17: * disk change. This is where it fits best, I think, as it should
18: * invalidate changed floppy-disk-caches.
19: */
20:
21: #include <stdarg.h>
22:
1.1 root 23: #include <linux/config.h>
24: #include <linux/sched.h>
25: #include <linux/kernel.h>
1.1.1.10 root 26: #include <linux/string.h>
27:
1.1 root 28: #include <asm/system.h>
1.1.1.2 root 29: #include <asm/io.h>
1.1 root 30:
1.1.1.11! root 31: #if defined(CONFIG_BLK_DEV_SR) && defined(CONFIG_SCSI)
! 32: extern int check_cdrom_media_change(int, int);
! 33: #endif
! 34:
1.1.1.6 root 35: static struct buffer_head * hash_table[NR_HASH];
1.1.1.10 root 36: static struct buffer_head * free_list = NULL;
37: static struct buffer_head * unused_list = NULL;
38: static struct wait_queue * buffer_wait = NULL;
39:
40: int nr_buffers = 0;
41: int nr_buffer_heads = 0;
1.1 root 42:
43: static inline void wait_on_buffer(struct buffer_head * bh)
44: {
45: cli();
46: while (bh->b_lock)
47: sleep_on(&bh->b_wait);
48: sti();
49: }
50:
1.1.1.4 root 51: static void sync_buffers(int dev)
1.1 root 52: {
53: int i;
54: struct buffer_head * bh;
55:
1.1.1.4 root 56: bh = free_list;
1.1.1.10 root 57: for (i = nr_buffers*2 ; i-- > 0 ; bh = bh->b_next_free) {
1.1.1.7 root 58: if (bh->b_lock)
1.1.1.4 root 59: continue;
1.1.1.7 root 60: if (!bh->b_dirt)
1.1.1.4 root 61: continue;
1.1.1.7 root 62: ll_rw_block(WRITE,bh);
1.1 root 63: }
1.1.1.4 root 64: }
65:
66: int sys_sync(void)
67: {
1.1.1.9 root 68: int i;
69:
70: for (i=0 ; i<NR_SUPER ; i++)
71: if (super_block[i].s_dev
72: && super_block[i].s_op
73: && super_block[i].s_op->write_super
74: && super_block[i].s_dirt)
75: super_block[i].s_op->write_super(&super_block[i]);
1.1.1.4 root 76: sync_inodes(); /* write out inodes into buffers */
77: sync_buffers(0);
1.1 root 78: return 0;
79: }
80:
1.1.1.2 root 81: int sync_dev(int dev)
1.1 root 82: {
1.1.1.9 root 83: struct super_block * sb;
84:
85: if (sb = get_super (dev))
86: if (sb->s_op && sb->s_op->write_super && sb->s_dirt)
87: sb->s_op->write_super (sb);
1.1.1.4 root 88: sync_buffers(dev);
1.1.1.2 root 89: sync_inodes();
1.1.1.4 root 90: sync_buffers(dev);
1.1 root 91: return 0;
92: }
93:
1.1.1.3 root 94: void inline invalidate_buffers(int dev)
95: {
96: int i;
97: struct buffer_head * bh;
98:
1.1.1.10 root 99: bh = free_list;
100: for (i = nr_buffers*2 ; --i > 0 ; bh = bh->b_next_free) {
1.1.1.3 root 101: if (bh->b_dev != dev)
102: continue;
103: wait_on_buffer(bh);
104: if (bh->b_dev == dev)
105: bh->b_uptodate = bh->b_dirt = 0;
106: }
107: }
108:
1.1.1.2 root 109: /*
110: * This routine checks whether a floppy has been changed, and
111: * invalidates all buffer-cache-entries in that case. This
112: * is a relatively slow routine, so we have to try to minimize using
113: * it. Thus it is called only upon a 'mount' or 'open'. This
114: * is the best way of combining speed and utility, I think.
115: * People changing diskettes in the middle of an operation deserve
116: * to loose :-)
117: *
118: * NOTE! Although currently this is only for floppies, the idea is
119: * that any additional removable block-device will use this routine,
120: * and that mount/open needn't know that floppies/whatever are
121: * special.
122: */
123: void check_disk_change(int dev)
124: {
125: int i;
1.1.1.5 root 126: struct buffer_head * bh;
1.1.1.2 root 127:
1.1.1.11! root 128: switch(MAJOR(dev)){
! 129: case 2: /* floppy disc */
! 130: if (!(bh = getblk(dev,0,1024)))
! 131: return;
! 132: i = floppy_change(bh);
! 133: brelse(bh);
! 134: break;
! 135:
! 136: #if defined(CONFIG_BLK_DEV_SR) && defined(CONFIG_SCSI)
! 137: case 11: /* CDROM */
! 138: i = check_cdrom_media_change(dev, 0);
! 139: if (i) printk("Flushing buffers and inodes for CDROM\n");
! 140: break;
! 141: #endif
! 142:
! 143: default:
1.1.1.2 root 144: return;
1.1.1.11! root 145: };
! 146:
! 147: if (!i) return;
! 148:
1.1.1.2 root 149: for (i=0 ; i<NR_SUPER ; i++)
1.1.1.3 root 150: if (super_block[i].s_dev == dev)
1.1.1.2 root 151: put_super(super_block[i].s_dev);
1.1.1.3 root 152: invalidate_inodes(dev);
153: invalidate_buffers(dev);
1.1.1.2 root 154: }
155:
1.1 root 156: #define _hashfn(dev,block) (((unsigned)(dev^block))%NR_HASH)
157: #define hash(dev,block) hash_table[_hashfn(dev,block)]
158:
1.1.1.4 root 159: static inline void remove_from_hash_queue(struct buffer_head * bh)
1.1 root 160: {
161: if (bh->b_next)
162: bh->b_next->b_prev = bh->b_prev;
163: if (bh->b_prev)
164: bh->b_prev->b_next = bh->b_next;
165: if (hash(bh->b_dev,bh->b_blocknr) == bh)
166: hash(bh->b_dev,bh->b_blocknr) = bh->b_next;
1.1.1.4 root 167: bh->b_next = bh->b_prev = NULL;
168: }
169:
170: static inline void remove_from_free_list(struct buffer_head * bh)
171: {
1.1 root 172: if (!(bh->b_prev_free) || !(bh->b_next_free))
173: panic("Free block list corrupted");
174: bh->b_prev_free->b_next_free = bh->b_next_free;
175: bh->b_next_free->b_prev_free = bh->b_prev_free;
176: if (free_list == bh)
177: free_list = bh->b_next_free;
1.1.1.4 root 178: bh->b_next_free = bh->b_prev_free = NULL;
179: }
180:
181: static inline void remove_from_queues(struct buffer_head * bh)
182: {
183: remove_from_hash_queue(bh);
184: remove_from_free_list(bh);
185: }
186:
187: static inline void put_first_free(struct buffer_head * bh)
188: {
189: if (!bh || (bh == free_list))
190: return;
191: remove_from_free_list(bh);
192: /* add to front of free list */
193: bh->b_next_free = free_list;
194: bh->b_prev_free = free_list->b_prev_free;
195: free_list->b_prev_free->b_next_free = bh;
196: free_list->b_prev_free = bh;
197: free_list = bh;
198: }
199:
200: static inline void put_last_free(struct buffer_head * bh)
201: {
202: if (!bh)
203: return;
204: if (bh == free_list) {
205: free_list = bh->b_next_free;
206: return;
207: }
208: remove_from_free_list(bh);
209: /* add to back of free list */
210: bh->b_next_free = free_list;
211: bh->b_prev_free = free_list->b_prev_free;
212: free_list->b_prev_free->b_next_free = bh;
213: free_list->b_prev_free = bh;
1.1 root 214: }
215:
216: static inline void insert_into_queues(struct buffer_head * bh)
217: {
218: /* put at end of free list */
219: bh->b_next_free = free_list;
220: bh->b_prev_free = free_list->b_prev_free;
221: free_list->b_prev_free->b_next_free = bh;
222: free_list->b_prev_free = bh;
223: /* put the buffer in new hash-queue if it has a device */
224: bh->b_prev = NULL;
225: bh->b_next = NULL;
226: if (!bh->b_dev)
227: return;
228: bh->b_next = hash(bh->b_dev,bh->b_blocknr);
229: hash(bh->b_dev,bh->b_blocknr) = bh;
1.1.1.7 root 230: if (bh->b_next)
231: bh->b_next->b_prev = bh;
1.1 root 232: }
233:
1.1.1.10 root 234: static struct buffer_head * find_buffer(int dev, int block, int size)
1.1 root 235: {
236: struct buffer_head * tmp;
237:
238: for (tmp = hash(dev,block) ; tmp != NULL ; tmp = tmp->b_next)
239: if (tmp->b_dev==dev && tmp->b_blocknr==block)
1.1.1.10 root 240: if (tmp->b_size == size)
241: return tmp;
242: else {
243: printk("wrong block-size on device %04x\n",dev);
244: return NULL;
245: }
1.1 root 246: return NULL;
247: }
248:
249: /*
250: * Why like this, I hear you say... The reason is race-conditions.
251: * As we don't lock buffers (unless we are readint them, that is),
252: * something might happen to it while we sleep (ie a read-error
253: * will force it bad). This shouldn't really happen currently, but
254: * the code is ready.
255: */
1.1.1.10 root 256: struct buffer_head * get_hash_table(int dev, int block, int size)
1.1 root 257: {
258: struct buffer_head * bh;
259:
1.1.1.2 root 260: for (;;) {
1.1.1.10 root 261: if (!(bh=find_buffer(dev,block,size)))
1.1.1.2 root 262: return NULL;
263: bh->b_count++;
264: wait_on_buffer(bh);
1.1.1.10 root 265: if (bh->b_dev == dev && bh->b_blocknr == block && bh->b_size == size) {
1.1.1.4 root 266: put_last_free(bh);
1.1.1.2 root 267: return bh;
1.1.1.4 root 268: }
1.1.1.2 root 269: bh->b_count--;
1.1 root 270: }
271: }
272:
273: /*
274: * Ok, this is getblk, and it isn't very clear, again to hinder
275: * race-conditions. Most of the code is seldom used, (ie repeating),
276: * so it should be much more efficient than it looks.
1.1.1.2 root 277: *
1.1.1.3 root 278: * The algoritm is changed: hopefully better, and an elusive bug removed.
1.1.1.4 root 279: *
280: * 14.02.92: changed it to sync dirty buffers a bit: better performance
281: * when the filesystem starts to get full of dirty blocks (I hope).
1.1 root 282: */
1.1.1.2 root 283: #define BADNESS(bh) (((bh)->b_dirt<<1)+(bh)->b_lock)
1.1.1.10 root 284: struct buffer_head * getblk(int dev, int block, int size)
1.1 root 285: {
1.1.1.4 root 286: struct buffer_head * bh, * tmp;
287: int buffers;
1.1 root 288:
289: repeat:
1.1.1.10 root 290: if (bh = get_hash_table(dev, block, size))
1.1.1.2 root 291: return bh;
1.1.1.10 root 292:
293: if (nr_free_pages > 30)
294: grow_buffers(size);
295:
296: buffers = nr_buffers;
297: bh = NULL;
298:
299: for (tmp = free_list; buffers-- > 0 ; tmp = tmp->b_next_free) {
300: if (tmp->b_count || tmp->b_size != size)
1.1.1.2 root 301: continue;
302: if (!bh || BADNESS(tmp)<BADNESS(bh)) {
303: bh = tmp;
304: if (!BADNESS(tmp))
1.1 root 305: break;
306: }
1.1.1.7 root 307: #if 0
1.1.1.4 root 308: if (tmp->b_dirt)
309: ll_rw_block(WRITEA,tmp);
1.1.1.7 root 310: #endif
311: }
1.1.1.10 root 312:
313: if (!bh && nr_free_pages > 5) {
314: grow_buffers(size);
315: goto repeat;
316: }
317:
1.1.1.3 root 318: /* and repeat until we find something good */
1.1.1.2 root 319: if (!bh) {
1.1 root 320: sleep_on(&buffer_wait);
321: goto repeat;
322: }
1.1.1.2 root 323: wait_on_buffer(bh);
1.1.1.10 root 324: if (bh->b_count || bh->b_size != size)
1.1 root 325: goto repeat;
1.1.1.8 root 326: if (bh->b_dirt) {
1.1.1.7 root 327: sync_buffers(bh->b_dev);
1.1.1.8 root 328: goto repeat;
1.1 root 329: }
1.1.1.2 root 330: /* NOTE!! While we slept waiting for this block, somebody else might */
331: /* already have added "this" block to the cache. check it */
1.1.1.10 root 332: if (find_buffer(dev,block,size))
1.1.1.2 root 333: goto repeat;
334: /* OK, FINALLY we know that this buffer is the only one of it's kind, */
335: /* and that it's unused (b_count=0), unlocked (b_lock=0), and clean */
336: bh->b_count=1;
337: bh->b_dirt=0;
338: bh->b_uptodate=0;
339: remove_from_queues(bh);
340: bh->b_dev=dev;
341: bh->b_blocknr=block;
342: insert_into_queues(bh);
343: return bh;
1.1 root 344: }
345:
346: void brelse(struct buffer_head * buf)
347: {
348: if (!buf)
349: return;
350: wait_on_buffer(buf);
351: if (!(buf->b_count--))
352: panic("Trying to free free buffer");
353: wake_up(&buffer_wait);
354: }
355:
356: /*
357: * bread() reads a specified block and returns the buffer that contains
358: * it. It returns NULL if the block was unreadable.
359: */
1.1.1.10 root 360: struct buffer_head * bread(int dev, int block, int size)
1.1 root 361: {
362: struct buffer_head * bh;
363:
1.1.1.10 root 364: if (!(bh = getblk(dev, block, size))) {
365: printk("bread: getblk returned NULL\n");
366: return NULL;
367: }
1.1 root 368: if (bh->b_uptodate)
369: return bh;
370: ll_rw_block(READ,bh);
1.1.1.2 root 371: wait_on_buffer(bh);
372: if (bh->b_uptodate)
373: return bh;
374: brelse(bh);
375: return NULL;
376: }
377:
1.1.1.3 root 378: #define COPYBLK(from,to) \
379: __asm__("cld\n\t" \
380: "rep\n\t" \
381: "movsl\n\t" \
382: ::"c" (BLOCK_SIZE/4),"S" (from),"D" (to) \
383: :"cx","di","si")
384:
385: /*
386: * bread_page reads four buffers into memory at the desired address. It's
387: * a function of its own, as there is some speed to be got by reading them
388: * all at the same time, not waiting for one to be read, and then another
389: * etc.
390: */
391: void bread_page(unsigned long address,int dev,int b[4])
392: {
393: struct buffer_head * bh[4];
394: int i;
395:
396: for (i=0 ; i<4 ; i++)
397: if (b[i]) {
1.1.1.10 root 398: if (bh[i] = getblk(dev, b[i], 1024))
1.1.1.3 root 399: if (!bh[i]->b_uptodate)
400: ll_rw_block(READ,bh[i]);
401: } else
402: bh[i] = NULL;
403: for (i=0 ; i<4 ; i++,address += BLOCK_SIZE)
404: if (bh[i]) {
405: wait_on_buffer(bh[i]);
406: if (bh[i]->b_uptodate)
407: COPYBLK((unsigned long) bh[i]->b_data,address);
408: brelse(bh[i]);
409: }
410: }
411:
1.1.1.2 root 412: /*
413: * Ok, breada can be used as bread, but additionally to mark other
414: * blocks for reading as well. End the argument list with a negative
415: * number.
416: */
417: struct buffer_head * breada(int dev,int first, ...)
418: {
419: va_list args;
420: struct buffer_head * bh, *tmp;
421:
422: va_start(args,first);
1.1.1.10 root 423: if (!(bh = getblk(dev, first, 1024))) {
424: printk("breada: getblk returned NULL\n");
425: return NULL;
426: }
1.1.1.2 root 427: if (!bh->b_uptodate)
428: ll_rw_block(READ,bh);
429: while ((first=va_arg(args,int))>=0) {
1.1.1.10 root 430: tmp = getblk(dev, first, 1024);
1.1.1.2 root 431: if (tmp) {
432: if (!tmp->b_uptodate)
1.1.1.7 root 433: ll_rw_block(READA,tmp);
1.1.1.2 root 434: tmp->b_count--;
435: }
436: }
437: va_end(args);
438: wait_on_buffer(bh);
1.1 root 439: if (bh->b_uptodate)
440: return bh;
441: brelse(bh);
442: return (NULL);
443: }
444:
1.1.1.10 root 445: static void put_unused_buffer_head(struct buffer_head * bh)
446: {
447: memset((void *) bh,0,sizeof(*bh));
448: bh->b_next_free = unused_list;
449: unused_list = bh;
450: }
451:
452: static void get_more_buffer_heads(void)
453: {
454: unsigned long page;
455: struct buffer_head * bh;
456:
457: if (unused_list)
458: return;
459: page = get_free_page(GFP_KERNEL);
460: if (!page)
461: return;
462: bh = (struct buffer_head *) page;
463: while ((unsigned long) (bh+1) <= page+4096) {
464: put_unused_buffer_head(bh);
465: bh++;
466: nr_buffer_heads++;
467: }
468: }
469:
470: static struct buffer_head * get_unused_buffer_head(void)
1.1 root 471: {
1.1.1.10 root 472: struct buffer_head * bh;
473:
474: get_more_buffer_heads();
475: if (!unused_list)
476: return NULL;
477: bh = unused_list;
478: unused_list = bh->b_next_free;
479: bh->b_next_free = NULL;
480: bh->b_data = NULL;
481: bh->b_size = 0;
482: return bh;
483: }
484:
485: /*
486: * Try to increase the number of buffers available: the size argument
487: * is used to determine what kind of buffers we want. Currently only
488: * 1024-byte buffers are supported by the rest of the system, but I
489: * think this will change eventually.
490: */
491: void grow_buffers(int size)
492: {
493: unsigned long page;
1.1 root 494: int i;
1.1.1.10 root 495: struct buffer_head *bh, *tmp;
1.1 root 496:
1.1.1.10 root 497: if ((size & 511) || (size > 4096)) {
498: printk("grow_buffers: size = %d\n",size);
499: return;
500: }
501: page = get_free_page(GFP_BUFFER);
502: if (!page)
503: return;
504: tmp = NULL;
505: i = 0;
506: for (i = 0 ; i+size <= 4096 ; i += size) {
507: bh = get_unused_buffer_head();
508: if (!bh)
509: goto no_grow;
510: bh->b_this_page = tmp;
511: tmp = bh;
512: bh->b_data = (char * ) (page+i);
513: bh->b_size = size;
514: }
515: tmp = bh;
516: while (1) {
1.1.1.11! root 517: if (free_list) {
! 518: tmp->b_next_free = free_list;
! 519: tmp->b_prev_free = free_list->b_prev_free;
! 520: free_list->b_prev_free->b_next_free = tmp;
! 521: free_list->b_prev_free = tmp;
! 522: } else {
! 523: tmp->b_prev_free = tmp;
! 524: tmp->b_next_free = tmp;
! 525: }
1.1.1.10 root 526: free_list = tmp;
527: ++nr_buffers;
528: if (tmp->b_this_page)
529: tmp = tmp->b_this_page;
530: else
1.1.1.6 root 531: break;
1.1.1.10 root 532: }
533: tmp->b_this_page = bh;
534: return;
535: /*
536: * In case anything failed, we just free everything we got.
537: */
538: no_grow:
539: bh = tmp;
540: while (bh) {
541: tmp = bh;
542: bh = bh->b_this_page;
543: put_unused_buffer_head(tmp);
544: }
545: free_page(page);
546: }
547:
548: /*
549: * try_to_free() checks if all the buffers on this particular page
550: * are unused, and free's the page if so.
551: */
552: static int try_to_free(struct buffer_head * bh)
553: {
554: unsigned long page;
555: struct buffer_head * tmp, * p;
556:
557: tmp = bh;
558: do {
559: if (!tmp)
560: return 0;
561: if (tmp->b_count || tmp->b_dirt || tmp->b_lock)
562: return 0;
563: tmp = tmp->b_this_page;
564: } while (tmp != bh);
565: page = (unsigned long) bh->b_data;
566: page &= 0xfffff000;
567: tmp = bh;
568: do {
569: p = tmp;
570: tmp = tmp->b_this_page;
571: nr_buffers--;
572: remove_from_queues(p);
573: put_unused_buffer_head(p);
574: } while (tmp != bh);
575: free_page(page);
576: return 1;
577: }
578:
579: /*
580: * Try to free up some pages by shrinking the buffer-cache
1.1.1.11! root 581: *
! 582: * Priority tells the routine how hard to try to shrink the
! 583: * buffers: 3 means "don't bother too much", while a value
! 584: * of 0 means "we'd better get some free pages now".
1.1.1.10 root 585: */
1.1.1.11! root 586: int shrink_buffers(unsigned int priority)
1.1.1.10 root 587: {
588: struct buffer_head *bh;
589: int i;
590:
1.1.1.11! root 591: if (priority < 2)
! 592: sync_buffers(0);
1.1.1.10 root 593: bh = free_list;
1.1.1.11! root 594: i = nr_buffers >> priority;
! 595: for ( ; i-- > 0 ; bh = bh->b_next_free) {
1.1.1.10 root 596: if (bh->b_count || !bh->b_this_page)
597: continue;
1.1.1.11! root 598: if (bh->b_lock)
! 599: if (priority)
! 600: continue;
! 601: else
! 602: wait_on_buffer(bh);
1.1.1.10 root 603: if (bh->b_dirt) {
604: ll_rw_block(WRITEA,bh);
605: continue;
1.1.1.6 root 606: }
1.1.1.10 root 607: if (try_to_free(bh))
608: return 1;
609: }
610: return 0;
611: }
612:
613: /*
1.1.1.11! root 614: * This initializes the initial buffer free list. nr_buffers is set
! 615: * to one less the actual number of buffers, as a sop to backwards
! 616: * compatibility --- the old code did this (I think unintentionally,
! 617: * but I'm not sure), and programs in the ps package expect it.
! 618: * - TYT 8/30/92
1.1.1.10 root 619: */
620: void buffer_init(void)
621: {
622: int i;
623:
624: for (i = 0 ; i < NR_HASH ; i++)
1.1.1.4 root 625: hash_table[i] = NULL;
1.1.1.11! root 626: free_list = 0;
! 627: grow_buffers(BLOCK_SIZE);
1.1.1.10 root 628: if (!free_list)
1.1.1.11! root 629: panic("Unable to initialize buffer free list!");
1.1.1.10 root 630: return;
631: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.