lkml.org 
[lkml]   [1999]   [Jan]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH] buffer over-serialization

On Sun, 17 Jan 1999, Simon Kirby wrote:

> Do you have a patch I could test or will this be in a new pre soon enough?
>
> Simon-
>
> | Simon Kirby | Systems Administration |
> | mailto:sim@netnation.com | NetNation Communications |
> | http://www.netnation.com/ | Tech: (604) 684-6892 |

Here you go.

Dax Kelson
Internet Connect, Inc.
--- buffer.c.orig Sat Jan 16 21:08:34 1999
+++ buffer.c Sun Jan 17 12:14:27 1999
@@ -615,6 +615,27 @@
return bh;
}

+static struct buffer_head * bread_get_hash_table(kdev_t dev, int block, int size)
+{
+ struct buffer_head * bh;
+ for (;;) {
+ bh = find_buffer(dev,block,size);
+ if (!bh)
+ break;
+ bh->b_count++;
+ bh->b_lru_time = jiffies;
+ if (buffer_uptodate(bh) || !buffer_locked(bh))
+ break;
+ __wait_on_buffer(bh);
+ if (bh->b_dev == dev &&
+ bh->b_blocknr == block &&
+ bh->b_size == size)
+ break;
+ bh->b_count--;
+ }
+ return bh;
+}
+
unsigned int get_hardblocksize(kdev_t dev)
{
/*
@@ -766,6 +787,59 @@
goto get_free;
goto repeat;
}
+/*
+ *
+ * This is the same as getblk, however, bread_getblk calls bread_get_hash_table
+ * which returns the locked buffer, and reads the data from there (or even _write_ it
+ * even if we're in the middle of writing it to disk which is fine, because we'll
+ * mark it dirty and later write out the correct version).
+ *
+ * 01.16.99: Created based on suggestion by Linus - Dax Kelson
+ *
+ */
+
+static struct buffer_head * bread_getblk(kdev_t dev, int block, int size)
+{
+ struct buffer_head * bh;
+ int isize;
+
+repeat:
+ bh = bread_get_hash_table(dev, block, size);
+ if (bh) {
+ if (!buffer_dirty(bh)) {
+ if (buffer_uptodate(bh))
+ put_last_lru(bh);
+ bh->b_flushtime = 0;
+ }
+ return bh;
+ }
+
+ isize = BUFSIZE_INDEX(size);
+get_free:
+ bh = free_list[isize];
+ if (!bh)
+ goto refill;
+ remove_from_free_list(bh);
+
+ /* OK, FINALLY we know that this buffer is the only one of its kind,
+ * and that it's unused (b_count=0), unlocked, and clean.
+ */
+ init_buffer(bh, dev, block, end_buffer_io_sync, NULL);
+ bh->b_lru_time = jiffies;
+ bh->b_state=0;
+ insert_into_queues(bh);
+ return bh;
+
+ /*
+ * If we block while refilling the free list, somebody may
+ * create the buffer first ... search the hashes again.
+ */
+refill:
+ refill_freelist(size);
+ if (!find_buffer(dev,block,size))
+ goto get_free;
+ goto repeat;
+}

void set_writetime(struct buffer_head * buf, int flag)
{
@@ -838,8 +912,6 @@
*/
void __brelse(struct buffer_head * buf)
{
- wait_on_buffer(buf);
-
/* If dirty, mark the time this buffer should be written back. */
set_writetime(buf, 0);
refile_buffer(buf);
@@ -873,10 +945,12 @@
/*
* bread() reads a specified block and returns the buffer that contains
* it. It returns NULL if the block was unreadable.
+ *
+ * 01.16.99: Now calls bread_getblk to fix over serialization bug
*/
struct buffer_head * bread(kdev_t dev, int block, int size)
{
- struct buffer_head * bh = getblk(dev, block, size);
+ struct buffer_head * bh = bread_getblk(dev, block, size);

if (bh) {
touch_buffer(bh);
\
 
 \ /
  Last update: 2005-03-22 13:49    [from the cache]
©2003-2011 Jasper Spaans