Merge branch 'master' of git://www.denx.de/git/u-boot-cfi-flash
[platform/kernel/u-boot.git] / fs / ext4 / ext4fs.c
index 1287bf0..735b256 100644 (file)
  * GRUB  --  GRand Unified Bootloader
  * Copyright (C) 2003, 2004  Free Software Foundation, Inc.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * ext4write : Based on generic ext4 protocol.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
-#include <malloc.h>
 #include <ext_common.h>
 #include <ext4fs.h>
-#include <linux/stat.h>
-#include <linux/time.h>
-#include <asm/byteorder.h>
 #include "ext4_common.h"
 
 int ext4fs_symlinknest;
-block_dev_desc_t *ext4_dev_desc;
+struct ext_filesystem ext_fs;
 
 struct ext_filesystem *get_fs(void)
 {
-       if (ext4_dev_desc == NULL || ext4_dev_desc->priv == NULL)
-               printf("Invalid Input Arguments %s\n", __func__);
-
-       return ext4_dev_desc->priv;
-}
-
-int init_fs(block_dev_desc_t *dev_desc)
-{
-       struct ext_filesystem *fs;
-       if (dev_desc == NULL) {
-               printf("Invalid Input Arguments %s\n", __func__);
-               return -EINVAL;
-       }
-
-       fs = zalloc(sizeof(struct ext_filesystem));
-       if (fs == NULL) {
-               printf("malloc failed: %s\n", __func__);
-               return -ENOMEM;
-       }
-
-       fs->dev_desc = dev_desc;
-       dev_desc->priv = fs;
-
-       return 0;
-}
-
-void deinit_fs(block_dev_desc_t *dev_desc)
-{
-       if (dev_desc == NULL) {
-               printf("Invalid Input Arguments %s\n", __func__);
-               return;
-       }
-       free(dev_desc->priv);
-       dev_desc->priv = NULL;
+       return &ext_fs;
 }
 
 void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot)
@@ -95,16 +48,18 @@ void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot)
 int ext4fs_read_file(struct ext2fs_node *node, int pos,
                unsigned int len, char *buf)
 {
+       struct ext_filesystem *fs = get_fs();
        int i;
-       int blockcnt;
-       int log2blocksize = LOG2_EXT2_BLOCK_SIZE(node->data);
-       int blocksize = 1 << (log2blocksize + DISK_SECTOR_BITS);
+       lbaint_t blockcnt;
+       int log2blksz = fs->dev_desc->log2blksz;
+       int log2_fs_blocksize = LOG2_BLOCK_SIZE(node->data) - log2blksz;
+       int blocksize = (1 << (log2_fs_blocksize + log2blksz));
        unsigned int filesize = __le32_to_cpu(node->inode.size);
-       int previous_block_number = -1;
-       int delayed_start = 0;
-       int delayed_extent = 0;
-       int delayed_skipfirst = 0;
-       int delayed_next = 0;
+       lbaint_t previous_block_number = -1;
+       lbaint_t delayed_start = 0;
+       lbaint_t delayed_extent = 0;
+       lbaint_t delayed_skipfirst = 0;
+       lbaint_t delayed_next = 0;
        char *delayed_buf = NULL;
        short status;
 
@@ -115,7 +70,7 @@ int ext4fs_read_file(struct ext2fs_node *node, int pos,
        blockcnt = ((len + pos) + blocksize - 1) / blocksize;
 
        for (i = pos / blocksize; i < blockcnt; i++) {
-               int blknr;
+               lbaint_t blknr;
                int blockoff = pos % blocksize;
                int blockend = blocksize;
                int skipfirst = 0;
@@ -123,7 +78,7 @@ int ext4fs_read_file(struct ext2fs_node *node, int pos,
                if (blknr < 0)
                        return -1;
 
-               blknr = blknr << log2blocksize;
+               blknr = blknr << log2_fs_blocksize;
 
                /* Last block.  */
                if (i == blockcnt - 1) {
@@ -145,7 +100,7 @@ int ext4fs_read_file(struct ext2fs_node *node, int pos,
                        if (previous_block_number != -1) {
                                if (delayed_next == blknr) {
                                        delayed_extent += blockend;
-                                       delayed_next += blockend >> SECTOR_BITS;
+                                       delayed_next += blockend >> log2blksz;
                                } else {        /* spill */
                                        status = ext4fs_devread(delayed_start,
                                                        delayed_skipfirst,
@@ -159,7 +114,7 @@ int ext4fs_read_file(struct ext2fs_node *node, int pos,
                                        delayed_skipfirst = skipfirst;
                                        delayed_buf = buf;
                                        delayed_next = blknr +
-                                               (blockend >> SECTOR_BITS);
+                                               (blockend >> log2blksz);
                                }
                        } else {
                                previous_block_number = blknr;
@@ -168,7 +123,7 @@ int ext4fs_read_file(struct ext2fs_node *node, int pos,
                                delayed_skipfirst = skipfirst;
                                delayed_buf = buf;
                                delayed_next = blknr +
-                                       (blockend >> SECTOR_BITS);
+                                       (blockend >> log2blksz);
                        }
                } else {
                        if (previous_block_number != -1) {
@@ -226,3 +181,40 @@ int ext4fs_read(char *buf, unsigned len)
 
        return ext4fs_read_file(ext4fs_file, 0, len, buf);
 }
+
+int ext4fs_probe(block_dev_desc_t *fs_dev_desc,
+                disk_partition_t *fs_partition)
+{
+       ext4fs_set_blk_dev(fs_dev_desc, fs_partition);
+
+       if (!ext4fs_mount(fs_partition->size)) {
+               ext4fs_close();
+               return -1;
+       }
+
+       return 0;
+}
+
+int ext4_read_file(const char *filename, void *buf, int offset, int len)
+{
+       int file_len;
+       int len_read;
+
+       if (offset != 0) {
+               printf("** Cannot support non-zero offset **\n");
+               return -1;
+       }
+
+       file_len = ext4fs_open(filename);
+       if (file_len < 0) {
+               printf("** File not found %s **\n", filename);
+               return -1;
+       }
+
+       if (len == 0)
+               len = file_len;
+
+       len_read = ext4fs_read(buf, len);
+
+       return len_read;
+}