blob: f77bc4b4ab0263a834c2aac2feb13f57c7ccf480 [file] [log] [blame]
From Aaditya.Kumar@ap.sony.com Fri Nov 23 03:49:36 2012
From: Aaditya Kumar <aaditya.kumar@ap.sony.com>
Date: Fri, 23 Nov 2012 17:13:54 +0530
Subject: [PATCH v2 RESEND 12/15] AXFS: axfs_bdev.c
To: Greg KH <gregkh@linuxfoundation.org>
Cc: "ltsi-dev@lists.linuxfoundation.org" <ltsi-dev@lists.linuxfoundation.org>, tim.bird@am.sony.com, frank.rowand@am.sony.com, takuzo.ohara@ap.sony.com, amit.agarwal@ap.sony.com, kan.iibuchi@jp.sony.com, aaditya.kumar.30@gmail.com
Message-ID: <50AF617A.9000300@ap.sony.com>
From: Jared Hulbert <jaredeh@gmail.com>
Allows axfs to use block devices or has dummy functions if block
device support is compiled out of the kernel.
Signed-off-by: Jared Hulbert <jaredeh@gmail.com>
Signed-off-by: Thomas Rony Jose <thomas.jose@ap.sony.com>
Signed-off-by: Aaditya Kumar <aaditya.kumar@ap.sony.com>
---
fs/axfs/axfs_bdev.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 170 insertions(+)
create mode 100644 fs/axfs/axfs_bdev.c
--- /dev/null
+++ b/fs/axfs/axfs_bdev.c
@@ -0,0 +1,170 @@
+/*
+ * Advanced XIP File System for Linux - AXFS
+ * Readonly, compressed, and XIP filesystem for Linux systems big and small
+ *
+ * Copyright(c) 2008 Numonyx
+ * Copyright 2011 Sony Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * Authors:
+ * Jared Hulbert <jaredeh@gmail.com>
+ *
+ * Project url: http://axfs.sourceforge.net
+ *
+ * axfs_bdev.c -
+ * Allows axfs to use block devices or has dummy functions if block
+ * device support is compiled out of the kernel.
+ *
+ */
+#include "axfs.h"
+
+#include <linux/mount.h>
+#ifdef CONFIG_BLOCK
+#include <linux/buffer_head.h>
+#include <linux/namei.h>
+
+struct block_device *axfs_bdev(struct super_block *sb)
+{
+ return sb->s_bdev;
+}
+
+int axfs_has_bdev(struct super_block *sb)
+{
+ if (axfs_bdev(sb) == NULL)
+ return false;
+
+ return true;
+}
+
+struct dentry *axfs_get_sb_bdev(struct file_system_type *fs_type, int flags,
+ const char *dev_name, struct axfs_super *sbi)
+{
+ return mount_bdev(fs_type, flags, dev_name, sbi, axfs_fill_super);
+}
+
+void axfs_kill_block_super(struct super_block *sb)
+{
+ kill_block_super(sb);
+}
+
+void axfs_copy_block(struct super_block *sb, void *dst_addr, u64 fsoffset,
+ u64 len)
+{
+ struct axfs_super *sbi = AXFS_SB(sb);
+ u64 boffset = axfs_fsoffset_to_devoffset(sbi, fsoffset);
+ u64 blksize = sb->s_blocksize;
+ unsigned long dst;
+ unsigned long src;
+ sector_t block;
+ size_t bytes;
+ struct buffer_head *bh;
+ u64 copied = 0;
+
+ if (len == 0)
+ return;
+
+ while (copied < len) {
+ /* Explicit casting for ARM linker errors. */
+ block = (sector_t) boffset + (sector_t) copied;
+ block = div64_u64(block, (sector_t) blksize);
+ bh = sb_bread(sb, block);
+ src = (unsigned long)bh->b_data;
+ dst = (unsigned long)dst_addr;
+ if (copied == 0) {
+ /* Explicit casting for ARM linker errors. */
+ bytes = (size_t) blksize;
+ bytes -= (size_t) boffset % (size_t) blksize;
+ if (bytes > len)
+ bytes = len;
+ /* Explicit casting for ARM linker errors. */
+ src += (unsigned long)boffset % (unsigned long)blksize;
+ } else {
+ dst += copied;
+ if ((len - copied) < blksize)
+ bytes = len - copied;
+ else
+ bytes = blksize;
+ }
+ memcpy((void *)dst, (void *)src, bytes);
+ copied += bytes;
+ brelse(bh);
+ }
+}
+
+int axfs_is_dev_bdev(char *path)
+{
+ struct nameidata nd;
+ int ret = false;
+
+ if (!path)
+ return false;
+ nd.flags |= LOOKUP_FOLLOW;
+ if (kern_path_parent(path, &nd))
+ return false;
+
+ if (S_ISBLK(nd.path.dentry->d_inode->i_mode))
+ ret = true;
+
+ path_put(&nd.path);
+ return ret;
+}
+
+int axfs_verify_bdev_sizes(struct super_block *sb, int *err)
+{
+ u64 io_dev_size;
+ loff_t bdev_size;
+
+ *err = 0;
+
+ if (!axfs_has_bdev(sb))
+ return false;
+
+ io_dev_size = axfs_get_io_dev_size(sb);
+
+ if (!io_dev_size)
+ return false;
+
+ bdev_size = i_size_read(axfs_bdev(sb)->bd_inode);
+ if (io_dev_size <= bdev_size)
+ return true;
+
+ printk(KERN_ERR "axfs: image (%lluB) doesn't fit in blkdev(%lluB)\n",
+ io_dev_size, bdev_size);
+ *err = -EIO;
+ return true;
+}
+
+#else
+
+int axfs_get_sb_bdev(struct file_system_type *fs_type, int flags,
+ const char *dev_name, struct axfs_super *sbi,
+ struct vfsmount *mnt, int *err)
+{
+ return false;
+}
+
+void axfs_kill_block_super(struct super_block *sb)
+{
+}
+
+int axfs_copy_block(struct super_block *sb, void *dst_addr, u64 fsoffset,
+ u64 len)
+{
+ return -EINVAL;
+}
+
+int axfs_is_dev_bdev(char *path)
+{
+ return false;
+}
+
+int axfs_verify_bdev_sizes(struct super_block *sb, int *err)
+{
+ *err = 0;
+ return true;
+}
+
+#endif /* CONFIG_BLOCK */