public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] linux-patches r1703 - genpatches-2.6/trunk/2.6.34
@ 2010-05-17  0:15 Mike Pagano (mpagano)
  0 siblings, 0 replies; only message in thread
From: Mike Pagano (mpagano) @ 2010-05-17  0:15 UTC (permalink / raw
  To: gentoo-commits

Author: mpagano
Date: 2010-05-17 00:15:12 +0000 (Mon, 17 May 2010)
New Revision: 1703

Removed:
   genpatches-2.6/trunk/2.6.34/4100_dm-bbr.patch
Modified:
   genpatches-2.6/trunk/2.6.34/0000_README
Log:
Removal of patches incompatible with 2.6.34

Modified: genpatches-2.6/trunk/2.6.34/0000_README
===================================================================
--- genpatches-2.6/trunk/2.6.34/0000_README	2010-05-14 13:53:52 UTC (rev 1702)
+++ genpatches-2.6/trunk/2.6.34/0000_README	2010-05-17 00:15:12 UTC (rev 1703)
@@ -39,10 +39,6 @@
 Individual Patch Descriptions:
 --------------------------------------------------------------------------
 
-Patch:  4100_dm-bbr.patch
-From:   EVMS 2.5.2
-Desc:   Bad block relocation support for LiveCD users
-
 Patch:	4200_fbcondecor-0.9.6.patch
 From:	http://dev.gentoo.org/~spock
 Desc:	Bootsplash successor by Michal Januszewski

Deleted: genpatches-2.6/trunk/2.6.34/4100_dm-bbr.patch
===================================================================
--- genpatches-2.6/trunk/2.6.34/4100_dm-bbr.patch	2010-05-14 13:53:52 UTC (rev 1702)
+++ genpatches-2.6/trunk/2.6.34/4100_dm-bbr.patch	2010-05-17 00:15:12 UTC (rev 1703)
@@ -1,1190 +0,0 @@
-BBR Target, updated by dsd@gentoo.org
-
-Incomplete changelog:
- 2008/06/16: updated for new API in 2.6.26
- 2007/07/08: updated for new API in 2.6.22
-
-Index: linux-2.6.26-gentoo/drivers/md/Kconfig
-===================================================================
---- linux-2.6.26-gentoo.orig/drivers/md/Kconfig
-+++ linux-2.6.26-gentoo/drivers/md/Kconfig
-@@ -288,4 +288,15 @@ config DM_UEVENT
- 	---help---
- 	Generate udev events for DM events.
- 
-+config BLK_DEV_DM_BBR
-+	tristate "Bad Block Relocation Device Target (EXPERIMENTAL)"
-+	depends on BLK_DEV_DM && EXPERIMENTAL
-+	---help---
-+	  Support for devices with software-based bad-block-relocation.
-+
-+	  To compile this as a module, choose M here: the module will be
-+	  called dm-bbr.
-+
-+	  If unsure, say N.
-+
- endif # MD
-Index: linux-2.6.26-gentoo/drivers/md/Makefile
-===================================================================
---- linux-2.6.26-gentoo.orig/drivers/md/Makefile
-+++ linux-2.6.26-gentoo/drivers/md/Makefile
-@@ -41,6 +41,7 @@ obj-$(CONFIG_DM_MULTIPATH_RDAC)	+= dm-rd
- obj-$(CONFIG_DM_SNAPSHOT)	+= dm-snapshot.o
- obj-$(CONFIG_DM_MIRROR)		+= dm-mirror.o dm-log.o
- obj-$(CONFIG_DM_ZERO)		+= dm-zero.o
-+obj-$(CONFIG_BLK_DEV_DM_BBR)	+= dm-bbr.o
- 
- quiet_cmd_unroll = UNROLL  $@
-       cmd_unroll = $(PERL) $(srctree)/$(src)/unroll.pl $(UNROLL) \
-Index: linux-2.6.26-gentoo/drivers/md/dm-bbr.c
-===================================================================
---- /dev/null
-+++ linux-2.6.26-gentoo/drivers/md/dm-bbr.c
-@@ -0,0 +1,1012 @@
-+/*
-+ *   (C) Copyright IBM Corp. 2002, 2004
-+ *
-+ *   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 of the License, or
-+ *   (at your option) any later version.
-+ *
-+ *   This program is distributed in the hope that it will be useful,
-+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
-+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
-+ *   the GNU General Public License for more details.
-+ *
-+ *   You should have received a copy of the GNU General Public License
-+ *   along with this program;  if not, write to the Free Software
-+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * linux/drivers/md/dm-bbr.c
-+ *
-+ * Bad-block-relocation (BBR) target for device-mapper.
-+ *
-+ * The BBR target is designed to remap I/O write failures to another safe
-+ * location on disk. Note that most disk drives have BBR built into them,
-+ * this means that our software BBR will be only activated when all hardware
-+ * BBR replacement sectors have been used.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/bio.h>
-+#include <linux/spinlock.h>
-+#include <linux/slab.h>
-+#include <linux/mempool.h>
-+#include <linux/workqueue.h>
-+#include <linux/vmalloc.h>
-+#include <linux/dm-io.h>
-+#include <linux/bio.h>
-+
-+#include "dm.h"
-+#include "dm-bio-record.h"
-+#include "dm-bbr.h"
-+
-+#define DM_MSG_PREFIX "bbr"
-+#define SECTOR_SIZE (1 << SECTOR_SHIFT)
-+
-+static struct workqueue_struct *dm_bbr_wq = NULL;
-+static void bbr_remap_handler(struct work_struct *work);
-+static struct kmem_cache *bbr_remap_cache;
-+static struct kmem_cache *bbr_io_cache;
-+static mempool_t *bbr_io_pool;
-+
-+/**
-+ * bbr_binary_tree_destroy
-+ *
-+ * Destroy the binary tree.
-+ **/
-+static void bbr_binary_tree_destroy(struct bbr_runtime_remap *root)
-+{
-+	struct bbr_runtime_remap **link = NULL;
-+	struct bbr_runtime_remap *node = root;
-+
-+	while (node) {
-+		if (node->left) {
-+			link = &node->left;
-+			node = node->left;
-+			continue;
-+		}
-+		if (node->right) {
-+			link = &node->right;
-+			node = node->right;
-+			continue;
-+		}
-+
-+		kmem_cache_free(bbr_remap_cache, node);
-+		if (node == root) {
-+			/* If root is deleted, we're done. */
-+			break;
-+		}
-+
-+		/* Back to root. */
-+		node = root;
-+		*link = NULL;
-+	}
-+}
-+
-+static void bbr_free_remap(struct bbr_private *bbr_id)
-+{
-+	spin_lock_irq(&bbr_id->remap_root_lock);
-+	bbr_binary_tree_destroy(bbr_id->remap_root);
-+	bbr_id->remap_root = NULL;
-+	spin_unlock_irq(&bbr_id->remap_root_lock);
-+}
-+
-+static struct bbr_private *bbr_alloc_private(void)
-+{
-+	struct bbr_private *bbr_id;
-+
-+	bbr_id = kzalloc(sizeof(*bbr_id), GFP_KERNEL);
-+	if (bbr_id == NULL)
-+		return NULL;
-+
-+	INIT_WORK(&bbr_id->remap_work, bbr_remap_handler);
-+	spin_lock_init(&bbr_id->remap_root_lock);
-+	spin_lock_init(&bbr_id->remap_ios_lock);
-+	bbr_id->in_use_replacement_blks = (atomic_t) ATOMIC_INIT(0);
-+
-+	return bbr_id;
-+}
-+
-+static void bbr_free_private(struct bbr_private *bbr_id)
-+{
-+	vfree(bbr_id->bbr_table);
-+	bbr_free_remap(bbr_id);
-+	kfree(bbr_id);
-+}
-+
-+static u32 crc_table[256];
-+static u32 crc_table_built = 0;
-+
-+static void build_crc_table(void)
-+{
-+	u32 i, j, crc;
-+
-+	for (i = 0; i <= 255; i++) {
-+		crc = i;
-+		for (j = 8; j > 0; j--) {
-+			if (crc & 1)
-+				crc = (crc >> 1) ^ CRC_POLYNOMIAL;
-+			else
-+				crc >>= 1;
-+		}
-+		crc_table[i] = crc;
-+	}
-+	crc_table_built = 1;
-+}
-+
-+static u32 calculate_crc(u32 crc, void *buffer, u32 buffersize)
-+{
-+	unsigned char *current_byte;
-+	u32 temp1, temp2, i;
-+
-+	current_byte = (unsigned char *) buffer;
-+	/* Make sure the crc table is available */
-+	if (!crc_table_built)
-+		build_crc_table();
-+	/* Process each byte in the buffer. */
-+	for (i = 0; i < buffersize; i++) {
-+		temp1 = (crc >> 8) & 0x00FFFFFF;
-+		temp2 = crc_table[(crc ^ (u32) * current_byte) &
-+				  (u32) 0xff];
-+		current_byte++;
-+		crc = temp1 ^ temp2;
-+	}
-+	return crc;
-+}
-+
-+/**
-+ * le_bbr_table_sector_to_cpu
-+ *
-+ * Convert bbr meta data from on-disk (LE) format
-+ * to the native cpu endian format.
-+ **/
-+static void le_bbr_table_sector_to_cpu(struct bbr_table *p)
-+{
-+	int i;
-+	p->signature		= le32_to_cpup(&p->signature);
-+	p->crc			= le32_to_cpup(&p->crc);
-+	p->sequence_number	= le32_to_cpup(&p->sequence_number);
-+	p->in_use_cnt		= le32_to_cpup(&p->in_use_cnt);
-+	for (i = 0; i < BBR_ENTRIES_PER_SECT; i++) {
-+		p->entries[i].bad_sect =
-+			le64_to_cpup(&p->entries[i].bad_sect);
-+		p->entries[i].replacement_sect =
-+			le64_to_cpup(&p->entries[i].replacement_sect);
-+	}
-+}
-+
-+/**
-+ * cpu_bbr_table_sector_to_le
-+ *
-+ * Convert bbr meta data from cpu endian format to on-disk (LE) format
-+ **/
-+static void cpu_bbr_table_sector_to_le(struct bbr_table *p,
-+				       struct bbr_table *le)
-+{
-+	int i;
-+	le->signature		= cpu_to_le32p(&p->signature);
-+	le->crc			= cpu_to_le32p(&p->crc);
-+	le->sequence_number	= cpu_to_le32p(&p->sequence_number);
-+	le->in_use_cnt		= cpu_to_le32p(&p->in_use_cnt);
-+	for (i = 0; i < BBR_ENTRIES_PER_SECT; i++) {
-+		le->entries[i].bad_sect =
-+			cpu_to_le64p(&p->entries[i].bad_sect);
-+		le->entries[i].replacement_sect =
-+			cpu_to_le64p(&p->entries[i].replacement_sect);
-+	}
-+}
-+
-+/**
-+ * validate_bbr_table_sector
-+ *
-+ * Check the specified BBR table sector for a valid signature and CRC. If it's
-+ * valid, endian-convert the table sector.
-+ **/
-+static int validate_bbr_table_sector(struct bbr_table *p)
-+{
-+	int org_crc, final_crc;
-+
-+	if (le32_to_cpup(&p->signature) != BBR_TABLE_SIGNATURE) {
-+		DMERR("BBR table signature doesn't match!");
-+		DMERR("Found 0x%x. Expecting 0x%x",
-+		      le32_to_cpup(&p->signature), BBR_TABLE_SIGNATURE);
-+		return -EINVAL;
-+	}
-+
-+	if (!p->crc) {
-+		DMERR("BBR table sector has no CRC!");
-+		return -EINVAL;
-+	}
-+
-+	org_crc = le32_to_cpup(&p->crc);
-+	p->crc = 0;
-+	final_crc = calculate_crc(INITIAL_CRC, (void *)p, sizeof(*p));
-+	if (final_crc != org_crc) {
-+		DMERR("CRC failed!");
-+		DMERR("Found 0x%x. Expecting 0x%x",
-+		      org_crc, final_crc);
-+		return -EINVAL;
-+	}
-+
-+	p->crc = cpu_to_le32p(&org_crc);
-+	le_bbr_table_sector_to_cpu(p);
-+
-+	return 0;
-+}
-+
-+/**
-+ * bbr_binary_tree_insert
-+ *
-+ * Insert a node into the binary tree.
-+ **/
-+static void bbr_binary_tree_insert(struct bbr_runtime_remap **root,
-+				   struct bbr_runtime_remap *newnode)
-+{
-+	struct bbr_runtime_remap **node = root;
-+	while (node && *node) {
-+		node = (newnode->remap.bad_sect > (*node)->remap.bad_sect) ?
-+			&(*node)->right : &(*node)->left;
-+	}
-+
-+	newnode->left = newnode->right = NULL;
-+	*node = newnode;
-+}
-+
-+/**
-+ * bbr_binary_search
-+ *
-+ * Search for a node that contains bad_sect == lsn.
-+ **/
-+static struct bbr_runtime_remap *bbr_binary_search(
-+	struct bbr_runtime_remap *root,
-+	u64 lsn)
-+{
-+	struct bbr_runtime_remap *node = root;
-+	while (node) {
-+		if (node->remap.bad_sect == lsn)
-+			break;
-+
-+		node = (lsn > node->remap.bad_sect) ? node->right : node->left;
-+	}
-+	return node;
-+}
-+
-+/**
-+ * bbr_insert_remap_entry
-+ *
-+ * Create a new remap entry and add it to the binary tree for this node.
-+ **/
-+static int bbr_insert_remap_entry(struct bbr_private *bbr_id,
-+				  struct bbr_table_entry *new_bbr_entry)
-+{
-+	struct bbr_runtime_remap *newnode;
-+
-+	newnode = kmem_cache_alloc(bbr_remap_cache, GFP_NOIO);
-+	if (!newnode) {
-+		DMERR("Could not allocate from remap cache!");
-+		return -ENOMEM;
-+	}
-+	newnode->remap.bad_sect = new_bbr_entry->bad_sect;
-+	newnode->remap.replacement_sect = new_bbr_entry->replacement_sect;
-+	spin_lock_irq(&bbr_id->remap_root_lock);
-+	bbr_binary_tree_insert(&bbr_id->remap_root, newnode);
-+	spin_unlock_irq(&bbr_id->remap_root_lock);
-+	return 0;
-+}
-+
-+/**
-+ * bbr_table_to_remap_list
-+ *
-+ * The on-disk bbr table is sorted by the replacement sector LBA. In order to
-+ * improve run time performance, the in memory remap list must be sorted by
-+ * the bad sector LBA. This function is called at discovery time to initialize
-+ * the remap list. This function assumes that at least one copy of meta data
-+ * is valid.
-+ **/
-+static u32 bbr_table_to_remap_list(struct bbr_private *bbr_id)
-+{
-+	u32 in_use_blks = 0;
-+	int i, j;
-+	struct bbr_table *p;
-+
-+	for (i = 0, p = bbr_id->bbr_table;
-+	     i < bbr_id->nr_sects_bbr_table;
-+	     i++, p++) {
-+		if (!p->in_use_cnt)
-+			break;
-+
-+		in_use_blks += p->in_use_cnt;
-+		for (j = 0; j < p->in_use_cnt; j++)
-+			bbr_insert_remap_entry(bbr_id, &p->entries[j]);
-+	}
-+	if (in_use_blks) {
-+		char b[32];
-+		DMWARN("There are %u BBR entries for device %s",
-+		       in_use_blks, format_dev_t(b, bbr_id->dev->bdev->bd_dev));
-+	}
-+
-+	return in_use_blks;
-+}
-+
-+/**
-+ * bbr_search_remap_entry
-+ *
-+ * Search remap entry for the specified sector. If found, return a pointer to
-+ * the table entry. Otherwise, return NULL.
-+ **/
-+static struct bbr_table_entry *bbr_search_remap_entry(
-+	struct bbr_private *bbr_id,
-+	u64 lsn)
-+{
-+	struct bbr_runtime_remap *p;
-+
-+	spin_lock_irq(&bbr_id->remap_root_lock);
-+	p = bbr_binary_search(bbr_id->remap_root, lsn);
-+	spin_unlock_irq(&bbr_id->remap_root_lock);
-+	return (p) ? &p->remap : NULL;
-+}
-+
-+/**
-+ * bbr_remap
-+ *
-+ * If *lsn is in the remap table, return TRUE and modify *lsn,
-+ * else, return FALSE.
-+ **/
-+static int bbr_remap(struct bbr_private *bbr_id,
-+			    u64 *lsn)
-+{
-+	struct bbr_table_entry *e;
-+
-+	if (atomic_read(&bbr_id->in_use_replacement_blks)) {
-+		e = bbr_search_remap_entry(bbr_id, *lsn);
-+		if (e) {
-+			*lsn = e->replacement_sect;
-+			return 1;
-+		}
-+	}
-+	return 0;
-+}
-+
-+/**
-+ * bbr_remap_probe
-+ *
-+ * If any of the sectors in the range [lsn, lsn+nr_sects] are in the remap
-+ * table return TRUE, Else, return FALSE.
-+ **/
-+static int bbr_remap_probe(struct bbr_private *bbr_id,
-+				  u64 lsn, u64 nr_sects)
-+{
-+	u64 tmp, cnt;
-+
-+	if (atomic_read(&bbr_id->in_use_replacement_blks)) {
-+		for (cnt = 0, tmp = lsn;
-+		     cnt < nr_sects;
-+		     cnt += bbr_id->blksize_in_sects, tmp = lsn + cnt) {
-+			if (bbr_remap(bbr_id,&tmp))
-+				return 1;
-+		}
-+	}
-+	return 0;
-+}
-+
-+static int rw_table(struct bbr_private *bbr_id, void *vma,
-+		    struct dm_io_region *ptr, int rw)
-+{
-+	bbr_id->vma_io_req.bi_rw = rw;
-+	bbr_id->vma_io_req.mem.ptr.vma = vma;
-+	bbr_id->vma_io_req.notify.fn = NULL;
-+
-+	return dm_io(&bbr_id->vma_io_req, 1, ptr, NULL);
-+}
-+
-+static int io_sync(struct bbr_private *bbr_id, struct page_list *pl,
-+		   unsigned offset, struct dm_io_region *ptr, int rw)
-+{
-+	bbr_id->page_io_req.bi_rw = rw;
-+	bbr_id->page_io_req.mem.ptr.pl = pl;
-+	bbr_id->page_io_req.mem.offset = offset;
-+	bbr_id->page_io_req.notify.fn = NULL;
-+
-+	return dm_io(&bbr_id->page_io_req, 1, ptr, NULL);
-+}
-+
-+/**
-+ * bbr_setup
-+ *
-+ * Read the remap tables from disk and set up the initial remap tree.
-+ **/
-+static int bbr_setup(struct bbr_private *bbr_id)
-+{
-+	struct bbr_table *table = bbr_id->bbr_table;
-+	struct dm_io_region job;
-+	int i, rc = 0;
-+
-+	job.bdev = bbr_id->dev->bdev;
-+	job.count = 1;
-+
-+	/* Read and verify each BBR table sector individually. */
-+	for (i = 0; i < bbr_id->nr_sects_bbr_table; i++, table++) {
-+		job.sector = bbr_id->lba_table1 + i;
-+		rc = rw_table(bbr_id, table, &job, READ);
-+		if (rc && bbr_id->lba_table2) {
-+			job.sector = bbr_id->lba_table2 + i;
-+			rc = rw_table(bbr_id, table, &job, READ);
-+		}
-+		if (rc)
-+			goto out;
-+
-+		rc = validate_bbr_table_sector(table);
-+		if (rc)
-+			goto out;
-+	}
-+	atomic_set(&bbr_id->in_use_replacement_blks,
-+		   bbr_table_to_remap_list(bbr_id));
-+
-+out:
-+	if (rc)
-+		DMERR("error during device setup: %d", rc);
-+	return rc;
-+}
-+
-+/**
-+ * bbr_io_remap_error
-+ * @bbr_id:		Private data for the BBR node.
-+ * @rw:			READ or WRITE.
-+ * @starting_lsn:	Starting sector of request to remap.
-+ * @count:		Number of sectors in the request.
-+ * @page:		Page containing the data for the request.
-+ * @offset:		Byte-offset of the data within the page.
-+ *
-+ * For the requested range, try to write each sector individually. For each
-+ * sector that fails, find the next available remap location and write the
-+ * data to that new location. Then update the table and write both copies
-+ * of the table to disk. Finally, update the in-memory mapping and do any
-+ * other necessary bookkeeping.
-+ **/
-+static int bbr_io_remap_error(struct bbr_private *bbr_id,
-+			      int rw,
-+			      u64 starting_lsn,
-+			      u64 count,
-+			      struct page *page,
-+			      unsigned int offset)
-+{
-+	struct bbr_table *bbr_table;
-+	struct dm_io_region job;
-+	struct page_list pl;
-+	unsigned long table_sector_index;
-+	unsigned long table_sector_offset;
-+	unsigned long index;
-+	u64 lsn, new_lsn;
-+	char b[32];
-+	int rc;
-+
-+	job.bdev = bbr_id->dev->bdev;
-+	job.count = 1;
-+	pl.page = page;
-+	pl.next = NULL;
-+
-+	/* For each sector in the request. */
-+	for (lsn = 0; lsn < count; lsn++, offset += SECTOR_SIZE) {
-+		job.sector = starting_lsn + lsn;
-+		rc = io_sync(bbr_id, &pl, offset, &job, rw);
-+		while (rc) {
-+			/* Find the next available relocation sector. */
-+			new_lsn = atomic_read(&bbr_id->in_use_replacement_blks);
-+			if (new_lsn >= bbr_id->nr_replacement_blks) {
-+				/* No more replacement sectors available. */
-+				return -EIO;
-+			}
-+			new_lsn += bbr_id->start_replacement_sect;
-+
-+			/* Write the data to its new location. */
-+			DMWARN("device %s: Trying to remap bad sector "PFU64" to sector "PFU64,
-+			       format_dev_t(b, bbr_id->dev->bdev->bd_dev),
-+			       starting_lsn + lsn, new_lsn);
-+			job.sector = new_lsn;
-+			rc = io_sync(bbr_id, &pl, offset, &job, rw);
-+			if (rc) {
-+				/* This replacement sector is bad.
-+				 * Try the next one.
-+				 */
-+				DMERR("device %s: replacement sector "PFU64" is bad. Skipping.",
-+				      format_dev_t(b, bbr_id->dev->bdev->bd_dev), new_lsn);
-+				atomic_inc(&bbr_id->in_use_replacement_blks);
-+				continue;
-+			}
-+
-+			/* Add this new entry to the on-disk table. */
-+			table_sector_index = new_lsn -
-+					     bbr_id->start_replacement_sect;
-+			table_sector_offset = table_sector_index /
-+					      BBR_ENTRIES_PER_SECT;
-+			index = table_sector_index % BBR_ENTRIES_PER_SECT;
-+
-+			bbr_table = &bbr_id->bbr_table[table_sector_offset];
-+			bbr_table->entries[index].bad_sect = starting_lsn + lsn;
-+			bbr_table->entries[index].replacement_sect = new_lsn;
-+			bbr_table->in_use_cnt++;
-+			bbr_table->sequence_number++;
-+			bbr_table->crc = 0;
-+			bbr_table->crc = calculate_crc(INITIAL_CRC,
-+						       bbr_table,
-+						       sizeof(struct bbr_table));
-+
-+			/* Write the table to disk. */
-+			cpu_bbr_table_sector_to_le(bbr_table, bbr_table);
-+			if (bbr_id->lba_table1) {
-+				job.sector = bbr_id->lba_table1 + table_sector_offset;
-+				rc = rw_table(bbr_id, bbr_table, &job, WRITE);
-+			}
-+			if (bbr_id->lba_table2) {
-+				job.sector = bbr_id->lba_table2 + table_sector_offset;
-+				rc |= rw_table(bbr_id, bbr_table, &job, WRITE);
-+			}
-+			le_bbr_table_sector_to_cpu(bbr_table);
-+
-+			if (rc) {
-+				/* Error writing one of the tables to disk. */
-+				DMERR("device %s: error updating BBR tables on disk.",
-+				      format_dev_t(b, bbr_id->dev->bdev->bd_dev));
-+				return rc;
-+			}
-+
-+			/* Insert a new entry in the remapping binary-tree. */
-+			rc = bbr_insert_remap_entry(bbr_id,
-+						    &bbr_table->entries[index]);
-+			if (rc) {
-+				DMERR("device %s: error adding new entry to remap tree.",
-+				      format_dev_t(b, bbr_id->dev->bdev->bd_dev));
-+				return rc;
-+			}
-+
-+			atomic_inc(&bbr_id->in_use_replacement_blks);
-+		}
-+	}
-+
-+	return 0;
-+}
-+
-+/**
-+ * bbr_io_process_request
-+ *
-+ * For each sector in this request, check if the sector has already
-+ * been remapped. If so, process all previous sectors in the request,
-+ * followed by the remapped sector. Then reset the starting lsn and
-+ * count, and keep going with the rest of the request as if it were
-+ * a whole new request. If any of the sync_io's return an error,
-+ * call the remapper to relocate the bad sector(s).
-+ *
-+ * 2.5 Note: When switching over to bio's for the I/O path, we have made
-+ * the assumption that the I/O request described by the bio is one
-+ * virtually contiguous piece of memory (even though the bio vector
-+ * describes it using a series of physical page addresses).
-+ **/
-+static int bbr_io_process_request(struct bbr_private *bbr_id,
-+				  struct bio *bio)
-+{
-+	struct dm_io_region job;
-+	u64 starting_lsn = bio->bi_sector;
-+	u64 count, lsn, remapped_lsn;
-+	struct page_list pl;
-+	unsigned int offset;
-+	int i, rw = bio_data_dir(bio);
-+	int rc = 0;
-+
-+	job.bdev = bbr_id->dev->bdev;
-+	pl.next = NULL;
-+
-+	/* Each bio can contain multiple vectors, each with a different page.
-+	 * Treat each vector as a separate request.
-+	 */
-+	/* KMC: Is this the right way to walk the bvec list? */
-+	for (i = 0;
-+	     i < bio->bi_vcnt;
-+	     i++, bio->bi_idx++, starting_lsn += count) {
-+
-+		/* Bvec info: number of sectors, page,
-+		 * and byte-offset within page.
-+		 */
-+		count = bio_iovec(bio)->bv_len >> SECTOR_SHIFT;
-+		pl.page = bio_iovec(bio)->bv_page;
-+		offset = bio_iovec(bio)->bv_offset;
-+
-+		/* For each sector in this bvec, check if the sector has
-+		 * already been remapped. If so, process all previous sectors
-+		 * in this request, followed by the remapped sector. Then reset
-+		 * the starting lsn and count and keep going with the rest of
-+		 * the request as if it were a whole new request.
-+		 */
-+		for (lsn = 0; lsn < count; lsn++) {
-+			remapped_lsn = starting_lsn + lsn;
-+			rc = bbr_remap(bbr_id, &remapped_lsn);
-+			if (!rc) {
-+				/* This sector is fine. */
-+				continue;
-+			}
-+
-+			/* Process all sectors in the request up to this one. */
-+			if (lsn > 0) {
-+				job.sector = starting_lsn;
-+				job.count = lsn;
-+				rc = io_sync(bbr_id, &pl, offset, &job, rw);
-+				if (rc) {
-+					/* If this I/O failed, then one of the
-+					 * sectors in this request needs to be
-+					 * relocated.
-+					 */
-+					rc = bbr_io_remap_error(bbr_id, rw,
-+								starting_lsn,
-+								lsn, pl.page,
-+								offset);
-+					if (rc) {
-+						/* KMC: Return? Or continue to next bvec? */
-+						return rc;
-+					}
-+				}
-+				offset += (lsn << SECTOR_SHIFT);
-+			}
-+
-+			/* Process the remapped sector. */
-+			job.sector = remapped_lsn;
-+			job.count = 1;
-+			rc = io_sync(bbr_id, &pl, offset, &job, rw);
-+			if (rc) {
-+				/* BUGBUG - Need more processing if this caused
-+				 * an error. If this I/O failed, then the
-+				 * existing remap is now bad, and we need to
-+				 * find a new remap. Can't use
-+				 * bbr_io_remap_error(), because the existing
-+				 * map entry needs to be changed, not added
-+				 * again, and the original table entry also
-+				 * needs to be changed.
-+				 */
-+				return rc;
-+			}
-+
-+			starting_lsn	+= (lsn + 1);
-+			count		-= (lsn + 1);
-+			lsn		= -1;
-+			offset		+= SECTOR_SIZE;
-+		}
-+
-+		/* Check for any remaining sectors after the last split. This
-+		 * could potentially be the whole request, but that should be a
-+		 * rare case because requests should only be processed by the
-+		 * thread if we know an error occurred or they contained one or
-+		 * more remapped sectors.
-+		 */
-+		if (count) {
-+			job.sector = starting_lsn;
-+			job.count = count;
-+			rc = io_sync(bbr_id, &pl, offset, &job, rw);
-+			if (rc) {
-+				/* If this I/O failed, then one of the sectors
-+				 * in this request needs to be relocated.
-+				 */
-+				rc = bbr_io_remap_error(bbr_id, rw, starting_lsn,
-+							count, pl.page, offset);
-+				if (rc) {
-+					/* KMC: Return? Or continue to next bvec? */
-+					return rc;
-+				}
-+			}
-+		}
-+	}
-+
-+	return 0;
-+}
-+
-+static void bbr_io_process_requests(struct bbr_private *bbr_id,
-+				    struct bio *bio)
-+{
-+	struct bio *next;
-+	int rc;
-+
-+	while (bio) {
-+		next = bio->bi_next;
-+		bio->bi_next = NULL;
-+
-+		rc = bbr_io_process_request(bbr_id, bio);
-+
-+		bio_endio(bio, rc);
-+
-+		bio = next;
-+	}
-+}
-+
-+/**
-+ * bbr_remap_handler
-+ *
-+ * This is the handler for the bbr work-queue.
-+ *
-+ * I/O requests should only be sent to this handler if we know that:
-+ * a) the request contains at least one remapped sector.
-+ *   or
-+ * b) the request caused an error on the normal I/O path.
-+ *
-+ * This function uses synchronous I/O, so sending a request to this
-+ * thread that doesn't need special processing will cause severe
-+ * performance degredation.
-+ **/
-+static void bbr_remap_handler(struct work_struct *work)
-+{
-+	struct bbr_private *bbr_id =
-+		container_of(work, struct bbr_private, remap_work);
-+	struct bio *bio;
-+	unsigned long flags;
-+
-+	spin_lock_irqsave(&bbr_id->remap_ios_lock, flags);
-+	bio = bio_list_get(&bbr_id->remap_ios);
-+	spin_unlock_irqrestore(&bbr_id->remap_ios_lock, flags);
-+
-+	bbr_io_process_requests(bbr_id, bio);
-+}
-+
-+/**
-+ * bbr_endio
-+ *
-+ * This is the callback for normal write requests. Check for an error
-+ * during the I/O, and send to the thread for processing if necessary.
-+ **/
-+static int bbr_endio(struct dm_target *ti, struct bio *bio,
-+		     int error, union map_info *map_context)
-+{
-+	struct bbr_private *bbr_id = ti->private;
-+	struct dm_bio_details *bbr_io = map_context->ptr;
-+
-+	if (error && bbr_io) {
-+		unsigned long flags;
-+		char b[32];
-+
-+		dm_bio_restore(bbr_io, bio);
-+		map_context->ptr = NULL;
-+
-+		DMERR("device %s: I/O failure on sector %lu. "
-+		      "Scheduling for retry.",
-+		      format_dev_t(b, bbr_id->dev->bdev->bd_dev),
-+		      (unsigned long)bio->bi_sector);
-+
-+		spin_lock_irqsave(&bbr_id->remap_ios_lock, flags);
-+		bio_list_add(&bbr_id->remap_ios, bio);
-+		spin_unlock_irqrestore(&bbr_id->remap_ios_lock, flags);
-+
-+		queue_work(dm_bbr_wq, &bbr_id->remap_work);
-+
-+		error = 1;
-+	}
-+
-+	if (bbr_io)
-+		mempool_free(bbr_io, bbr_io_pool);
-+
-+	return error;
-+}
-+
-+/**
-+ * Construct a bbr mapping
-+ **/
-+static int bbr_ctr(struct dm_target *ti, unsigned int argc, char **argv)
-+{
-+	struct bbr_private *bbr_id;
-+	unsigned long block_size;
-+	char *end;
-+	int rc = -EINVAL;
-+
-+	if (argc != 8) {
-+		ti->error = "dm-bbr requires exactly 8 arguments: "
-+			    "device offset table1_lsn table2_lsn table_size start_replacement nr_replacement_blks block_size";
-+		goto out1;
-+	}
-+
-+	bbr_id = bbr_alloc_private();
-+	if (!bbr_id) {
-+		ti->error = "dm-bbr: Error allocating bbr private data.";
-+		goto out1;
-+	}
-+
-+	bbr_id->offset = simple_strtoull(argv[1], &end, 10);
-+	bbr_id->lba_table1 = simple_strtoull(argv[2], &end, 10);
-+	bbr_id->lba_table2 = simple_strtoull(argv[3], &end, 10);
-+	bbr_id->nr_sects_bbr_table = simple_strtoull(argv[4], &end, 10);
-+	bbr_id->start_replacement_sect = simple_strtoull(argv[5], &end, 10);
-+	bbr_id->nr_replacement_blks = simple_strtoull(argv[6], &end, 10);
-+	block_size = simple_strtoul(argv[7], &end, 10);
-+	bbr_id->blksize_in_sects = (block_size >> SECTOR_SHIFT);
-+
-+	bbr_id->vma_io_req.mem.type = DM_IO_VMA;
-+	bbr_id->vma_io_req.client = dm_io_client_create(1);
-+	if (IS_ERR(bbr_id->vma_io_req.client)) {
-+		rc = PTR_ERR(bbr_id->vma_io_req.client);
-+		DMWARN("couldn't allocate disk VMA io client");
-+		goto out2;
-+	}
-+
-+	bbr_id->page_io_req.mem.type = DM_IO_PAGE_LIST;
-+	bbr_id->page_io_req.client = dm_io_client_create(1);
-+	if (IS_ERR(bbr_id->page_io_req.client)) {
-+		rc = PTR_ERR(bbr_id->page_io_req.client);
-+		DMWARN("couldn't allocate pagelist io client");
-+		goto out3;
-+	}
-+
-+	bbr_id->bbr_table = vmalloc(bbr_id->nr_sects_bbr_table << SECTOR_SHIFT);
-+	if (!bbr_id->bbr_table) {
-+		ti->error = "dm-bbr: Error allocating bbr table.";
-+		goto out4;
-+	}
-+
-+	if (dm_get_device(ti, argv[0], 0, ti->len,
-+			  dm_table_get_mode(ti->table), &bbr_id->dev)) {
-+		ti->error = "dm-bbr: Device lookup failed";
-+		goto out4;
-+	}
-+
-+	rc = bbr_setup(bbr_id);
-+	if (rc) {
-+		ti->error = "dm-bbr: Device setup failed";
-+		goto out5;
-+	}
-+
-+	ti->private = bbr_id;
-+	return 0;
-+
-+out5:
-+	dm_put_device(ti, bbr_id->dev);
-+out4:
-+	dm_io_client_destroy(bbr_id->page_io_req.client);
-+out3:
-+	dm_io_client_destroy(bbr_id->vma_io_req.client);
-+out2:
-+	bbr_free_private(bbr_id);
-+out1:
-+	return rc;
-+}
-+
-+static void bbr_dtr(struct dm_target *ti)
-+{
-+	struct bbr_private *bbr_id = ti->private;
-+
-+	dm_put_device(ti, bbr_id->dev);
-+	dm_io_client_destroy(bbr_id->page_io_req.client);
-+	dm_io_client_destroy(bbr_id->vma_io_req.client);
-+	bbr_free_private(bbr_id);
-+}
-+
-+static int bbr_map(struct dm_target *ti, struct bio *bio,
-+		   union map_info *map_context)
-+{
-+	struct bbr_private *bbr_id = ti->private;
-+	struct dm_bio_details *bbr_io;
-+	unsigned long flags;
-+	int rc = 1;
-+
-+	bio->bi_sector += bbr_id->offset;
-+
-+	if (atomic_read(&bbr_id->in_use_replacement_blks) == 0 ||
-+	    !bbr_remap_probe(bbr_id, bio->bi_sector, bio_sectors(bio))) {
-+		/* No existing remaps or this request doesn't
-+		 * contain any remapped sectors.
-+		 */
-+		bio->bi_bdev = bbr_id->dev->bdev;
-+
-+		bbr_io = mempool_alloc(bbr_io_pool, GFP_NOIO);
-+		dm_bio_record(bbr_io, bio);
-+		map_context->ptr = bbr_io;
-+	} else {
-+		/* This request has at least one remapped sector.
-+		 * Give it to the work-queue for processing.
-+		 */
-+		map_context->ptr = NULL;
-+		spin_lock_irqsave(&bbr_id->remap_ios_lock, flags);
-+		bio_list_add(&bbr_id->remap_ios, bio);
-+		spin_unlock_irqrestore(&bbr_id->remap_ios_lock, flags);
-+
-+		queue_work(dm_bbr_wq, &bbr_id->remap_work);
-+		rc = 0;
-+	}
-+
-+	return rc;
-+}
-+
-+static int bbr_status(struct dm_target *ti, status_type_t type,
-+		      char *result, unsigned int maxlen)
-+{
-+	struct bbr_private *bbr_id = ti->private;
-+	char b[BDEVNAME_SIZE];
-+
-+	switch (type) {
-+	case STATUSTYPE_INFO:
-+		result[0] = '\0';
-+		break;
-+
-+	case STATUSTYPE_TABLE:
-+		snprintf(result, maxlen, "%s "PFU64" "PFU64" "PFU64" "PFU64" "PFU64" "PFU64" %u",
-+			 format_dev_t(b, bbr_id->dev->bdev->bd_dev),
-+			 bbr_id->offset, bbr_id->lba_table1, bbr_id->lba_table2,
-+			 bbr_id->nr_sects_bbr_table,
-+			 bbr_id->start_replacement_sect,
-+			 bbr_id->nr_replacement_blks,
-+			 bbr_id->blksize_in_sects << SECTOR_SHIFT);
-+		 break;
-+	}
-+	return 0;
-+}
-+
-+static struct target_type bbr_target = {
-+	.name	= "bbr",
-+	.version= {1, 0, 1},
-+	.module	= THIS_MODULE,
-+	.ctr	= bbr_ctr,
-+	.dtr	= bbr_dtr,
-+	.map	= bbr_map,
-+	.end_io	= bbr_endio,
-+	.status	= bbr_status,
-+};
-+
-+int __init dm_bbr_init(void)
-+{
-+	int rc;
-+
-+	rc = dm_register_target(&bbr_target);
-+	if (rc) {
-+		DMERR("error registering target.");
-+		goto err1;
-+	}
-+
-+	bbr_remap_cache = kmem_cache_create("bbr-remap",
-+					    sizeof(struct bbr_runtime_remap),
-+					    0, SLAB_HWCACHE_ALIGN, NULL);
-+	if (!bbr_remap_cache) {
-+		DMERR("error creating remap cache.");
-+		rc = ENOMEM;
-+		goto err2;
-+	}
-+
-+	bbr_io_cache = kmem_cache_create("bbr-io", sizeof(struct dm_bio_details),
-+					 0, SLAB_HWCACHE_ALIGN, NULL);
-+	if (!bbr_io_cache) {
-+		DMERR("error creating io cache.");
-+		rc = ENOMEM;
-+		goto err3;
-+	}
-+
-+	bbr_io_pool = mempool_create(256, mempool_alloc_slab,
-+				     mempool_free_slab, bbr_io_cache);
-+	if (!bbr_io_pool) {
-+		DMERR("error creating io mempool.");
-+		rc = ENOMEM;
-+		goto err4;
-+	}
-+
-+	dm_bbr_wq = create_workqueue("dm-bbr");
-+	if (!dm_bbr_wq) {
-+		DMERR("error creating work-queue.");
-+		rc = ENOMEM;
-+		goto err5;
-+	}
-+
-+	return 0;
-+
-+err5:
-+	mempool_destroy(bbr_io_pool);
-+err4:
-+	kmem_cache_destroy(bbr_io_cache);
-+err3:
-+	kmem_cache_destroy(bbr_remap_cache);
-+err2:
-+	dm_unregister_target(&bbr_target);
-+err1:
-+	return rc;
-+}
-+
-+void __exit dm_bbr_exit(void)
-+{
-+	destroy_workqueue(dm_bbr_wq);
-+	mempool_destroy(bbr_io_pool);
-+	kmem_cache_destroy(bbr_io_cache);
-+	kmem_cache_destroy(bbr_remap_cache);
-+	dm_unregister_target(&bbr_target);
-+}
-+
-+module_init(dm_bbr_init);
-+module_exit(dm_bbr_exit);
-+MODULE_LICENSE("GPL");
-Index: linux-2.6.26-gentoo/drivers/md/dm-bbr.h
-===================================================================
---- /dev/null
-+++ linux-2.6.26-gentoo/drivers/md/dm-bbr.h
-@@ -0,0 +1,130 @@
-+/*
-+ *   (C) Copyright IBM Corp. 2002, 2004
-+ *
-+ *   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 of the License, or
-+ *   (at your option) any later version.
-+ *
-+ *   This program is distributed in the hope that it will be useful,
-+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
-+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
-+ *   the GNU General Public License for more details.
-+ *
-+ *   You should have received a copy of the GNU General Public License
-+ *   along with this program;  if not, write to the Free Software
-+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * linux/drivers/md/dm-bbr.h
-+ *
-+ * Bad-block-relocation (BBR) target for device-mapper.
-+ *
-+ * The BBR target is designed to remap I/O write failures to another safe
-+ * location on disk. Note that most disk drives have BBR built into them,
-+ * this means that our software BBR will be only activated when all hardware
-+ * BBR replacement sectors have been used.
-+ */
-+
-+#include <linux/dm-io.h>
-+
-+#define BBR_TABLE_SIGNATURE		0x42627254 /* BbrT */
-+#define BBR_ENTRIES_PER_SECT		31
-+#define INITIAL_CRC			0xFFFFFFFF
-+#define CRC_POLYNOMIAL			0xEDB88320L
-+
-+/**
-+ * Macros to cleanly print 64-bit numbers on both 32-bit and 64-bit machines.
-+ * Use these in place of %Ld, %Lu, and %Lx.
-+ **/
-+#if BITS_PER_LONG > 32
-+#define PFU64 "%llu"
-+#else
-+#define PFU64 "%Lu"
-+#endif
-+
-+/**
-+ * struct bbr_table_entry
-+ * @bad_sect:		LBA of bad location.
-+ * @replacement_sect:	LBA of new location.
-+ *
-+ * Structure to describe one BBR remap.
-+ **/
-+struct bbr_table_entry {
-+	u64 bad_sect;
-+	u64 replacement_sect;
-+};
-+
-+/**
-+ * struct bbr_table
-+ * @signature:		Signature on each BBR table sector.
-+ * @crc:		CRC for this table sector.
-+ * @sequence_number:	Used to resolve conflicts when primary and secondary
-+ *			tables do not match.
-+ * @in_use_cnt:		Number of in-use table entries.
-+ * @entries:		Actual table of remaps.
-+ *
-+ * Structure to describe each sector of the metadata table. Each sector in this
-+ * table can describe 31 remapped sectors.
-+ **/
-+struct bbr_table {
-+	u32			signature;
-+	u32			crc;
-+	u32			sequence_number;
-+	u32			in_use_cnt;
-+	struct bbr_table_entry	entries[BBR_ENTRIES_PER_SECT];
-+};
-+
-+/**
-+ * struct bbr_runtime_remap
-+ *
-+ * Node in the binary tree used to keep track of remaps.
-+ **/
-+struct bbr_runtime_remap {
-+	struct bbr_table_entry		remap;
-+	struct bbr_runtime_remap	*left;
-+	struct bbr_runtime_remap	*right;
-+};
-+
-+/**
-+ * struct bbr_private
-+ * @dev:			Info about underlying device.
-+ * @bbr_table:			Copy of metadata table.
-+ * @remap_root:			Binary tree containing all remaps.
-+ * @remap_root_lock:		Lock for the binary tree.
-+ * @remap_work:			For adding work items to the work-queue.
-+ * @remap_ios:			List of I/Os for the work-queue to handle.
-+ * @remap_ios_lock:		Lock for the remap_ios list.
-+ * @offset:			LBA of data area.
-+ * @lba_table1:			LBA of primary BBR table.
-+ * @lba_table2:			LBA of secondary BBR table.
-+ * @nr_sects_bbr_table:		Size of each BBR table.
-+ * @nr_replacement_blks:	Number of replacement blocks.
-+ * @start_replacement_sect:	LBA of start of replacement blocks.
-+ * @blksize_in_sects:		Size of each block.
-+ * @in_use_replacement_blks:	Current number of remapped blocks.
-+ *
-+ * Private data for each BBR target.
-+ **/
-+struct bbr_private {
-+	struct dm_dev			*dev;
-+	struct bbr_table		*bbr_table;
-+	struct bbr_runtime_remap	*remap_root;
-+	spinlock_t			remap_root_lock;
-+
-+	struct dm_io_request vma_io_req;
-+	struct dm_io_request page_io_req;
-+
-+	struct work_struct		remap_work;
-+	struct bio_list			remap_ios;
-+	spinlock_t			remap_ios_lock;
-+
-+	u64				offset;
-+	u64				lba_table1;
-+	u64				lba_table2;
-+	u64				nr_sects_bbr_table;
-+	u64				start_replacement_sect;
-+	u64				nr_replacement_blks;
-+	u32				blksize_in_sects;
-+	atomic_t			in_use_replacement_blks;
-+};
-+




^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2010-05-17  0:15 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-17  0:15 [gentoo-commits] linux-patches r1703 - genpatches-2.6/trunk/2.6.34 Mike Pagano (mpagano)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox