Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block

* 'for-linus' of git://git.kernel.dk/linux-2.6-block:
  scatterlist: add more safeguards
  Revert "ll_rw_blk: temporarily enable max_segments tweaking"
  mmc: Add missing sg_init_table() call
  block: Fix memory leak in alloc_disk_node()
  alpha: fix sg_page breakage
  blktrace: Make sure BLKTRACETEARDOWN does the full cleanup.
diff --git a/arch/alpha/kernel/pci-noop.c b/arch/alpha/kernel/pci-noop.c
index 174b729..468b76c 100644
--- a/arch/alpha/kernel/pci-noop.c
+++ b/arch/alpha/kernel/pci-noop.c
@@ -12,6 +12,7 @@
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/dma-mapping.h>
+#include <linux/scatterlist.h>
 
 #include "proto.h"
 
@@ -172,18 +173,19 @@
 EXPORT_SYMBOL(dma_alloc_coherent);
 
 int
-dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+dma_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
 	   enum dma_data_direction direction)
 {
 	int i;
+	struct scatterlist *sg;
 
-	for (i = 0; i < nents; i++ ) {
+	for_each_sg(sgl, sg, nents, i) {
 		void *va;
 
-		BUG_ON(!sg[i].page);
-		va = page_address(sg[i].page) + sg[i].offset;
-		sg_dma_address(sg + i) = (dma_addr_t)virt_to_bus(va);
-		sg_dma_len(sg + i) = sg[i].length;
+		BUG_ON(!sg_page(sg));
+		va = sg_virt(sg);
+		sg_dma_address(sg) = (dma_addr_t)virt_to_bus(va);
+		sg_dma_len(sg) = sg->length;
 	}
 
 	return nents;
diff --git a/block/blktrace.c b/block/blktrace.c
index d00ac39..498a0a5 100644
--- a/block/blktrace.c
+++ b/block/blktrace.c
@@ -202,6 +202,7 @@
 static struct dentry *blk_create_tree(const char *blk_name)
 {
 	struct dentry *dir = NULL;
+	int created = 0;
 
 	mutex_lock(&blk_tree_mutex);
 
@@ -209,13 +210,17 @@
 		blk_tree_root = debugfs_create_dir("block", NULL);
 		if (!blk_tree_root)
 			goto err;
+		created = 1;
 	}
 
 	dir = debugfs_create_dir(blk_name, blk_tree_root);
 	if (dir)
 		root_users++;
-	else
-		blk_remove_root();
+	else {
+		/* Delete root only if we created it */
+		if (created)
+			blk_remove_root();
+	}
 
 err:
 	mutex_unlock(&blk_tree_mutex);
diff --git a/block/genhd.c b/block/genhd.c
index e609996..f2ac914 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -715,6 +715,7 @@
 			disk->part = kmalloc_node(size,
 				GFP_KERNEL | __GFP_ZERO, node_id);
 			if (!disk->part) {
+				free_disk_stats(disk);
 				kfree(disk);
 				return NULL;
 			}
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 3b927be..8b91994 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -4080,23 +4080,7 @@
 	return queue_var_show(max_hw_sectors_kb, (page));
 }
 
-static ssize_t queue_max_segments_show(struct request_queue *q, char *page)
-{
-	return queue_var_show(q->max_phys_segments, page);
-}
 
-static ssize_t queue_max_segments_store(struct request_queue *q,
-					const char *page, size_t count)
-{
-	unsigned long segments;
-	ssize_t ret = queue_var_store(&segments, page, count);
-
-	spin_lock_irq(q->queue_lock);
-	q->max_phys_segments = segments;
-	spin_unlock_irq(q->queue_lock);
-
-	return ret;
-}
 static struct queue_sysfs_entry queue_requests_entry = {
 	.attr = {.name = "nr_requests", .mode = S_IRUGO | S_IWUSR },
 	.show = queue_requests_show,
@@ -4120,12 +4104,6 @@
 	.show = queue_max_hw_sectors_show,
 };
 
-static struct queue_sysfs_entry queue_max_segments_entry = {
-	.attr = {.name = "max_segments", .mode = S_IRUGO | S_IWUSR },
-	.show = queue_max_segments_show,
-	.store = queue_max_segments_store,
-};
-
 static struct queue_sysfs_entry queue_iosched_entry = {
 	.attr = {.name = "scheduler", .mode = S_IRUGO | S_IWUSR },
 	.show = elv_iosched_show,
@@ -4137,7 +4115,6 @@
 	&queue_ra_entry.attr,
 	&queue_max_hw_sectors_entry.attr,
 	&queue_max_sectors_entry.attr,
-	&queue_max_segments_entry.attr,
 	&queue_iosched_entry.attr,
 	NULL,
 };
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index 1b9c9b6..30cd13b 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -180,12 +180,13 @@
 		blk_queue_max_hw_segments(mq->queue, host->max_hw_segs);
 		blk_queue_max_segment_size(mq->queue, host->max_seg_size);
 
-		mq->sg = kzalloc(sizeof(struct scatterlist) *
+		mq->sg = kmalloc(sizeof(struct scatterlist) *
 			host->max_phys_segs, GFP_KERNEL);
 		if (!mq->sg) {
 			ret = -ENOMEM;
 			goto cleanup_queue;
 		}
+		sg_init_table(mq->sg, host->max_phys_segs);
 	}
 
 	init_MUTEX(&mq->thread_sem);
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index 2597350..416e000 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -26,6 +26,16 @@
 
 #define SG_MAGIC	0x87654321
 
+/*
+ * We overload the LSB of the page pointer to indicate whether it's
+ * a valid sg entry, or whether it points to the start of a new scatterlist.
+ * Those low bits are there for everyone! (thanks mason :-)
+ */
+#define sg_is_chain(sg)		((sg)->page_link & 0x01)
+#define sg_is_last(sg)		((sg)->page_link & 0x02)
+#define sg_chain_ptr(sg)	\
+	((struct scatterlist *) ((sg)->page_link & ~0x03))
+
 /**
  * sg_assign_page - Assign a given page to an SG entry
  * @sg:		    SG entry
@@ -47,6 +57,7 @@
 	BUG_ON((unsigned long) page & 0x03);
 #ifdef CONFIG_DEBUG_SG
 	BUG_ON(sg->sg_magic != SG_MAGIC);
+	BUG_ON(sg_is_chain(sg));
 #endif
 	sg->page_link = page_link | (unsigned long) page;
 }
@@ -73,7 +84,14 @@
 	sg->length = len;
 }
 
-#define sg_page(sg)	((struct page *) ((sg)->page_link & ~0x3))
+static inline struct page *sg_page(struct scatterlist *sg)
+{
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sg->sg_magic != SG_MAGIC);
+	BUG_ON(sg_is_chain(sg));
+#endif
+	return (struct page *)((sg)->page_link & ~0x3);
+}
 
 /**
  * sg_set_buf - Set sg entry to point at given data
@@ -88,16 +106,6 @@
 	sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf));
 }
 
-/*
- * We overload the LSB of the page pointer to indicate whether it's
- * a valid sg entry, or whether it points to the start of a new scatterlist.
- * Those low bits are there for everyone! (thanks mason :-)
- */
-#define sg_is_chain(sg)		((sg)->page_link & 0x01)
-#define sg_is_last(sg)		((sg)->page_link & 0x02)
-#define sg_chain_ptr(sg)	\
-	((struct scatterlist *) ((sg)->page_link & ~0x03))
-
 /**
  * sg_next - return the next scatterlist entry in a list
  * @sg:		The current sg entry
@@ -179,6 +187,13 @@
 #ifndef ARCH_HAS_SG_CHAIN
 	BUG();
 #endif
+
+	/*
+	 * offset and length are unused for chain entry.  Clear them.
+	 */
+	prv->offset = 0;
+	prv->length = 0;
+
 	/*
 	 * Set lowest bit to indicate a link pointer, and make sure to clear
 	 * the termination bit if it happens to be set.