#include "ext4_config.h"
#include "ext4_bcache.h"
+#include "ext4_blockdev.h"
#include "ext4_debug.h"
#include "ext4_errno.h"
#include <string.h>
#include <stdlib.h>
-static int
-ext4_bcache_lba_compare(struct ext4_buf *a,
- struct ext4_buf *b)
+static int ext4_bcache_lba_compare(struct ext4_buf *a, struct ext4_buf *b)
{
- return a->lba - b->lba;
+ if (a->lba > b->lba)
+ return 1;
+ else if (a->lba < b->lba)
+ return -1;
+ return 0;
}
-static int
-ext4_bcache_lru_compare(struct ext4_buf *a,
- struct ext4_buf *b)
+static int ext4_bcache_lru_compare(struct ext4_buf *a, struct ext4_buf *b)
{
- return a->lru_id - b->lru_id;
+ if (a->lru_id > b->lru_id)
+ return 1;
+ else if (a->lru_id < b->lru_id)
+ return -1;
+ return 0;
}
RB_GENERATE_INTERNAL(ext4_buf_lba, ext4_buf, lba_node,
/*Forcibly drop dirty buffer.*/
if (ext4_bcache_test_flag(buf, BC_DIRTY))
- SLIST_REMOVE(&bc->dirty_list,
- buf,
- ext4_buf,
- dirty_node);
+ ext4_bcache_remove_dirty_node(bc, buf);
ext4_buf_free(buf);
bc->ref_blocks--;
buf->lru_id = ++bc->lru_ctr;
RB_REMOVE(ext4_buf_lru, &bc->lru_root, buf);
if (ext4_bcache_test_flag(buf, BC_DIRTY))
- SLIST_REMOVE(&bc->dirty_list,
- buf,
- ext4_buf,
- dirty_node);
+ ext4_bcache_remove_dirty_node(bc, buf);
}
- buf->refctr++;
+ ext4_bcache_inc_ref(buf);
- b->uptodate = ext4_bcache_test_flag(buf, BC_UPTODATE);
- /* Right now we don't propagate the dirty flag from ext4_buf to
- * ext4_block. */
- b->dirty = false;
b->buf = buf;
b->data = buf->data;
/* One more buffer in bcache now. :-) */
bc->ref_blocks++;
- buf->refctr = 1;
+ ext4_bcache_inc_ref(buf);
/* Assign new value to LRU id and increment LRU counter
* by 1*/
buf->lru_id = ++bc->lru_ctr;
- b->uptodate = false;
- b->dirty = false;
b->buf = buf;
b->data = buf->data;
ext4_assert(buf->refctr);
/*Just decrease reference counter*/
- buf->refctr--;
-
- /* If buffer is modified, buf will be mark up-to-date and dirty. */
- if (b->dirty) {
- ext4_bcache_set_flag(buf, BC_DIRTY);
- ext4_bcache_set_flag(buf, BC_UPTODATE);
- b->uptodate = true;
- }
- /* Someone might want to drop this buffer from bcache. */
- if (!b->uptodate)
- ext4_bcache_clear_flag(buf, BC_UPTODATE);
+ ext4_bcache_dec_ref(buf);
/* We are the last one touching this buffer, do the cleanups. */
if (!buf->refctr) {
RB_INSERT(ext4_buf_lru, &bc->lru_root, buf);
/* This buffer is ready to be flushed. */
- if (ext4_bcache_test_flag(buf, BC_DIRTY))
- SLIST_INSERT_HEAD(&bc->dirty_list, buf, dirty_node);
+ if (ext4_bcache_test_flag(buf, BC_DIRTY)) {
+ if (bc->bdev->cache_write_back)
+ ext4_bcache_insert_dirty_node(bc, buf);
+ else
+ ext4_block_flush_buf(bc->bdev, buf);
+ }
/* The buffer is invalidated...drop it. */
if (!ext4_bcache_test_flag(buf, BC_UPTODATE))
b->lb_id = 0;
b->data = 0;
- b->uptodate = false;
- b->dirty = false;
return EOK;
}