Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v3.5-rc1 90 lines 2.0 kB view raw
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/blkdev.h> 13#include "ext2.h" 14#include "xip.h" 15 16static inline int 17__inode_direct_access(struct inode *inode, sector_t block, 18 void **kaddr, unsigned long *pfn) 19{ 20 struct block_device *bdev = inode->i_sb->s_bdev; 21 const struct block_device_operations *ops = bdev->bd_disk->fops; 22 sector_t sector; 23 24 sector = block * (PAGE_SIZE / 512); /* ext2 block to bdev sector */ 25 26 BUG_ON(!ops->direct_access); 27 return ops->direct_access(bdev, sector, kaddr, pfn); 28} 29 30static inline int 31__ext2_get_block(struct inode *inode, pgoff_t pgoff, int create, 32 sector_t *result) 33{ 34 struct buffer_head tmp; 35 int rc; 36 37 memset(&tmp, 0, sizeof(struct buffer_head)); 38 rc = ext2_get_block(inode, pgoff, &tmp, create); 39 *result = tmp.b_blocknr; 40 41 /* did we get a sparse block (hole in the file)? */ 42 if (!tmp.b_blocknr && !rc) { 43 BUG_ON(create); 44 rc = -ENODATA; 45 } 46 47 return rc; 48} 49 50int 51ext2_clear_xip_target(struct inode *inode, sector_t block) 52{ 53 void *kaddr; 54 unsigned long pfn; 55 int rc; 56 57 rc = __inode_direct_access(inode, block, &kaddr, &pfn); 58 if (!rc) 59 clear_page(kaddr); 60 return rc; 61} 62 63void ext2_xip_verify_sb(struct super_block *sb) 64{ 65 struct ext2_sb_info *sbi = EXT2_SB(sb); 66 67 if ((sbi->s_mount_opt & EXT2_MOUNT_XIP) && 68 !sb->s_bdev->bd_disk->fops->direct_access) { 69 sbi->s_mount_opt &= (~EXT2_MOUNT_XIP); 70 ext2_msg(sb, KERN_WARNING, 71 "warning: ignoring xip option - " 72 "not supported by bdev"); 73 } 74} 75 76int ext2_get_xip_mem(struct address_space *mapping, pgoff_t pgoff, int create, 77 void **kmem, unsigned long *pfn) 78{ 79 int rc; 80 sector_t block; 81 82 /* first, retrieve the sector number */ 83 rc = __ext2_get_block(mapping->host, pgoff, create, &block); 84 if (rc) 85 return rc; 86 87 /* retrieve address of the target data */ 88 rc = __inode_direct_access(mapping->host, block, kmem, pfn); 89 return rc; 90}