aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorLachlan McIlroy <lachlan@redback.melbourne.sgi.com>2009-01-14 00:29:51 -0500
committerLachlan McIlroy <lachlan@redback.melbourne.sgi.com>2009-01-14 00:29:51 -0500
commitcb7a97d01521797cad9f63e8478403c3e51fea49 (patch)
tree84cddf20369f82f10c1c3712e6cce20dd1b9d863 /block
parent0335cb76aa3fa913a2164bc9b669e5aef9d56fa3 (diff)
parenta6525042bfdfcab128bd91fad264de10fd24a55e (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6 into for-linus
Diffstat (limited to 'block')
-rw-r--r--block/Kconfig6
-rw-r--r--block/blk-map.c19
2 files changed, 16 insertions, 9 deletions
diff --git a/block/Kconfig b/block/Kconfig
index ac0956f77785..0cbb3b88b59a 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -36,6 +36,12 @@ config LBD
36 This option also enables support for single files larger than 36 This option also enables support for single files larger than
37 2TB. 37 2TB.
38 38
39 The ext4 filesystem requires that this feature be enabled in
40 order to support filesystems that have the huge_file feature
41 enabled. Otherwise, it will refuse to mount any filesystems
42 that use the huge_file feature, which is enabled by default
43 by mke2fs.ext4. The GFS2 filesystem also requires this feature.
44
39 If unsure, say N. 45 If unsure, say N.
40 46
41config BLK_DEV_IO_TRACE 47config BLK_DEV_IO_TRACE
diff --git a/block/blk-map.c b/block/blk-map.c
index 2990447f45e9..f103729b462f 100644
--- a/block/blk-map.c
+++ b/block/blk-map.c
@@ -42,7 +42,7 @@ static int __blk_rq_unmap_user(struct bio *bio)
42 42
43static int __blk_rq_map_user(struct request_queue *q, struct request *rq, 43static int __blk_rq_map_user(struct request_queue *q, struct request *rq,
44 struct rq_map_data *map_data, void __user *ubuf, 44 struct rq_map_data *map_data, void __user *ubuf,
45 unsigned int len, int null_mapped, gfp_t gfp_mask) 45 unsigned int len, gfp_t gfp_mask)
46{ 46{
47 unsigned long uaddr; 47 unsigned long uaddr;
48 struct bio *bio, *orig_bio; 48 struct bio *bio, *orig_bio;
@@ -63,7 +63,7 @@ static int __blk_rq_map_user(struct request_queue *q, struct request *rq,
63 if (IS_ERR(bio)) 63 if (IS_ERR(bio))
64 return PTR_ERR(bio); 64 return PTR_ERR(bio);
65 65
66 if (null_mapped) 66 if (map_data && map_data->null_mapped)
67 bio->bi_flags |= (1 << BIO_NULL_MAPPED); 67 bio->bi_flags |= (1 << BIO_NULL_MAPPED);
68 68
69 orig_bio = bio; 69 orig_bio = bio;
@@ -114,17 +114,15 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq,
114{ 114{
115 unsigned long bytes_read = 0; 115 unsigned long bytes_read = 0;
116 struct bio *bio = NULL; 116 struct bio *bio = NULL;
117 int ret, null_mapped = 0; 117 int ret;
118 118
119 if (len > (q->max_hw_sectors << 9)) 119 if (len > (q->max_hw_sectors << 9))
120 return -EINVAL; 120 return -EINVAL;
121 if (!len) 121 if (!len)
122 return -EINVAL; 122 return -EINVAL;
123 if (!ubuf) { 123
124 if (!map_data || rq_data_dir(rq) != READ) 124 if (!ubuf && (!map_data || !map_data->null_mapped))
125 return -EINVAL; 125 return -EINVAL;
126 null_mapped = 1;
127 }
128 126
129 while (bytes_read != len) { 127 while (bytes_read != len) {
130 unsigned long map_len, end, start; 128 unsigned long map_len, end, start;
@@ -143,13 +141,16 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq,
143 map_len -= PAGE_SIZE; 141 map_len -= PAGE_SIZE;
144 142
145 ret = __blk_rq_map_user(q, rq, map_data, ubuf, map_len, 143 ret = __blk_rq_map_user(q, rq, map_data, ubuf, map_len,
146 null_mapped, gfp_mask); 144 gfp_mask);
147 if (ret < 0) 145 if (ret < 0)
148 goto unmap_rq; 146 goto unmap_rq;
149 if (!bio) 147 if (!bio)
150 bio = rq->bio; 148 bio = rq->bio;
151 bytes_read += ret; 149 bytes_read += ret;
152 ubuf += ret; 150 ubuf += ret;
151
152 if (map_data)
153 map_data->offset += ret;
153 } 154 }
154 155
155 if (!bio_flagged(bio, BIO_USER_MAPPED)) 156 if (!bio_flagged(bio, BIO_USER_MAPPED))