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    [W:0.030 / U:92.260 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site