[Ocfs2-tools-devel] Re: [PATCH 1/2] The io_cache implementation
tao.ma
tao.ma at oracle.com
Tue Mar 27 02:22:47 PDT 2007
looks good to me now.
sob.
Joel Becker wrote:
> On Tue, Mar 27, 2007 at 01:43:51AM -0700, Joel Becker wrote:
>
>> On Tue, Mar 27, 2007 at 02:48:45PM +0800, tao.ma wrote:
>>
>>>> + ret = io_cache_read_one_block(channel, blkno, data);
>>>>
>>>>
>>> Should data change accordingly? data + i * channel->io_blksize?
>>> The same error happens in io_cache_write_block.
>>>
>>>> + memcpy(icb->icb_buf, data, channel->io_blksize);
>>>> + io_cache_seen(ic, icb);
>>>> +
>>>> + ret = unix_io_write_block(channel, blkno, 1, icb->icb_buf);
>>>> + return ret;
>>>> +}
>>>>
>>>>
>>> I think the "memcpy" should be moved after the success of
>>> "unix_io_write_block" so that we can keep consistent of the buffer and
>>> the real content on the disk.
>>>
>> Hmm, while I liked the idea of "writing out of the cache", you
>> make a valid point that we want the cache to reflect the disk. On the
>> other hand, we have no idea what the disk looks like when a write fails
>> - it could be an EIO that actually modified the platter.
>> Perhaps just remove the block from the cache on failure to force
>> a real re-read from disk?
>>
>
> Ok, here's a patch against my committed code that fixes both
> problems. It also consolidates the logic for removing a block from the
> lookup table and for stealing a block from the LRU. What do you think?
> Also, this makes it clear that my test program doesn't test
> multiblock reads or writes. I'll have to add that tomorrow.
>
> Joel
>
> Index: libocfs2/unix_io.c
> ===================================================================
> --- libocfs2/unix_io.c (revision 1325)
> +++ libocfs2/unix_io.c (working copy)
> @@ -212,6 +212,29 @@ static void io_cache_seen(struct io_cach
> list_add_tail(&icb->icb_list, &ic->ic_lru);
> }
>
> +static void io_cache_disconnect(struct io_cache *ic,
> + struct io_cache_block *icb)
> +{
> + /*
> + * This icb should longer be looked up.
> + * If rb_parent is NULL, it's already disconnected.
> + */
> + if (icb->icb_node.rb_parent) {
> + rb_erase(&icb->icb_node, &ic->ic_lookup);
> + memset(&icb->icb_node, 0, sizeof(struct rb_node));
> + }
> +}
> +
> +static struct io_cache_block *io_cache_pop_lru(struct io_cache *ic)
> +{
> + struct io_cache_block *icb;
> +
> + icb = list_entry(ic->ic_lru.next, struct io_cache_block, icb_list);
> + io_cache_disconnect(ic, icb);
> +
> + return icb;
> +}
> +
> static errcode_t io_cache_read_one_block(io_channel *channel, int64_t blkno,
> char *data)
> {
> @@ -223,14 +246,8 @@ static errcode_t io_cache_read_one_block
> if (icb)
> goto found;
>
> - /*
> - * Ok, this blkno isn't in the cache. Steal something.
> - */
> - icb = list_entry(ic->ic_lru.next, struct io_cache_block, icb_list);
> - if (icb->icb_node.rb_parent) {
> - rb_erase(&icb->icb_node, &ic->ic_lookup);
> - memset(&icb->icb_node, 0, sizeof(struct rb_node));
> - }
> + /* Ok, this blkno isn't in the cache. Steal something. */
> + icb = io_cache_pop_lru(ic);
>
> /*
> * If the read fails, we leave the block at the end of the LRU
> @@ -258,7 +275,7 @@ static errcode_t io_cache_read_block(io_
> int i;
> errcode_t ret = 0;
>
> - for (i = 0; i < count; i++, blkno++) {
> + for (i = 0; i < count; i++, blkno++, data += channel->io_blksize) {
> ret = io_cache_read_one_block(channel, blkno, data);
> if (ret)
> break;
> @@ -278,14 +295,8 @@ static errcode_t io_cache_write_one_bloc
> if (icb)
> goto found;
>
> - /*
> - * Ok, this blkno isn't in the cache. Steal something.
> - */
> - icb = list_entry(ic->ic_lru.next, struct io_cache_block, icb_list);
> - if (icb->icb_node.rb_parent) {
> - rb_erase(&icb->icb_node, &ic->ic_lookup);
> - memset(&icb->icb_node, 0, sizeof(struct rb_node));
> - }
> + /* Ok, this blkno isn't in the cache. Steal something. */
> + icb = io_cache_pop_lru(ic);
>
> icb->icb_blkno = blkno;
> io_cache_insert(ic, icb);
> @@ -295,6 +306,9 @@ found:
> io_cache_seen(ic, icb);
>
> ret = unix_io_write_block(channel, blkno, 1, icb->icb_buf);
> + if (ret)
> + io_cache_disconnect(ic, icb);
> +
> return ret;
> }
>
> @@ -305,7 +319,7 @@ static errcode_t io_cache_write_block(io
> int i;
> errcode_t ret = 0;
>
> - for (i = 0; i < count; i++, blkno++) {
> + for (i = 0; i < count; i++, blkno++, data += channel->io_blksize) {
> ret = io_cache_write_one_block(channel, blkno, data);
> if (ret)
> break;
>
<http://www.oracle.com/cdc/>
More information about the Ocfs2-tools-devel
mailing list