fs: Create a common fs_devread for ext4/reiserfs/zfs
authorMarek BehĂșn <marek.behun@nic.cz>
Sun, 3 Sep 2017 15:00:24 +0000 (17:00 +0200)
committerTom Rini <trini@konsulko.com>
Tue, 3 Oct 2017 01:51:50 +0000 (21:51 -0400)
The ext4, reiserfs and zfs filesystems all have their own implementation
of the same function, *_devread. Generalize this function into fs_devread
and put the code into fs/fs_internal.c.

Signed-off-by: Marek Behun <marek.behun@nic.cz>
[trini: Move fs/fs_internal.o hunk to the end of fs/Makefile as all
cases need it]
Signed-off-by: Tom Rini <trini@konsulko.com>
fs/Makefile
fs/ext4/dev.c
fs/fs_internal.c [new file with mode: 0644]
fs/reiserfs/dev.c
fs/zfs/dev.c
include/fs_internal.h [new file with mode: 0644]

index 5770f41c0b01a1a9b87220b09a842bdec25f24b9..b53c9d7cca71809bf70c5bc1780e1512cbcb18ca 100644 (file)
@@ -23,3 +23,4 @@ obj-$(CONFIG_CMD_UBIFS) += ubifs/
 obj-$(CONFIG_YAFFS2) += yaffs2/
 obj-$(CONFIG_CMD_ZFS) += zfs/
 endif
+obj-y += fs_internal.o
index ae2ba6a9015c8bc3bd15cef9ca59a82680ddce33..f04fa08f64e4d61fc5fd49a36c5223a3189be453 100644 (file)
@@ -26,7 +26,7 @@
 #include <common.h>
 #include <blk.h>
 #include <config.h>
-#include <memalign.h>
+#include <fs_internal.h>
 #include <ext4fs.h>
 #include <ext_common.h>
 #include "ext4_common.h"
@@ -47,85 +47,11 @@ void ext4fs_set_blk_dev(struct blk_desc *rbdd, disk_partition_t *info)
                get_fs()->dev_desc->log2blksz;
 }
 
-int ext4fs_devread(lbaint_t sector, int byte_offset, int byte_len, char *buf)
+int ext4fs_devread(lbaint_t sector, int byte_offset, int byte_len,
+                  char *buffer)
 {
-       unsigned block_len;
-       int log2blksz = ext4fs_blk_desc->log2blksz;
-       ALLOC_CACHE_ALIGN_BUFFER(char, sec_buf, (ext4fs_blk_desc ?
-                                                ext4fs_blk_desc->blksz :
-                                                0));
-       if (ext4fs_blk_desc == NULL) {
-               printf("** Invalid Block Device Descriptor (NULL)\n");
-               return 0;
-       }
-
-       /* Check partition boundaries */
-       if ((sector + ((byte_offset + byte_len - 1) >> log2blksz))
-           >= part_info->size) {
-               printf("%s read outside partition " LBAFU "\n", __func__,
-                      sector);
-               return 0;
-       }
-
-       /* Get the read to the beginning of a partition */
-       sector += byte_offset >> log2blksz;
-       byte_offset &= ext4fs_blk_desc->blksz - 1;
-
-       debug(" <" LBAFU ", %d, %d>\n", sector, byte_offset, byte_len);
-
-       if (byte_offset != 0) {
-               int readlen;
-               /* read first part which isn't aligned with start of sector */
-               if (blk_dread(ext4fs_blk_desc, part_info->start + sector, 1,
-                             (void *)sec_buf) != 1) {
-                       printf(" ** ext2fs_devread() read error **\n");
-                       return 0;
-               }
-               readlen = min((int)ext4fs_blk_desc->blksz - byte_offset,
-                             byte_len);
-               memcpy(buf, sec_buf + byte_offset, readlen);
-               buf += readlen;
-               byte_len -= readlen;
-               sector++;
-       }
-
-       if (byte_len == 0)
-               return 1;
-
-       /* read sector aligned part */
-       block_len = byte_len & ~(ext4fs_blk_desc->blksz - 1);
-
-       if (block_len == 0) {
-               ALLOC_CACHE_ALIGN_BUFFER(u8, p, ext4fs_blk_desc->blksz);
-
-               block_len = ext4fs_blk_desc->blksz;
-               blk_dread(ext4fs_blk_desc, part_info->start + sector, 1,
-                         (void *)p);
-               memcpy(buf, p, byte_len);
-               return 1;
-       }
-
-       if (blk_dread(ext4fs_blk_desc, part_info->start + sector,
-                     block_len >> log2blksz, (void *)buf) !=
-                       block_len >> log2blksz) {
-               printf(" ** %s read error - block\n", __func__);
-               return 0;
-       }
-       block_len = byte_len & ~(ext4fs_blk_desc->blksz - 1);
-       buf += block_len;
-       byte_len -= block_len;
-       sector += block_len / ext4fs_blk_desc->blksz;
-
-       if (byte_len != 0) {
-               /* read rest of data which are not in whole sector */
-               if (blk_dread(ext4fs_blk_desc, part_info->start + sector, 1,
-                             (void *)sec_buf) != 1) {
-                       printf("* %s read error - last part\n", __func__);
-                       return 0;
-               }
-               memcpy(buf, sec_buf, byte_len);
-       }
-       return 1;
+       return fs_devread(get_fs()->dev_desc, part_info, sector, byte_offset,
+                         byte_len, buffer);
 }
 
 int ext4_read_superblock(char *buffer)
diff --git a/fs/fs_internal.c b/fs/fs_internal.c
new file mode 100644 (file)
index 0000000..58b4410
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * 2017 by Marek Behun <marek.behun@nic.cz>
+ *
+ * Derived from code in ext4/dev.c, which was based on reiserfs/dev.c
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#include <common.h>
+#include <compiler.h>
+#include <part.h>
+#include <memalign.h>
+
+int fs_devread(struct blk_desc *blk, disk_partition_t *partition,
+              lbaint_t sector, int byte_offset, int byte_len, char *buf)
+{
+       unsigned block_len;
+       int log2blksz = blk->log2blksz;
+       ALLOC_CACHE_ALIGN_BUFFER(char, sec_buf, (blk ? blk->blksz : 0));
+       if (blk == NULL) {
+               printf("** Invalid Block Device Descriptor (NULL)\n");
+               return 0;
+       }
+
+       /* Check partition boundaries */
+       if ((sector + ((byte_offset + byte_len - 1) >> log2blksz))
+           >= partition->size) {
+               printf("%s read outside partition " LBAFU "\n", __func__,
+                      sector);
+               return 0;
+       }
+
+       /* Get the read to the beginning of a partition */
+       sector += byte_offset >> log2blksz;
+       byte_offset &= blk->blksz - 1;
+
+       debug(" <" LBAFU ", %d, %d>\n", sector, byte_offset, byte_len);
+
+       if (byte_offset != 0) {
+               int readlen;
+               /* read first part which isn't aligned with start of sector */
+               if (blk_dread(blk, partition->start + sector, 1,
+                             (void *)sec_buf) != 1) {
+                       printf(" ** %s read error **\n", __func__);
+                       return 0;
+               }
+               readlen = min((int)blk->blksz - byte_offset,
+                             byte_len);
+               memcpy(buf, sec_buf + byte_offset, readlen);
+               buf += readlen;
+               byte_len -= readlen;
+               sector++;
+       }
+
+       if (byte_len == 0)
+               return 1;
+
+       /* read sector aligned part */
+       block_len = byte_len & ~(blk->blksz - 1);
+
+       if (block_len == 0) {
+               ALLOC_CACHE_ALIGN_BUFFER(u8, p, blk->blksz);
+
+               block_len = blk->blksz;
+               blk_dread(blk, partition->start + sector, 1,
+                         (void *)p);
+               memcpy(buf, p, byte_len);
+               return 1;
+       }
+
+       if (blk_dread(blk, partition->start + sector,
+                     block_len >> log2blksz, (void *)buf) !=
+                       block_len >> log2blksz) {
+               printf(" ** %s read error - block\n", __func__);
+               return 0;
+       }
+       block_len = byte_len & ~(blk->blksz - 1);
+       buf += block_len;
+       byte_len -= block_len;
+       sector += block_len / blk->blksz;
+
+       if (byte_len != 0) {
+               /* read rest of data which are not in whole sector */
+               if (blk_dread(blk, partition->start + sector, 1,
+                             (void *)sec_buf) != 1) {
+                       printf("* %s read error - last part\n", __func__);
+                       return 0;
+               }
+               memcpy(buf, sec_buf, byte_len);
+       }
+       return 1;
+}
index 5a1ab0a3648a12099283baf9a9e6c92b1416c114..7b786e4ed359f84bb55cbf5781a252e4d9c605eb 100644 (file)
@@ -9,7 +9,7 @@
 #include <common.h>
 #include <config.h>
 #include <reiserfs.h>
-
+#include <fs_internal.h>
 #include "reiserfs_private.h"
 
 static struct blk_desc *reiserfs_blk_desc;
@@ -22,78 +22,8 @@ void reiserfs_set_blk_dev(struct blk_desc *rbdd, disk_partition_t *info)
        part_info = info;
 }
 
-
-int reiserfs_devread (int sector, int byte_offset, int byte_len, char *buf)
+int reiserfs_devread(int sector, int byte_offset, int byte_len, char *buf)
 {
-       char sec_buf[SECTOR_SIZE];
-       unsigned block_len;
-/*
-       unsigned len = byte_len;
-       u8 *start = buf;
-*/
-       /*
-       *  Check partition boundaries
-       */
-       if (sector < 0
-           || ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS))
-           >= part_info->size)) {
-/*             errnum = ERR_OUTSIDE_PART; */
-               printf (" ** reiserfs_devread() read outside partition\n");
-               return 0;
-       }
-
-       /*
-        *  Get the read to the beginning of a partition.
-        */
-       sector += byte_offset >> SECTOR_BITS;
-       byte_offset &= SECTOR_SIZE - 1;
-
-#if defined(DEBUG)
-       printf (" <%d, %d, %d> ", sector, byte_offset, byte_len);
-#endif
-
-
-       if (reiserfs_blk_desc == NULL)
-               return 0;
-
-
-       if (byte_offset != 0) {
-               /* read first part which isn't aligned with start of sector */
-               if (reiserfs_blk_desc->block_read(reiserfs_blk_desc,
-                                                 part_info->start + sector,
-                                                 1, (void *)sec_buf) != 1) {
-                       printf (" ** reiserfs_devread() read error\n");
-                       return 0;
-               }
-               memcpy(buf, sec_buf+byte_offset, min(SECTOR_SIZE-byte_offset, byte_len));
-               buf+=min(SECTOR_SIZE-byte_offset, byte_len);
-               byte_len-=min(SECTOR_SIZE-byte_offset, byte_len);
-               sector++;
-       }
-
-       /* read sector aligned part */
-       block_len = byte_len & ~(SECTOR_SIZE-1);
-       if (reiserfs_blk_desc->block_read(reiserfs_blk_desc,
-                                         part_info->start + sector,
-                                         block_len / SECTOR_SIZE, (void *)buf)
-                       != block_len/SECTOR_SIZE) {
-               printf (" ** reiserfs_devread() read error - block\n");
-               return 0;
-       }
-       buf+=block_len;
-       byte_len-=block_len;
-       sector+= block_len/SECTOR_SIZE;
-
-       if ( byte_len != 0 ) {
-               /* read rest of data which are not in whole sector */
-               if (reiserfs_blk_desc->block_read(reiserfs_blk_desc,
-                                                 part_info->start + sector,
-                                                 1, (void *)sec_buf) != 1) {
-                       printf (" ** reiserfs_devread() read error - last part\n");
-                       return 0;
-               }
-               memcpy(buf, sec_buf, byte_len);
-       }
-
-       return 1;
+       return fs_devread(reiserfs_blk_desc, part_info, sector, byte_offset,
+                         byte_len, buf);
 }
index 2f409e66cddf0f6f5748144a962c1fd335c9f154..7dda42b48baf555adab71a8fbd4751f77766a8cf 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <common.h>
 #include <config.h>
+#include <fs_internal.h>
 #include <zfs_common.h>
 
 static struct blk_desc *zfs_blk_desc;
@@ -25,87 +26,6 @@ void zfs_set_blk_dev(struct blk_desc *rbdd, disk_partition_t *info)
 /* err */
 int zfs_devread(int sector, int byte_offset, int byte_len, char *buf)
 {
-       short sec_buffer[SECTOR_SIZE/sizeof(short)];
-       char *sec_buf = (char *)sec_buffer;
-       unsigned block_len;
-
-       /*
-        *      Check partition boundaries
-        */
-       if ((sector < 0) ||
-               ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) >=
-                part_info->size)) {
-               /*              errnum = ERR_OUTSIDE_PART; */
-               printf(" ** zfs_devread() read outside partition sector %d\n", sector);
-               return 1;
-       }
-
-       /*
-        *      Get the read to the beginning of a partition.
-        */
-       sector += byte_offset >> SECTOR_BITS;
-       byte_offset &= SECTOR_SIZE - 1;
-
-       debug(" <%d, %d, %d>\n", sector, byte_offset, byte_len);
-
-       if (zfs_blk_desc == NULL) {
-               printf("** Invalid Block Device Descriptor (NULL)\n");
-               return 1;
-       }
-
-       if (byte_offset != 0) {
-               /* read first part which isn't aligned with start of sector */
-               if (zfs_blk_desc->block_read(zfs_blk_desc,
-                                            part_info->start + sector, 1,
-                                            (void *)sec_buf) != 1) {
-                       printf(" ** zfs_devread() read error **\n");
-                       return 1;
-               }
-               memcpy(buf, sec_buf + byte_offset,
-                          min(SECTOR_SIZE - byte_offset, byte_len));
-               buf += min(SECTOR_SIZE - byte_offset, byte_len);
-               byte_len -= min(SECTOR_SIZE - byte_offset, byte_len);
-               sector++;
-       }
-
-       if (byte_len == 0)
-               return 0;
-
-       /*      read sector aligned part */
-       block_len = byte_len & ~(SECTOR_SIZE - 1);
-
-       if (block_len == 0) {
-               u8 p[SECTOR_SIZE];
-
-               block_len = SECTOR_SIZE;
-               zfs_blk_desc->block_read(zfs_blk_desc,
-                                        part_info->start + sector,
-                                        1, (void *)p);
-               memcpy(buf, p, byte_len);
-               return 0;
-       }
-
-       if (zfs_blk_desc->block_read(zfs_blk_desc, part_info->start + sector,
-                                    block_len / SECTOR_SIZE,
-                                    (void *)buf) != block_len / SECTOR_SIZE) {
-               printf(" ** zfs_devread() read error - block\n");
-               return 1;
-       }
-
-       block_len = byte_len & ~(SECTOR_SIZE - 1);
-       buf += block_len;
-       byte_len -= block_len;
-       sector += block_len / SECTOR_SIZE;
-
-       if (byte_len != 0) {
-               /* read rest of data which are not in whole sector */
-               if (zfs_blk_desc->block_read(zfs_blk_desc,
-                                            part_info->start + sector,
-                                            1, (void *)sec_buf) != 1) {
-                       printf(" ** zfs_devread() read error - last part\n");
-                       return 1;
-               }
-               memcpy(buf, sec_buf, byte_len);
-       }
-       return 0;
+       return fs_devread(zfs_blk_desc, part_info, sector, byte_offset,
+                         byte_len, buf);
 }
diff --git a/include/fs_internal.h b/include/fs_internal.h
new file mode 100644 (file)
index 0000000..9d6dddd
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * 2017 by Marek Behun <marek.behun@nic.cz>
+ *
+ * Derived from code in ext4/dev.c, which was based on reiserfs/dev.c
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#ifndef __U_BOOT_FS_INTERNAL_H__
+#define __U_BOOT_FS_INTERNAL_H__
+
+#include <part.h>
+
+int fs_devread(struct blk_desc *, disk_partition_t *, lbaint_t, int, int,
+              char *);
+
+#endif /* __U_BOOT_FS_INTERNAL_H__ */