From 958e4c15bbe3ce6979fbb2afec29ea8f5e39c40a Mon Sep 17 00:00:00 2001 From: Krzysztof Mazur Date: Wed, 18 May 2011 18:34:58 +0200 Subject: [PATCH 29/84] lsbd: fix caching problems This patch should fix some, but probably not all, problems with buffer cache while remounting and resizing. --- drivers/block/lsbd.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/block/lsbd.c b/drivers/block/lsbd.c index e0f091e..b1a910f 100644 --- a/drivers/block/lsbd.c +++ b/drivers/block/lsbd.c @@ -950,15 +950,19 @@ static int lsbd_load_params(struct lsbd *p) static void lsbd_stop(struct lsbd *p, struct block_device *bdev) { struct completion event; + kdev_t dev = to_kdev_t(bdev->bd_dev); lsbd_info(p, "stopping lsbd task (pid = %d)\n", p->tsk->pid); init_completion(&event); + p->event = &event; p->stop = 1; + fsync_dev(dev); + send_sig(SIGKILL, p->tsk, 1); wait_for_completion(&event); p->tsk = NULL; - invalidate_bdev(bdev, 0); + invalidate_bdev(bdev, 1); MOD_DEC_USE_COUNT; } @@ -1081,6 +1085,7 @@ static int lsbd_write_blocks(struct lsbd *p, unsigned int num) static int lsbd_partition(struct lsbd *p, struct lsbd_part_info *part) { int mirrored = 0; + kdev_t dev; lsbd_debug(p, "part: %d %d %d %d\n", part->num, part->flags, part->start, part->size); @@ -1142,6 +1147,10 @@ static int lsbd_partition(struct lsbd *p, struct lsbd_part_info *part) schedule_timeout(10); vfree(ol); } else { + dev = MKDEV(LSBD_MAJOR, p->id << PART_BITS); + fsync_dev(dev); + invalidate_buffers(dev); + p->lsectors = part->size; lsbd_write_blocks(p, 1); } @@ -1163,6 +1172,11 @@ static int lsbd_partition(struct lsbd *p, struct lsbd_part_info *part) p->part[part->num].size = part->size; lsbd_update_part(p, part->num); + dev = MKDEV(LSBD_MAJOR, (p->id << PART_BITS) + part->num); + lsbd_info(p, "sync & invalidate %02x:%02x\n", MAJOR(dev), MINOR(dev)); + fsync_dev(dev); + invalidate_buffers(dev); + /* * write partition table to device */ @@ -1914,7 +1928,7 @@ static int lsbd_thread(void *data) want_write = 1; spin_unlock_irq(&p->wqueue_lock); want_clean = (lsbd_clean_blocks(p) < LSBD_CLEAN_WINDOW); - if (!(want_write || want_clean)) + if (!(want_write || want_clean || p->stop)) schedule(); current->state = TASK_RUNNING; remove_wait_queue(&p->wqueue_wait, &wait); @@ -1930,7 +1944,7 @@ static int lsbd_thread(void *data) spin_unlock(¤t->sigmask_lock); } - if (p->stop) + if (!want_write && p->stop) break; /* -- 1.8.4.652.g0d6e0ce