linux/fs/ext2/xip.c
<<
>>
Prefs
   1/*
   2 *  linux/fs/ext2/xip.c
   3 *
   4 * Copyright (C) 2005 IBM Corporation
   5 * Author: Carsten Otte (cotte@de.ibm.com)
   6 */
   7
   8#include <linux/mm.h>
   9#include <linux/fs.h>
  10#include <linux/genhd.h>
  11#include <linux/buffer_head.h>
  12#include <linux/ext2_fs_sb.h>
  13#include <linux/ext2_fs.h>
  14#include "ext2.h"
  15#include "xip.h"
  16
  17static inline int
  18__inode_direct_access(struct inode *inode, sector_t sector,
  19                      unsigned long *data)
  20{
  21        BUG_ON(!inode->i_sb->s_bdev->bd_disk->fops->direct_access);
  22        return inode->i_sb->s_bdev->bd_disk->fops
  23                ->direct_access(inode->i_sb->s_bdev,sector,data);
  24}
  25
  26static inline int
  27__ext2_get_sector(struct inode *inode, sector_t offset, int create,
  28                   sector_t *result)
  29{
  30        struct buffer_head tmp;
  31        int rc;
  32
  33        memset(&tmp, 0, sizeof(struct buffer_head));
  34        rc = ext2_get_block(inode, offset/ (PAGE_SIZE/512), &tmp,
  35                            create);
  36        *result = tmp.b_blocknr;
  37
  38        /* did we get a sparse block (hole in the file)? */
  39        if (!tmp.b_blocknr && !rc) {
  40                BUG_ON(create);
  41                rc = -ENODATA;
  42        }
  43
  44        return rc;
  45}
  46
  47int
  48ext2_clear_xip_target(struct inode *inode, int block)
  49{
  50        sector_t sector = block * (PAGE_SIZE/512);
  51        unsigned long data;
  52        int rc;
  53
  54        rc = __inode_direct_access(inode, sector, &data);
  55        if (!rc)
  56                clear_page((void*)data);
  57        return rc;
  58}
  59
  60void ext2_xip_verify_sb(struct super_block *sb)
  61{
  62        struct ext2_sb_info *sbi = EXT2_SB(sb);
  63
  64        if ((sbi->s_mount_opt & EXT2_MOUNT_XIP) &&
  65            !sb->s_bdev->bd_disk->fops->direct_access) {
  66                sbi->s_mount_opt &= (~EXT2_MOUNT_XIP);
  67                ext2_warning(sb, __FUNCTION__,
  68                             "ignoring xip option - not supported by bdev");
  69        }
  70}
  71
  72struct page *
  73ext2_get_xip_page(struct address_space *mapping, sector_t offset,
  74                   int create)
  75{
  76        int rc;
  77        unsigned long data;
  78        sector_t sector;
  79
  80        /* first, retrieve the sector number */
  81        rc = __ext2_get_sector(mapping->host, offset, create, &sector);
  82        if (rc)
  83                goto error;
  84
  85        /* retrieve address of the target data */
  86        rc = __inode_direct_access
  87                (mapping->host, sector * (PAGE_SIZE/512), &data);
  88        if (!rc)
  89                return virt_to_page(data);
  90
  91 error:
  92        return ERR_PTR(rc);
  93}
  94