⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dm-reverse.c

📁 Linux Device Mapper Source Code
💻 C
字号:
/* * Copyright (C) 2001 Sistina Software (UK) Limited. * * This file is released under the GPL. */#include "dm.h"#include <linux/module.h>#include <linux/init.h>#include <linux/blkdev.h>#include <linux/bio.h>#include <linux/slab.h>MODULE_AUTHOR("Christophe Saout <christophe@saout.de>");MODULE_DESCRIPTION(DM_NAME " target for reverse block mapping");MODULE_LICENSE("GPL");struct reverse_c {	uint32_t chunk_shift;	sector_t chunk_mask;	sector_t chunk_last;	struct dm_dev *dev;	sector_t start;};/* * Construct a reverse mapping. * <chunk size (2^^n)> <dev_path> <offset> */static int reverse_ctr(struct dm_target *ti, unsigned int argc, char **argv){	struct reverse_c *rc;	uint32_t chunk_size;	sector_t chunk_count;	char *end;	if (argc != 3) {		ti->error = "dm-reverse: Not enough arguments";		return -EINVAL;	}	chunk_size = simple_strtoul(argv[0], &end, 10);	if (*end) {		ti->error = "dm-reverse: Invalid chunk_size";		return -EINVAL;	}	/*	 * chunk_size is a power of two	 */	if (!chunk_size || (chunk_size & (chunk_size - 1))) {		ti->error = "dm-reverse: Invalid chunk size";		return -EINVAL;	}	/*	 * How do we handle a small last <-> first chunk? 	 * We simply don't... so	 * length has to be a multiple of the chunk size	 */	chunk_count = ti->len;	if (sector_div(chunk_count, chunk_size) > 0) {		ti->error = "dm-reverse: Size must be a multiple of the chunk size";		return -EINVAL;	}	rc = kmalloc(sizeof(*rc), GFP_KERNEL);	if (rc == NULL) {		ti->error = "dm-reverse: Cannot allocate reverse context ";		return -ENOMEM;	}	if (sscanf(argv[2], SECTOR_FORMAT, &rc->start) != 1) {		ti->error = "dm-reverse: Invalid device sector";		goto bad;	}	if (dm_get_device(ti, argv[1], rc->start, ti->len,	                  dm_table_get_mode(ti->table), &rc->dev)) {		ti->error = "dm-reverse: Device lookup failed";		goto bad;	}	ti->split_io = chunk_size;	rc->chunk_last = chunk_count - 1;	rc->chunk_mask = ((sector_t) chunk_size) - 1;	for (rc->chunk_shift = 0; chunk_size; rc->chunk_shift++)		chunk_size >>= 1;	rc->chunk_shift--;	ti->private = rc;	return 0;bad:	kfree(rc);	return -EINVAL;}static void reverse_dtr(struct dm_target *ti){	struct reverse_c *rc = (struct reverse_c *) ti->private;	dm_put_device(ti, rc->dev);	kfree(rc);}static int reverse_map(struct dm_target *ti, struct bio *bio){	struct reverse_c *rc = (struct reverse_c *) ti->private;	sector_t offset = bio->bi_sector - ti->begin;	uint32_t chunk = (uint32_t) (offset >> rc->chunk_shift);	chunk = rc->chunk_last - chunk;	bio->bi_bdev = rc->dev->bdev;	bio->bi_sector = rc->start + (chunk << rc->chunk_shift)	                 + (offset & rc->chunk_mask);	return 1;}static int reverse_status(struct dm_target *ti,			 status_type_t type, char *result, unsigned int maxlen){	struct reverse_c *rc = (struct reverse_c *) ti->private;	char b[BDEVNAME_SIZE];	switch (type) {	case STATUSTYPE_INFO:		result[0] = '\0';		break;	case STATUSTYPE_TABLE:		snprintf(result, maxlen, SECTOR_FORMAT " %s " SECTOR_FORMAT,		         rc->chunk_mask + 1, bdevname(rc->dev->bdev, b), rc->start);		break;	}	return 0;}static struct target_type reverse_target = {	.name   = "reverse",	.module = THIS_MODULE,	.ctr    = reverse_ctr,	.dtr    = reverse_dtr,	.map    = reverse_map,	.status = reverse_status,};int __init dm_reverse_init(void){	int r;	r = dm_register_target(&reverse_target);	if (r < 0)		DMWARN("reverse target registration failed");	return r;}void dm_reverse_exit(void){	if (dm_unregister_target(&reverse_target))		DMWARN("reverse target unregistration failed");	return;}module_init(dm_reverse_init)module_exit(dm_reverse_exit)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -