summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/dev.c1
-rw-r--r--fs/btrfs/disk-io.c1
-rw-r--r--fs/btrfs/volumes.c2
-rw-r--r--fs/cbfs/cbfs.c2
-rw-r--r--fs/cramfs/cramfs.c2
-rw-r--r--fs/cramfs/uncompress.c2
-rw-r--r--fs/erofs/Kconfig15
-rw-r--r--fs/erofs/decompress.c83
-rw-r--r--fs/erofs/erofs_fs.h1
-rw-r--r--fs/ext4/dev.c1
-rw-r--r--fs/ext4/ext4_common.c6
-rw-r--r--fs/ext4/ext4_journal.c3
-rw-r--r--fs/ext4/ext4_write.c21
-rw-r--r--fs/ext4/ext4fs.c1
-rw-r--r--fs/fat/fat.c3
-rw-r--r--fs/fat/fat_write.c45
-rw-r--r--fs/fs.c2
-rw-r--r--fs/fs_internal.c1
-rw-r--r--fs/jffs2/compr_zlib.c2
-rw-r--r--fs/jffs2/jffs2_1pass.c1
-rw-r--r--fs/jffs2/mergesort.c1
-rw-r--r--fs/sandbox/host_bootdev.c1
-rw-r--r--fs/sandbox/sandboxfs.c2
-rw-r--r--fs/semihostingfs.c2
-rw-r--r--fs/ubifs/super.c1
-rw-r--r--fs/ubifs/ubifs.c1
-rw-r--r--fs/yaffs2/yaffs_mtdif.c1
-rw-r--r--fs/yaffs2/yaffs_mtdif2.c1
-rw-r--r--fs/yaffs2/yaffs_uboot_glue.c1
-rw-r--r--fs/zfs/dev.c3
-rw-r--r--fs/zfs/zfs.c31
-rw-r--r--fs/zfs/zfs_fletcher.c1
-rw-r--r--fs/zfs/zfs_lzjb.c1
-rw-r--r--fs/zfs/zfs_sha256.c1
34 files changed, 197 insertions, 46 deletions
diff --git a/fs/btrfs/dev.c b/fs/btrfs/dev.c
index cb3b9713a5f..e27a032c9f6 100644
--- a/fs/btrfs/dev.c
+++ b/fs/btrfs/dev.c
@@ -5,7 +5,6 @@
* 2017 Marek BehĂșn, CZ.NIC, kabel@kernel.org
*/
-#include <common.h>
#include <blk.h>
#include <compiler.h>
#include <fs_internal.h>
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 7eaa7e94960..e5bfaf461c2 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1,5 +1,4 @@
// SPDX-License-Identifier: GPL-2.0+
-#include <common.h>
#include <fs_internal.h>
#include <log.h>
#include <uuid.h>
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 7d4095d9ca8..8ec545eded7 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
#include <stdlib.h>
-#include <common.h>
+#include <errno.h>
#include <fs_internal.h>
#include "ctree.h"
#include "disk-io.h"
diff --git a/fs/cbfs/cbfs.c b/fs/cbfs/cbfs.c
index 714f4baafc9..ad5583233bb 100644
--- a/fs/cbfs/cbfs.c
+++ b/fs/cbfs/cbfs.c
@@ -3,10 +3,10 @@
* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
*/
-#include <common.h>
#include <cbfs.h>
#include <log.h>
#include <malloc.h>
+#include <linux/errno.h>
#include <asm/byteorder.h>
/* Offset of master header from the start of a coreboot ROM */
diff --git a/fs/cramfs/cramfs.c b/fs/cramfs/cramfs.c
index abb2de34eb0..22148ff8fe2 100644
--- a/fs/cramfs/cramfs.c
+++ b/fs/cramfs/cramfs.c
@@ -24,7 +24,7 @@
* The actual compression is based on zlib, see the other files.
*/
-#include <common.h>
+#include <stdio.h>
#include <malloc.h>
#include <asm/byteorder.h>
#include <linux/stat.h>
diff --git a/fs/cramfs/uncompress.c b/fs/cramfs/uncompress.c
index 0d071b69f4c..2141edf22e4 100644
--- a/fs/cramfs/uncompress.c
+++ b/fs/cramfs/uncompress.c
@@ -20,7 +20,7 @@
* then is used by multiple filesystems.
*/
-#include <common.h>
+#include <stdio.h>
#include <cyclic.h>
#include <malloc.h>
#include <watchdog.h>
diff --git a/fs/erofs/Kconfig b/fs/erofs/Kconfig
index ee4e777c5c8..c8463357ca2 100644
--- a/fs/erofs/Kconfig
+++ b/fs/erofs/Kconfig
@@ -19,3 +19,18 @@ config FS_EROFS_ZIP
help
Enable fixed-sized output compression for EROFS.
If you don't want to enable compression feature, say N.
+
+config FS_EROFS_ZIP_DEFLATE
+ bool "EROFS DEFLATE compressed data support"
+ depends on FS_EROFS_ZIP
+ select ZLIB
+ help
+ Saying Y here includes support for reading EROFS file systems
+ containing DEFLATE compressed data. It gives better compression
+ ratios than the default LZ4 format, while it costs more CPU
+ overhead.
+
+ DEFLATE support is an experimental feature for now and so most
+ file systems will be readable without selecting this option.
+
+ If unsure, say N.
diff --git a/fs/erofs/decompress.c b/fs/erofs/decompress.c
index e04e5c34a8d..ec74816534c 100644
--- a/fs/erofs/decompress.c
+++ b/fs/erofs/decompress.c
@@ -1,6 +1,85 @@
// SPDX-License-Identifier: GPL-2.0+
#include "decompress.h"
+#if IS_ENABLED(CONFIG_ZLIB)
+#include <u-boot/zlib.h>
+
+/* report a zlib or i/o error */
+static int zerr(int ret)
+{
+ switch (ret) {
+ case Z_STREAM_ERROR:
+ return -EINVAL;
+ case Z_DATA_ERROR:
+ return -EIO;
+ case Z_MEM_ERROR:
+ return -ENOMEM;
+ case Z_ERRNO:
+ default:
+ return -EFAULT;
+ }
+}
+
+static int z_erofs_decompress_deflate(struct z_erofs_decompress_req *rq)
+{
+ u8 *dest = (u8 *)rq->out;
+ u8 *src = (u8 *)rq->in;
+ u8 *buff = NULL;
+ unsigned int inputmargin = 0;
+ z_stream strm;
+ int ret;
+
+ while (!src[inputmargin & (erofs_blksiz() - 1)])
+ if (!(++inputmargin & (erofs_blksiz() - 1)))
+ break;
+
+ if (inputmargin >= rq->inputsize)
+ return -EFSCORRUPTED;
+
+ if (rq->decodedskip) {
+ buff = malloc(rq->decodedlength);
+ if (!buff)
+ return -ENOMEM;
+ dest = buff;
+ }
+
+ /* allocate inflate state */
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+ strm.avail_in = 0;
+ strm.next_in = Z_NULL;
+ ret = inflateInit2(&strm, -15);
+ if (ret != Z_OK) {
+ free(buff);
+ return zerr(ret);
+ }
+
+ strm.next_in = src + inputmargin;
+ strm.avail_in = rq->inputsize - inputmargin;
+ strm.next_out = dest;
+ strm.avail_out = rq->decodedlength;
+
+ ret = inflate(&strm, rq->partial_decoding ? Z_SYNC_FLUSH : Z_FINISH);
+ if (ret != Z_STREAM_END || strm.total_out != rq->decodedlength) {
+ if (ret != Z_OK || !rq->partial_decoding) {
+ ret = zerr(ret);
+ goto out_inflate_end;
+ }
+ }
+
+ if (rq->decodedskip)
+ memcpy(rq->out, dest + rq->decodedskip,
+ rq->decodedlength - rq->decodedskip);
+
+out_inflate_end:
+ inflateEnd(&strm);
+ if (buff)
+ free(buff);
+ return ret;
+}
+#endif
+
#if IS_ENABLED(CONFIG_LZ4)
#include <u-boot/lz4.h>
static int z_erofs_decompress_lz4(struct z_erofs_decompress_req *rq)
@@ -94,5 +173,9 @@ int z_erofs_decompress(struct z_erofs_decompress_req *rq)
if (rq->alg == Z_EROFS_COMPRESSION_LZ4)
return z_erofs_decompress_lz4(rq);
#endif
+#if IS_ENABLED(CONFIG_ZLIB)
+ if (rq->alg == Z_EROFS_COMPRESSION_DEFLATE)
+ return z_erofs_decompress_deflate(rq);
+#endif
return -EOPNOTSUPP;
}
diff --git a/fs/erofs/erofs_fs.h b/fs/erofs/erofs_fs.h
index 158e2c68a1a..5bac4fe1a1d 100644
--- a/fs/erofs/erofs_fs.h
+++ b/fs/erofs/erofs_fs.h
@@ -304,6 +304,7 @@ enum {
enum {
Z_EROFS_COMPRESSION_LZ4 = 0,
Z_EROFS_COMPRESSION_LZMA = 1,
+ Z_EROFS_COMPRESSION_DEFLATE = 2,
Z_EROFS_COMPRESSION_MAX
};
diff --git a/fs/ext4/dev.c b/fs/ext4/dev.c
index 168443de1ff..3fd8980b1d6 100644
--- a/fs/ext4/dev.c
+++ b/fs/ext4/dev.c
@@ -22,7 +22,6 @@
* fs/ext2/dev.c file in uboot.
*/
-#include <common.h>
#include <blk.h>
#include <config.h>
#include <fs_internal.h>
diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c
index 365c5147c4b..857c15d878e 100644
--- a/fs/ext4/ext4_common.c
+++ b/fs/ext4/ext4_common.c
@@ -18,7 +18,6 @@
* ext4write : Based on generic ext4 protocol.
*/
-#include <common.h>
#include <blk.h>
#include <ext_common.h>
#include <ext4fs.h>
@@ -765,11 +764,6 @@ int ext4fs_get_parent_inode_num(const char *dirname, char *dname, int flags)
struct ext2_inode *first_inode = NULL;
struct ext2_inode temp_inode;
- if (*dirname != '/') {
- printf("Please supply Absolute path\n");
- return -1;
- }
-
/* TODO: input validation make equivalent to linux */
depth_dirname = zalloc(strlen(dirname) + 1);
if (!depth_dirname)
diff --git a/fs/ext4/ext4_journal.c b/fs/ext4/ext4_journal.c
index 1a340b4764c..02c4ac2cb93 100644
--- a/fs/ext4/ext4_journal.c
+++ b/fs/ext4/ext4_journal.c
@@ -13,7 +13,6 @@
* Copyright 1998-2000 Red Hat, Inc --- All Rights Reserved
*/
-#include <common.h>
#include <blk.h>
#include <ext4fs.h>
#include <log.h>
@@ -430,7 +429,7 @@ int ext4fs_check_journal_state(int recovery_flag)
printf("Recovery required\n");
} else {
if (recovery_flag == RECOVER)
- printf("File System is consistent\n");
+ log_debug("File System is consistent\n");
goto end;
}
diff --git a/fs/ext4/ext4_write.c b/fs/ext4/ext4_write.c
index ea4c5d4157c..38da3923c47 100644
--- a/fs/ext4/ext4_write.c
+++ b/fs/ext4/ext4_write.c
@@ -21,7 +21,6 @@
*/
-#include <common.h>
#include <blk.h>
#include <log.h>
#include <malloc.h>
@@ -847,6 +846,7 @@ int ext4fs_write(const char *fname, const char *buffer,
{
int ret = 0;
struct ext2_inode *file_inode = NULL;
+ struct ext2_inode *existing_file_inode = NULL;
unsigned char *inode_buffer = NULL;
int parent_inodeno;
int inodeno;
@@ -900,6 +900,15 @@ int ext4fs_write(const char *fname, const char *buffer,
/* check if the filename is already present in root */
existing_file_inodeno = ext4fs_filename_unlink(filename);
if (existing_file_inodeno != -1) {
+ existing_file_inode = (struct ext2_inode *)zalloc(fs->inodesz);
+ if (!existing_file_inode)
+ goto fail;
+ ret = ext4fs_iget(existing_file_inodeno, existing_file_inode);
+ if (ret) {
+ free(existing_file_inode);
+ goto fail;
+ }
+
ret = ext4fs_delete_file(existing_file_inodeno);
fs->first_pass_bbmap = 0;
fs->curr_blkno = 0;
@@ -948,9 +957,15 @@ int ext4fs_write(const char *fname, const char *buffer,
sizebytes = 0;
}
} else {
- file_inode->mode = cpu_to_le16(S_IFREG | S_IRWXU | S_IRGRP |
- S_IROTH | S_IXGRP | S_IXOTH);
+ if (existing_file_inode) {
+ file_inode->mode = existing_file_inode->mode;
+ } else {
+ file_inode->mode = cpu_to_le16(S_IFREG | S_IRWXU | S_IRGRP |
+ S_IROTH | S_IXGRP | S_IXOTH);
+ }
}
+ if (existing_file_inode)
+ free(existing_file_inode);
/* ToDo: Update correct time */
file_inode->mtime = cpu_to_le32(timestamp);
file_inode->atime = cpu_to_le32(timestamp);
diff --git a/fs/ext4/ext4fs.c b/fs/ext4/ext4fs.c
index 33e200ffa3c..da59cb008fc 100644
--- a/fs/ext4/ext4fs.c
+++ b/fs/ext4/ext4fs.c
@@ -20,7 +20,6 @@
* ext4write : Based on generic ext4 protocol.
*/
-#include <common.h>
#include <blk.h>
#include <ext_common.h>
#include <ext4fs.h>
diff --git a/fs/fat/fat.c b/fs/fat/fat.c
index 14e53cf2d5a..e2570e81676 100644
--- a/fs/fat/fat.c
+++ b/fs/fat/fat.c
@@ -10,7 +10,6 @@
#define LOG_CATEGORY LOGC_FS
-#include <common.h>
#include <blk.h>
#include <config.h>
#include <exports.h>
@@ -1254,7 +1253,7 @@ out:
static void __maybe_unused fat2rtc(u16 date, u16 time, struct rtc_time *tm)
{
tm->tm_mday = date & 0x1f;
- tm->tm_mon = (date & 0x1e0) >> 4;
+ tm->tm_mon = (date & 0x1e0) >> 5;
tm->tm_year = (date >> 9) + 1980;
tm->tm_sec = (time & 0x1f) << 1;
diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index 8b5d669b005..ea877ee9171 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -7,7 +7,6 @@
#define LOG_CATEGORY LOGC_FS
-#include <common.h>
#include <command.h>
#include <config.h>
#include <div64.h>
@@ -18,6 +17,7 @@
#include <rand.h>
#include <asm/byteorder.h>
#include <asm/cache.h>
+#include <dm/uclass.h>
#include <linux/ctype.h>
#include <linux/math64.h>
#include "fat.c"
@@ -1152,6 +1152,41 @@ getit:
}
/**
+ * dentry_set_time() - set change time
+ *
+ * @dentptr: directory entry
+ */
+static void dentry_set_time(dir_entry *dentptr)
+{
+ if (CONFIG_IS_ENABLED(DM_RTC)) {
+ struct udevice *dev;
+ struct rtc_time tm;
+ u16 date;
+ u16 time;
+
+ uclass_first_device(UCLASS_RTC, &dev);
+ if (!dev)
+ goto err;
+ if (dm_rtc_get(dev, &tm))
+ goto err;
+ if (tm.tm_year < 1980 || tm.tm_year > 2107)
+ goto err;
+ date = (tm.tm_mday & 0x1f) |
+ ((tm.tm_mon & 0xf) << 5) |
+ ((tm.tm_year - 1980) << 9);
+ time = (tm.tm_sec > 1) |
+ ((tm.tm_min & 0x3f) << 5) |
+ (tm.tm_hour << 11);
+ dentptr->date = date;
+ dentptr->time = time;
+ return;
+ }
+err:
+ dentptr->date = 0x2821; /* 2000-01-01 */
+ dentptr->time = 0;
+}
+
+/**
* fill_dentry() - fill directory entry with shortname
*
* @mydata: private filesystem parameters
@@ -1171,6 +1206,12 @@ static void fill_dentry(fsdata *mydata, dir_entry *dentptr,
dentptr->attr = attr;
+ /* Set change date */
+ dentry_set_time(dentptr);
+ /* Set creation date */
+ dentptr->cdate = dentptr->date;
+ dentptr->ctime = dentptr->time;
+
memcpy(&dentptr->nameext, shortname, SHORT_NAME_SIZE);
}
@@ -1376,6 +1417,8 @@ int file_fat_write_at(const char *filename, loff_t pos, void *buffer,
/* Update file size in a directory entry */
retdent->size = cpu_to_le32(pos + size);
+ /* Update change date */
+ dentry_set_time(retdent);
} else {
/* Create a new file */
char shortname[SHORT_NAME_SIZE];
diff --git a/fs/fs.c b/fs/fs.c
index acf465bdd80..bed1f7242f4 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -9,7 +9,6 @@
#include <config.h>
#include <display_options.h>
#include <errno.h>
-#include <common.h>
#include <env.h>
#include <lmb.h>
#include <log.h>
@@ -21,6 +20,7 @@
#include <fs.h>
#include <sandboxfs.h>
#include <semihostingfs.h>
+#include <time.h>
#include <ubifs_uboot.h>
#include <btrfs.h>
#include <asm/global_data.h>
diff --git a/fs/fs_internal.c b/fs/fs_internal.c
index 111f91b355d..51c1719361b 100644
--- a/fs/fs_internal.c
+++ b/fs/fs_internal.c
@@ -7,7 +7,6 @@
#define LOG_CATEGORY LOGC_CORE
-#include <common.h>
#include <blk.h>
#include <compiler.h>
#include <log.h>
diff --git a/fs/jffs2/compr_zlib.c b/fs/jffs2/compr_zlib.c
index d306b6dc4cf..e1e3c15e75e 100644
--- a/fs/jffs2/compr_zlib.c
+++ b/fs/jffs2/compr_zlib.c
@@ -35,8 +35,6 @@
*
*/
-#include <common.h>
-#include <config.h>
#include <jffs2/jffs2.h>
#include <jffs2/mini_inflate.h>
diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c
index 49ba82ef959..5b7d7f4ae88 100644
--- a/fs/jffs2/jffs2_1pass.c
+++ b/fs/jffs2/jffs2_1pass.c
@@ -111,7 +111,6 @@
*/
-#include <common.h>
#include <config.h>
#include <malloc.h>
#include <div64.h>
diff --git a/fs/jffs2/mergesort.c b/fs/jffs2/mergesort.c
index fca77aa6511..495937d792d 100644
--- a/fs/jffs2/mergesort.c
+++ b/fs/jffs2/mergesort.c
@@ -7,7 +7,6 @@
* http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
*/
-#include <common.h>
#include "jffs2_private.h"
int sort_list(struct b_list *list)
diff --git a/fs/sandbox/host_bootdev.c b/fs/sandbox/host_bootdev.c
index 3ef53627608..3f74972a9f8 100644
--- a/fs/sandbox/host_bootdev.c
+++ b/fs/sandbox/host_bootdev.c
@@ -6,7 +6,6 @@
* Written by Simon Glass <sjg@chromium.org>
*/
-#include <common.h>
#include <bootdev.h>
#include <bootflow.h>
#include <bootmeth.h>
diff --git a/fs/sandbox/sandboxfs.c b/fs/sandbox/sandboxfs.c
index 4ae41d5b4db..773b583fa43 100644
--- a/fs/sandbox/sandboxfs.c
+++ b/fs/sandbox/sandboxfs.c
@@ -3,7 +3,7 @@
* Copyright (c) 2012, Google Inc.
*/
-#include <common.h>
+#include <stdio.h>
#include <fs.h>
#include <malloc.h>
#include <os.h>
diff --git a/fs/semihostingfs.c b/fs/semihostingfs.c
index 3592338a686..77e39ca407e 100644
--- a/fs/semihostingfs.c
+++ b/fs/semihostingfs.c
@@ -4,7 +4,7 @@
* Copyright (c) 2012, Google Inc.
*/
-#include <common.h>
+#include <stdio.h>
#include <fs.h>
#include <malloc.h>
#include <os.h>
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 3e7160352e6..788f88f0495 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -29,7 +29,6 @@
#include <linux/writeback.h>
#else
-#include <common.h>
#include <malloc.h>
#include <memalign.h>
#include <linux/bitops.h>
diff --git a/fs/ubifs/ubifs.c b/fs/ubifs/ubifs.c
index a509584e5d7..75de01e95f7 100644
--- a/fs/ubifs/ubifs.c
+++ b/fs/ubifs/ubifs.c
@@ -11,7 +11,6 @@
* Adrian Hunter
*/
-#include <common.h>
#include <env.h>
#include <gzip.h>
#include <log.h>
diff --git a/fs/yaffs2/yaffs_mtdif.c b/fs/yaffs2/yaffs_mtdif.c
index 50fed2d4b15..0eec22bc4a5 100644
--- a/fs/yaffs2/yaffs_mtdif.c
+++ b/fs/yaffs2/yaffs_mtdif.c
@@ -12,7 +12,6 @@
*/
/* XXX U-BOOT XXX */
-#include <common.h>
#include "yportenv.h"
diff --git a/fs/yaffs2/yaffs_mtdif2.c b/fs/yaffs2/yaffs_mtdif2.c
index 81a4d964f3e..2bf171f99f1 100644
--- a/fs/yaffs2/yaffs_mtdif2.c
+++ b/fs/yaffs2/yaffs_mtdif2.c
@@ -14,7 +14,6 @@
/* mtd interface for YAFFS2 */
/* XXX U-BOOT XXX */
-#include <common.h>
#include <linux/bug.h>
#include <linux/errno.h>
diff --git a/fs/yaffs2/yaffs_uboot_glue.c b/fs/yaffs2/yaffs_uboot_glue.c
index 0a920561149..deddbaac51e 100644
--- a/fs/yaffs2/yaffs_uboot_glue.c
+++ b/fs/yaffs2/yaffs_uboot_glue.c
@@ -19,7 +19,6 @@
* This version now uses the ydevconfig mechanism to set up partitions.
*/
-#include <common.h>
#include <div64.h>
#include <malloc.h>
#include <linux/printk.h>
diff --git a/fs/zfs/dev.c b/fs/zfs/dev.c
index 251e7d1f74f..722c6a86176 100644
--- a/fs/zfs/dev.c
+++ b/fs/zfs/dev.c
@@ -8,7 +8,6 @@
*/
-#include <common.h>
#include <config.h>
#include <fs_internal.h>
#include <zfs_common.h>
@@ -26,5 +25,5 @@ void zfs_set_blk_dev(struct blk_desc *rbdd, struct disk_partition *info)
int zfs_devread(int sector, int byte_offset, int byte_len, char *buf)
{
return fs_devread(zfs_blk_desc, part_info, sector, byte_offset,
- byte_len, buf);
+ byte_len, buf) ? 0 : 1;
}
diff --git a/fs/zfs/zfs.c b/fs/zfs/zfs.c
index 1fec96cd5ce..c44e7ece5df 100644
--- a/fs/zfs/zfs.c
+++ b/fs/zfs/zfs.c
@@ -10,7 +10,6 @@
* Copyright 2004 Sun Microsystems, Inc.
*/
-#include <common.h>
#include <log.h>
#include <malloc.h>
#include <linux/stat.h>
@@ -655,7 +654,7 @@ dmu_read(dnode_end_t *dn, uint64_t blkid, void **buf,
dn->endian)
<< SPA_MINBLOCKSHIFT;
*buf = malloc(size);
- if (*buf) {
+ if (!*buf) {
err = ZFS_ERR_OUT_OF_MEMORY;
break;
}
@@ -1559,6 +1558,10 @@ nvlist_find_value(char *nvlist, char *name, int valtype, char **val,
return 0;
}
+int is_word_aligned_ptr(void *ptr) {
+ return ((uintptr_t)ptr & (sizeof(void *) - 1)) == 0;
+}
+
int
zfs_nvlist_lookup_uint64(char *nvlist, char *name, uint64_t *out)
{
@@ -1574,6 +1577,20 @@ zfs_nvlist_lookup_uint64(char *nvlist, char *name, uint64_t *out)
return ZFS_ERR_BAD_FS;
}
+ /* On arm64, calling be64_to_cpu() on a value stored at a memory address
+ * that's not 8-byte aligned causes the CPU to reset. Avoid that by copying the
+ * value somewhere else if needed.
+ */
+ if (!is_word_aligned_ptr((void *)nvpair)) {
+ uint64_t *alignedptr = malloc(sizeof(uint64_t));
+ if (!alignedptr)
+ return 0;
+ memcpy(alignedptr, nvpair, sizeof(uint64_t));
+ *out = be64_to_cpu(*alignedptr);
+ free(alignedptr);
+ return 1;
+ }
+
*out = be64_to_cpu(*(uint64_t *) nvpair);
return 1;
}
@@ -1617,6 +1634,11 @@ zfs_nvlist_lookup_nvlist(char *nvlist, char *name)
&size, 0);
if (!found)
return 0;
+
+ /* Allocate 12 bytes in addition to the nvlist size: One uint32 before the
+ * nvlist to hold the encoding method, and two zero uint32's after the
+ * nvlist as the NULL terminator.
+ */
ret = calloc(1, size + 3 * sizeof(uint32_t));
if (!ret)
return 0;
@@ -2112,7 +2134,7 @@ zfs_read(zfs_file_t file, char *buf, uint64_t len)
* Find requested blkid and the offset within that block.
*/
uint64_t blkid = file->offset + red;
- blkid = do_div(blkid, blksz);
+ uint64_t blkoff = do_div(blkid, blksz);
free(data->file_buf);
data->file_buf = 0;
@@ -2127,8 +2149,7 @@ zfs_read(zfs_file_t file, char *buf, uint64_t len)
movesize = min(length, data->file_end - (int)file->offset - red);
- memmove(buf, data->file_buf + file->offset + red
- - data->file_start, movesize);
+ memmove(buf, data->file_buf + blkoff, movesize);
buf += movesize;
length -= movesize;
red += movesize;
diff --git a/fs/zfs/zfs_fletcher.c b/fs/zfs/zfs_fletcher.c
index 008a303ec79..b06c335626a 100644
--- a/fs/zfs/zfs_fletcher.c
+++ b/fs/zfs/zfs_fletcher.c
@@ -8,7 +8,6 @@
* Use is subject to license terms.
*/
-#include <common.h>
#include <malloc.h>
#include <linux/stat.h>
#include <linux/time.h>
diff --git a/fs/zfs/zfs_lzjb.c b/fs/zfs/zfs_lzjb.c
index b42d4980129..e79c5b4278f 100644
--- a/fs/zfs/zfs_lzjb.c
+++ b/fs/zfs/zfs_lzjb.c
@@ -8,7 +8,6 @@
* Use is subject to license terms.
*/
-#include <common.h>
#include <malloc.h>
#include <linux/stat.h>
#include <linux/time.h>
diff --git a/fs/zfs/zfs_sha256.c b/fs/zfs/zfs_sha256.c
index cb5b1c06834..602d75254ff 100644
--- a/fs/zfs/zfs_sha256.c
+++ b/fs/zfs/zfs_sha256.c
@@ -8,7 +8,6 @@
* Use is subject to license terms.
*/
-#include <common.h>
#include <malloc.h>
#include <linux/stat.h>
#include <linux/time.h>