Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.16-rc4 91 lines 2.1 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 tmp.b_size = 1 << inode->i_blkbits; 39 rc = ext2_get_block(inode, pgoff, &tmp, create); 40 *result = tmp.b_blocknr; 41 42 /* did we get a sparse block (hole in the file)? */ 43 if (!tmp.b_blocknr && !rc) { 44 BUG_ON(create); 45 rc = -ENODATA; 46 } 47 48 return rc; 49} 50 51int 52ext2_clear_xip_target(struct inode *inode, sector_t block) 53{ 54 void *kaddr; 55 unsigned long pfn; 56 int rc; 57 58 rc = __inode_direct_access(inode, block, &kaddr, &pfn); 59 if (!rc) 60 clear_page(kaddr); 61 return rc; 62} 63 64void ext2_xip_verify_sb(struct super_block *sb) 65{ 66 struct ext2_sb_info *sbi = EXT2_SB(sb); 67 68 if ((sbi->s_mount_opt & EXT2_MOUNT_XIP) && 69 !sb->s_bdev->bd_disk->fops->direct_access) { 70 sbi->s_mount_opt &= (~EXT2_MOUNT_XIP); 71 ext2_msg(sb, KERN_WARNING, 72 "warning: ignoring xip option - " 73 "not supported by bdev"); 74 } 75} 76 77int ext2_get_xip_mem(struct address_space *mapping, pgoff_t pgoff, int create, 78 void **kmem, unsigned long *pfn) 79{ 80 int rc; 81 sector_t block; 82 83 /* first, retrieve the sector number */ 84 rc = __ext2_get_block(mapping->host, pgoff, create, &block); 85 if (rc) 86 return rc; 87 88 /* retrieve address of the target data */ 89 rc = __inode_direct_access(mapping->host, block, kmem, pfn); 90 return rc; 91}