Skip to contentSkip to conversation

AXFS: axfs_bdev.c

PATCH In review Jared Hulbert 3 participants 4 messages Aug 21, 2008 – Aug 24, 2008 Memory technology devices (MTD)

lore
Share & tools
lore
#0 lore raw

PATCH 7/10 AXFS: axfs_bdev.c

All the block device code goes here.

---

fs/axfs/axfs_bdev.c new file +158 -0
new file mode 100644
index 0000000..4c6f83c
@@ -0,0 +1,158 @@
+/*
+ * Advanced XIP File System for Linux - AXFS
+ *   Readonly, compressed, and XIP filesystem for Linux systems big and small
+ *
+ * Copyright(c) 2008 Numonyx
+ *
+ * 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 <[email protected]>
+ *
+ * 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 <linux/axfs.h>
+#include <linux/mount.h>
+#ifdef CONFIG_BLOCK
+#include <linux/buffer_head.h>
+#include <linux/namei.h>
+
+int axfs_fill_super(struct super_block *sb, void *data, int silent);
+
+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)
+{
+	*err = get_sb_bdev(fs_type, flags, dev_name, sbi, axfs_fill_super, mnt);
+
+	if (*err)
+		return FALSE;
+	return TRUE;
+}
+
+void axfs_kill_block_super(struct super_block *sb)
+{
+	kill_block_super(sb);
+}
+
+/******************************************************************************
+ *
+ * axfs_copy_block_data
+ *
+ * Description: Helper function to read data from block device
+ *
+ * Parameters:
+ *    (IN) sb - pointer to super block structure.
+ *
+ *    (IN) dst_addr - pointer to buffer into which data is to be read.
+ *
+ *    (IN) boffset - offset within block device
+ *
+ *    (IN) len - length of data to be read
+ *
+ * Returns:
+ *     0 or error number
+ *
+ *****************************************************************************/
+int 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_2_DEVOFFSET(sbi, fsoffset);
+	u64 blocks;
+	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 0;
+
+	blocks = len / blksize;
+	if ((len % blksize) > 0)
+		blocks += 1;
+
+	while (copied < len) {
+		/* Explicit casting for ARM linker errors. */
+		block = (sector_t) boffset + (sector_t) copied;
+		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);
+	}
+	return 0;
+}
+
+int axfs_is_dev_bdev(char *path)
+{
+	struct nameidata nd;
+	int ret = FALSE;
+
+	if (!path)
+		return FALSE;
+
+	if (path_lookup(path, LOOKUP_FOLLOW, &nd))
+		return FALSE;
+
+	if (S_ISBLK(nd.path.dentry->d_inode->i_mode))
+		ret = TRUE;
+
+	path_put(&nd.path);
+	return ret;
+}
+
+#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;
+}
+
+#endif /* CONFIG_BLOCK */
#1 lore raw
Quoted 11 lines · Jared Hulbert
fs/axfs/axfs_bdev.c new file +11 -0
+/******************************************************************************
+ *
+ * axfs_copy_block_data
+ *
+ * Description: Helper function to read data from block device
+ *
+ * Parameters:
+ *    (IN) sb - pointer to super block structure.
+ *
+ *    (IN) dst_addr - pointer to buffer into which data is to be read.
+ *

fs/axfs/axfs_bdev.c line 66

Quoted 10 lines
fs/axfs/axfs_bdev.c new file +10 -0
+ *    (IN) boffset - offset within block device
+ *
+ *    (IN) len - length of data to be read
+ *
+ * Returns:
+ *     0 or error number
+ *
+ *****************************************************************************/
+int axfs_copy_block(struct super_block *sb, void *dst_addr, u64 fsoffset,
+		    u64 len)

mismatch between documentation and implementation WRT the function name ;)

Quoted 11 lines
fs/axfs/axfs_bdev.c new file +11 -0
+{
+	struct axfs_super *sbi = AXFS_SB(sb);
+	u64 boffset = AXFS_FSOFFSET_2_DEVOFFSET(sbi, fsoffset);
+	u64 blocks;
+	u64 blksize = sb->s_blocksize;
+	unsigned long dst;
+	unsigned long src;
+	sector_t block;
+	size_t bytes;
+	struct buffer_head *bh;
+	u64 copied = 0;

fs/axfs/axfs_bdev.c line 87

Quoted 10 lines
fs/axfs/axfs_bdev.c new file +10 -0
+
+	if (len == 0)
+		return 0;
+
+	blocks = len / blksize;
+	if ((len % blksize) > 0)
+		blocks += 1;
+
+	while (copied < len) {
+		/* Explicit casting for ARM linker errors. */

did it try to emit some external div()? Is this still needed?

#2 lore raw
Quoted 1 line

mismatch between documentation and implementation WRT the function name ;)

oops.

Quoted 15 lines
Quoted 15 lines
fs/axfs/axfs_bdev.c new file +15 -0
+{
+      struct axfs_super *sbi = AXFS_SB(sb);
+      u64 boffset = AXFS_FSOFFSET_2_DEVOFFSET(sbi, fsoffset);
+      u64 blocks;
+      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 0;
+
Quoted 8 lines

fs/axfs/axfs_bdev.c line 87

Quoted 6 lines
fs/axfs/axfs_bdev.c new file +6 -0
+      blocks = len / blksize;
+      if ((len % blksize) > 0)
+              blocks += 1;
+
+      while (copied < len) {
+              /* Explicit casting for ARM linker errors. */

did it try to emit some external div()? Is this still needed?

exactly. I haven't heard otherwise, it was a Freescale ARM11 build that had the issue... I don't have the set up.

#3 lore raw
In reply to Jared Hulbert
Quoted 84 lines · Jared Hulbert

All the block device code goes here.

---

fs/axfs/axfs_bdev.c new file +74 -0
new file mode 100644
index 0000000..4c6f83c
@@ -0,0 +1,158 @@
+/*
+ * Advanced XIP File System for Linux - AXFS
+ *   Readonly, compressed, and XIP filesystem for Linux systems big and small
+ *
+ * Copyright(c) 2008 Numonyx
+ *
+ * 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 <[email protected]>
+ *
+ * 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 <linux/axfs.h>
+#include <linux/mount.h>
+#ifdef CONFIG_BLOCK
+#include <linux/buffer_head.h>
+#include <linux/namei.h>
+
+int axfs_fill_super(struct super_block *sb, void *data, int silent);
+
+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)
+{
+       *err = get_sb_bdev(fs_type, flags, dev_name, sbi, axfs_fill_super, mnt);
+
+       if (*err)
+               return FALSE;
+       return TRUE;
+}
+
+void axfs_kill_block_super(struct super_block *sb)
+{
+       kill_block_super(sb);
+}
+
+/******************************************************************************
+ *
+ * axfs_copy_block_data
+ *
+ * Description: Helper function to read data from block device
+ *
+ * Parameters:
+ *    (IN) sb - pointer to super block structure.
+ *
+ *    (IN) dst_addr - pointer to buffer into which data is to be read.
+ *
+ *    (IN) boffset - offset within block device
+ *
+ *    (IN) len - length of data to be read
+ *
+ * Returns:
+ *     0 or error number
+ *
+ *****************************************************************************/
+int 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_2_DEVOFFSET(sbi, fsoffset);
+       u64 blocks;
+       u64 blksize = sb->s_blocksize;
+       unsigned long dst;
+       unsigned long src;
+       sector_t block;

fs/axfs/axfs_bdev.c line 84

Quoted 10 lines
fs/axfs/axfs_bdev.c new file +10 -0
+       size_t bytes;
+       struct buffer_head *bh;
+       u64 copied = 0;
+
+       if (len == 0)
+               return 0;
+
+       blocks = len / blksize;
+       if ((len % blksize) > 0)
+               blocks += 1;

blocks ??
You have to drop blocks variable since anyone don't use it.

Quoted 80 lines
fs/axfs/axfs_bdev.c new file +73 -1
+       while (copied < len) {
+               /* Explicit casting for ARM linker errors. */
+               block = (sector_t) boffset + (sector_t) copied;
+               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);
+       }
+       return 0;
+}
+
+int axfs_is_dev_bdev(char *path)
+{
+       struct nameidata nd;
+       int ret = FALSE;
+
+       if (!path)
+               return FALSE;
+
+       if (path_lookup(path, LOOKUP_FOLLOW, &nd))
+               return FALSE;
+
+       if (S_ISBLK(nd.path.dentry->d_inode->i_mode))
+               ret = TRUE;
+
+       path_put(&nd.path);
+       return ret;
+}
+
+#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;
+}
+
+#endif /* CONFIG_BLOCK */
 
 
--

To unsubscribe from this list: send the line "unsubscribe linux-embedded" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

Signature · 2 lines
Kinds regards,
MinChan Kim