From 842a502400ebd14c358cfca5bfc75c5f350d3bdc Mon Sep 17 00:00:00 2001 From: Krzysztof Mazur Date: Wed, 16 Feb 2011 17:04:21 +0100 Subject: [PATCH 19/84] lsbd: don't use bread bread uses buffer cache and causes some problems because lsbd thread bypasses buffer cache. --- drivers/block/lsbd.c | 48 ++++++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/drivers/block/lsbd.c b/drivers/block/lsbd.c index 318b16a..fbf4bd6 100644 --- a/drivers/block/lsbd.c +++ b/drivers/block/lsbd.c @@ -3,7 +3,7 @@ * * Log-Structured Block Device * - * Copyright (C) 2010 Krzysztof Mazur + * Copyright (C) 2010, 2011 Krzysztof Mazur * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -263,21 +263,6 @@ static unsigned int lsbd_block_size(struct lsbd *p) return p->sectors_per_block * p->sector_size; } -/** - * lsbs_bread - read block - * @p: LSBD device - * @block: block number - * @size: number of bytes to read - * - * This function NULL on failure; pointer to allocated buffer otherwise. - * - * This function cannot be called from lsbd_thread. - */ -struct buffer_head *lsbd_bread(struct lsbd *p, int block, int size) -{ - return bread(p->dev, block * p->sectors_per_block, size); -} - static struct buffer_head *__lsbd_get_buffer(struct lsbd *p) { struct buffer_head *bh; @@ -378,6 +363,9 @@ struct buffer_head *lsbd_getblk(struct lsbd *p, int block, unsigned int sector) bh->b_blocknr = block * p->sectors_per_block + sector; bh->b_rsector = (block * p->sectors_per_block + sector) * (p->sector_size >> 9); + lsbd_debug(p, "getblk: %d.%d: mapped to physical sector %ld, %ld\n", + block, sector, bh->b_blocknr, + bh->b_rsector); return bh; } @@ -541,19 +529,21 @@ static int lsbd_find_current_block(struct lsbd *p) */ for (i = 0; i < p->blocks; i++) { reads++; - bh = lsbd_bread(p, i, p->sector_size); + bh = lsbd_sread(p, i, 0); if (bh == NULL) continue; b = (void *) bh->b_data; if (!lsbd_block_verify_ok(p, b)) { brelse(bh); + lsbd_put_buffer(p, bh); continue; } base = i; epoch = cpu_to_be64(b->epoch); brelse(bh); + lsbd_put_buffer(p, bh); break; } if (i == p->blocks) { @@ -572,7 +562,7 @@ static int lsbd_find_current_block(struct lsbd *p) while (blocks > 1) { lsbd_debug(p, "block: %d, blocks: %d\n", block, blocks); reads++; - bh = lsbd_bread(p, block, p->sector_size); + bh = lsbd_sread(p, block, 0); if (bh == NULL) { lsbd_debug(p, "block %d: I/O\n", block); block++; @@ -587,6 +577,7 @@ static int lsbd_find_current_block(struct lsbd *p) if (!lsbd_block_verify_ok(p, b)) { lsbd_debug(p, "block %d: verify\n", block); brelse(bh); + lsbd_put_buffer(p, bh); block++; if (block >= base + blocks) { blocks = blocks / 2; @@ -607,6 +598,7 @@ static int lsbd_find_current_block(struct lsbd *p) } block = base + blocks / 2; brelse(bh); + lsbd_put_buffer(p, bh); } lsbd_debug(p, "block: %d, blocks: %d\n", block, blocks); @@ -678,13 +670,14 @@ int lsbd_read_lcache(struct lsbd *p) block = p->cur_block; do { readed_blocks++; - bh = lsbd_bread(p, block, p->sector_size); + bh = lsbd_sread(p, block, 0); if (bh == NULL) continue; b = (void *) bh->b_data; if (!lsbd_block_verify_ok(p, b)) { brelse(bh); + lsbd_put_buffer(p, bh); continue; } @@ -717,6 +710,7 @@ int lsbd_read_lcache(struct lsbd *p) lcache_offset = be32_to_cpu(b->lcache_offset); if (lcache_offset > p->sector_size) { brelse(bh); + lsbd_put_buffer(p, bh); continue; } @@ -732,6 +726,7 @@ int lsbd_read_lcache(struct lsbd *p) if (be32_to_cpu(b->lcache_checksum) != lsbd_checksum(cache, lcache_chunk * sizeof(*cache))) { brelse(bh); + lsbd_put_buffer(p, bh); continue; } @@ -761,6 +756,7 @@ int lsbd_read_lcache(struct lsbd *p) } } brelse(bh); + lsbd_put_buffer(p, bh); } while ((readed < p->lsectors) && ((block = block_prev(p, block)) != p->cur_block)); @@ -856,7 +852,7 @@ static int lsbd_load_params(struct lsbd *p) for (; i > 0; i--, block = block_prev(p, block)) { lsbd_debug(p, "params: block %d\n", block); - bh = lsbd_bread(p, block, p->sector_size); + bh = lsbd_sread(p, block, 0); if (bh == NULL) continue; @@ -864,6 +860,7 @@ static int lsbd_load_params(struct lsbd *p) if (!lsbd_block_verify_ok(p, b)) { lsbd_debug(p, "params: block %d failed\n", block); brelse(bh); + lsbd_put_buffer(p, bh); continue; } @@ -879,6 +876,7 @@ static int lsbd_load_params(struct lsbd *p) "and larger than 4 KiB\n", sector_size); brelse(bh); + lsbd_put_buffer(p, bh); return -EINVAL; } @@ -902,6 +900,7 @@ static int lsbd_load_params(struct lsbd *p) "avail, %d total\n", p->blocks, blocks); brelse(bh); + lsbd_put_buffer(p, bh); return -EINVAL; } @@ -916,6 +915,7 @@ static int lsbd_load_params(struct lsbd *p) lsbd_load_partitions(p, b); brelse(bh); + lsbd_put_buffer(p, bh); return 0; } return 1; @@ -1739,6 +1739,9 @@ static int lsbd_write_block(struct lsbd *p) b->age = cpu_to_be64(be64_to_cpu(b->age) + 1); b->epoch = cpu_to_be64(p->epoch); + lsbd_debug(p, "block %d: epoch %Ld, age %Ld\n", p->cur_block, + p->epoch, be64_to_cpu(b->age)); + b->ptab_offset = cpu_to_be32(0x400); sects = (void *)(bh[0]->b_data + be32_to_cpu(b->ptab_offset)); @@ -1885,9 +1888,10 @@ static int lsbd_thread(void *data) current->state = TASK_RUNNING; remove_wait_queue(&p->wqueue_wait, &wait); - lsbd_debug(p, "lsbd_thread: %s %s\n", + lsbd_debug(p, "lsbd_thread: %s %s: clean: %d/%d\n", want_write ? "want_write" : "", - want_clean ? "want_clean" : ""); + want_clean ? "want_clean" : "", + lsbd_clean_blocks(p), LSBD_CLEAN_WINDOW); if (signal_pending(current)) { spin_lock(¤t->sigmask_lock); -- 1.8.4.652.g0d6e0ce