From 6fda16bbc87ca189e8095d1dc12b339925b7a8cd Mon Sep 17 00:00:00 2001 From: Krzysztof Mazur Date: Wed, 8 Jun 2011 06:51:31 +0200 Subject: [PATCH 41/84] lsbd: split lsbd_make_request() to many functions The lsbd_make_request() was too big. --- drivers/block/lsbd.c | 200 +++++++++++++++++++++++++++------------------------ 1 file changed, 107 insertions(+), 93 deletions(-) diff --git a/drivers/block/lsbd.c b/drivers/block/lsbd.c index dc317fe..55e4b59 100644 --- a/drivers/block/lsbd.c +++ b/drivers/block/lsbd.c @@ -1460,119 +1460,133 @@ static int lsbd_read_zero_sector(struct buffer_head *bh) return 0; } -static int lsbd_make_request(request_queue_t *q, int rw, - struct buffer_head *bh) -{ - struct lsbd *p = &lsbd_dev[MINOR(bh->b_rdev) >> PART_BITS]; +/** + * lsbd_make_read - make READ/READA request + * @p: LSBD device + * @rw: READ/READA + * @bh: buffer + * + * This function reads buffer from LSBD device. + */ +static int lsbd_make_read(struct lsbd *p, int rw, struct buffer_head *bh) +{ unsigned int partition = lsbd_minor_to_partition(MINOR(bh->b_rdev)); unsigned int lsector = LSBD_SECT_INVALID; + unsigned int sector; - /* - * Reading is quite simple - request are just remapped to lower - * level device - */ - if (rw == READA || rw == READ) { - unsigned int sector; - - lsector = bh->b_rsector >> 3; -// lsbd_debug(p, "reading sector %d (%ld)\n", lsector, -// bh->b_rsector); -// lsbd_debug(p, "blocknr %ld, size %hd\n", bh->b_blocknr, -// bh->b_size); - - lsector = lsbd_map_sector(p, partition, lsector); - if (lsector == LSBD_SECT_INVALID) { - buffer_IO_error(bh); - return 0; - } + lsector = bh->b_rsector >> 3; - sector = p->lcache[lsector]; - lsbd_debug(p, "read %d, mapped to %d\n", lsector, - sector); - if (sector == LSBD_SECT_INVALID) { - buffer_IO_error(bh); - return 0; - } + lsector = lsbd_map_sector(p, partition, lsector); + if (lsector == LSBD_SECT_INVALID) { + buffer_IO_error(bh); + return 0; + } - if (sector == LSBD_SECT_ZERO) - return lsbd_read_zero_sector(bh); + sector = p->lcache[lsector]; + lsbd_debug(p, "read %d, mapped to %d\n", lsector, sector); + if (sector == LSBD_SECT_INVALID) { + buffer_IO_error(bh); + return 0; + } - if (sector >= p->psectors) { - lsbd_info(p, "invalid lcache entry: %d -> %d\n", - lsector, sector); - buffer_IO_error(bh); - return 0; - } + if (sector == LSBD_SECT_ZERO) + return lsbd_read_zero_sector(bh); - /* - * for non-mirrored devices read can be redirected - * to lower level device. - */ - if (!p->mirrored) { - bh->b_rsector = (unsigned long) p->lcache[lsector] << 3; - lsbd_debug(p, "mapped to physical %ld\n", - bh->b_rsector); + if (sector >= p->psectors) { + lsbd_info(p, "invalid lcache entry: %d -> %d\n", lsector, + sector); + buffer_IO_error(bh); + return 0; + } - bh->b_rdev = p->dev; - return 1; - } - /* - * read from mirrored device is more tricky, if single - * read fails second mirror can be used. - */ - lsbd_read_mirrored(p, bh, sector); - if (buffer_uptodate(bh)) - return 0; - - p->read_errors++; - /* try to switch this sector to mirror and retry */ - lsbd_switch_mirror(p, lsector, sector); - sector = p->lcache[lsector]; - if (sector >= p->psectors) { - lsbd_info(p, "invalid lcache entry: %d -> %d\n", - lsector, sector); - buffer_IO_error(bh); - return 0; - } - lsbd_read_mirrored(p, bh, sector); + /* + * reading non-mirrored device is quite simple - requests are + * just remapped to lower level device + */ + if (!p->mirrored) { + bh->b_rsector = (unsigned long) p->lcache[lsector] << 3; + lsbd_debug(p, "mapped to physical %ld\n", bh->b_rsector); - /* TODO: rewrite this sector */ - if (buffer_uptodate(bh)) - return 0; + bh->b_rdev = p->dev; + return 1; + } - lsbd_info(p, "uncorrectable error sector %d (physical %d " - "and %d)\n", lsector, - sector ^ p->sectors_per_block, sector); - p->uncorrectable++; + /* + * read from mirrored device is more tricky, if single + * read fails second mirror can be used. + */ + lsbd_read_mirrored(p, bh, sector); + if (buffer_uptodate(bh)) + return 0; + + p->read_errors++; + /* try to switch this sector to mirror and retry */ + lsbd_switch_mirror(p, lsector, sector); + sector = p->lcache[lsector]; + if (sector >= p->psectors) { + lsbd_info(p, "invalid lcache entry: %d -> %d\n", + lsector, sector); buffer_IO_error(bh); return 0; } + lsbd_read_mirrored(p, bh, sector); - /* - * Writting to LSBD is quite complex. Because of this write - * requests are handled by single thread. - */ - if (rw == WRITE) { - unsigned int queue = LSBD_QUEUE_NORMAL; + /* TODO: rewrite this sector */ + if (buffer_uptodate(bh)) + return 0; - lsector = bh->b_rsector >> 3; + lsbd_info(p, "uncorrectable error sector %d (physical %d and %d)\n", + lsector, sector ^ p->sectors_per_block, sector); + p->uncorrectable++; + buffer_IO_error(bh); + return 0; +} - lsector = lsbd_map_sector(p, partition, lsector); - if (lsector == LSBD_SECT_INVALID) { - buffer_IO_error(bh); - return 0; - } +/** + * lsbd_make_write - make WRITE request + * @p: LSBD device + * @bh: buffer + * + * This function writes buffer from LSBD device. + * + * Writting to LSBD is quite complex. Because of this write + * requests are handled by single thread. + */ +static int lsbd_make_write(struct lsbd *p, struct buffer_head *bh) +{ + unsigned int partition = lsbd_minor_to_partition(MINOR(bh->b_rdev)); + unsigned int lsector = LSBD_SECT_INVALID; + unsigned int queue = LSBD_QUEUE_NORMAL; - if (current->rt_priority) - queue = LSBD_QUEUE_HIGH; + lsector = bh->b_rsector >> 3; - if (lsbd_queue_bh(p, bh, lsector, queue)) { - buffer_IO_error(bh); - } else { - p->sectors_written++; - } + lsector = lsbd_map_sector(p, partition, lsector); + if (lsector == LSBD_SECT_INVALID) { + buffer_IO_error(bh); return 0; } + + if (current->rt_priority) + queue = LSBD_QUEUE_HIGH; + + if (lsbd_queue_bh(p, bh, lsector, queue)) { + buffer_IO_error(bh); + } else { + p->sectors_written++; + } + return 0; +} + +static int lsbd_make_request(request_queue_t *q, int rw, struct buffer_head *bh) +{ + struct lsbd *p = &lsbd_dev[MINOR(bh->b_rdev) >> PART_BITS]; + + if (rw == READA || rw == READ) + return lsbd_make_read(p, rw, bh); + + if (rw == WRITE) + return lsbd_make_write(p, bh); + buffer_IO_error(bh); return 0; } -- 1.8.4.652.g0d6e0ce