[PATCH 04/12] cmsfs: block mapping code

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Josef 'Jeff' Sipek <jeffpc@xxxxxxxxxxxxxx>
---
 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 <jeffpc@xxxxxxxxxxxxxx>
+ *
+ * Based on cmsfs from 2.4.12-ac6:
+ *
+ *  (C) 2001  Rick Troth <rtroth@xxxxxxx>
+ *  (C) 2001  BMC Software, Inc., Houston, Texas, USA
+ *
+ */
+
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/buffer_head.h>
+#include <linux/mpage.h>
+
+#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

--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux