projects
/
oweals
/
u-boot.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
fs: ext4: fix crash on ext4ls
[oweals/u-boot.git]
/
fs
/
ext4
/
ext4fs.c
diff --git
a/fs/ext4/ext4fs.c
b/fs/ext4/ext4fs.c
index cbdc22026deb63a24968cbd3c0078407940bc5a2..2a28031d14ca1f23a43dc72ac53e8f1e2b731cde 100644
(file)
--- a/
fs/ext4/ext4fs.c
+++ b/
fs/ext4/ext4fs.c
@@
-1,3
+1,4
@@
+// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2011 - 2012 Samsung Electronics
* EXT4 filesystem implementation in Uboot by
/*
* (C) Copyright 2011 - 2012 Samsung Electronics
* EXT4 filesystem implementation in Uboot by
@@
-17,14
+18,13
@@
* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
*
* ext4write : Based on generic ext4 protocol.
* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
*
* ext4write : Based on generic ext4 protocol.
- *
- * SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <ext_common.h>
#include <ext4fs.h>
#include "ext4_common.h"
*/
#include <common.h>
#include <ext_common.h>
#include <ext4fs.h>
#include "ext4_common.h"
+#include <div64.h>
int ext4fs_symlinknest;
struct ext_filesystem ext_fs;
int ext4fs_symlinknest;
struct ext_filesystem ext_fs;
@@
-45,8
+45,8
@@
void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot)
* Optimized read file API : collects and defers contiguous sector
* reads into one potentially more efficient larger sequential read action
*/
* Optimized read file API : collects and defers contiguous sector
* reads into one potentially more efficient larger sequential read action
*/
-int ext4fs_read_file(struct ext2fs_node *node,
in
t pos,
-
unsigned int len, char *buf
)
+int ext4fs_read_file(struct ext2fs_node *node,
loff_
t pos,
+
loff_t len, char *buf, loff_t *actread
)
{
struct ext_filesystem *fs = get_fs();
int i;
{
struct ext_filesystem *fs = get_fs();
int i;
@@
-54,7
+54,7
@@
int ext4fs_read_file(struct ext2fs_node *node, int pos,
int log2blksz = fs->dev_desc->log2blksz;
int log2_fs_blocksize = LOG2_BLOCK_SIZE(node->data) - log2blksz;
int blocksize = (1 << (log2_fs_blocksize + log2blksz));
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);
+ unsigned int filesize = le32_to_cpu(node->inode.size);
lbaint_t previous_block_number = -1;
lbaint_t delayed_start = 0;
lbaint_t delayed_extent = 0;
lbaint_t previous_block_number = -1;
lbaint_t delayed_start = 0;
lbaint_t delayed_extent = 0;
@@
-63,15
+63,18
@@
int ext4fs_read_file(struct ext2fs_node *node, int pos,
char *delayed_buf = NULL;
short status;
char *delayed_buf = NULL;
short status;
+ if (blocksize <= 0)
+ return -1;
+
/* Adjust len so it we can't read past the end of the file. */
/* Adjust len so it we can't read past the end of the file. */
- if (len > filesize)
- len =
filesize
;
+ if (len
+ pos
> filesize)
+ len =
(filesize - pos)
;
- blockcnt =
((len + pos) + blocksize - 1) / blocksize
;
+ blockcnt =
lldiv(((len + pos) + blocksize - 1), blocksize)
;
- for (i =
pos / blocksize
; i < blockcnt; i++) {
- l
baint_
t blknr;
- int blockoff = pos
% blocksize
;
+ for (i =
lldiv(pos, blocksize)
; i < blockcnt; i++) {
+ l
ong in
t blknr;
+ int blockoff = pos
- (blocksize * i)
;
int blockend = blocksize;
int skipfirst = 0;
blknr = read_allocated_block(&(node->inode), i);
int blockend = blocksize;
int skipfirst = 0;
blknr = read_allocated_block(&(node->inode), i);
@@
-82,7
+85,7
@@
int ext4fs_read_file(struct ext2fs_node *node, int pos,
/* Last block. */
if (i == blockcnt - 1) {
/* Last block. */
if (i == blockcnt - 1) {
- blockend = (len + pos)
% blocksize
;
+ blockend = (len + pos)
- (blocksize * i)
;
/* The last portion is exactly blocksize. */
if (!blockend)
/* The last portion is exactly blocksize. */
if (!blockend)
@@
-90,7
+93,7
@@
int ext4fs_read_file(struct ext2fs_node *node, int pos,
}
/* First block. */
}
/* First block. */
- if (i ==
pos / blocksize
) {
+ if (i ==
lldiv(pos, blocksize)
) {
skipfirst = blockoff;
blockend -= skipfirst;
}
skipfirst = blockoff;
blockend -= skipfirst;
}
@@
-126,6
+129,7
@@
int ext4fs_read_file(struct ext2fs_node *node, int pos,
(blockend >> log2blksz);
}
} else {
(blockend >> log2blksz);
}
} else {
+ int n;
if (previous_block_number != -1) {
/* spill */
status = ext4fs_devread(delayed_start,
if (previous_block_number != -1) {
/* spill */
status = ext4fs_devread(delayed_start,
@@
-136,7
+140,11
@@
int ext4fs_read_file(struct ext2fs_node *node, int pos,
return -1;
previous_block_number = -1;
}
return -1;
previous_block_number = -1;
}
- memset(buf, 0, blocksize - skipfirst);
+ /* Zero no more than `len' bytes. */
+ n = blocksize - skipfirst;
+ if (n > len)
+ n = len;
+ memset(buf, 0, n);
}
buf += blocksize - skipfirst;
}
}
buf += blocksize - skipfirst;
}
@@
-150,12
+158,13
@@
int ext4fs_read_file(struct ext2fs_node *node, int pos,
previous_block_number = -1;
}
previous_block_number = -1;
}
- return len;
+ *actread = len;
+ return 0;
}
int ext4fs_ls(const char *dirname)
{
}
int ext4fs_ls(const char *dirname)
{
- struct ext2fs_node *dirnode;
+ struct ext2fs_node *dirnode
= NULL
;
int status;
if (dirname == NULL)
int status;
if (dirname == NULL)
@@
-165,6
+174,8
@@
int ext4fs_ls(const char *dirname)
FILETYPE_DIRECTORY);
if (status != 1) {
printf("** Can not find directory. **\n");
FILETYPE_DIRECTORY);
if (status != 1) {
printf("** Can not find directory. **\n");
+ if (dirnode)
+ ext4fs_free_node(dirnode, &ext4fs_root->diropen);
return 1;
}
return 1;
}
@@
-176,26
+187,27
@@
int ext4fs_ls(const char *dirname)
int ext4fs_exists(const char *filename)
{
int ext4fs_exists(const char *filename)
{
- int file_len;
+ loff_t file_len;
+ int ret;
-
file_len = ext4fs_open(filename
);
- return
file_len >
= 0;
+
ret = ext4fs_open(filename, &file_len
);
+ return
ret =
= 0;
}
}
-int ext4fs_size(const char *filename)
+int ext4fs_size(const char *filename
, loff_t *size
)
{
{
- return ext4fs_open(filename);
+ return ext4fs_open(filename
, size
);
}
}
-int ext4fs_read(char *buf,
unsigned len
)
+int ext4fs_read(char *buf,
loff_t offset, loff_t len, loff_t *actread
)
{
if (ext4fs_root == NULL || ext4fs_file == NULL)
{
if (ext4fs_root == NULL || ext4fs_file == NULL)
- return
0
;
+ return
-1
;
- return ext4fs_read_file(ext4fs_file,
0, len, buf
);
+ return ext4fs_read_file(ext4fs_file,
offset, len, buf, actread
);
}
}
-int ext4fs_probe(
block_dev_desc_t
*fs_dev_desc,
+int ext4fs_probe(
struct blk_desc
*fs_dev_desc,
disk_partition_t *fs_partition)
{
ext4fs_set_blk_dev(fs_dev_desc, fs_partition);
disk_partition_t *fs_partition)
{
ext4fs_set_blk_dev(fs_dev_desc, fs_partition);
@@
-208,18
+220,14
@@
int ext4fs_probe(block_dev_desc_t *fs_dev_desc,
return 0;
}
return 0;
}
-int ext4_read_file(const char *filename, void *buf, int offset, int len)
+int ext4_read_file(const char *filename, void *buf, loff_t offset, loff_t len,
+ loff_t *len_read)
{
{
-
in
t file_len;
- int
len_read
;
+
loff_
t file_len;
+ int
ret
;
- if (offset != 0) {
- printf("** Cannot support non-zero offset **\n");
- return -1;
- }
-
- file_len = ext4fs_open(filename);
- if (file_len < 0) {
+ ret = ext4fs_open(filename, &file_len);
+ if (ret < 0) {
printf("** File not found %s **\n", filename);
return -1;
}
printf("** File not found %s **\n", filename);
return -1;
}
@@
-227,7
+235,20
@@
int ext4_read_file(const char *filename, void *buf, int offset, int len)
if (len == 0)
len = file_len;
if (len == 0)
len = file_len;
- len_read = ext4fs_read(buf, len);
+ return ext4fs_read(buf, offset, len, len_read);
+}
- return len_read;
+int ext4fs_uuid(char *uuid_str)
+{
+ if (ext4fs_root == NULL)
+ return -1;
+
+#ifdef CONFIG_LIB_UUID
+ uuid_bin_to_str((unsigned char *)ext4fs_root->sblock.unique_id,
+ uuid_str, UUID_STR_FORMAT_STD);
+
+ return 0;
+#else
+ return -ENOSYS;
+#endif
}
}