]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
rd: support XIP
authorNick Piggin <npiggin@suse.de>
Fri, 8 Feb 2008 12:19:50 +0000 (04:19 -0800)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Fri, 8 Feb 2008 17:22:30 +0000 (09:22 -0800)
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>
drivers/block/Kconfig
drivers/block/brd.c

index 8be67cd3fe01b0635a75cf2ac3c942cda0b2e5a6..b6d230b3209f24567be22208be6d8236af88282d 100644 (file)
@@ -357,6 +357,16 @@ config BLK_DEV_RAM_SIZE
          The default value is 4096 kilobytes. Only change this if you know
          what you are doing.
 
          The default value is 4096 kilobytes. Only change this if you know
          what you are doing.
 
+config BLK_DEV_XIP
+       bool "Support XIP filesystems on RAM block device"
+       depends on BLK_DEV_RAM
+       default n
+       help
+         Support XIP filesystems (such as ext2 with XIP support on) on
+         top of block ram device. This will slightly enlarge the kernel, and
+         will prevent RAM block device backing store memory from being
+         allocated from highmem (only a problem for highmem systems).
+
 config CDROM_PKTCDVD
        tristate "Packet writing on CD/DVD media"
        depends on !UML
 config CDROM_PKTCDVD
        tristate "Packet writing on CD/DVD media"
        depends on !UML
index 50b659bedc8fe57893de5f52635b989037210b3c..85364804364fc3a058114b30379927dcd974621f 100644 (file)
@@ -89,6 +89,7 @@ static struct page *brd_insert_page(struct brd_device *brd, sector_t sector)
 {
        pgoff_t idx;
        struct page *page;
 {
        pgoff_t idx;
        struct page *page;
+       gfp_t gfp_flags;
 
        page = brd_lookup_page(brd, sector);
        if (page)
 
        page = brd_lookup_page(brd, sector);
        if (page)
@@ -97,7 +98,16 @@ static struct page *brd_insert_page(struct brd_device *brd, sector_t sector)
        /*
         * Must use NOIO because we don't want to recurse back into the
         * block or filesystem layers from page reclaim.
        /*
         * Must use NOIO because we don't want to recurse back into the
         * block or filesystem layers from page reclaim.
+        *
+        * Cannot support XIP and highmem, because our ->direct_access
+        * routine for XIP must return memory that is always addressable.
+        * If XIP was reworked to use pfns and kmap throughout, this
+        * restriction might be able to be lifted.
         */
         */
+       gfp_flags = GFP_NOIO | __GFP_ZERO;
+#ifndef CONFIG_BLK_DEV_XIP
+       gfp_flags |= __GFP_HIGHMEM;
+#endif
        page = alloc_page(GFP_NOIO | __GFP_HIGHMEM | __GFP_ZERO);
        if (!page)
                return NULL;
        page = alloc_page(GFP_NOIO | __GFP_HIGHMEM | __GFP_ZERO);
        if (!page)
                return NULL;
@@ -307,6 +317,28 @@ out:
        return 0;
 }
 
        return 0;
 }
 
+#ifdef CONFIG_BLK_DEV_XIP
+static int brd_direct_access (struct block_device *bdev, sector_t sector,
+                       unsigned long *data)
+{
+       struct brd_device *brd = bdev->bd_disk->private_data;
+       struct page *page;
+
+       if (!brd)
+               return -ENODEV;
+       if (sector & (PAGE_SECTORS-1))
+               return -EINVAL;
+       if (sector + PAGE_SECTORS > get_capacity(bdev->bd_disk))
+               return -ERANGE;
+       page = brd_insert_page(brd, sector);
+       if (!page)
+               return -ENOMEM;
+       *data = (unsigned long)page_address(page);
+
+       return 0;
+}
+#endif
+
 static int brd_ioctl(struct inode *inode, struct file *file,
                        unsigned int cmd, unsigned long arg)
 {
 static int brd_ioctl(struct inode *inode, struct file *file,
                        unsigned int cmd, unsigned long arg)
 {
@@ -342,8 +374,11 @@ static int brd_ioctl(struct inode *inode, struct file *file,
 }
 
 static struct block_device_operations brd_fops = {
 }
 
 static struct block_device_operations brd_fops = {
-       .owner =        THIS_MODULE,
-       .ioctl =        brd_ioctl,
+       .owner =                THIS_MODULE,
+       .ioctl =                brd_ioctl,
+#ifdef CONFIG_BLK_DEV_XIP
+       .direct_access =        brd_direct_access,
+#endif
 };
 
 /*
 };
 
 /*