patch-1.3.67 linux/fs/buffer.c
Next file: linux/fs/exec.c
Previous file: linux/drivers/scsi/scsi.c
Back to the patch index
Back to the overall index
- Lines: 81
- Date:
Mon Feb 19 15:31:37 1996
- Orig file:
v1.3.66/linux/fs/buffer.c
- Orig date:
Sat Feb 17 16:02:53 1996
diff -u --recursive --new-file v1.3.66/linux/fs/buffer.c linux/fs/buffer.c
@@ -56,6 +56,7 @@
buffers to discard when more memory is needed */
static struct buffer_head * next_to_age[NR_LIST] = {NULL, };
static struct buffer_head * free_list[NR_SIZES] = {NULL, };
+
static struct buffer_head * unused_list = NULL;
struct buffer_head * reuse_list = NULL;
static struct wait_queue * buffer_wait = NULL;
@@ -846,8 +847,7 @@
refile_buffer(buf);
if (buf->b_count) {
- if (!--buf->b_count)
- wake_up(&buffer_wait);
+ buf->b_count--;
return;
}
printk("VFS: brelse: Trying to free free buffer\n");
@@ -867,7 +867,6 @@
remove_from_hash_queue(buf);
buf->b_dev = NODEV;
refile_buffer(buf);
- wake_up(&buffer_wait);
}
/*
@@ -966,6 +965,7 @@
((volatile struct buffer_head *) bh)->b_wait = wait;
bh->b_next_free = unused_list;
unused_list = bh;
+ wake_up(&buffer_wait);
}
static void get_more_buffer_heads(void)
@@ -973,11 +973,26 @@
int i;
struct buffer_head * bh;
- if (unused_list)
- return;
+ for (;;) {
+ if (unused_list)
+ return;
- if (!(bh = (struct buffer_head*) get_free_page(GFP_KERNEL)))
- return;
+ /*
+ * This is critical. We can't swap out pages to get
+ * more buffer heads, because the swap-out may need
+ * more buffer-heads itself. Thus GFP_ATOMIC.
+ */
+ bh = (struct buffer_head *) get_free_page(GFP_ATOMIC);
+ if (bh)
+ break;
+
+ /*
+ * Uhhuh. We're _really_ low on memory. Now we just
+ * wait for old buffer heads to become free due to
+ * finishing IO..
+ */
+ sleep_on(&buffer_wait);
+ }
for (nr_buffer_heads+=i=PAGE_SIZE/sizeof*bh ; i>0; i--) {
bh->b_next_free = unused_list; /* only make link */
@@ -1217,6 +1232,7 @@
page->free_after = 0;
free_page(page_address(page));
}
+ wake_up(&buffer_wait);
}
/*
@@ -1307,7 +1323,6 @@
free_list[isize] = bh;
buffer_pages[MAP_NR(page)] = bh;
tmp->b_this_page = bh;
- wake_up(&buffer_wait);
buffermem += PAGE_SIZE;
return 1;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this