patch-2.4.0-test9 linux/drivers/block/linear.c
Next file: linux/drivers/block/ll_rw_blk.c
Previous file: linux/drivers/block/ida_ioctl.h
Back to the patch index
Back to the overall index
- Lines: 214
- Date:
Wed Dec 31 16:00:00 1969
- Orig file:
v2.4.0-test8/linux/drivers/block/linear.c
- Orig date:
Thu Aug 10 12:35:50 2000
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/block/linear.c linux/drivers/block/linear.c
@@ -1,213 +0,0 @@
-/*
- linear.c : Multiple Devices driver for Linux
- Copyright (C) 1994-96 Marc ZYNGIER
- <zyngier@ufr-info-p7.ibp.fr> or
- <maz@gloups.fdn.fr>
-
- Linear mode management functions.
-
- 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
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- You should have received a copy of the GNU General Public License
- (for example /usr/src/linux/COPYING); if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/module.h>
-
-#include <linux/raid/md.h>
-#include <linux/malloc.h>
-
-#include <linux/raid/linear.h>
-
-#define MAJOR_NR MD_MAJOR
-#define MD_DRIVER
-#define MD_PERSONALITY
-
-static int linear_run (mddev_t *mddev)
-{
- linear_conf_t *conf;
- struct linear_hash *table;
- mdk_rdev_t *rdev;
- int size, i, j, nb_zone;
- unsigned int curr_offset;
-
- MOD_INC_USE_COUNT;
-
- conf = kmalloc (sizeof (*conf), GFP_KERNEL);
- if (!conf)
- goto out;
- mddev->private = conf;
-
- if (md_check_ordering(mddev)) {
- printk("linear: disks are not ordered, aborting!\n");
- goto out;
- }
- /*
- * Find the smallest device.
- */
-
- conf->smallest = NULL;
- curr_offset = 0;
- ITERATE_RDEV_ORDERED(mddev,rdev,j) {
- dev_info_t *disk = conf->disks + j;
-
- disk->dev = rdev->dev;
- disk->size = rdev->size;
- disk->offset = curr_offset;
-
- curr_offset += disk->size;
-
- if (!conf->smallest || (disk->size < conf->smallest->size))
- conf->smallest = disk;
- }
-
- nb_zone = conf->nr_zones =
- md_size[mdidx(mddev)] / conf->smallest->size +
- ((md_size[mdidx(mddev)] % conf->smallest->size) ? 1 : 0);
-
- conf->hash_table = kmalloc (sizeof (struct linear_hash) * nb_zone,
- GFP_KERNEL);
- if (!conf->hash_table)
- goto out;
-
- /*
- * Here we generate the linear hash table
- */
- table = conf->hash_table;
- i = 0;
- size = 0;
- for (j = 0; j < mddev->nb_dev; j++) {
- dev_info_t *disk = conf->disks + j;
-
- if (size < 0) {
- table->dev1 = disk;
- table++;
- }
- size += disk->size;
-
- while (size) {
- table->dev0 = disk;
- size -= conf->smallest->size;
- if (size < 0)
- break;
- table->dev1 = NULL;
- table++;
- }
- }
- table->dev1 = NULL;
-
- return 0;
-
-out:
- if (conf)
- kfree(conf);
- MOD_DEC_USE_COUNT;
- return 1;
-}
-
-static int linear_stop (mddev_t *mddev)
-{
- linear_conf_t *conf = mddev_to_conf(mddev);
-
- kfree(conf->hash_table);
- kfree(conf);
-
- MOD_DEC_USE_COUNT;
-
- return 0;
-}
-
-static int linear_make_request (mddev_t *mddev,
- int rw, struct buffer_head * bh)
-{
- linear_conf_t *conf = mddev_to_conf(mddev);
- struct linear_hash *hash;
- dev_info_t *tmp_dev;
- long block;
-
- block = bh->b_rsector >> 1;
- hash = conf->hash_table + (block / conf->smallest->size);
-
- if (block >= (hash->dev0->size + hash->dev0->offset)) {
- if (!hash->dev1) {
- printk ("linear_make_request : hash->dev1==NULL for block %ld\n",
- block);
- return -1;
- }
- tmp_dev = hash->dev1;
- } else
- tmp_dev = hash->dev0;
-
- if (block >= (tmp_dev->size + tmp_dev->offset)
- || block < tmp_dev->offset) {
- printk ("linear_make_request: Block %ld out of bounds on dev %s size %ld offset %ld\n", block, kdevname(tmp_dev->dev), tmp_dev->size, tmp_dev->offset);
- return -1;
- }
- bh->b_rdev = tmp_dev->dev;
- bh->b_rsector = bh->b_rsector - (tmp_dev->offset << 1);
-
- return 1;
-}
-
-static int linear_status (char *page, mddev_t *mddev)
-{
- int sz = 0;
-
-#undef MD_DEBUG
-#ifdef MD_DEBUG
- int j;
- linear_conf_t *conf = mddev_to_conf(mddev);
-
- sz += sprintf(page+sz, " ");
- for (j = 0; j < conf->nr_zones; j++)
- {
- sz += sprintf(page+sz, "[%s",
- partition_name(conf->hash_table[j].dev0->dev));
-
- if (conf->hash_table[j].dev1)
- sz += sprintf(page+sz, "/%s] ",
- partition_name(conf->hash_table[j].dev1->dev));
- else
- sz += sprintf(page+sz, "] ");
- }
- sz += sprintf(page+sz, "\n");
-#endif
- sz += sprintf(page+sz, " %dk rounding", mddev->param.chunk_size/1024);
- return sz;
-}
-
-
-static mdk_personality_t linear_personality=
-{
- name: "linear",
- make_request: linear_make_request,
- run: linear_run,
- stop: linear_stop,
- status: linear_status,
-};
-
-#ifndef MODULE
-
-void md__init linear_init (void)
-{
- register_md_personality (LINEAR, &linear_personality);
-}
-
-#else
-
-int init_module (void)
-{
- return (register_md_personality (LINEAR, &linear_personality));
-}
-
-void cleanup_module (void)
-{
- unregister_md_personality (LINEAR);
-}
-
-#endif
-
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)