📄 linear.c
字号:
/* 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_PERSONALITYstatic 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[-1].dev1 = disk; } size += disk->size; while (size>0) { table->dev0 = disk; table->dev1 = NULL; size -= conf->smallest->size; table++; } } if (table-conf->hash_table != nb_zone) BUG(); 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); buffer_IO_error(bh); return 0; } 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); buffer_IO_error(bh); return 0; } 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,};static int md__init linear_init (void){ return register_md_personality (LINEAR, &linear_personality);}static void linear_exit (void){ unregister_md_personality (LINEAR);}module_init(linear_init);module_exit(linear_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -