From mboxrd@z Thu Jan 1 00:00:00 1970 From: Josef 'Jeff' Sipek Subject: [PATCH 04/12] cmsfs: block mapping code Date: Sun, 21 Sep 2008 21:29:20 -0400 Message-ID: <1222046968-3364-5-git-send-email-jeffpc@josefsipek.net> References: <1222046968-3364-1-git-send-email-jeffpc@josefsipek.net> Cc: hch@infradead.org, Josef 'Jeff' Sipek To: linux-fsdevel@vger.kernel.org Return-path: Received: from [148.100.96.56] ([148.100.96.56]:57677 "EHLO ldave2.osdl.marist.edu" rhost-flags-FAIL-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1752976AbYIVBmg (ORCPT ); Sun, 21 Sep 2008 21:42:36 -0400 In-Reply-To: <1222046968-3364-1-git-send-email-jeffpc@josefsipek.net> Sender: linux-fsdevel-owner@vger.kernel.org List-ID: Signed-off-by: Josef 'Jeff' Sipek --- fs/cmsfs/bmap.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 104 insertions(+), 0 deletions(-) create mode 100644 fs/cmsfs/bmap.c diff --git a/fs/cmsfs/bmap.c b/fs/cmsfs/bmap.c new file mode 100644 index 0000000..ce9eccf --- /dev/null +++ b/fs/cmsfs/bmap.c @@ -0,0 +1,104 @@ +/* + * CMSFS + * + * (C) 2008 Josef 'Jeff' Sipek + * + * Based on cmsfs from 2.4.12-ac6: + * + * (C) 2001 Rick Troth + * (C) 2001 BMC Software, Inc., Houston, Texas, USA + * + */ + +#include +#include +#include +#include +#include + +#include "cmsfs.h" + +/** + * cmsfs_get_blocks - map a inode offset to a disk block + * @inode: inode to map + * @iblock: inode offset to map (in fs blocks) + * @bh_result: resulting buffer_head + * @create: ? + */ +static int cmsfs_get_blocks(struct inode *inode, sector_t iblock, + struct buffer_head *bh_result, int create) +{ + struct cmsfs_inode_info *cinode = CMSFS_I(inode); + struct super_block *sb = inode->i_sb; + struct buffer_head *bh; + + BUG_ON(create); + + /* indirection? */ + if (cinode->level != 0) { + int ptrs_per_blk; + int i, lvl; + void *bp; + u32 b1, b2; + + b2 = ~0; /* to avoid potentially uninit var warning */ + + /* pointers per block */ + if (cinode->psize > 0) + ptrs_per_blk = CMSFS_SB(sb)->blksz / cinode->psize; + else + ptrs_per_blk = CMSFS_SB(sb)->blksz / 4; + + /* read first block for indirection */ + b1 = iblock; + for (i = 0; i < cinode->level; i++) + b1 = b1 / ptrs_per_blk; + bh = sb_bread(sb, cinode->origin - 1 + b1); + if (!bh) + goto fail; + + for (lvl = 1; lvl <= cinode->level; lvl++) { + /* read next block for indirection */ + b1 = iblock; + for (i = lvl; i < cinode->level; i++) + b1 = b1 / ptrs_per_blk; + b1 = b1 % ptrs_per_blk; + bp = bh->b_data; + bp += b1 * cinode->psize; + b2 = be32_to_cpu(*(u32*)bp); + + brelse(bh); + + /* read next block for indirection */ + bh = sb_bread(sb, b2 - 1); + if (!bh) + goto fail; + } + + clear_buffer_new(bh_result); + map_bh(bh_result, inode->i_sb, b2-1); + } else { + clear_buffer_new(bh_result); + map_bh(bh_result, inode->i_sb, + cinode->origin - 1 + iblock); + } + + return 0; + +fail: + return -EIO; +} + +/** + * cmsfs_readpage - read a page for an inode + * @unused: (unused) + * @page: page to read + */ +static int cmsfs_readpage(struct file *unused, struct page *page) +{ + return mpage_readpage(page, cmsfs_get_blocks); +} + +struct address_space_operations cmsfs_aops = { + .readpage = cmsfs_readpage, +}; -- 1.5.6.3