]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/ext2/xip.c
Merge branch 'for-linus' of git://git.o-hand.com/linux-rpurdie-leds
[linux-2.6-omap-h63xx.git] / fs / ext2 / xip.c
index 0aa5ac159c0940947925425c06d2a688c0bb05bc..b72b85884223fc3761208f6bc891b39e3213d034 100644 (file)
 #include <linux/buffer_head.h>
 #include <linux/ext2_fs_sb.h>
 #include <linux/ext2_fs.h>
+#include <linux/blkdev.h>
 #include "ext2.h"
 #include "xip.h"
 
 static inline int
-__inode_direct_access(struct inode *inode, sector_t sector,
-                     unsigned long *data)
+__inode_direct_access(struct inode *inode, sector_t block,
+                     void **kaddr, unsigned long *pfn)
 {
-       BUG_ON(!inode->i_sb->s_bdev->bd_disk->fops->direct_access);
-       return inode->i_sb->s_bdev->bd_disk->fops
-               ->direct_access(inode->i_sb->s_bdev,sector,data);
+       struct block_device *bdev = inode->i_sb->s_bdev;
+       struct block_device_operations *ops = bdev->bd_disk->fops;
+       sector_t sector;
+
+       sector = block * (PAGE_SIZE / 512); /* ext2 block to bdev sector */
+
+       BUG_ON(!ops->direct_access);
+       return ops->direct_access(bdev, sector, kaddr, pfn);
 }
 
 static inline int
-__ext2_get_sector(struct inode *inode, sector_t offset, int create,
+__ext2_get_block(struct inode *inode, pgoff_t pgoff, int create,
                   sector_t *result)
 {
        struct buffer_head tmp;
        int rc;
 
        memset(&tmp, 0, sizeof(struct buffer_head));
-       rc = ext2_get_block(inode, offset/ (PAGE_SIZE/512), &tmp,
-                           create);
+       rc = ext2_get_block(inode, pgoff, &tmp, create);
        *result = tmp.b_blocknr;
 
        /* did we get a sparse block (hole in the file)? */
-       if (!(*result)) {
+       if (!tmp.b_blocknr && !rc) {
                BUG_ON(create);
                rc = -ENODATA;
        }
@@ -45,15 +50,15 @@ __ext2_get_sector(struct inode *inode, sector_t offset, int create,
 }
 
 int
-ext2_clear_xip_target(struct inode *inode, int block)
+ext2_clear_xip_target(struct inode *inode, sector_t block)
 {
-       sector_t sector = block * (PAGE_SIZE/512);
-       unsigned long data;
+       void *kaddr;
+       unsigned long pfn;
        int rc;
 
-       rc = __inode_direct_access(inode, sector, &data);
+       rc = __inode_direct_access(inode, block, &kaddr, &pfn);
        if (!rc)
-               clear_page((void*)data);
+               clear_page(kaddr);
        return rc;
 }
 
@@ -64,30 +69,23 @@ void ext2_xip_verify_sb(struct super_block *sb)
        if ((sbi->s_mount_opt & EXT2_MOUNT_XIP) &&
            !sb->s_bdev->bd_disk->fops->direct_access) {
                sbi->s_mount_opt &= (~EXT2_MOUNT_XIP);
-               ext2_warning(sb, __FUNCTION__,
+               ext2_warning(sb, __func__,
                             "ignoring xip option - not supported by bdev");
        }
 }
 
-struct page *
-ext2_get_xip_page(struct address_space *mapping, sector_t offset,
-                  int create)
+int ext2_get_xip_mem(struct address_space *mapping, pgoff_t pgoff, int create,
+                               void **kmem, unsigned long *pfn)
 {
        int rc;
-       unsigned long data;
-       sector_t sector;
+       sector_t block;
 
        /* first, retrieve the sector number */
-       rc = __ext2_get_sector(mapping->host, offset, create, &sector);
+       rc = __ext2_get_block(mapping->host, pgoff, create, &block);
        if (rc)
-               goto error;
+               return rc;
 
        /* retrieve address of the target data */
-       rc = __inode_direct_access
-               (mapping->host, sector * (PAGE_SIZE/512), &data);
-       if (!rc)
-               return virt_to_page(data);
-
- error:
-       return ERR_PTR(rc);
+       rc = __inode_direct_access(mapping->host, block, kmem, pfn);
+       return rc;
 }