aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorNick Piggin <npiggin@suse.de>2008-02-08 07:19:50 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-08 12:22:30 -0500
commit75acb9cd2ef0bbb463098fdd40cbcdda79d45fa3 (patch)
treeacb8f0a63ac1249146041b06eaaa003ea24c8c7a /drivers
parent9db5579be4bb5320c3248f6acf807aedf05ae143 (diff)
rd: support XIP
Support direct_access XIP method with brd. Signed-off-by: Nick Piggin <npiggin@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/Kconfig10
-rw-r--r--drivers/block/brd.c39
2 files changed, 47 insertions, 2 deletions
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 8be67cd3fe01..b6d230b3209f 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -357,6 +357,16 @@ config BLK_DEV_RAM_SIZE
357 The default value is 4096 kilobytes. Only change this if you know 357 The default value is 4096 kilobytes. Only change this if you know
358 what you are doing. 358 what you are doing.
359 359
360config BLK_DEV_XIP
361 bool "Support XIP filesystems on RAM block device"
362 depends on BLK_DEV_RAM
363 default n
364 help
365 Support XIP filesystems (such as ext2 with XIP support on) on
366 top of block ram device. This will slightly enlarge the kernel, and
367 will prevent RAM block device backing store memory from being
368 allocated from highmem (only a problem for highmem systems).
369
360config CDROM_PKTCDVD 370config CDROM_PKTCDVD
361 tristate "Packet writing on CD/DVD media" 371 tristate "Packet writing on CD/DVD media"
362 depends on !UML 372 depends on !UML
diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index 50b659bedc8f..85364804364f 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -89,6 +89,7 @@ static struct page *brd_insert_page(struct brd_device *brd, sector_t sector)
89{ 89{
90 pgoff_t idx; 90 pgoff_t idx;
91 struct page *page; 91 struct page *page;
92 gfp_t gfp_flags;
92 93
93 page = brd_lookup_page(brd, sector); 94 page = brd_lookup_page(brd, sector);
94 if (page) 95 if (page)
@@ -97,7 +98,16 @@ static struct page *brd_insert_page(struct brd_device *brd, sector_t sector)
97 /* 98 /*
98 * Must use NOIO because we don't want to recurse back into the 99 * Must use NOIO because we don't want to recurse back into the
99 * block or filesystem layers from page reclaim. 100 * block or filesystem layers from page reclaim.
101 *
102 * Cannot support XIP and highmem, because our ->direct_access
103 * routine for XIP must return memory that is always addressable.
104 * If XIP was reworked to use pfns and kmap throughout, this
105 * restriction might be able to be lifted.
100 */ 106 */
107 gfp_flags = GFP_NOIO | __GFP_ZERO;
108#ifndef CONFIG_BLK_DEV_XIP
109 gfp_flags |= __GFP_HIGHMEM;
110#endif
101 page = alloc_page(GFP_NOIO | __GFP_HIGHMEM | __GFP_ZERO); 111 page = alloc_page(GFP_NOIO | __GFP_HIGHMEM | __GFP_ZERO);
102 if (!page) 112 if (!page)
103 return NULL; 113 return NULL;
@@ -307,6 +317,28 @@ out:
307 return 0; 317 return 0;
308} 318}
309 319
320#ifdef CONFIG_BLK_DEV_XIP
321static int brd_direct_access (struct block_device *bdev, sector_t sector,
322 unsigned long *data)
323{
324 struct brd_device *brd = bdev->bd_disk->private_data;
325 struct page *page;
326
327 if (!brd)
328 return -ENODEV;
329 if (sector & (PAGE_SECTORS-1))
330 return -EINVAL;
331 if (sector + PAGE_SECTORS > get_capacity(bdev->bd_disk))
332 return -ERANGE;
333 page = brd_insert_page(brd, sector);
334 if (!page)
335 return -ENOMEM;
336 *data = (unsigned long)page_address(page);
337
338 return 0;
339}
340#endif
341
310static int brd_ioctl(struct inode *inode, struct file *file, 342static int brd_ioctl(struct inode *inode, struct file *file,
311 unsigned int cmd, unsigned long arg) 343 unsigned int cmd, unsigned long arg)
312{ 344{
@@ -342,8 +374,11 @@ static int brd_ioctl(struct inode *inode, struct file *file,
342} 374}
343 375
344static struct block_device_operations brd_fops = { 376static struct block_device_operations brd_fops = {
345 .owner = THIS_MODULE, 377 .owner = THIS_MODULE,
346 .ioctl = brd_ioctl, 378 .ioctl = brd_ioctl,
379#ifdef CONFIG_BLK_DEV_XIP
380 .direct_access = brd_direct_access,
381#endif
347}; 382};
348 383
349/* 384/*