| 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 */ |