From 30bc03c9fa6e9bb2189f4ea30c767b9739c5df4a Mon Sep 17 00:00:00 2001 From: "fix94.1" Date: Sun, 22 Apr 2012 17:40:21 +0000 Subject: [PATCH] -updated libntfs-wii to version 2012.1.15 -updated libext2fs to e2fsprogs 1.42 -updated libfat to R4883 Thanks to USB Loader GX for the new libs --- Makefile | 2 +- portlibs/include/ext2.h | 63 +- portlibs/include/fat.h | 4 +- portlibs/include/ntfs.h | 1 + portlibs/lib/libext2fs.a | Bin 448290 -> 0 bytes portlibs/lib/libfat.a | Bin 76528 -> 0 bytes portlibs/lib/libntfs.a | Bin 558826 -> 0 bytes .../{libext2fs => libcustomext2fs}/AUTHORS | 0 .../{libext2fs => libcustomext2fs}/CREDITS | 3 +- .../{libext2fs => libcustomext2fs}/LICENSE | 0 portlibs/sources/libcustomext2fs/Makefile | 27 + .../include/ext2.h | 63 +- .../source/Makefile | 15 +- .../source/alloc.c | 20 +- .../source/alloc_sb.c | 14 +- .../source/alloc_stats.c | 4 +- .../source/alloc_tables.c | 74 +- .../source/badblocks.c | 3 +- .../source/bb_compat.c | 1 + .../source/bb_inode.c | 1 + .../source/bit_ops.h | 0 .../source/bitmaps.c | 58 +- .../source/bitops.c | 1 + .../source/bitops.h | 7 +- .../source/blkmap64_ba.c | 1 + .../source/blknum.c | 39 +- .../source/block.c | 12 + .../source/bmap.c | 159 ++- .../source/bmap64.h | 1 + .../source/bmove.c | 3 +- .../source/brel.h | 0 .../source/brel_ma.c | 1 + .../source/check_desc.c | 7 +- .../source/closefs.c | 35 +- .../source/com_err.c | 0 .../source/com_err.h | 0 .../sources/libcustomext2fs/source/config.h | 603 +++++++++ .../source/crc16.c | 1 + .../source/crc16.h | 0 .../sources/libcustomext2fs/source/crc32c.c | 1144 +++++++++++++++++ .../libcustomext2fs/source/crc32c_defs.h | 51 + .../libcustomext2fs/source/crc32c_table.h | 1065 +++++++++++++++ .../source/csum.c | 11 +- .../source/dblist.c | 7 +- .../source/dblist_dir.c | 1 + .../source/dir_iterate.c | 1 + .../source/dirblock.c | 1 + .../source/dirhash.c | 4 + .../source/disc_cache.c | 8 +- .../source/disc_cache.h | 0 .../source/dupfs.c | 1 + .../source/e2image.h | 21 +- .../source/expanddir.c | 25 +- .../source/ext2.c | 27 +- .../sources/libcustomext2fs/source/ext2_err.c | 199 +++ .../sources/libcustomext2fs/source/ext2_err.h | 169 +++ .../source/ext2_ext_attr.h | 0 .../source/ext2_frag.c | 0 .../source/ext2_frag.h | 0 .../source/ext2_fs.h | 111 +- .../source/ext2_internal.c | 4 +- .../source/ext2_internal.h | 0 .../source/ext2_io.h | 3 +- .../libcustomext2fs/source/ext2_types.h | 143 +++ .../source/ext2dir.c | 0 .../source/ext2dir.h | 0 .../source/ext2file.c | 26 +- .../source/ext2file.h | 0 .../source/ext2fs.h | 193 ++- .../source/ext2fsP.h | 4 +- .../source/ext3_extents.h | 0 .../source/ext_attr.c | 8 +- .../source/extent.c | 8 +- .../source/fiemap.h | 0 .../source/fileio.c | 51 +- .../source/finddev.c | 6 + .../source/flushb.c | 5 + .../source/freefs.c | 6 + .../source/gekko_io.c | 89 +- .../source/gekko_io.h | 2 +- .../source/gen_bitmap.c | 14 +- .../source/gen_bitmap64.c | 66 +- .../source/get_pathname.c | 1 + .../source/getsectsize.c | 13 +- .../source/getsize.c | 19 +- .../source/i_block.c | 4 + .../source/icount.c | 40 +- .../source/imager.c | 1 + .../source/ind_block.c | 1 + .../source/initialize.c | 75 +- .../sources/libcustomext2fs/source/inline.c | 72 ++ .../source/inode.c | 13 +- .../source/inode_io.c | 3 +- .../source/io_manager.c | 1 + .../source/irel.h | 0 .../source/irel_ma.c | 1 + .../source/ismounted.c | 1 + .../source/jfs_compat.h | 0 .../source/jfs_dat.h | 0 .../source/jfs_user.h | 0 .../source/kernel-jbd.h | 0 .../source/kernel-list.h | 0 .../source/link.c | 5 +- .../source/llseek.c | 1 + .../source/lookup.c | 1 + .../source/mem2.h | 0 .../source/mem_allocate.h | 8 + .../source/mkdir.c | 18 +- .../source/mkjournal.c | 90 +- portlibs/sources/libcustomext2fs/source/mmp.c | 417 ++++++ .../source/namei.c | 6 +- .../source/native.c | 1 + .../source/newdir.c | 1 + .../source/openfs.c | 53 +- .../source/partitions.h | 0 .../source/progress.c | 3 +- .../source/punch.c | 9 +- .../source/read_bb.c | 1 + .../source/read_bb_file.c | 1 + .../source/res_gdt.c | 20 +- .../source/rw_bitmaps.c | 44 +- .../source/sparse.c | 1 + .../source/swapfs.c | 62 +- .../source/tdb.c | 15 +- .../source/tdb.h | 2 - .../source/unlink.c | 1 + .../source/valid_blk.c | 10 +- .../source/version.c | 7 +- .../sources/libcustomext2fs/source/version.h | 11 + .../source/write_bb_file.c | 1 + portlibs/sources/libcustomfat/Makefile | 31 + .../{libfat => libcustomfat/include}/fat.h | 4 +- .../include}/libfatversion.h | 4 +- portlibs/sources/libcustomfat/libfat.pnproj | 1 + portlibs/sources/libcustomfat/libfat.pnps | 1 + portlibs/sources/libcustomfat/libogc/Makefile | 132 ++ .../sources/libcustomfat/libogc/include/fat.h | 86 ++ .../{libfat => libcustomfat/source}/bit_ops.h | 0 .../{libfat => libcustomfat/source}/cache.c | 0 .../{libfat => libcustomfat/source}/cache.h | 0 .../{libfat => libcustomfat/source}/common.h | 0 .../source}/directory.c | 14 +- .../source}/directory.h | 5 +- .../{libfat => libcustomfat/source}/disc.c | 0 .../{libfat => libcustomfat/source}/disc.h | 0 .../{libfat => libcustomfat/source}/fatdir.c | 18 +- .../{libfat => libcustomfat/source}/fatdir.h | 0 .../{libfat => libcustomfat/source}/fatfile.c | 31 + .../{libfat => libcustomfat/source}/fatfile.h | 0 .../source}/fatfile_frag.c | 0 .../source}/fatfile_frag.h | 0 .../source}/file_allocation_table.c | 8 +- .../source}/file_allocation_table.h | 0 .../source}/filetime.c | 0 .../source}/filetime.h | 0 .../{libfat => libcustomfat/source}/libfat.c | 0 .../{libfat => libcustomfat/source}/lock.c | 0 .../{libfat => libcustomfat/source}/lock.h | 0 .../{libfat => libcustomfat/source}/mem2.h | 0 .../source}/mem_allocate.h | 0 .../source}/partition.c | 208 ++- .../source}/partition.h | 0 portlibs/sources/libcustomntfs/AUTHORS | 27 + portlibs/sources/libcustomntfs/CREDITS | 50 + portlibs/sources/libcustomntfs/LICENSE | 340 +++++ .../{libext2fs => libcustomntfs}/Makefile | 14 +- portlibs/sources/libcustomntfs/READMII | 54 + portlibs/sources/libcustomntfs/include/ntfs.h | 148 +++ .../sources/libcustomntfs/source/Makefile | 130 ++ .../{libntfs => libcustomntfs/source}/acls.c | 14 +- .../{libntfs => libcustomntfs/source}/acls.h | 0 .../source}/attrib.c | 49 +- .../source}/attrib.h | 0 .../source}/attrib_frag.c | 0 .../source}/attrlist.c | 0 .../source}/attrlist.h | 0 .../source}/bit_ops.h | 0 .../source}/bitmap.c | 0 .../source}/bitmap.h | 0 .../source}/bootsect.c | 0 .../source}/bootsect.h | 0 .../{libntfs => libcustomntfs/source}/cache.c | 3 - .../{libntfs => libcustomntfs/source}/cache.h | 0 .../source}/cache2.c | 0 .../source}/cache2.h | 0 .../source}/collate.c | 0 .../source}/collate.h | 0 .../source}/compat.c | 0 .../source}/compat.h | 0 .../source}/compress.c | 416 +++--- .../source}/compress.h | 0 .../source}/config.h | 12 +- .../{libntfs => libcustomntfs/source}/debug.c | 0 .../{libntfs => libcustomntfs/source}/debug.h | 4 +- .../source}/device.c | 55 + .../source}/device.h | 0 .../source}/device_io.c | 0 .../source}/device_io.h | 0 .../{libntfs => libcustomntfs/source}/dir.c | 30 +- .../{libntfs => libcustomntfs/source}/dir.h | 0 .../{libntfs => libcustomntfs/source}/efs.c | 2 - .../{libntfs => libcustomntfs/source}/efs.h | 0 .../source}/endians.h | 0 .../source}/gekko_io.c | 0 .../source}/gekko_io.h | 0 .../{libntfs => libcustomntfs/source}/index.c | 510 ++++---- .../{libntfs => libcustomntfs/source}/index.h | 0 .../{libntfs => libcustomntfs/source}/inode.c | 105 +- .../{libntfs => libcustomntfs/source}/inode.h | 0 .../source}/layout.h | 6 +- .../source}/lcnalloc.c | 182 +-- .../source}/lcnalloc.h | 0 .../source}/logfile.c | 9 +- .../source}/logfile.h | 0 .../source}/logging.c | 0 .../source}/logging.h | 0 .../{libntfs => libcustomntfs/source}/mem2.h | 0 .../source}/mem_allocate.h | 0 .../{libntfs => libcustomntfs/source}/mft.c | 12 +- .../{libntfs => libcustomntfs/source}/mft.h | 0 .../{libntfs => libcustomntfs/source}/misc.c | 0 .../{libntfs => libcustomntfs/source}/misc.h | 0 .../{libntfs => libcustomntfs/source}/mst.c | 24 +- .../{libntfs => libcustomntfs/source}/mst.h | 3 + .../{libntfs => libcustomntfs/source}/ntfs.c | 0 .../{libntfs => libcustomntfs/source}/ntfs.h | 0 .../source}/ntfsdir.c | 0 .../source}/ntfsdir.h | 0 .../source}/ntfsfile.c | 0 .../source}/ntfsfile.h | 0 .../source}/ntfsfile_frag.c | 0 .../source}/ntfsfile_frag.h | 0 .../source}/ntfsinternal.c | 0 .../source}/ntfsinternal.h | 0 .../source}/ntfstime.h | 12 + .../source}/object_id.c | 2 - .../source}/object_id.h | 0 .../{libntfs => libcustomntfs/source}/param.h | 18 + .../sources/libcustomntfs/source/realpath.c | 103 ++ .../sources/libcustomntfs/source/realpath.h | 24 + .../source}/reparse.c | 0 .../source}/reparse.h | 0 .../source}/runlist.c | 9 +- .../source}/runlist.h | 0 .../source}/security.c | 80 +- .../source}/security.h | 0 .../source}/support.h | 0 .../{libntfs => libcustomntfs/source}/types.h | 2 +- .../source}/unistr.c | 92 +- .../source}/unistr.h | 0 .../source}/volume.c | 140 +- .../source}/volume.h | 6 + .../source}/xattrs.c | 0 .../source}/xattrs.h | 0 portlibs/sources/libext2fs/source/config.h | 10 - portlibs/sources/libext2fs/source/ext2_err.h | 152 --- .../sources/libext2fs/source/ext2_types.h | 18 - portlibs/sources/libext2fs/source/inline.c | 32 - portlibs/sources/libfat/Makefile | 32 - portlibs/sources/libntfs/Makefile | 32 - 260 files changed, 7489 insertions(+), 1748 deletions(-) delete mode 100644 portlibs/lib/libext2fs.a delete mode 100644 portlibs/lib/libfat.a delete mode 100644 portlibs/lib/libntfs.a rename portlibs/sources/{libext2fs => libcustomext2fs}/AUTHORS (100%) rename portlibs/sources/{libext2fs => libcustomext2fs}/CREDITS (91%) rename portlibs/sources/{libext2fs => libcustomext2fs}/LICENSE (100%) create mode 100644 portlibs/sources/libcustomext2fs/Makefile rename portlibs/sources/{libext2fs => libcustomext2fs}/include/ext2.h (54%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/Makefile (91%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/alloc.c (93%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/alloc_sb.c (89%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/alloc_stats.c (96%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/alloc_tables.c (81%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/badblocks.c (99%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/bb_compat.c (98%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/bb_inode.c (99%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/bit_ops.h (100%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/bitmaps.c (82%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/bitops.c (99%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/bitops.h (98%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/blkmap64_ba.c (99%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/blknum.c (92%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/block.c (97%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/bmap.c (70%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/bmap64.h (98%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/bmove.c (98%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/brel.h (100%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/brel_ma.c (99%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/check_desc.c (93%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/closefs.c (95%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/com_err.c (100%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/com_err.h (100%) create mode 100644 portlibs/sources/libcustomext2fs/source/config.h rename portlibs/sources/{libext2fs => libcustomext2fs}/source/crc16.c (99%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/crc16.h (100%) create mode 100644 portlibs/sources/libcustomext2fs/source/crc32c.c create mode 100644 portlibs/sources/libcustomext2fs/source/crc32c_defs.h create mode 100644 portlibs/sources/libcustomext2fs/source/crc32c_table.h rename portlibs/sources/{libext2fs => libcustomext2fs}/source/csum.c (96%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/dblist.c (98%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/dblist_dir.c (98%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/dir_iterate.c (99%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/dirblock.c (99%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/dirhash.c (98%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/disc_cache.c (99%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/disc_cache.h (100%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/dupfs.c (99%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/e2image.h (88%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/expanddir.c (85%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/ext2.c (94%) create mode 100644 portlibs/sources/libcustomext2fs/source/ext2_err.c create mode 100644 portlibs/sources/libcustomext2fs/source/ext2_err.h rename portlibs/sources/{libext2fs => libcustomext2fs}/source/ext2_ext_attr.h (100%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/ext2_frag.c (100%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/ext2_frag.h (100%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/ext2_fs.h (87%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/ext2_internal.c (99%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/ext2_internal.h (100%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/ext2_io.h (98%) create mode 100644 portlibs/sources/libcustomext2fs/source/ext2_types.h rename portlibs/sources/{libext2fs => libcustomext2fs}/source/ext2dir.c (100%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/ext2dir.h (100%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/ext2file.c (96%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/ext2file.h (100%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/ext2fs.h (90%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/ext2fsP.h (97%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/ext3_extents.h (100%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/ext_attr.c (97%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/extent.c (99%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/fiemap.h (100%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/fileio.c (87%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/finddev.c (96%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/flushb.c (93%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/freefs.c (94%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/gekko_io.c (89%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/gekko_io.h (98%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/gen_bitmap.c (99%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/gen_bitmap64.c (90%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/get_pathname.c (99%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/getsectsize.c (88%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/getsize.c (96%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/i_block.c (94%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/icount.c (97%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/imager.c (99%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/ind_block.c (98%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/initialize.c (85%) create mode 100644 portlibs/sources/libcustomext2fs/source/inline.c rename portlibs/sources/{libext2fs => libcustomext2fs}/source/inode.c (99%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/inode_io.c (99%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/io_manager.c (99%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/irel.h (100%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/irel_ma.c (99%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/ismounted.c (99%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/jfs_compat.h (100%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/jfs_dat.h (100%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/jfs_user.h (100%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/kernel-jbd.h (100%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/kernel-list.h (100%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/link.c (96%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/llseek.c (99%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/lookup.c (98%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/mem2.h (100%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/mem_allocate.h (77%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/mkdir.c (85%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/mkjournal.c (86%) create mode 100644 portlibs/sources/libcustomext2fs/source/mmp.c rename portlibs/sources/{libext2fs => libcustomext2fs}/source/namei.c (98%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/native.c (95%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/newdir.c (98%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/openfs.c (88%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/partitions.h (100%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/progress.c (96%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/punch.c (97%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/read_bb.c (99%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/read_bb_file.c (99%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/res_gdt.c (92%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/rw_bitmaps.c (90%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/sparse.c (98%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/swapfs.c (85%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/tdb.c (99%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/tdb.h (99%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/unlink.c (98%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/valid_blk.c (86%) rename portlibs/sources/{libext2fs => libcustomext2fs}/source/version.c (87%) create mode 100644 portlibs/sources/libcustomext2fs/source/version.h rename portlibs/sources/{libext2fs => libcustomext2fs}/source/write_bb_file.c (97%) create mode 100644 portlibs/sources/libcustomfat/Makefile rename portlibs/sources/{libfat => libcustomfat/include}/fat.h (99%) rename portlibs/sources/{libfat => libcustomfat/include}/libfatversion.h (65%) create mode 100644 portlibs/sources/libcustomfat/libfat.pnproj create mode 100644 portlibs/sources/libcustomfat/libfat.pnps create mode 100644 portlibs/sources/libcustomfat/libogc/Makefile create mode 100644 portlibs/sources/libcustomfat/libogc/include/fat.h rename portlibs/sources/{libfat => libcustomfat/source}/bit_ops.h (100%) rename portlibs/sources/{libfat => libcustomfat/source}/cache.c (100%) rename portlibs/sources/{libfat => libcustomfat/source}/cache.h (100%) rename portlibs/sources/{libfat => libcustomfat/source}/common.h (100%) rename portlibs/sources/{libfat => libcustomfat/source}/directory.c (98%) rename portlibs/sources/{libfat => libcustomfat/source}/directory.h (97%) rename portlibs/sources/{libfat => libcustomfat/source}/disc.c (100%) rename portlibs/sources/{libfat => libcustomfat/source}/disc.h (100%) rename portlibs/sources/{libfat => libcustomfat/source}/fatdir.c (98%) rename portlibs/sources/{libfat => libcustomfat/source}/fatdir.h (100%) rename portlibs/sources/{libfat => libcustomfat/source}/fatfile.c (97%) rename portlibs/sources/{libfat => libcustomfat/source}/fatfile.h (100%) rename portlibs/sources/{libfat => libcustomfat/source}/fatfile_frag.c (100%) rename portlibs/sources/{libfat => libcustomfat/source}/fatfile_frag.h (100%) rename portlibs/sources/{libfat => libcustomfat/source}/file_allocation_table.c (97%) rename portlibs/sources/{libfat => libcustomfat/source}/file_allocation_table.h (100%) rename portlibs/sources/{libfat => libcustomfat/source}/filetime.c (100%) rename portlibs/sources/{libfat => libcustomfat/source}/filetime.h (100%) rename portlibs/sources/{libfat => libcustomfat/source}/libfat.c (100%) rename portlibs/sources/{libfat => libcustomfat/source}/lock.c (100%) rename portlibs/sources/{libfat => libcustomfat/source}/lock.h (100%) rename portlibs/sources/{libfat => libcustomfat/source}/mem2.h (100%) rename portlibs/sources/{libfat => libcustomfat/source}/mem_allocate.h (100%) rename portlibs/sources/{libfat => libcustomfat/source}/partition.c (72%) rename portlibs/sources/{libfat => libcustomfat/source}/partition.h (100%) create mode 100644 portlibs/sources/libcustomntfs/AUTHORS create mode 100644 portlibs/sources/libcustomntfs/CREDITS create mode 100644 portlibs/sources/libcustomntfs/LICENSE rename portlibs/sources/{libext2fs => libcustomntfs}/Makefile (50%) create mode 100644 portlibs/sources/libcustomntfs/READMII create mode 100644 portlibs/sources/libcustomntfs/include/ntfs.h create mode 100644 portlibs/sources/libcustomntfs/source/Makefile rename portlibs/sources/{libntfs => libcustomntfs/source}/acls.c (99%) rename portlibs/sources/{libntfs => libcustomntfs/source}/acls.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/attrib.c (99%) rename portlibs/sources/{libntfs => libcustomntfs/source}/attrib.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/attrib_frag.c (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/attrlist.c (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/attrlist.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/bit_ops.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/bitmap.c (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/bitmap.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/bootsect.c (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/bootsect.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/cache.c (99%) rename portlibs/sources/{libntfs => libcustomntfs/source}/cache.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/cache2.c (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/cache2.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/collate.c (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/collate.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/compat.c (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/compat.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/compress.c (88%) rename portlibs/sources/{libntfs => libcustomntfs/source}/compress.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/config.h (97%) rename portlibs/sources/{libntfs => libcustomntfs/source}/debug.c (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/debug.h (96%) rename portlibs/sources/{libntfs => libcustomntfs/source}/device.c (94%) rename portlibs/sources/{libntfs => libcustomntfs/source}/device.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/device_io.c (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/device_io.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/dir.c (99%) rename portlibs/sources/{libntfs => libcustomntfs/source}/dir.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/efs.c (99%) rename portlibs/sources/{libntfs => libcustomntfs/source}/efs.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/endians.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/gekko_io.c (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/gekko_io.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/index.c (97%) rename portlibs/sources/{libntfs => libcustomntfs/source}/index.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/inode.c (96%) rename portlibs/sources/{libntfs => libcustomntfs/source}/inode.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/layout.h (99%) rename portlibs/sources/{libntfs => libcustomntfs/source}/lcnalloc.c (92%) rename portlibs/sources/{libntfs => libcustomntfs/source}/lcnalloc.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/logfile.c (99%) rename portlibs/sources/{libntfs => libcustomntfs/source}/logfile.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/logging.c (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/logging.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/mem2.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/mem_allocate.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/mft.c (99%) rename portlibs/sources/{libntfs => libcustomntfs/source}/mft.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/misc.c (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/misc.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/mst.c (94%) rename portlibs/sources/{libntfs => libcustomntfs/source}/mst.h (92%) rename portlibs/sources/{libntfs => libcustomntfs/source}/ntfs.c (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/ntfs.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/ntfsdir.c (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/ntfsdir.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/ntfsfile.c (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/ntfsfile.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/ntfsfile_frag.c (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/ntfsfile_frag.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/ntfsinternal.c (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/ntfsinternal.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/ntfstime.h (94%) rename portlibs/sources/{libntfs => libcustomntfs/source}/object_id.c (99%) rename portlibs/sources/{libntfs => libcustomntfs/source}/object_id.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/param.h (86%) create mode 100644 portlibs/sources/libcustomntfs/source/realpath.c create mode 100644 portlibs/sources/libcustomntfs/source/realpath.h rename portlibs/sources/{libntfs => libcustomntfs/source}/reparse.c (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/reparse.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/runlist.c (99%) rename portlibs/sources/{libntfs => libcustomntfs/source}/runlist.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/security.c (99%) rename portlibs/sources/{libntfs => libcustomntfs/source}/security.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/support.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/types.h (99%) rename portlibs/sources/{libntfs => libcustomntfs/source}/unistr.c (98%) rename portlibs/sources/{libntfs => libcustomntfs/source}/unistr.h (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/volume.c (94%) rename portlibs/sources/{libntfs => libcustomntfs/source}/volume.h (97%) rename portlibs/sources/{libntfs => libcustomntfs/source}/xattrs.c (100%) rename portlibs/sources/{libntfs => libcustomntfs/source}/xattrs.h (100%) delete mode 100644 portlibs/sources/libext2fs/source/config.h delete mode 100644 portlibs/sources/libext2fs/source/ext2_err.h delete mode 100644 portlibs/sources/libext2fs/source/ext2_types.h delete mode 100644 portlibs/sources/libext2fs/source/inline.c delete mode 100644 portlibs/sources/libfat/Makefile delete mode 100644 portlibs/sources/libntfs/Makefile diff --git a/Makefile b/Makefile index 0aa924fd..81b706e3 100644 --- a/Makefile +++ b/Makefile @@ -78,7 +78,7 @@ LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map,--section-start,.init=0x80A00 #--------------------------------------------------------------------------------- # any extra libraries we wish to link with the project #--------------------------------------------------------------------------------- -LIBS := -lpng -lm -lz -lwiiuse -lbte -lasnd -logc -lfreetype -lvorbisidec -lmad -ljpeg -lwiilight -lntfs -lfat -lext2fs -lmodplay +LIBS := -lcustomfat -lcustomntfs -lcustomext2fs -lpng -lm -lz -lwiiuse -lbte -lasnd -logc -lfreetype -lvorbisidec -lmad -ljpeg -lwiilight -lmodplay #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing diff --git a/portlibs/include/ext2.h b/portlibs/include/ext2.h index 059e18be..7b6bc868 100644 --- a/portlibs/include/ext2.h +++ b/portlibs/include/ext2.h @@ -1,22 +1,22 @@ - /** - * ext2.h - devoptab file routines for EXT2/3/4-based devices. - * - * Copyright (c) 2010 Dimok - * - * This program/include file 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. - * - * This program/include file 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ +/******************************************************************************** + * ext2.h - devoptab file routines for EXT2/3/4-based devices. * + * * + * Copyright (c) 2010 Dimok * + * * + * This program/include file 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. * + * * + * This program/include file 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + ********************************************************************************/ #ifndef __EXT2_H_ #define __EXT2_H_ @@ -28,17 +28,24 @@ extern "C" { #include #include -/* EXT2 cache options */ -#define CACHE_DEFAULT_PAGE_COUNT 8 /* The default number of pages in the cache */ -#define CACHE_DEFAULT_PAGE_SIZE 128 /* The default number of sectors per cache page */ +/** + * EXT2 cache options + * + * It is recommended to use more pages instead of large page sizes for cache due to the sporadic write behaviour of ext file system. + * It will significantly increase the speed. A page size of 32 is mostly suffiecient. The larger the page count the faster the + * read/write between smaller files will be. Larger page sizes result in faster read/write of single big files. + */ +#define EXT2_CACHE_DEFAULT_PAGE_COUNT 64 /* The default number of pages in the cache */ +#define EXT2_CACHE_DEFAULT_PAGE_SIZE 32 /* The default number of sectors per cache page */ /* EXT2 mount flags */ -#define EXT2_FLAG_RW 0x00001 /* Open the filesystem for reading and writing. Without this flag, the filesystem is opened for reading only. */ -#define EXT2_FLAG_FORCE 0x00400 /* Open the filesystem regardless of the feature sets listed in the superblock */ -#define EXT2_FLAG_JOURNAL_DEV_OK 0x01000 /* Only open external journal devices if this flag is set (e.g. ext3/ext4) */ -#define EXT2_FLAG_64BITS 0x20000 /* Use the new style 64-Bit bitmaps. For more information see gen_bitmap64.c */ -#define EXT2_FLAG_PRINT_PROGRESS 0x40000 /* If this flag is set the progress of file operations will be printed to stdout */ -#define EXT2_FLAG_DEFAULT (EXT2_FLAG_RW | EXT2_FLAG_64BITS | EXT2_FLAG_JOURNAL_DEV_OK) +#define EXT2_FLAG_RW 0x00001 /* Open the filesystem for reading and writing. Without this flag, the filesystem is opened for reading only. */ +#define EXT2_FLAG_FORCE 0x00400 /* Open the filesystem regardless of the feature sets listed in the superblock */ +#define EXT2_FLAG_JOURNAL_DEV_OK 0x01000 /* Only open external journal devices if this flag is set (e.g. ext3/ext4) */ +#define EXT2_FLAG_64BITS 0x20000 /* Use the new style 64-Bit bitmaps. For more information see gen_bitmap64.c */ +#define EXT2_FLAG_PRINT_PROGRESS 0x40000 /* If this flag is set the progress of file operations will be printed to stdout */ +#define EXT2_FLAG_SKIP_MMP 0x100000 /* Open without multi-mount protection check. */ +#define EXT2_FLAG_DEFAULT (EXT2_FLAG_RW | EXT2_FLAG_64BITS | EXT2_FLAG_JOURNAL_DEV_OK | EXT2_FLAG_SKIP_MMP) /** * Find all EXT2/3/4 partitions on a block device. diff --git a/portlibs/include/fat.h b/portlibs/include/fat.h index 82c973d3..b0ffc13a 100644 --- a/portlibs/include/fat.h +++ b/portlibs/include/fat.h @@ -1,7 +1,7 @@ /* fat.h Simple functionality for startup, mounting and unmounting of FAT-based devices. - + Copyright (c) 2006 - 2009 Michael "Chishm" Chisholm Dave "WinterMute" Murphy @@ -71,7 +71,7 @@ extern bool fatInitDefault (void); /* Mount the device pointed to by interface, and set up a devoptab entry for it as "name:". You can then access the filesystem using "name:/". -This will mount the active partition or the first valid partition on the disc, +This will mount the active partition or the first valid partition on the disc, and will use a cache size optimized for the host system. */ extern bool fatMountSimple (const char* name, const DISC_INTERFACE* interface); diff --git a/portlibs/include/ntfs.h b/portlibs/include/ntfs.h index 22474232..62f2f719 100644 --- a/portlibs/include/ntfs.h +++ b/portlibs/include/ntfs.h @@ -1,6 +1,7 @@ /** * ntfs.h - Simple functionality for startup, mounting and unmounting of NTFS-based devices. * + * Copyright (c) 2010 Dimok * Copyright (c) 2009 Rhys "Shareese" Koedijk * Copyright (c) 2006 Michael "Chishm" Chisholm * diff --git a/portlibs/lib/libext2fs.a b/portlibs/lib/libext2fs.a deleted file mode 100644 index adc7df355ce4bbe5ecfb1f36a04d05818cb4bc5c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 448290 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 O;&SmqZVBRMVE#W)iw6n- diff --git a/portlibs/lib/libfat.a b/portlibs/lib/libfat.a deleted file mode 100644 index a96633389ec1549d948d31ebd25c9554bf8f794c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 76528 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 L-*-mU3(fxriKsl< diff --git a/portlibs/lib/libntfs.a b/portlibs/lib/libntfs.a deleted file mode 100644 index b55d8fd4c3cc309670f5aa3dd098d496d83def9e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 558826 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

r`%^KoyyJYwu-hOeUrt|JmOXuvvps5&Br8KRB| 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 #include -/* EXT2 cache options */ -#define CACHE_DEFAULT_PAGE_COUNT 8 /* The default number of pages in the cache */ -#define CACHE_DEFAULT_PAGE_SIZE 128 /* The default number of sectors per cache page */ +/** + * EXT2 cache options + * + * It is recommended to use more pages instead of large page sizes for cache due to the sporadic write behaviour of ext file system. + * It will significantly increase the speed. A page size of 32 is mostly suffiecient. The larger the page count the faster the + * read/write between smaller files will be. Larger page sizes result in faster read/write of single big files. + */ +#define EXT2_CACHE_DEFAULT_PAGE_COUNT 64 /* The default number of pages in the cache */ +#define EXT2_CACHE_DEFAULT_PAGE_SIZE 32 /* The default number of sectors per cache page */ /* EXT2 mount flags */ -#define EXT2_FLAG_RW 0x00001 /* Open the filesystem for reading and writing. Without this flag, the filesystem is opened for reading only. */ -#define EXT2_FLAG_FORCE 0x00400 /* Open the filesystem regardless of the feature sets listed in the superblock */ -#define EXT2_FLAG_JOURNAL_DEV_OK 0x01000 /* Only open external journal devices if this flag is set (e.g. ext3/ext4) */ -#define EXT2_FLAG_64BITS 0x20000 /* Use the new style 64-Bit bitmaps. For more information see gen_bitmap64.c */ -#define EXT2_FLAG_PRINT_PROGRESS 0x40000 /* If this flag is set the progress of file operations will be printed to stdout */ -#define EXT2_FLAG_DEFAULT (EXT2_FLAG_RW | EXT2_FLAG_64BITS | EXT2_FLAG_JOURNAL_DEV_OK) +#define EXT2_FLAG_RW 0x00001 /* Open the filesystem for reading and writing. Without this flag, the filesystem is opened for reading only. */ +#define EXT2_FLAG_FORCE 0x00400 /* Open the filesystem regardless of the feature sets listed in the superblock */ +#define EXT2_FLAG_JOURNAL_DEV_OK 0x01000 /* Only open external journal devices if this flag is set (e.g. ext3/ext4) */ +#define EXT2_FLAG_64BITS 0x20000 /* Use the new style 64-Bit bitmaps. For more information see gen_bitmap64.c */ +#define EXT2_FLAG_PRINT_PROGRESS 0x40000 /* If this flag is set the progress of file operations will be printed to stdout */ +#define EXT2_FLAG_SKIP_MMP 0x100000 /* Open without multi-mount protection check. */ +#define EXT2_FLAG_DEFAULT (EXT2_FLAG_RW | EXT2_FLAG_64BITS | EXT2_FLAG_JOURNAL_DEV_OK | EXT2_FLAG_SKIP_MMP) /** * Find all EXT2/3/4 partitions on a block device. diff --git a/portlibs/sources/libext2fs/source/Makefile b/portlibs/sources/libcustomext2fs/source/Makefile similarity index 91% rename from portlibs/sources/libext2fs/source/Makefile rename to portlibs/sources/libcustomext2fs/source/Makefile index 3f44c911..6c4c348a 100644 --- a/portlibs/sources/libext2fs/source/Makefile +++ b/portlibs/sources/libcustomext2fs/source/Makefile @@ -28,9 +28,7 @@ LIBDIR := ../lib #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -CFLAGS = -O3 -Wall $(MACHDEP) $(INCLUDE) -DGEKKO \ - -DHAVE_UNISTD_H -DHAVE_SYS_STAT_H -DHAVE_SYS_TYPES_H -DHAVE_UTIME_H -DWORDS_BIGENDIAN \ - -DHAVE_ERRNO_H -DHAVE_STRDUP -DHAVE_SYS_RESOURCE_H +CFLAGS = -O2 -Wall -Wno-unused $(MACHDEP) $(INCLUDE) -DGEKKO -DWORDS_BIGENDIAN CXXFLAGS = $(CFLAGS) ASFLAGS := -g export EXT2BIN := $(LIBDIR)/$(PLATFORM)/libext2fs.a @@ -100,14 +98,13 @@ clean: all: $(EXT2BIN) install: - cp ../include/ext2.h ../../../include - cp ext2_frag.h ../../../include - cp ../lib/wii/libext2fs.a ../../../lib + cp ../include/ext2.h $(DEVKITPRO)/libogc/include + cp ../lib/wii/libext2fs.a $(DEVKITPRO)/libogc/lib/wii + cp ../lib/cube/libext2fs.a $(DEVKITPRO)/libogc/lib/cube wii-install: - cp ../include/ext2.h ../../../include - cp ext2_frag.h ../../../include - cp ../lib/wii/libext2fs.a ../../../lib + cp ../include/ext2.h $(DEVKITPRO)/libogc/include + cp ../lib/wii/libext2fs.a $(DEVKITPRO)/libogc/lib/wii #--------------------------------------------------------------------------------- else diff --git a/portlibs/sources/libext2fs/source/alloc.c b/portlibs/sources/libcustomext2fs/source/alloc.c similarity index 93% rename from portlibs/sources/libext2fs/source/alloc.c rename to portlibs/sources/libcustomext2fs/source/alloc.c index 3a8f3328..948a0ecb 100644 --- a/portlibs/sources/libext2fs/source/alloc.c +++ b/portlibs/sources/libcustomext2fs/source/alloc.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #if HAVE_UNISTD_H #include @@ -52,6 +53,11 @@ static void check_block_uninit(ext2_filsys fs, ext2fs_block_bitmap map, else old_desc_blocks = fs->desc_blocks + fs->super->s_reserved_gdt_blocks; + for (i=0; i < fs->super->s_blocks_per_group; i++, blk++) + ext2fs_fast_unmark_block_bitmap2(map, blk); + + blk = (group * fs->super->s_blocks_per_group) + + fs->super->s_first_data_block; for (i=0; i < fs->super->s_blocks_per_group; i++, blk++) { if ((blk == super_blk) || (old_desc_blk && old_desc_blocks && @@ -64,8 +70,6 @@ static void check_block_uninit(ext2_filsys fs, ext2fs_block_bitmap map, (blk < ext2fs_inode_table_loc(fs, group) + fs->inode_blocks_per_group))) ext2fs_fast_mark_block_bitmap2(map, blk); - else - ext2fs_fast_unmark_block_bitmap2(map, blk); } ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT); ext2fs_group_desc_csum_set(fs, group); @@ -149,6 +153,7 @@ errcode_t ext2fs_new_block2(ext2_filsys fs, blk64_t goal, ext2fs_block_bitmap map, blk64_t *ret) { blk64_t i; + int c_ratio; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); @@ -159,6 +164,9 @@ errcode_t ext2fs_new_block2(ext2_filsys fs, blk64_t goal, if (!goal || (goal >= ext2fs_blocks_count(fs->super))) goal = fs->super->s_first_data_block; i = goal; + c_ratio = 1 << ext2fs_get_bitmap_granularity(map); + if (c_ratio > 1) + goal &= ~EXT2FS_CLUSTER_MASK(fs); check_block_uninit(fs, map, (i - fs->super->s_first_data_block) / EXT2_BLOCKS_PER_GROUP(fs->super)); @@ -173,7 +181,7 @@ errcode_t ext2fs_new_block2(ext2_filsys fs, blk64_t goal, *ret = i; return 0; } - i++; + i = (i + c_ratio) & ~(c_ratio - 1); if (i >= ext2fs_blocks_count(fs->super)) i = fs->super->s_first_data_block; } while (i != goal); @@ -254,6 +262,7 @@ errcode_t ext2fs_get_free_blocks2(ext2_filsys fs, blk64_t start, blk64_t finish, int num, ext2fs_block_bitmap map, blk64_t *ret) { blk64_t b = start; + int c_ratio; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); @@ -267,6 +276,9 @@ errcode_t ext2fs_get_free_blocks2(ext2_filsys fs, blk64_t start, blk64_t finish, finish = start; if (!num) num = 1; + c_ratio = 1 << ext2fs_get_bitmap_granularity(map); + b &= ~(c_ratio - 1); + finish &= ~(c_ratio -1); do { if (b+num-1 > ext2fs_blocks_count(fs->super)) b = fs->super->s_first_data_block; @@ -274,7 +286,7 @@ errcode_t ext2fs_get_free_blocks2(ext2_filsys fs, blk64_t start, blk64_t finish, *ret = b; return 0; } - b++; + b += c_ratio; } while (b != finish); return EXT2_ET_BLOCK_ALLOC_FAIL; } diff --git a/portlibs/sources/libext2fs/source/alloc_sb.c b/portlibs/sources/libcustomext2fs/source/alloc_sb.c similarity index 89% rename from portlibs/sources/libext2fs/source/alloc_sb.c rename to portlibs/sources/libcustomext2fs/source/alloc_sb.c index d5fca3b2..0d1c0000 100644 --- a/portlibs/sources/libext2fs/source/alloc_sb.c +++ b/portlibs/sources/libcustomext2fs/source/alloc_sb.c @@ -10,6 +10,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -59,6 +60,9 @@ int ext2fs_reserve_super_and_bgd(ext2_filsys fs, if (super_blk || (group == 0)) ext2fs_mark_block_bitmap2(bmap, super_blk); + if ((group == 0) && (fs->blocksize == 1024) && + EXT2FS_CLUSTER_RATIO(fs) > 1) + ext2fs_mark_block_bitmap2(bmap, 0); if (old_desc_blk) { if (fs->super->s_reserved_gdt_blocks && fs->block_map == bmap) @@ -71,15 +75,7 @@ int ext2fs_reserve_super_and_bgd(ext2_filsys fs, if (new_desc_blk) ext2fs_mark_block_bitmap2(bmap, new_desc_blk); - if (group == fs->group_desc_count-1) { - num_blocks = (ext2fs_blocks_count(fs->super) - - fs->super->s_first_data_block) % - fs->super->s_blocks_per_group; - if (!num_blocks) - num_blocks = fs->super->s_blocks_per_group; - } else - num_blocks = fs->super->s_blocks_per_group; - + num_blocks = ext2fs_group_blocks_count(fs, group); num_blocks -= 2 + fs->inode_blocks_per_group + used_blks; return num_blocks ; diff --git a/portlibs/sources/libext2fs/source/alloc_stats.c b/portlibs/sources/libcustomext2fs/source/alloc_stats.c similarity index 96% rename from portlibs/sources/libext2fs/source/alloc_stats.c rename to portlibs/sources/libcustomext2fs/source/alloc_stats.c index 0f276659..adec3636 100644 --- a/portlibs/sources/libext2fs/source/alloc_stats.c +++ b/portlibs/sources/libcustomext2fs/source/alloc_stats.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include "ext2_fs.h" @@ -77,7 +78,8 @@ void ext2fs_block_alloc_stats2(ext2_filsys fs, blk64_t blk, int inuse) ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT); ext2fs_group_desc_csum_set(fs, group); - ext2fs_free_blocks_count_add(fs->super, -inuse); + ext2fs_free_blocks_count_add(fs->super, + -inuse * EXT2FS_CLUSTER_RATIO(fs)); ext2fs_mark_super_dirty(fs); ext2fs_mark_bb_dirty(fs); if (fs->block_alloc_stats) diff --git a/portlibs/sources/libext2fs/source/alloc_tables.c b/portlibs/sources/libcustomext2fs/source/alloc_tables.c similarity index 81% rename from portlibs/sources/libext2fs/source/alloc_tables.c rename to portlibs/sources/libcustomext2fs/source/alloc_tables.c index 1c4532b6..9f3d4e04 100644 --- a/portlibs/sources/libext2fs/source/alloc_tables.c +++ b/portlibs/sources/libcustomext2fs/source/alloc_tables.c @@ -10,6 +10,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -35,45 +36,45 @@ * tables can be allocated continously and in order. */ static blk64_t flexbg_offset(ext2_filsys fs, dgrp_t group, blk64_t start_blk, - ext2fs_block_bitmap bmap, int offset, int size, + ext2fs_block_bitmap bmap, int rem_grp, int elem_size) { - int flexbg, flexbg_size; + int flexbg, flexbg_size, size; blk64_t last_blk, first_free = 0; dgrp_t last_grp; flexbg_size = 1 << fs->super->s_log_groups_per_flex; flexbg = group / flexbg_size; + size = rem_grp * elem_size; if (size > (int) (fs->super->s_blocks_per_group / 8)) size = (int) fs->super->s_blocks_per_group / 8; - if (offset) - offset -= 1; - /* * Don't do a long search if the previous block * search is still valid. */ - if (start_blk && group % flexbg_size) { - if (ext2fs_test_block_bitmap_range2(bmap, start_blk + elem_size, - size)) - return start_blk + elem_size; - } + if (start_blk && ext2fs_test_block_bitmap_range2(bmap, start_blk, + elem_size)) + return start_blk; start_blk = ext2fs_group_first_block2(fs, flexbg_size * flexbg); last_grp = group | (flexbg_size - 1); - if (last_grp > fs->group_desc_count) - last_grp = fs->group_desc_count; + if (last_grp > fs->group_desc_count-1) + last_grp = fs->group_desc_count-1; last_blk = ext2fs_group_last_block2(fs, last_grp); /* Find the first available block */ - if (ext2fs_get_free_blocks2(fs, start_blk, last_blk, 1, bmap, - &first_free)) + if (ext2fs_get_free_blocks2(fs, start_blk, last_blk, size, + bmap, &first_free) == 0) return first_free; - if (ext2fs_get_free_blocks2(fs, first_free + offset, last_blk, size, - bmap, &first_free)) + if (ext2fs_get_free_blocks2(fs, start_blk, last_blk, elem_size, + bmap, &first_free) == 0) + return first_free; + + if (ext2fs_get_free_blocks2(fs, 0, last_blk, elem_size, bmap, + &first_free) == 0) return first_free; return first_free; @@ -82,10 +83,11 @@ static blk64_t flexbg_offset(ext2_filsys fs, dgrp_t group, blk64_t start_blk, errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group, ext2fs_block_bitmap bmap) { + unsigned int j; errcode_t retval; blk64_t group_blk, start_blk, last_blk, new_blk, blk; dgrp_t last_grp = 0; - int j, rem_grps = 0, flexbg_size = 0; + int rem_grps = 0, flexbg_size = 0; group_blk = ext2fs_group_first_block2(fs, group); last_blk = ext2fs_group_last_block2(fs, group); @@ -98,9 +100,9 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group, fs->super->s_log_groups_per_flex) { flexbg_size = 1 << fs->super->s_log_groups_per_flex; last_grp = group | (flexbg_size - 1); - rem_grps = last_grp - group; - if (last_grp > fs->group_desc_count) - last_grp = fs->group_desc_count; + if (last_grp > fs->group_desc_count-1) + last_grp = fs->group_desc_count-1; + rem_grps = last_grp - group + 1; } /* @@ -122,10 +124,10 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group, if (flexbg_size) { blk64_t prev_block = 0; - if (group && ext2fs_block_bitmap_loc(fs, group - 1)) - prev_block = ext2fs_block_bitmap_loc(fs, group - 1); + if (group % flexbg_size) + prev_block = ext2fs_block_bitmap_loc(fs, group - 1) + 1; start_blk = flexbg_offset(fs, group, prev_block, bmap, - 0, rem_grps, 1); + rem_grps, 1); last_blk = ext2fs_group_last_block2(fs, last_grp); } @@ -150,10 +152,13 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group, if (flexbg_size) { blk64_t prev_block = 0; - if (group && ext2fs_inode_bitmap_loc(fs, group - 1)) - prev_block = ext2fs_inode_bitmap_loc(fs, group - 1); + if (group % flexbg_size) + prev_block = ext2fs_inode_bitmap_loc(fs, group - 1) + 1; + else + prev_block = ext2fs_block_bitmap_loc(fs, group) + + flexbg_size; start_blk = flexbg_offset(fs, group, prev_block, bmap, - flexbg_size, rem_grps, 1); + rem_grps, 1); last_blk = ext2fs_group_last_block2(fs, last_grp); } @@ -181,15 +186,16 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group, */ if (flexbg_size) { blk64_t prev_block = 0; - if (group && ext2fs_inode_table_loc(fs, group - 1)) - prev_block = ext2fs_inode_table_loc(fs, group - 1); - if (last_grp == fs->group_desc_count) - rem_grps = last_grp - group; + + if (group % flexbg_size) + prev_block = ext2fs_inode_table_loc(fs, group - 1) + + fs->inode_blocks_per_group; + else + prev_block = ext2fs_inode_bitmap_loc(fs, group) + + flexbg_size; + group_blk = flexbg_offset(fs, group, prev_block, bmap, - flexbg_size * 2, - fs->inode_blocks_per_group * - rem_grps, - fs->inode_blocks_per_group); + rem_grps, fs->inode_blocks_per_group); last_blk = ext2fs_group_last_block2(fs, last_grp); } diff --git a/portlibs/sources/libext2fs/source/badblocks.c b/portlibs/sources/libcustomext2fs/source/badblocks.c similarity index 99% rename from portlibs/sources/libext2fs/source/badblocks.c rename to portlibs/sources/libcustomext2fs/source/badblocks.c index 5eb28b78..0f23983b 100644 --- a/portlibs/sources/libext2fs/source/badblocks.c +++ b/portlibs/sources/libcustomext2fs/source/badblocks.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -177,7 +178,7 @@ int ext2fs_u32_list_find(ext2_u32_list bb, __u32 blk) return high; while (low < high) { - mid = (low+high)/2; + mid = ((unsigned)low + (unsigned)high)/2; if (mid == low || mid == high) break; if (blk == bb->list[mid]) diff --git a/portlibs/sources/libext2fs/source/bb_compat.c b/portlibs/sources/libcustomext2fs/source/bb_compat.c similarity index 98% rename from portlibs/sources/libext2fs/source/bb_compat.c rename to portlibs/sources/libcustomext2fs/source/bb_compat.c index a94e3e48..373792a2 100644 --- a/portlibs/sources/libext2fs/source/bb_compat.c +++ b/portlibs/sources/libcustomext2fs/source/bb_compat.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H diff --git a/portlibs/sources/libext2fs/source/bb_inode.c b/portlibs/sources/libcustomext2fs/source/bb_inode.c similarity index 99% rename from portlibs/sources/libext2fs/source/bb_inode.c rename to portlibs/sources/libcustomext2fs/source/bb_inode.c index 0b6c3dd2..268eecf8 100644 --- a/portlibs/sources/libext2fs/source/bb_inode.c +++ b/portlibs/sources/libcustomext2fs/source/bb_inode.c @@ -13,6 +13,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H diff --git a/portlibs/sources/libext2fs/source/bit_ops.h b/portlibs/sources/libcustomext2fs/source/bit_ops.h similarity index 100% rename from portlibs/sources/libext2fs/source/bit_ops.h rename to portlibs/sources/libcustomext2fs/source/bit_ops.h diff --git a/portlibs/sources/libext2fs/source/bitmaps.c b/portlibs/sources/libcustomext2fs/source/bitmaps.c similarity index 82% rename from portlibs/sources/libext2fs/source/bitmaps.c rename to portlibs/sources/libcustomext2fs/source/bitmaps.c index c53d61ec..e518295d 100644 --- a/portlibs/sources/libext2fs/source/bitmaps.c +++ b/portlibs/sources/libcustomext2fs/source/bitmaps.c @@ -10,6 +10,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -27,6 +28,7 @@ #include "ext2_fs.h" #include "ext2fs.h" #include "ext2fsP.h" +#include "bmap64.h" void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap) { @@ -90,9 +92,9 @@ errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs, fs->write_bitmaps = ext2fs_write_bitmaps; - start = fs->super->s_first_data_block; - end = ext2fs_blocks_count(fs->super)-1; - real_end = ((__u64) EXT2_BLOCKS_PER_GROUP(fs->super) + start = EXT2FS_B2C(fs, fs->super->s_first_data_block); + end = EXT2FS_B2C(fs, ext2fs_blocks_count(fs->super)-1); + real_end = ((__u64) EXT2_CLUSTERS_PER_GROUP(fs->super) * (__u64) fs->group_desc_count)-1 + start; if (fs->flags & EXT2_FLAG_64BITS) @@ -110,6 +112,56 @@ errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs, (ext2fs_generic_bitmap *) ret)); } +/* + * ext2fs_allocate_block_bitmap() really allocates a per-cluster + * bitmap for backwards compatibility. This function allocates a + * block bitmap which is truly per-block, even if clusters/bigalloc + * are enabled. mke2fs and e2fsck need this for tracking the + * allocation of the file system metadata blocks. + */ +errcode_t ext2fs_allocate_subcluster_bitmap(ext2_filsys fs, + const char *descr, + ext2fs_block_bitmap *ret) +{ + __u64 start, end, real_end; + ext2fs_generic_bitmap bmap; + errcode_t retval; + + EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); + + fs->write_bitmaps = ext2fs_write_bitmaps; + + if (!fs->cluster_ratio_bits) + return ext2fs_allocate_block_bitmap(fs, descr, ret); + + if ((fs->flags & EXT2_FLAG_64BITS) == 0) + return EXT2_ET_CANT_USE_LEGACY_BITMAPS; + + start = fs->super->s_first_data_block; + end = ext2fs_blocks_count(fs->super)-1; + real_end = ((__u64) EXT2_BLOCKS_PER_GROUP(fs->super) + * (__u64) fs->group_desc_count)-1 + start; + + retval = ext2fs_alloc_generic_bmap(fs, EXT2_ET_MAGIC_BLOCK_BITMAP64, + EXT2FS_BMAP64_BITARRAY, start, + end, real_end, descr, &bmap); + if (retval) + return retval; + bmap->cluster_bits = 0; + *ret = bmap; + return 0; +} + +int ext2fs_get_bitmap_granularity(ext2fs_block_bitmap bitmap) +{ + ext2fs_generic_bitmap bmap = bitmap; + + if (!EXT2FS_IS_64_BITMAP(bmap)) + return 0; + + return bmap->cluster_bits; +} + errcode_t ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap, ext2_ino_t end, ext2_ino_t *oend) { diff --git a/portlibs/sources/libext2fs/source/bitops.c b/portlibs/sources/libcustomext2fs/source/bitops.c similarity index 99% rename from portlibs/sources/libext2fs/source/bitops.c rename to portlibs/sources/libcustomext2fs/source/bitops.c index a3f72c31..9322a353 100644 --- a/portlibs/sources/libext2fs/source/bitops.c +++ b/portlibs/sources/libcustomext2fs/source/bitops.c @@ -10,6 +10,7 @@ * %End-Header% */ +#include "config.h" #include #if HAVE_SYS_TYPES_H #include diff --git a/portlibs/sources/libext2fs/source/bitops.h b/portlibs/sources/libcustomext2fs/source/bitops.h similarity index 98% rename from portlibs/sources/libext2fs/source/bitops.h rename to portlibs/sources/libcustomext2fs/source/bitops.h index bf6ee82a..a7412833 100644 --- a/portlibs/sources/libext2fs/source/bitops.h +++ b/portlibs/sources/libcustomext2fs/source/bitops.h @@ -12,6 +12,8 @@ #ifndef _BITOPS_H_ #define _BITOPS_H_ +#include "config.h" + extern int ext2fs_set_bit(unsigned int nr,void * addr); extern int ext2fs_clear_bit(unsigned int nr, void * addr); extern int ext2fs_test_bit(unsigned int nr, const void * addr); @@ -33,6 +35,8 @@ extern __u64 ext2fs_swab64(__u64 val); #define ext2fs_le32_to_cpu(x) ext2fs_swab32((x)) #define ext2fs_cpu_to_le16(x) ext2fs_swab16((x)) #define ext2fs_le16_to_cpu(x) ext2fs_swab16((x)) +#define ext2fs_cpu_to_be64(x) ((__u64)(x)) +#define ext2fs_be64_to_cpu(x) ((__u64)(x)) #define ext2fs_cpu_to_be32(x) ((__u32)(x)) #define ext2fs_be32_to_cpu(x) ((__u32)(x)) #define ext2fs_cpu_to_be16(x) ((__u16)(x)) @@ -44,6 +48,8 @@ extern __u64 ext2fs_swab64(__u64 val); #define ext2fs_le32_to_cpu(x) ((__u32)(x)) #define ext2fs_cpu_to_le16(x) ((__u16)(x)) #define ext2fs_le16_to_cpu(x) ((__u16)(x)) +#define ext2fs_cpu_to_be64(x) ext2fs_swab64((x)) +#define ext2fs_be64_to_cpu(x) ext2fs_swab64((x)) #define ext2fs_cpu_to_be32(x) ext2fs_swab32((x)) #define ext2fs_be32_to_cpu(x) ext2fs_swab32((x)) #define ext2fs_cpu_to_be16(x) ext2fs_swab16((x)) @@ -634,5 +640,4 @@ _INLINE_ void ext2fs_fast_unmark_block_bitmap_range2(ext2fs_block_bitmap bitmap, #undef _INLINE_ #endif - #endif diff --git a/portlibs/sources/libext2fs/source/blkmap64_ba.c b/portlibs/sources/libcustomext2fs/source/blkmap64_ba.c similarity index 99% rename from portlibs/sources/libext2fs/source/blkmap64_ba.c rename to portlibs/sources/libcustomext2fs/source/blkmap64_ba.c index 395aba97..9253af20 100644 --- a/portlibs/sources/libext2fs/source/blkmap64_ba.c +++ b/portlibs/sources/libcustomext2fs/source/blkmap64_ba.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H diff --git a/portlibs/sources/libext2fs/source/blknum.c b/portlibs/sources/libcustomext2fs/source/blknum.c similarity index 92% rename from portlibs/sources/libext2fs/source/blknum.c rename to portlibs/sources/libcustomext2fs/source/blknum.c index b3e6dcad..33da7d6f 100644 --- a/portlibs/sources/libext2fs/source/blknum.c +++ b/portlibs/sources/libcustomext2fs/source/blknum.c @@ -11,6 +11,7 @@ * %End-Header% */ +#include "config.h" #include "ext2fs.h" /* @@ -42,6 +43,25 @@ blk64_t ext2fs_group_last_block2(ext2_filsys fs, dgrp_t group) (fs->super->s_blocks_per_group - 1)); } +/* + * Return the number of blocks in a group + */ +int ext2fs_group_blocks_count(ext2_filsys fs, dgrp_t group) +{ + int num_blocks; + + if (group == fs->group_desc_count - 1) { + num_blocks = (ext2fs_blocks_count(fs->super) - + fs->super->s_first_data_block) % + fs->super->s_blocks_per_group; + if (!num_blocks) + num_blocks = fs->super->s_blocks_per_group; + } else + num_blocks = fs->super->s_blocks_per_group; + + return num_blocks; +} + /* * Return the inode data block count */ @@ -455,23 +475,24 @@ void ext2fs_bg_checksum_set(ext2_filsys fs, dgrp_t group, __u16 checksum) /* * Get the acl block of a file - * - * XXX Ignoring 64-bit file system flag - most places where this is - * called don't have access to the fs struct, and the high bits should - * be 0 in the non-64-bit case anyway. */ -blk64_t ext2fs_file_acl_block(const struct ext2_inode *inode) +blk64_t ext2fs_file_acl_block(ext2_filsys fs, const struct ext2_inode *inode) { - return (inode->i_file_acl | - (__u64) inode->osd2.linux2.l_i_file_acl_high << 32); + blk64_t blk = inode->i_file_acl; + + if (fs && fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT) + blk |= ((__u64) inode->osd2.linux2.l_i_file_acl_high) << 32; + return blk; } /* * Set the acl block of a file */ -void ext2fs_file_acl_block_set(struct ext2_inode *inode, blk64_t blk) +void ext2fs_file_acl_block_set(ext2_filsys fs, struct ext2_inode *inode, + blk64_t blk) { inode->i_file_acl = blk; - inode->osd2.linux2.l_i_file_acl_high = (__u64) blk >> 32; + if (fs && fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT) + inode->osd2.linux2.l_i_file_acl_high = (__u64) blk >> 32; } diff --git a/portlibs/sources/libext2fs/source/block.c b/portlibs/sources/libcustomext2fs/source/block.c similarity index 97% rename from portlibs/sources/libext2fs/source/block.c rename to portlibs/sources/libcustomext2fs/source/block.c index 0e4ec775..6a5c10df 100644 --- a/portlibs/sources/libext2fs/source/block.c +++ b/portlibs/sources/libcustomext2fs/source/block.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -453,6 +454,17 @@ errcode_t ext2fs_block_iterate3(ext2_filsys fs, uninit = 0; if (extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT) uninit = EXT2_EXTENT_SET_BMAP_UNINIT; +#if 0 + printf("lblk %llu pblk %llu len %d blockcnt %llu\n", + extent.e_lblk, extent.e_pblk, + extent.e_len, blockcnt); +#endif + if (extent.e_lblk + extent.e_len <= blockcnt) + continue; + if (extent.e_lblk > blockcnt) + blockcnt = extent.e_lblk; + j = blockcnt - extent.e_lblk; + blk += j; for (blockcnt = extent.e_lblk, j = 0; j < extent.e_len; blk++, blockcnt++, j++) { diff --git a/portlibs/sources/libext2fs/source/bmap.c b/portlibs/sources/libcustomext2fs/source/bmap.c similarity index 70% rename from portlibs/sources/libext2fs/source/bmap.c rename to portlibs/sources/libcustomext2fs/source/bmap.c index fbcb3753..16d51e0b 100644 --- a/portlibs/sources/libext2fs/source/bmap.c +++ b/portlibs/sources/libcustomext2fs/source/bmap.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -129,6 +130,106 @@ static _BMAP_INLINE_ errcode_t block_tind_bmap(ext2_filsys fs, int flags, return retval; } +static errcode_t extent_bmap(ext2_filsys fs, ext2_ino_t ino, + struct ext2_inode *inode, + ext2_extent_handle_t handle, + char *block_buf, int bmap_flags, blk64_t block, + int *ret_flags, int *blocks_alloc, + blk64_t *phys_blk); + +static errcode_t implied_cluster_alloc(ext2_filsys fs, ext2_ino_t ino, + struct ext2_inode *inode, + ext2_extent_handle_t handle, + blk64_t block, blk64_t *phys_blk) +{ + blk64_t base_block, pblock = 0; + int i; + + if (!EXT2_HAS_RO_COMPAT_FEATURE(fs->super, + EXT4_FEATURE_RO_COMPAT_BIGALLOC)) + return 0; + + base_block = block & ~EXT2FS_CLUSTER_MASK(fs); + for (i = 0; i < EXT2FS_CLUSTER_RATIO(fs); i++) { + if (block == base_block) + return 0; + extent_bmap(fs, ino, inode, handle, 0, 0, + base_block + i, 0, 0, &pblock); + if (pblock) + break; + } + if (pblock == 0) + return 0; + *phys_blk = pblock - i + (block - base_block); + return 0; +} + +static errcode_t extent_bmap(ext2_filsys fs, ext2_ino_t ino, + struct ext2_inode *inode, + ext2_extent_handle_t handle, + char *block_buf, int bmap_flags, blk64_t block, + int *ret_flags, int *blocks_alloc, + blk64_t *phys_blk) +{ + struct ext2fs_extent extent; + unsigned int offset; + errcode_t retval = 0; + blk64_t blk64 = 0; + int alloc = 0; + + if (bmap_flags & BMAP_SET) { + retval = ext2fs_extent_set_bmap(handle, block, + *phys_blk, 0); + return retval; + } + retval = ext2fs_extent_goto(handle, block); + if (retval) { + /* If the extent is not found, return phys_blk = 0 */ + if (retval == EXT2_ET_EXTENT_NOT_FOUND) + goto got_block; + return retval; + } + retval = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT, &extent); + if (retval) + return retval; + offset = block - extent.e_lblk; + if (block >= extent.e_lblk && (offset <= extent.e_len)) { + *phys_blk = extent.e_pblk + offset; + if (ret_flags && extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT) + *ret_flags |= BMAP_RET_UNINIT; + } +got_block: + if ((*phys_blk == 0) && (bmap_flags & BMAP_ALLOC)) { + implied_cluster_alloc(fs, ino, inode, handle, block, &blk64); + if (blk64) + goto set_extent; + retval = extent_bmap(fs, ino, inode, handle, block_buf, + 0, block-1, 0, blocks_alloc, &blk64); + if (retval) + blk64 = 0; + retval = ext2fs_alloc_block2(fs, blk64, block_buf, + &blk64); + if (retval) + return retval; + blk64 &= ~EXT2FS_CLUSTER_MASK(fs); + blk64 += EXT2FS_CLUSTER_MASK(fs) & block; + alloc++; + set_extent: + retval = ext2fs_extent_set_bmap(handle, block, + blk64, 0); + if (retval) + return retval; + /* Update inode after setting extent */ + retval = ext2fs_read_inode(fs, ino, inode); + if (retval) + return retval; + *blocks_alloc += alloc; + *phys_blk = blk64; + } + return 0; +} + + errcode_t ext2fs_bmap2(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode, char *block_buf, int bmap_flags, blk64_t block, int *ret_flags, blk64_t *phys_blk) @@ -156,54 +257,6 @@ errcode_t ext2fs_bmap2(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode, } addr_per_block = (blk_t) fs->blocksize >> 2; - if (inode->i_flags & EXT4_EXTENTS_FL) { - struct ext2fs_extent extent; - unsigned int offset; - - retval = ext2fs_extent_open2(fs, ino, inode, &handle); - if (retval) - goto done; - if (bmap_flags & BMAP_SET) { - retval = ext2fs_extent_set_bmap(handle, block, - *phys_blk, 0); - goto done; - } - retval = ext2fs_extent_goto(handle, block); - if (retval) { - /* If the extent is not found, return phys_blk = 0 */ - if (retval == EXT2_ET_EXTENT_NOT_FOUND) - goto got_block; - goto done; - } - retval = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT, &extent); - if (retval) - goto done; - offset = block - extent.e_lblk; - if (block >= extent.e_lblk && (offset <= extent.e_len)) { - *phys_blk = extent.e_pblk + offset; - if (ret_flags && extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT) - *ret_flags |= BMAP_RET_UNINIT; - } - got_block: - if ((*phys_blk == 0) && (bmap_flags & BMAP_ALLOC)) { - retval = ext2fs_alloc_block(fs, b, block_buf, &b); - if (retval) - goto done; - retval = ext2fs_extent_set_bmap(handle, block, - (blk64_t) b, 0); - if (retval) - goto done; - /* Update inode after setting extent */ - retval = ext2fs_read_inode(fs, ino, inode); - if (retval) - return retval; - blocks_alloc++; - *phys_blk = b; - } - retval = 0; - goto done; - } - if (!block_buf) { retval = ext2fs_get_array(2, fs->blocksize, &buf); if (retval) @@ -211,6 +264,16 @@ errcode_t ext2fs_bmap2(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode, block_buf = buf; } + if (inode->i_flags & EXT4_EXTENTS_FL) { + retval = ext2fs_extent_open2(fs, ino, inode, &handle); + if (retval) + goto done; + retval = extent_bmap(fs, ino, inode, handle, block_buf, + bmap_flags, block, ret_flags, + &blocks_alloc, phys_blk); + goto done; + } + if (block < EXT2_NDIR_BLOCKS) { if (bmap_flags & BMAP_SET) { b = *phys_blk; diff --git a/portlibs/sources/libext2fs/source/bmap64.h b/portlibs/sources/libcustomext2fs/source/bmap64.h similarity index 98% rename from portlibs/sources/libext2fs/source/bmap64.h rename to portlibs/sources/libcustomext2fs/source/bmap64.h index b0aa84c1..30565440 100644 --- a/portlibs/sources/libext2fs/source/bmap64.h +++ b/portlibs/sources/libcustomext2fs/source/bmap64.h @@ -16,6 +16,7 @@ struct ext2fs_struct_generic_bitmap { int flags; __u64 start, end; __u64 real_end; + int cluster_bits; char *description; void *private; errcode_t base_error_code; diff --git a/portlibs/sources/libext2fs/source/bmove.c b/portlibs/sources/libcustomext2fs/source/bmove.c similarity index 98% rename from portlibs/sources/libext2fs/source/bmove.c rename to portlibs/sources/libcustomext2fs/source/bmove.c index deabf38c..e2ea405a 100644 --- a/portlibs/sources/libext2fs/source/bmove.c +++ b/portlibs/sources/libcustomext2fs/source/bmove.c @@ -10,6 +10,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -140,7 +141,7 @@ errcode_t ext2fs_move_blocks(ext2_filsys fs, while (ino) { if ((inode.i_links_count == 0) || - !ext2fs_inode_has_valid_blocks(&inode)) + !ext2fs_inode_has_valid_blocks2(fs, &inode)) goto next; pb.ino = ino; diff --git a/portlibs/sources/libext2fs/source/brel.h b/portlibs/sources/libcustomext2fs/source/brel.h similarity index 100% rename from portlibs/sources/libext2fs/source/brel.h rename to portlibs/sources/libcustomext2fs/source/brel.h diff --git a/portlibs/sources/libext2fs/source/brel_ma.c b/portlibs/sources/libcustomext2fs/source/brel_ma.c similarity index 99% rename from portlibs/sources/libext2fs/source/brel_ma.c rename to portlibs/sources/libcustomext2fs/source/brel_ma.c index 1a55702b..e8a8280e 100644 --- a/portlibs/sources/libext2fs/source/brel_ma.c +++ b/portlibs/sources/libcustomext2fs/source/brel_ma.c @@ -12,6 +12,7 @@ * %End-Header% */ +#include "config.h" #include #include #include diff --git a/portlibs/sources/libext2fs/source/check_desc.c b/portlibs/sources/libcustomext2fs/source/check_desc.c similarity index 93% rename from portlibs/sources/libext2fs/source/check_desc.c rename to portlibs/sources/libcustomext2fs/source/check_desc.c index 7929cd95..a6fcc454 100644 --- a/portlibs/sources/libext2fs/source/check_desc.c +++ b/portlibs/sources/libcustomext2fs/source/check_desc.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -37,11 +38,11 @@ errcode_t ext2fs_check_desc(ext2_filsys fs) blk64_t first_block = fs->super->s_first_data_block; blk64_t last_block = ext2fs_blocks_count(fs->super)-1; blk64_t blk, b; - int j; + unsigned int j; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); - retval = ext2fs_allocate_block_bitmap(fs, "check_desc map", &bmap); + retval = ext2fs_allocate_subcluster_bitmap(fs, "check_desc map", &bmap); if (retval) return retval; @@ -53,8 +54,6 @@ errcode_t ext2fs_check_desc(ext2_filsys fs) EXT4_FEATURE_INCOMPAT_FLEX_BG)) { first_block = ext2fs_group_first_block2(fs, i); last_block = ext2fs_group_last_block2(fs, i); - if (i == (fs->group_desc_count - 1)) - last_block = ext2fs_blocks_count(fs->super)-1; } /* diff --git a/portlibs/sources/libext2fs/source/closefs.c b/portlibs/sources/libcustomext2fs/source/closefs.c similarity index 95% rename from portlibs/sources/libext2fs/source/closefs.c rename to portlibs/sources/libcustomext2fs/source/closefs.c index 8242622b..103fca89 100644 --- a/portlibs/sources/libext2fs/source/closefs.c +++ b/portlibs/sources/libcustomext2fs/source/closefs.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #if HAVE_UNISTD_H #include @@ -73,6 +74,8 @@ errcode_t ext2fs_super_and_bgd_loc2(ext2_filsys fs, int has_super; group_block = ext2fs_group_first_block2(fs, group); + if (group_block == 0 && fs->blocksize == 1024) + group_block = 1; /* Deal with 1024 blocksize && bigalloc */ if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) old_desc_blocks = fs->super->s_first_meta_bg; @@ -150,14 +153,7 @@ int ext2fs_super_and_bgd_loc(ext2_filsys fs, &ret_new_desc_blk2, &ret_used_blks); - if (group == fs->group_desc_count-1) { - numblocks = (ext2fs_blocks_count(fs->super) - - (blk64_t) fs->super->s_first_data_block) % - (blk64_t) fs->super->s_blocks_per_group; - if (!numblocks) - numblocks = fs->super->s_blocks_per_group; - } else - numblocks = fs->super->s_blocks_per_group; + numblocks = ext2fs_group_blocks_count(fs, group); if (ret_super_blk) *ret_super_blk = (blk_t)ret_super_blk2; @@ -265,6 +261,11 @@ static errcode_t write_backup_super(ext2_filsys fs, dgrp_t group, } errcode_t ext2fs_flush(ext2_filsys fs) +{ + return ext2fs_flush2(fs, 0); +} + +errcode_t ext2fs_flush2(ext2_filsys fs, int flags) { dgrp_t i; errcode_t retval; @@ -406,14 +407,16 @@ write_primary_superblock_only: ext2fs_swap_super(super_shadow); #endif - retval = io_channel_flush(fs->io); + if (!(flags & EXT2_FLAG_FLUSH_NO_SYNC)) + retval = io_channel_flush(fs->io); retval = write_primary_superblock(fs, super_shadow); if (retval) goto errout; fs->flags &= ~EXT2_FLAG_DIRTY; - retval = io_channel_flush(fs->io); + if (!(flags & EXT2_FLAG_FLUSH_NO_SYNC)) + retval = io_channel_flush(fs->io); errout: fs->super->s_state = fs_state; #ifdef WORDS_BIGENDIAN @@ -426,6 +429,11 @@ errout: } errcode_t ext2fs_close(ext2_filsys fs) +{ + return ext2fs_close2(fs, 0); +} + +errcode_t ext2fs_close2(ext2_filsys fs, int flags) { errcode_t retval; int meta_blks; @@ -451,10 +459,15 @@ errcode_t ext2fs_close(ext2_filsys fs) fs->flags |= EXT2_FLAG_SUPER_ONLY | EXT2_FLAG_DIRTY; } if (fs->flags & EXT2_FLAG_DIRTY) { - retval = ext2fs_flush(fs); + retval = ext2fs_flush2(fs, flags); if (retval) return retval; } + + retval = ext2fs_mmp_stop(fs); + if (retval) + return retval; + ext2fs_free(fs); return 0; } diff --git a/portlibs/sources/libext2fs/source/com_err.c b/portlibs/sources/libcustomext2fs/source/com_err.c similarity index 100% rename from portlibs/sources/libext2fs/source/com_err.c rename to portlibs/sources/libcustomext2fs/source/com_err.c diff --git a/portlibs/sources/libext2fs/source/com_err.h b/portlibs/sources/libcustomext2fs/source/com_err.h similarity index 100% rename from portlibs/sources/libext2fs/source/com_err.h rename to portlibs/sources/libcustomext2fs/source/com_err.h diff --git a/portlibs/sources/libcustomext2fs/source/config.h b/portlibs/sources/libcustomext2fs/source/config.h new file mode 100644 index 00000000..e21896f8 --- /dev/null +++ b/portlibs/sources/libcustomext2fs/source/config.h @@ -0,0 +1,603 @@ +/* lib/config.h. Generated from config.h.in by configure. */ +/* lib/config.h.in. Generated from configure.in by autoheader. */ +#ifndef __CONFIG_H_ +#define __CONFIG_H_ + +/* Define if building universal (internal helper macro) */ +/* #undef AC_APPLE_UNIVERSAL_BUILD */ + +/* Define to 1 if debugging the blkid library */ +/* #undef CONFIG_BLKID_DEBUG */ + +/* Define to 1 to compile findfs */ +/* #undef CONFIG_BUILD_FINDFS 1 */ + +/* Define to 1 if debugging ext3/4 journal code */ +/* #undef CONFIG_JBD_DEBUG */ + +/* Define to 1 if the testio I/O manager should be enabled */ +/* #undef CONFIG_TESTIO_DEBUG 1 */ + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +/* #undef CRAY_STACKSEG_END */ + +/* Define to 1 if using `alloca.c'. */ +/* #undef C_ALLOCA */ + +/* Define to 1 if ext2 compression enabled */ +/* #undef ENABLE_COMPRESSION */ + +/* Define to 1 if ext3/4 htree support enabled */ +#define ENABLE_HTREE 1 + +/* Define to 1 if translation of program messages to the user's native + language is requested. */ +#define ENABLE_NLS 1 + +/* Define to 1 if you have `alloca', as a function or macro. */ +#define HAVE_ALLOCA 1 + +/* Define to 1 if you have and it should be used (not on Ultrix). + */ +#define HAVE_ALLOCA_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ARGZ_H 1 + +/* Define to 1 if you have the `asprintf' function. */ +#define HAVE_ASPRINTF 1 + +/* Define to 1 if you have the `backtrace' function. */ +/* #undef HAVE_BACKTRACE 1 */ + +/* Define to 1 if you have the `blkid_probe_get_topology' function. */ +/* #undef HAVE_BLKID_PROBE_GET_TOPOLOGY */ + +/* Define to 1 if you have the `chflags' function. */ +/* #undef HAVE_CHFLAGS */ + +/* Define if the GNU dcgettext() function is already present or preinstalled. + */ +/* #undef HAVE_DCGETTEXT 1 */ + +/* Define to 1 if you have the declaration of `feof_unlocked', and to 0 if you + don't. */ +/* #undef HAVE_DECL_FEOF_UNLOCKED 1 */ + +/* Define to 1 if you have the declaration of `fgets_unlocked', and to 0 if + you don't. */ +/* #undef HAVE_DECL_FGETS_UNLOCKED 0 */ + +/* Define to 1 if you have the declaration of `getc_unlocked', and to 0 if you + don't. */ +/* #undef HAVE_DECL_GETC_UNLOCKED 1 */ + +/* Define to 1 if you have the declaration of `_snprintf', and to 0 if you + don't. */ +/* #undef HAVE_DECL__SNPRINTF 0 */ + +/* Define to 1 if you have the declaration of `_snwprintf', and to 0 if you + don't. */ +/* #undef HAVE_DECL__SNWPRINTF 0 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_DIRENT_H 1 + +/* Define to 1 if dlopen/libdl exists */ +/* #undef HAVE_DLOPEN 1 */ + +/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ +/* #undef HAVE_DOPRNT */ + +/* Define to 1 if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_EXECINFO_H 1 */ + +/* Define to 1 if Ext2 ioctls present */ +/* #undef HAVE_EXT2_IOCTLS 1 */ + +/* Define to 1 if you have the `fallocate' function. */ +/* #undef HAVE_FALLOCATE 1 */ + +/* Define to 1 if you have the `fallocate64' function. */ +/* #undef HAVE_FALLOCATE64 1 */ + +/* Define to 1 if you have the `fchown' function. */ +/* #undef HAVE_FCHOWN 1 */ + +/* Define to 1 if you have the `fdatasync' function. */ +/* #undef HAVE_FDATASYNC 1 */ + +/* Define to 1 if you have the `fstat64' function. */ +/* #undef HAVE_FSTAT64 1 */ + +/* Define to 1 if you have the `ftruncate64' function. */ +/* #undef HAVE_FTRUNCATE64 1 */ + +/* Define to 1 if you have the `fwprintf' function. */ +/* #undef HAVE_FWPRINTF 1 */ + +/* Define to 1 if you have the `getcwd' function. */ +/* #undef HAVE_GETCWD 1 */ + +/* Define to 1 if you have the `getdtablesize' function. */ +/* #undef HAVE_GETDTABLESIZE 1 */ + +/* Define to 1 if you have the `getegid' function. */ +/* #undef HAVE_GETEGID 1 */ + +/* Define to 1 if you have the `geteuid' function. */ +/* #undef HAVE_GETEUID 1 */ + +/* Define to 1 if you have the `getgid' function. */ +/* #undef HAVE_GETGID 1 */ + +/* Define to 1 if you have the `getmntinfo' function. */ +/* #undef HAVE_GETMNTINFO */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GETOPT_H 1 */ + +/* Define to 1 if you have the `getpagesize' function. */ +/* #undef HAVE_GETPAGESIZE 1 */ + +/* Define to 1 if you have the `getrlimit' function. */ +/* #undef HAVE_GETRLIMIT 1 */ + +/* Define to 1 if you have the `getrusage' function. */ +/* #undef HAVE_GETRUSAGE 1 */ + +/* Define if the GNU gettext() function is already present or preinstalled. */ +/* #undef HAVE_GETTEXT 1 */ + +/* Define to 1 if you have the `getuid' function. */ +/* #undef HAVE_GETUID 1 */ + +/* Define if you have the iconv() function. */ +/* #undef HAVE_ICONV 1 */ + +/* Define if you have the 'intmax_t' type in or . */ +#define HAVE_INTMAX_T 1 + +/* Define to 1 if the system has the type `intptr_t'. */ +#define HAVE_INTPTR_T 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define if exists, doesn't clash with , and + declares uintmax_t. */ +#define HAVE_INTTYPES_H_WITH_UINTMAX 1 + +/* Define to 1 if you have the `jrand48' function. */ +/* #undef HAVE_JRAND48 1 */ + +/* Define if you have and nl_langinfo(CODESET). */ +/* #undef HAVE_LANGINFO_CODESET 1 */ + +/* Define if your file defines LC_MESSAGES. */ +#define HAVE_LC_MESSAGES 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LINUX_FALLOC_H 1 */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LINUX_FD_H 1 */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LINUX_MAJOR_H 1 */ + +/* Define to 1 if you have the `llseek' function. */ +/* #undef HAVE_LLSEEK 1 */ + +/* Define to 1 if llseek declared in unistd.h */ +/* #undef HAVE_LLSEEK_PROTOTYPE */ + +/* Define to 1 if you have the header file. */ +#define HAVE_LOCALE_H 1 + +/* Define if you have the 'long double' type. */ +#define HAVE_LONG_DOUBLE 1 + +/* Define if you have the 'long long' type. */ +#define HAVE_LONG_LONG 1 + +/* Define to 1 if you have the `lseek64' function. */ +/* #undef HAVE_LSEEK64 1 */ + +/* Define to 1 if lseek64 declared in unistd.h */ +#define HAVE_LSEEK64_PROTOTYPE 1 + +/* Define to 1 if you have the `mallinfo' function. */ +/* #undef HAVE_MALLINFO 1 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_MALLOC_H 1 + +/* Define to 1 if you have the `mbstowcs' function. */ +#define HAVE_MBSTOWCS 1 + +/* Define to 1 if you have the `memalign' function. */ +#define HAVE_MEMALIGN 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MEMORY_H 1 */ + +/* Define to 1 if you have the `mempcpy' function. */ +/* #undef HAVE_MEMPCPY 1 */ + +/* Define to 1 if you have the `mmap' function. */ +/* #undef HAVE_MMAP 1 */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MNTENT_H 1 */ + +/* Define to 1 if you have the `munmap' function. */ +/* #undef HAVE_MUNMAP 1 */ + +/* Define to 1 if you have the `nanosleep' function. */ +#define HAVE_NANOSLEEP 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_NETINET_IN_H 1 */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_NET_IF_DL_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_NET_IF_H 1 */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_NL_TYPES_H 1 */ + +/* Define to 1 if you have the `open64' function. */ +/* #undef HAVE_OPEN64 1 */ + +/* Define to 1 if optreset for getopt is present */ +/* #undef HAVE_OPTRESET */ + +/* Define to 1 if you have the `pathconf' function. */ +/* #undef HAVE_PATHCONF 1 */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_PATHS_H 1 */ + +/* Define to 1 if you have the `posix_fadvise' function. */ +/* #undef HAVE_POSIX_FADVISE 1 */ + +/* Define to 1 if you have the `posix_memalign' function. */ +/* #undef HAVE_POSIX_MEMALIGN 1 */ + +/* Define if your printf() function supports format strings with positions. */ +#define HAVE_POSIX_PRINTF 1 + +/* Define to 1 if you have the `prctl' function. */ +/* #undef HAVE_PRCTL 1 */ + +/* Define to 1 if you have the `putenv' function. */ +/* #undef HAVE_PUTENV 1 */ + +/* Define to 1 if you have the `quotactl' function. */ +/* #undef HAVE_QUOTACTL 1 */ + +/* Define to 1 if dirent has d_reclen */ +/* #undef HAVE_RECLEN_DIRENT 1 */ + +/* Define to 1 if if struct sockaddr contains sa_len */ +/* #undef HAVE_SA_LEN */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SEMAPHORE_H 1 */ + +/* Define to 1 if sem_init() exists */ +/* #undef HAVE_SEM_INIT 1 */ + +/* Define to 1 if you have the `setenv' function. */ +/* #undef HAVE_SETENV 1 */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SETJMP_H 1 */ + +/* Define to 1 if you have the `setlocale' function. */ +#define HAVE_SETLOCALE 1 + +/* Define to 1 if you have the `setresgid' function. */ +/* #undef HAVE_SETRESGID 1 */ + +/* Define to 1 if you have the `setresuid' function. */ +/* #undef HAVE_SETRESUID 1*/ + +/* Define to 1 if you have the header file. */ +#define HAVE_SIGNAL_H 1 + +/* Define to 1 if you have the `snprintf' function. */ +#define HAVE_SNPRINTF 1 + +/* Define to 1 if you have the `srandom' function. */ +/* #undef HAVE_SRANDOM 1 */ + +/* Define to 1 if struct stat has st_flags */ +/* #undef HAVE_STAT_FLAGS */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDARG_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define if exists, doesn't clash with , and declares + uintmax_t. */ +#define HAVE_STDINT_H_WITH_UINTMAX 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `stpcpy' function. */ +#define HAVE_STPCPY 1 + +/* Define to 1 if you have the `strcasecmp' function. */ +#define HAVE_STRCASECMP 1 + +/* Define to 1 if you have the `strdup' function. */ +#define HAVE_STRDUP 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STRINGS_H 1 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strnlen' function. */ +#define HAVE_STRNLEN 1 + +/* Define to 1 if you have the `strptime' function. */ +#define HAVE_STRPTIME 1 + +/* Define to 1 if you have the `strtoul' function. */ +#define HAVE_STRTOUL 1 + +/* Define to 1 if you have the `strtoull' function. */ +#define HAVE_STRTOULL 1 + +/* Define to 1 if you have the `sync_file_range' function. */ +/* #undef HAVE_SYNC_FILE_RANGE 1 */ + +/* Define to 1 if you have the `sysconf' function. */ +/* #undef HAVE_SYSCONF 1 */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_DISKLABEL_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_DISK_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_FILE_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_IOCTL_H 1 */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_MKDEV_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_MMAN_H 1 */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_MOUNT_H 1 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_PRCTL_H 1 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_QUEUE_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_QUOTA_H 1 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_RESOURCE_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SELECT_H 1 */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SOCKET_H 1 */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SOCKIO_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SYSCALL_H 1 */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SYSMACROS_H 1 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_UN_H 1 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_TERMIOS_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_TERMIO_H 1 */ + +/* Define to 1 if you have the `tsearch' function. */ +/* #undef HAVE_TSEARCH 1 */ + +/* Define to 1 if ssize_t declared */ +#define HAVE_TYPE_SSIZE_T 1 + +/* Define if you have the 'uintmax_t' type in or . */ +#define HAVE_UINTMAX_T 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the 'unsigned long long' type. */ +#define HAVE_UNSIGNED_LONG_LONG 1 + +/* Define to 1 if you have the `usleep' function. */ +#define HAVE_USLEEP 1 + +/* Define to 1 if you have the `utime' function. */ +/* #undef HAVE_UTIME 1 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_UTIME_H 1 + +/* Define to 1 if you have the `valloc' function. */ +/* #undef HAVE_VALLOC 1 */ + +/* Define to 1 if you have the `vprintf' function. */ +#define HAVE_VPRINTF 1 + +/* Define if you have the 'wchar_t' type. */ +#define HAVE_WCHAR_T 1 + +/* Define to 1 if you have the `wcslen' function. */ +#define HAVE_WCSLEN 1 + +/* Define if you have the 'wint_t' type. */ +#define HAVE_WINT_T 1 + +/* Define to 1 if you have the `__argz_count' function. */ +/* #undef HAVE___ARGZ_COUNT 1 */ + +/* Define to 1 if you have the `__argz_next' function. */ +/* #undef HAVE___ARGZ_NEXT 1 */ + +/* Define to 1 if you have the `__argz_stringify' function. */ +/* #undef HAVE___ARGZ_STRINGIFY 1 */ + +/* Define to 1 if you have the `__fsetlocking' function. */ +/* #undef HAVE___FSETLOCKING 1 */ + +/* Define to 1 if you have the `__secure_getenv' function. */ +/* #undef HAVE___SECURE_GETENV 1 */ + +/* Define as const if the declaration of iconv() needs const. */ +/* #undef ICONV_CONST */ + +/* Define if integer division by zero raises signal SIGFPE. */ +/* #undef INTDIV0_RAISES_SIGFPE 1 */ + +/* package name for gettext */ +#define PACKAGE "e2fsprogs" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "" + +/* Define if exists and defines unusable PRI* macros. */ +/* #undef PRI_MACROS_BROKEN */ + +/* The size of `int', as computed by sizeof. */ +#define SIZEOF_INT 4 + +/* The size of `long', as computed by sizeof. */ +#define SIZEOF_LONG 4 + +/* The size of `long long', as computed by sizeof. */ +#define SIZEOF_LONG_LONG 8 + +/* The size of `short', as computed by sizeof. */ +#define SIZEOF_SHORT 2 + +/* Define as the maximum value of type 'size_t', if the system doesn't define + it. */ +/* #undef SIZE_MAX */ + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +/* #undef STACK_DIRECTION */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* If the compiler supports a TLS storage class define it to that here */ +/* #undef TLS __thread */ + +/* Define to 1 to build uuidd */ +/* #undef USE_UUIDD 1 */ + +/* version for gettext */ +#define VERSION "0.14.1" + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#define WORDS_BIGENDIAN 1 + +/* Define to 1 if Apple Darwin libintl workaround is needed */ +/* #undef _INTL_REDIRECT_MACROS */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +/* Define to `long int' if does not define. */ +/* #undef off_t */ + +/* Define as the type of the result of subtracting two pointers, if the system + doesn't define it. */ +/* #undef ptrdiff_t */ + +/* Define to empty if the C compiler doesn't support this keyword. */ +/* #undef signed */ + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ + +/* Define to unsigned long or unsigned long long if and + don't define. */ +/* #undef uintmax_t */ + +#endif diff --git a/portlibs/sources/libext2fs/source/crc16.c b/portlibs/sources/libcustomext2fs/source/crc16.c similarity index 99% rename from portlibs/sources/libext2fs/source/crc16.c rename to portlibs/sources/libcustomext2fs/source/crc16.c index 02d81e44..4176b268 100644 --- a/portlibs/sources/libext2fs/source/crc16.c +++ b/portlibs/sources/libcustomext2fs/source/crc16.c @@ -5,6 +5,7 @@ * Version 2. See the file COPYING for more details. */ +#include "config.h" #if HAVE_SYS_TYPES_H #include #endif diff --git a/portlibs/sources/libext2fs/source/crc16.h b/portlibs/sources/libcustomext2fs/source/crc16.h similarity index 100% rename from portlibs/sources/libext2fs/source/crc16.h rename to portlibs/sources/libcustomext2fs/source/crc16.h diff --git a/portlibs/sources/libcustomext2fs/source/crc32c.c b/portlibs/sources/libcustomext2fs/source/crc32c.c new file mode 100644 index 00000000..6be43369 --- /dev/null +++ b/portlibs/sources/libcustomext2fs/source/crc32c.c @@ -0,0 +1,1144 @@ +/* + * crc32c.c + * + * August 26, 2011 Darrick J. Wong + * Reuse Bob Pearson's slice-by-8 implementation for e2fsprogs. + * + * July 20, 2011 Bob Pearson + * added slice by 8 algorithm to the existing conventional and + * slice by 4 algorithms. + * + * Oct 15, 2000 Matt Domsch + * Nicer crc32 functions/docs submitted by linux@horizon.com. Thanks! + * Code was from the public domain, copyright abandoned. Code was + * subsequently included in the kernel, thus was re-licensed under the + * GNU GPL v2. + * + * Oct 12, 2000 Matt Domsch + * Same crc32 function was used in 5 other places in the kernel. + * I made one version, and deleted the others. + * There are various incantations of crc32(). Some use a seed of 0 or ~0. + * Some xor at the end with ~0. The generic crc32() function takes + * seed as an argument, and doesn't xor at the end. Then individual + * users can do whatever they need. + * drivers/net/smc9194.c uses seed ~0, doesn't xor with ~0. + * fs/jffs2 uses seed 0, doesn't xor with ~0. + * fs/partitions/efi.c uses seed ~0, xor's with ~0. + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ +#include "config.h" +#include +#include +#include +#define __force +#define min(x, y) ((x) > (y) ? (y) : (x)) +#define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask)) +#define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1) +#define ALIGN(x, a) __ALIGN_KERNEL((x), (a)) +#define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a))) +#include "crc32c_defs.h" + +#include "ext2fs.h" +#ifdef WORDS_BIGENDIAN +#define __constant_cpu_to_le32(x) ___constant_swab32((x)) +#define __constant_cpu_to_be32(x) (x) +#define __be32_to_cpu(x) (x) +#define __cpu_to_be32(x) (x) +#define __cpu_to_le32(x) (ext2fs_cpu_to_le32((x))) +#define __le32_to_cpu(x) (ext2fs_le32_to_cpu((x))) +#else +#define __constant_cpu_to_le32(x) (x) +#define __constant_cpu_to_be32(x) ___constant_swab32((x)) +#define __be32_to_cpu(x) (ext2fs_be32_to_cpu((x))) +#define __cpu_to_be32(x) (ext2fs_cpu_to_be32((x))) +#define __cpu_to_le32(x) (x) +#define __le32_to_cpu(x) (x) +#endif + +#if CRC_LE_BITS > 8 +# define tole(x) (__force uint32_t) __constant_cpu_to_le32(x) +#else +# define tole(x) (x) +#endif + +#if CRC_BE_BITS > 8 +# define tobe(x) (__force uint32_t) __constant_cpu_to_be32(x) +#else +# define tobe(x) (x) +#endif + +#include "crc32c_table.h" + +#if CRC_LE_BITS == 32 +/* slice by 4 algorithm */ +static uint32_t crc32c_le_body(uint32_t crc, uint8_t const *buf, size_t len) +{ + const uint8_t *p8; + const uint32_t *p32; + size_t init_bytes; + size_t words; + size_t end_bytes; + size_t i; + uint32_t q; + uint8_t i0, i1, i2, i3; + + crc = (__force uint32_t) __cpu_to_le32(crc); + + /* unroll loop into 'init_bytes' odd bytes followed by + * 'words' aligned 4 byte words followed by + * 'end_bytes' odd bytes at the end */ + p8 = buf; + p32 = (uint32_t *)PTR_ALIGN(p8, 4); + init_bytes = min((uintptr_t)p32 - (uintptr_t)p8, len); + words = (len - init_bytes) >> 2; + end_bytes = (len - init_bytes) & 3; + + for (i = 0; i < init_bytes; i++) { +#ifndef WORDS_BIGENDIAN + i0 = *p8++ ^ crc; + crc = t0_le[i0] ^ (crc >> 8); +#else + i0 = *p8++ ^ (crc >> 24); + crc = t0_le[i0] ^ (crc << 8); +#endif + } + + /* using pre-increment below slightly faster */ + p32--; + + for (i = 0; i < words; i++) { +#ifndef WORDS_BIGENDIAN + q = *++p32 ^ crc; + i3 = q; + i2 = q >> 8; + i1 = q >> 16; + i0 = q >> 24; + crc = t3_le[i3] ^ t2_le[i2] ^ t1_le[i1] ^ t0_le[i0]; +#else + q = *++p32 ^ crc; + i3 = q >> 24; + i2 = q >> 16; + i1 = q >> 8; + i0 = q; + crc = t3_le[i3] ^ t2_le[i2] ^ t1_le[i1] ^ t0_le[i0]; +#endif + } + + p8 = (uint8_t *)(++p32); + + for (i = 0; i < end_bytes; i++) { +#ifndef WORDS_BIGENDIAN + i0 = *p8++ ^ crc; + crc = t0_le[i0] ^ (crc >> 8); +#else + i0 = *p8++ ^ (crc >> 24); + crc = t0_le[i0] ^ (crc << 8); +#endif + } + + return __le32_to_cpu((__force __le32)crc); +} +#endif + +#if CRC_BE_BITS == 32 +static uint32_t crc32c_be_body(uint32_t crc, uint8_t const *buf, size_t len) +{ + const uint8_t *p8; + const uint32_t *p32; + size_t init_bytes; + size_t words; + size_t end_bytes; + size_t i; + uint32_t q; + uint8_t i0, i1, i2, i3; + + crc = (__force uint32_t) __cpu_to_be32(crc); + + p8 = buf; + p32 = (uint32_t *)PTR_ALIGN(p8, 4); + init_bytes = min((uintptr_t)p32 - (uintptr_t)p8, len); + words = (len - init_bytes) >> 2; + end_bytes = (len - init_bytes) & 3; + + for (i = 0; i < init_bytes; i++) { +#ifndef WORDS_BIGENDIAN + i0 = *p8++ ^ crc; + crc = t0_be[i0] ^ (crc >> 8); +#else + i0 = *p8++ ^ (crc >> 24); + crc = t0_be[i0] ^ (crc << 8); +#endif + } + + p32--; + + for (i = 0; i < words; i++) { +#ifndef WORDS_BIGENDIAN + q = *++p32 ^ crc; + i3 = q; + i2 = q >> 8; + i1 = q >> 16; + i0 = q >> 24; + crc = t3_be[i3] ^ t2_be[i2] ^ t1_be[i1] ^ t0_be[i0]; +#else + q = *++p32 ^ crc; + i3 = q >> 24; + i2 = q >> 16; + i1 = q >> 8; + i0 = q; + crc = t3_be[i3] ^ t2_be[i2] ^ t1_be[i1] ^ t0_be[i0]; +#endif + } + + p8 = (uint8_t *)(++p32); + + for (i = 0; i < end_bytes; i++) { +#ifndef WORDS_BIGENDIAN + i0 = *p8++ ^ crc; + crc = t0_be[i0] ^ (crc >> 8); +#else + i0 = *p8++ ^ (crc >> 24); + crc = t0_be[i0] ^ (crc << 8); +#endif + } + + return __be32_to_cpu((__force __be32)crc); +} +#endif + +#if CRC_LE_BITS == 64 +/* slice by 8 algorithm */ +static uint32_t crc32c_le_body(uint32_t crc, uint8_t const *buf, size_t len) +{ + const uint8_t *p8; + const uint32_t *p32; + size_t init_bytes; + size_t words; + size_t end_bytes; + size_t i; + uint32_t q; + uint8_t i0, i1, i2, i3; + + crc = (__force uint32_t) __cpu_to_le32(crc); + + p8 = buf; + p32 = (uint32_t *)PTR_ALIGN(p8, 8); + init_bytes = min((uintptr_t)p32 - (uintptr_t)p8, len); + words = (len - init_bytes) >> 3; + end_bytes = (len - init_bytes) & 7; + + for (i = 0; i < init_bytes; i++) { +#ifndef WORDS_BIGENDIAN + i0 = *p8++ ^ crc; + crc = t0_le[i0] ^ (crc >> 8); +#else + i0 = *p8++ ^ (crc >> 24); + crc = t0_le[i0] ^ (crc << 8); +#endif + } + + p32--; + + for (i = 0; i < words; i++) { +#ifndef WORDS_BIGENDIAN + q = *++p32 ^ crc; + i3 = q; + i2 = q >> 8; + i1 = q >> 16; + i0 = q >> 24; + crc = t7_le[i3] ^ t6_le[i2] ^ t5_le[i1] ^ t4_le[i0]; + + q = *++p32; + i3 = q; + i2 = q >> 8; + i1 = q >> 16; + i0 = q >> 24; + crc ^= t3_le[i3] ^ t2_le[i2] ^ t1_le[i1] ^ t0_le[i0]; +#else + q = *++p32 ^ crc; + i3 = q >> 24; + i2 = q >> 16; + i1 = q >> 8; + i0 = q; + crc = t7_le[i3] ^ t6_le[i2] ^ t5_le[i1] ^ t4_le[i0]; + + q = *++p32; + i3 = q >> 24; + i2 = q >> 16; + i1 = q >> 8; + i0 = q; + crc ^= t3_le[i3] ^ t2_le[i2] ^ t1_le[i1] ^ t0_le[i0]; +#endif + } + + p8 = (uint8_t *)(++p32); + + for (i = 0; i < end_bytes; i++) { +#ifndef WORDS_BIGENDIAN + i0 = *p8++ ^ crc; + crc = t0_le[i0] ^ (crc >> 8); +#else + i0 = *p8++ ^ (crc >> 24); + crc = t0_le[i0] ^ (crc << 8); +#endif + } + + return __le32_to_cpu(crc); +} +#endif + +#if CRC_BE_BITS == 64 +static uint32_t crc32c_be_body(uint32_t crc, uint8_t const *buf, size_t len) +{ + const uint8_t *p8; + const uint32_t *p32; + size_t init_bytes; + size_t words; + size_t end_bytes; + size_t i; + uint32_t q; + uint8_t i0, i1, i2, i3; + + crc = (__force uint32_t) __cpu_to_be32(crc); + + p8 = buf; + p32 = (uint32_t *)PTR_ALIGN(p8, 8); + init_bytes = min((uintptr_t)p32 - (uintptr_t)p8, len); + words = (len - init_bytes) >> 3; + end_bytes = (len - init_bytes) & 7; + + for (i = 0; i < init_bytes; i++) { +#ifndef WORDS_BIGENDIAN + i0 = *p8++ ^ crc; + crc = t0_be[i0] ^ (crc >> 8); +#else + i0 = *p8++ ^ (crc >> 24); + crc = t0_be[i0] ^ (crc << 8); +#endif + } + + p32--; + + for (i = 0; i < words; i++) { +#ifndef WORDS_BIGENDIAN + q = *++p32 ^ crc; + i3 = q; + i2 = q >> 8; + i1 = q >> 16; + i0 = q >> 24; + crc = t7_be[i3] ^ t6_be[i2] ^ t5_be[i1] ^ t4_be[i0]; + + q = *++p32; + i3 = q; + i2 = q >> 8; + i1 = q >> 16; + i0 = q >> 24; + crc ^= t3_be[i3] ^ t2_be[i2] ^ t1_be[i1] ^ t0_be[i0]; +#else + q = *++p32 ^ crc; + i3 = q >> 24; + i2 = q >> 16; + i1 = q >> 8; + i0 = q; + crc = t7_be[i3] ^ t6_be[i2] ^ t5_be[i1] ^ t4_be[i0]; + + q = *++p32; + i3 = q >> 24; + i2 = q >> 16; + i1 = q >> 8; + i0 = q; + crc ^= t3_be[i3] ^ t2_be[i2] ^ t1_be[i1] ^ t0_be[i0]; +#endif + } + + p8 = (uint8_t *)(++p32); + + for (i = 0; i < end_bytes; i++) { +#ifndef WORDS_BIGENDIAN + i0 = *p8++ ^ crc; + crc = t0_be[i0] ^ (crc >> 8); +#else + i0 = *p8++ ^ (crc >> 24); + crc = t0_be[i0] ^ (crc << 8); +#endif + } + + return __be32_to_cpu(crc); +} +#endif + +/** + * crc32c_le() - Calculate bitwise little-endian CRC32c. + * @crc: seed value for computation. ~0 for ext4, sometimes 0 for + * other uses, or the previous crc32c value if computing incrementally. + * @p: pointer to buffer over which CRC is run + * @len: length of buffer @p + */ +uint32_t ext2fs_crc32c_le(uint32_t crc, unsigned char const *p, size_t len) +{ +#if CRC_LE_BITS == 1 + int i; + while (len--) { + crc ^= *p++; + for (i = 0; i < 8; i++) + crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0); + } +# elif CRC_LE_BITS == 2 + while (len--) { + crc ^= *p++; + crc = (crc >> 2) ^ t0_le[crc & 0x03]; + crc = (crc >> 2) ^ t0_le[crc & 0x03]; + crc = (crc >> 2) ^ t0_le[crc & 0x03]; + crc = (crc >> 2) ^ t0_le[crc & 0x03]; + } +# elif CRC_LE_BITS == 4 + while (len--) { + crc ^= *p++; + crc = (crc >> 4) ^ t0_le[crc & 0x0f]; + crc = (crc >> 4) ^ t0_le[crc & 0x0f]; + } +# elif CRC_LE_BITS == 8 + while (len--) { + crc ^= *p++; + crc = (crc >> 8) ^ t0_le[crc & 0xff]; + } +# else + crc = crc32c_le_body(crc, p, len); +# endif + return crc; +} + +/** + * crc32c_be() - Calculate bitwise big-endian CRC32c. + * @crc: seed value for computation. ~0 for ext4, sometimes 0 for + * other uses, or the previous crc32c value if computing incrementally. + * @p: pointer to buffer over which CRC is run + * @len: length of buffer @p + */ +uint32_t ext2fs_crc32c_be(uint32_t crc, unsigned char const *p, size_t len) +{ +#if CRC_BE_BITS == 1 + int i; + while (len--) { + crc ^= *p++ << 24; + for (i = 0; i < 8; i++) + crc = (crc << 1) ^ + ((crc & 0x80000000) ? CRCPOLY_BE : 0); + } +# elif CRC_BE_BITS == 2 + while (len--) { + crc ^= *p++ << 24; + crc = (crc << 2) ^ t0_be[crc >> 30]; + crc = (crc << 2) ^ t0_be[crc >> 30]; + crc = (crc << 2) ^ t0_be[crc >> 30]; + crc = (crc << 2) ^ t0_be[crc >> 30]; + } +# elif CRC_BE_BITS == 4 + while (len--) { + crc ^= *p++ << 24; + crc = (crc << 4) ^ t0_be[crc >> 28]; + crc = (crc << 4) ^ t0_be[crc >> 28]; + } +# elif CRC_BE_BITS == 8 + while (len--) { + crc ^= *p++ << 24; + crc = (crc << 8) ^ t0_be[crc >> 24]; + } +# else + crc = crc32c_be_body(crc, p, len); +# endif + return crc; +} + +#ifdef UNITTEST +static uint8_t test_buf[] = { + 0xd9, 0xd7, 0x6a, 0x13, 0x3a, 0xb1, 0x05, 0x48, + 0xda, 0xad, 0x14, 0xbd, 0x03, 0x3a, 0x58, 0x5e, + 0x6e, 0xd1, 0x56, 0xc9, 0x2e, 0xc4, 0xcb, 0x6b, + 0xe8, 0x77, 0x52, 0x37, 0x4e, 0x0f, 0x55, 0xd2, + 0x12, 0x65, 0x90, 0xc2, 0x41, 0x49, 0x81, 0x01, + 0xf5, 0x01, 0xeb, 0x2d, 0x78, 0x74, 0x23, 0x5d, + 0x84, 0x5c, 0x81, 0x92, 0x21, 0xe9, 0x8d, 0x1d, + 0x89, 0xf2, 0x4a, 0xac, 0xdd, 0xf9, 0xaf, 0xee, + 0x44, 0xe7, 0x6e, 0xed, 0xfb, 0xd8, 0x89, 0x0e, + 0x96, 0x62, 0xcd, 0xa4, 0x4b, 0xa9, 0xe5, 0x45, + 0xb1, 0x29, 0x9b, 0x0f, 0xfc, 0xbd, 0x83, 0xab, + 0xa8, 0x54, 0x96, 0x44, 0x2c, 0x7f, 0xbb, 0xe7, + 0x52, 0x29, 0x08, 0xee, 0x14, 0xc5, 0xc2, 0xec, + 0x5a, 0xeb, 0x40, 0x40, 0xea, 0xd1, 0x3d, 0x15, + 0x73, 0xaa, 0x8c, 0x73, 0xfc, 0xf2, 0x2b, 0x49, + 0x0b, 0x13, 0x96, 0xd9, 0x8e, 0x4b, 0xbc, 0xe0, + 0xf4, 0xd2, 0xe0, 0x2e, 0x7a, 0xf0, 0x5d, 0x1f, + 0xd2, 0x92, 0x97, 0xe0, 0xaa, 0x59, 0xab, 0xc9, + 0x5c, 0xa6, 0x51, 0x1a, 0xe3, 0xd6, 0x06, 0xb9, + 0xae, 0xb8, 0x76, 0x36, 0x79, 0x37, 0x52, 0xf6, + 0x34, 0xaf, 0x27, 0x19, 0xe1, 0xc0, 0x2b, 0xdd, + 0x01, 0x15, 0xcd, 0xce, 0x44, 0xf6, 0x4c, 0x18, + 0x92, 0x69, 0xbe, 0x8a, 0x76, 0x23, 0x52, 0x13, + 0x3f, 0xf9, 0xe0, 0xf5, 0x06, 0x28, 0x7c, 0xc7, + 0xf3, 0x42, 0x0f, 0xdd, 0x40, 0x33, 0xf7, 0x99, + 0xe2, 0xad, 0x26, 0xd9, 0x53, 0x10, 0x72, 0x0c, + 0x4e, 0x43, 0x4c, 0x61, 0xfe, 0xd9, 0xc1, 0x16, + 0xa1, 0x93, 0xca, 0x3c, 0x75, 0x7f, 0x07, 0x7a, + 0x65, 0xb3, 0x53, 0x2a, 0x52, 0x00, 0xa0, 0x62, + 0xe0, 0xa3, 0x1f, 0xad, 0xd7, 0xbb, 0xc0, 0x83, + 0x5d, 0x54, 0x87, 0x5f, 0xc8, 0x2f, 0xc8, 0xbf, + 0x69, 0x04, 0x91, 0xc8, 0xa6, 0x1d, 0x4d, 0x46, + 0x91, 0xfc, 0x26, 0xf4, 0x16, 0xd1, 0xa4, 0xbf, + 0x5c, 0xa2, 0x6c, 0xdd, 0xb4, 0x40, 0xf2, 0x2e, + 0xa2, 0xad, 0xf7, 0xf4, 0xa5, 0x8a, 0x3e, 0x23, + 0x64, 0x08, 0xc8, 0xa1, 0xa0, 0xf0, 0x5d, 0x70, + 0xd2, 0x77, 0xfd, 0xc8, 0x50, 0x83, 0x0f, 0xd6, + 0x2b, 0xe4, 0x1f, 0x52, 0x34, 0x33, 0x68, 0xfd, + 0x92, 0xbe, 0x9f, 0x97, 0x6b, 0x8d, 0x81, 0x91, + 0x0f, 0xef, 0x65, 0xc8, 0x0d, 0x15, 0x01, 0x77, + 0x58, 0xb2, 0xf4, 0x1b, 0x06, 0x7e, 0xf5, 0xca, + 0x15, 0x2e, 0x38, 0xd8, 0x81, 0x1c, 0x1c, 0xa0, + 0xb6, 0x13, 0x6a, 0x2b, 0x71, 0x34, 0x52, 0xd7, + 0x1d, 0xbd, 0x37, 0x59, 0xbc, 0x86, 0x25, 0x2b, + 0xa8, 0x93, 0xce, 0x1a, 0x03, 0x16, 0xfe, 0x01, + 0x57, 0x99, 0x24, 0x25, 0x2c, 0xb3, 0xab, 0x1e, + 0x2d, 0x65, 0x20, 0x89, 0x17, 0x02, 0x0e, 0x0a, + 0xf5, 0x1e, 0xc7, 0xff, 0x1f, 0x61, 0xa9, 0x54, + 0x18, 0xd4, 0xba, 0x50, 0x57, 0x02, 0xa1, 0xab, + 0x22, 0x2e, 0x07, 0xea, 0xa9, 0xa3, 0x83, 0x4f, + 0x27, 0xf5, 0xc5, 0xee, 0x3c, 0x3b, 0x10, 0xad, + 0x32, 0x2b, 0x1c, 0x03, 0xcb, 0xaf, 0x98, 0x83, + 0x54, 0xc3, 0x68, 0x63, 0xd4, 0xe0, 0x0e, 0x3c, + 0x1a, 0x4e, 0xc0, 0x81, 0xd0, 0xe8, 0x6a, 0x62, + 0x6b, 0x3e, 0x6f, 0xc4, 0xc6, 0x33, 0x4e, 0x26, + 0x21, 0xf5, 0x04, 0xdf, 0xfa, 0xce, 0x45, 0xaf, + 0xdc, 0x5e, 0x1b, 0xad, 0x93, 0xca, 0xf5, 0xcf, + 0xd7, 0xee, 0x0c, 0x5c, 0x5e, 0xb4, 0xf0, 0x92, + 0xd2, 0xf2, 0xf0, 0xa9, 0x1e, 0xab, 0x80, 0x68, + 0x46, 0xef, 0xcc, 0x26, 0x0c, 0x5c, 0xdd, 0x4e, + 0x83, 0xb8, 0xb9, 0x53, 0x6e, 0xf8, 0x93, 0x38, + 0x67, 0xa4, 0x41, 0x87, 0x72, 0xe7, 0x7e, 0x86, + 0xc9, 0x49, 0x00, 0x33, 0xb1, 0x38, 0x6c, 0x71, + 0xd7, 0x1d, 0x8e, 0x61, 0x01, 0xb6, 0x57, 0xa9, + 0xf1, 0xac, 0x15, 0xc2, 0x83, 0x77, 0xca, 0x64, + 0xca, 0x7b, 0x6c, 0xa1, 0x10, 0x1b, 0x13, 0xd0, + 0xd3, 0x9e, 0x9e, 0x10, 0x70, 0xc8, 0x1a, 0xbb, + 0x3f, 0x19, 0x86, 0xab, 0x01, 0x0e, 0xea, 0x34, + 0x22, 0xea, 0xe2, 0x15, 0xb7, 0xed, 0x21, 0x21, + 0x75, 0xa5, 0xe7, 0x08, 0xa1, 0x38, 0xe0, 0x91, + 0x05, 0x60, 0xea, 0xa7, 0x50, 0x27, 0x18, 0x07, + 0x9d, 0xe0, 0x18, 0x2b, 0xd4, 0x07, 0x59, 0x00, + 0xe6, 0x45, 0x18, 0x2a, 0x30, 0x6e, 0xf3, 0xb4, + 0xd0, 0xef, 0xa6, 0x5b, 0x71, 0xa2, 0x5a, 0x3b, + 0x89, 0x4c, 0xaf, 0x3f, 0xcb, 0x9f, 0x03, 0xfb, + 0x43, 0x7c, 0x6b, 0xd3, 0x6a, 0xea, 0xce, 0x4a, + 0x5f, 0x64, 0xb5, 0x62, 0xda, 0x5d, 0x27, 0xb7, + 0xb8, 0x11, 0xca, 0x33, 0x30, 0xec, 0x70, 0xf0, + 0x1b, 0x03, 0x50, 0xff, 0x5e, 0xa6, 0x08, 0xde, + 0x37, 0x70, 0xc0, 0x81, 0x55, 0x60, 0x17, 0xa1, + 0x85, 0xae, 0x26, 0x44, 0xe4, 0x67, 0x3c, 0x91, + 0xfd, 0xc4, 0x3d, 0x97, 0x72, 0x23, 0xf3, 0x3c, + 0x8f, 0xe0, 0xe2, 0xf2, 0x09, 0x96, 0x10, 0x67, + 0xb5, 0xfe, 0xff, 0x3d, 0x4a, 0xc8, 0x62, 0x11, + 0xa5, 0x98, 0xc1, 0x2d, 0x40, 0x82, 0x88, 0x8b, + 0xe5, 0xb0, 0x75, 0xbf, 0x2f, 0xa8, 0x6a, 0x55, + 0x49, 0x2e, 0x9c, 0x29, 0xd2, 0x7c, 0xbf, 0xf3, + 0xaa, 0x3a, 0x16, 0x4a, 0xa4, 0x15, 0xf3, 0x48, + 0xde, 0x38, 0x13, 0x44, 0x26, 0x02, 0xe6, 0xe9, + 0xa8, 0x24, 0x89, 0xb5, 0x43, 0x95, 0xe4, 0x4c, + 0xc3, 0xa0, 0xdf, 0xcc, 0x42, 0xf8, 0x8d, 0xb0, + 0x3b, 0xea, 0x10, 0xb7, 0xe1, 0x40, 0x54, 0xb9, + 0xa3, 0x2d, 0xfb, 0xb4, 0x91, 0xc0, 0x3e, 0x94, + 0xf1, 0xa1, 0x3c, 0xbe, 0xef, 0xb8, 0x70, 0x55, + 0x0a, 0x26, 0x93, 0xbf, 0xe6, 0x21, 0x92, 0x32, + 0x3c, 0x39, 0x27, 0x6a, 0x23, 0x48, 0x02, 0x35, + 0x3c, 0xd4, 0xcc, 0x04, 0xc0, 0x4e, 0xa7, 0x02, + 0x63, 0x37, 0xc2, 0xb8, 0x56, 0x1d, 0x57, 0x57, + 0x42, 0x04, 0x8d, 0xee, 0xcf, 0x8b, 0xc9, 0xc3, + 0xba, 0x3b, 0x15, 0xd7, 0xaf, 0xbf, 0x9e, 0xcd, + 0x44, 0xcf, 0xf0, 0x00, 0xb7, 0x3a, 0xfc, 0xa8, + 0x12, 0xab, 0x3a, 0x62, 0x01, 0x21, 0x46, 0xe9, + 0x1e, 0x48, 0x37, 0xfc, 0x13, 0x4d, 0xf6, 0x2a, + 0x72, 0x40, 0x75, 0x38, 0x71, 0xf2, 0x17, 0x20, + 0x2c, 0xdd, 0xc0, 0x49, 0xbc, 0x63, 0x33, 0xea, + 0x06, 0x75, 0x41, 0xe7, 0x5c, 0x1f, 0xfb, 0xf9, + 0x68, 0x83, 0xc2, 0x5a, 0x4a, 0x1e, 0x61, 0x08, + 0x57, 0xf3, 0x00, 0xba, 0x77, 0x92, 0x63, 0xa5, + 0xb7, 0xfe, 0x97, 0x22, 0xda, 0x5e, 0xd3, 0xaf, + 0xbc, 0x89, 0x0d, 0x4c, 0x37, 0xa9, 0x27, 0x4a, + 0x7f, 0xdb, 0x81, 0x39, 0x11, 0x86, 0x12, 0xf9, + 0x10, 0x50, 0xe4, 0xdb, 0x72, 0xf9, 0xae, 0x10, + 0x7c, 0xed, 0x50, 0x5c, 0x61, 0xeb, 0x42, 0x1e, + 0xa4, 0xf4, 0xf0, 0xfa, 0x45, 0x4d, 0x95, 0x2b, + 0xd4, 0x67, 0x4a, 0xe3, 0x8a, 0x15, 0x55, 0x92, + 0x77, 0x64, 0x8c, 0x51, 0x38, 0xf9, 0x26, 0x3e, + 0x68, 0xe2, 0xac, 0xbb, 0x64, 0x77, 0xe2, 0x82, + 0xa4, 0x42, 0x41, 0x38, 0xa0, 0xf0, 0xc9, 0xd8, + 0x6c, 0xe0, 0xef, 0x4c, 0xda, 0xb4, 0x92, 0xef, + 0x1b, 0xe3, 0x9b, 0xc1, 0x44, 0x3c, 0xb9, 0xb7, + 0x39, 0xac, 0x5c, 0x32, 0x39, 0xb4, 0x21, 0x85, + 0x93, 0xbc, 0xf2, 0x51, 0x43, 0xb7, 0xae, 0x1e, + 0x61, 0x9c, 0x38, 0x9c, 0xaa, 0xff, 0xde, 0xfc, + 0xbf, 0x85, 0xef, 0x17, 0x34, 0x36, 0x71, 0x5f, + 0x04, 0x16, 0xa6, 0x9e, 0xfd, 0x3a, 0x03, 0xd8, + 0xbf, 0x71, 0x70, 0x20, 0x8f, 0x7c, 0xfb, 0xff, + 0x61, 0xe0, 0xe2, 0x60, 0xa7, 0xb1, 0xc0, 0xe0, + 0xd9, 0x3f, 0xdc, 0x8d, 0x4a, 0xa4, 0x52, 0x61, + 0xaf, 0x9d, 0xdf, 0x8a, 0x0d, 0x41, 0xc0, 0x25, + 0x68, 0x12, 0x7b, 0xd5, 0xc7, 0xdb, 0x68, 0x70, + 0x2d, 0x7d, 0x95, 0x12, 0x03, 0x23, 0x0c, 0xe8, + 0x14, 0x41, 0x11, 0x28, 0xec, 0x9d, 0xd3, 0x28, + 0x77, 0x7a, 0x3c, 0x93, 0x8e, 0x5c, 0x7e, 0xb3, + 0x42, 0x9a, 0x18, 0x25, 0x93, 0xc8, 0xea, 0x43, + 0x1b, 0xbe, 0xd5, 0x27, 0xf1, 0xd4, 0xe0, 0x1e, + 0xce, 0xc7, 0xc7, 0x2c, 0x25, 0x35, 0x58, 0xb8, + 0x6c, 0xf3, 0xa2, 0xad, 0xe7, 0x58, 0x49, 0x47, + 0xf7, 0xca, 0xde, 0x8b, 0x81, 0xb7, 0x75, 0xf4, + 0x95, 0xa7, 0x5c, 0xc3, 0x2c, 0x0e, 0x1c, 0x52, + 0x9a, 0xc3, 0x2a, 0x00, 0x21, 0xa7, 0x51, 0x6b, + 0xf0, 0x05, 0x87, 0x8c, 0x42, 0x1b, 0xc3, 0x2e, + 0xa3, 0x76, 0x22, 0xd5, 0x7f, 0x56, 0x10, 0xef, + 0x98, 0x85, 0x65, 0x86, 0x71, 0x87, 0xd2, 0x8c, + 0xc0, 0x47, 0x20, 0xe8, 0xb5, 0x1c, 0xe3, 0xdd, + 0x3c, 0x5c, 0x03, 0xbb, 0x0e, 0x97, 0x3b, 0xe1, + 0x56, 0x9a, 0xd5, 0x0a, 0x63, 0xd5, 0x33, 0xaf, + 0x36, 0xca, 0xcf, 0x8f, 0x00, 0x28, 0xa3, 0x45, + 0xb8, 0xcd, 0xde, 0x73, 0xd4, 0xfa, 0x2d, 0x6f, + 0xdb, 0x93, 0xaa, 0xdd, 0x7f, 0xd2, 0x22, 0x9c, + 0x96, 0x48, 0x1e, 0xa8, 0x63, 0xbe, 0xbc, 0x0d, + 0x14, 0x3c, 0x2e, 0x11, 0x1f, 0xd2, 0xf4, 0x57, + 0xb3, 0x47, 0xf8, 0xa6, 0x1b, 0xc3, 0xa7, 0x95, + 0x2d, 0xd4, 0xca, 0xb8, 0x0d, 0xfb, 0x06, 0x85, + 0xda, 0x63, 0xf0, 0x3e, 0x9d, 0x5e, 0xee, 0xce, + 0xed, 0x74, 0x1d, 0x2c, 0x97, 0x3f, 0x71, 0x95, + 0x12, 0x03, 0xc5, 0x92, 0x46, 0x84, 0x1b, 0x07, + 0xe6, 0xb4, 0x1d, 0x3a, 0xf1, 0x89, 0x90, 0x50, + 0x10, 0x29, 0x34, 0xc0, 0x90, 0xbe, 0x4a, 0xa9, + 0x0d, 0xb0, 0x7b, 0xfb, 0x35, 0xee, 0x4e, 0x34, + 0xec, 0x5a, 0x58, 0xbc, 0xb8, 0xda, 0x38, 0x88, + 0x8c, 0x74, 0x1e, 0xc9, 0xab, 0x78, 0x2e, 0x2a, + 0x17, 0x8a, 0x43, 0x3d, 0xa1, 0x2a, 0x41, 0xb5, + 0xd6, 0xe8, 0x5b, 0xc5, 0x4a, 0x1c, 0x3c, 0x9f, + 0x8d, 0x3a, 0x69, 0x88, 0xf8, 0x80, 0xd2, 0x11, + 0xfc, 0x7e, 0x80, 0x8e, 0x7f, 0x85, 0x64, 0x9c, + 0x46, 0x58, 0xc8, 0x48, 0x98, 0x4b, 0xf5, 0x73, + 0x3f, 0x49, 0xce, 0x53, 0x2c, 0xd5, 0xfc, 0x33, + 0xf1, 0x6f, 0xd8, 0xe9, 0x2e, 0x70, 0x2e, 0xdc, + 0xe5, 0x43, 0x80, 0x38, 0xf2, 0x87, 0xed, 0x85, + 0xe4, 0x3e, 0x45, 0x14, 0x20, 0xcf, 0xa0, 0x61, + 0x4f, 0xe8, 0xd7, 0x5b, 0xb3, 0x0d, 0x0e, 0x4e, + 0x4d, 0xce, 0xbe, 0xba, 0xaa, 0x90, 0x09, 0xcb, + 0x4b, 0x5d, 0x08, 0xff, 0x52, 0xd5, 0x23, 0xbc, + 0xad, 0x8d, 0xd3, 0x06, 0x4a, 0xa0, 0x51, 0x56, + 0xa7, 0xd8, 0x33, 0xab, 0xbc, 0xd0, 0xdf, 0x92, + 0x87, 0x20, 0x2d, 0x7b, 0x5e, 0xfa, 0x30, 0xa7, + 0x06, 0x06, 0xe5, 0x4f, 0x2c, 0xb5, 0x61, 0xd7, + 0x54, 0xd3, 0xdf, 0xd0, 0x0a, 0xb0, 0x06, 0xce, + 0xf6, 0x86, 0xb7, 0x8e, 0xaa, 0x7b, 0x78, 0xd5, + 0xb9, 0xeb, 0x07, 0xac, 0x5f, 0xc5, 0xd2, 0x8c, + 0x40, 0xe0, 0x7f, 0x98, 0xd4, 0xe5, 0x4b, 0xca, + 0xfb, 0x47, 0xef, 0xef, 0xb9, 0x4d, 0x6d, 0x8f, + 0x82, 0x68, 0x74, 0x84, 0xe0, 0x0a, 0x93, 0x0f, + 0xb2, 0x01, 0xa9, 0x9f, 0x68, 0x6a, 0xe8, 0xf7, + 0xfb, 0x0b, 0xde, 0x17, 0xe0, 0x30, 0x38, 0x51, + 0xbc, 0x07, 0xb8, 0x2c, 0x91, 0x0f, 0xc1, 0x0e, + 0xa6, 0xf9, 0xf0, 0xd5, 0x48, 0x76, 0x8a, 0xde, + 0x74, 0xe3, 0x30, 0x65, 0x56, 0xb3, 0x5c, 0xe2, + 0x89, 0x8d, 0xda, 0x80, 0xad, 0x0f, 0x22, 0xfb, + 0x24, 0x1d, 0x16, 0xdd, 0x34, 0x4b, 0x90, 0x58, + 0x4e, 0x0c, 0x13, 0x28, 0xcf, 0x1d, 0xa4, 0xaa, + 0xb7, 0xf3, 0xb1, 0x66, 0xad, 0x3b, 0xcf, 0x79, + 0x12, 0x04, 0xd7, 0x79, 0xd9, 0x5f, 0xdf, 0x89, + 0xb2, 0x5b, 0xa7, 0x9a, 0x26, 0x1e, 0x67, 0x46, + 0x7c, 0x66, 0x95, 0x67, 0xe6, 0x45, 0x8b, 0x1f, + 0x65, 0x79, 0x9f, 0x6d, 0x11, 0x81, 0x17, 0x0d, + 0x11, 0xb0, 0x5c, 0xb4, 0xc7, 0x27, 0x87, 0xab, + 0x5d, 0x0a, 0x18, 0xae, 0x4e, 0x06, 0xa3, 0x3d, + 0xc7, 0xb0, 0x22, 0xba, 0x03, 0xa4, 0x0f, 0xe5, + 0x1c, 0x72, 0x2a, 0x04, 0xce, 0x83, 0xe9, 0xf3, + 0xd7, 0xc9, 0x67, 0x6c, 0x1e, 0x6b, 0x3c, 0x9b, + 0x0b, 0x5e, 0x6a, 0xa6, 0x79, 0x0a, 0xf1, 0xbe, + 0xd7, 0xb4, 0x6f, 0x45, 0x1e, 0xfb, 0x78, 0x97, + 0xaf, 0x34, 0x76, 0x95, 0x52, 0xf7, 0x3d, 0x5d, + 0x07, 0x28, 0x57, 0x9c, 0x4a, 0x0f, 0xcf, 0x0b, + 0x1b, 0xc4, 0xc2, 0x72, 0xd7, 0x72, 0x38, 0x9b, + 0xea, 0xeb, 0xee, 0xae, 0x34, 0xc8, 0x01, 0xd7, + 0xa5, 0xe3, 0xce, 0x41, 0xad, 0x02, 0x60, 0x23, + 0x18, 0x36, 0xba, 0x17, 0xfa, 0xcf, 0xe4, 0xda, + 0xdc, 0xfc, 0x82, 0xdc, 0x7c, 0x11, 0xf4, 0xb8, + 0x52, 0x5d, 0xf7, 0x2f, 0xc8, 0xfe, 0x4a, 0xe6, + 0xb9, 0xaf, 0x4b, 0x17, 0x18, 0x91, 0xc2, 0xfe, + 0xd7, 0x3a, 0x77, 0x0c, 0xa0, 0x43, 0x9c, 0x6f, + 0x13, 0x06, 0xbe, 0x6e, 0xe0, 0x1a, 0x3c, 0xf3, + 0xf5, 0xcc, 0x78, 0xfb, 0x5d, 0xd5, 0xda, 0xb7, + 0x58, 0xea, 0x86, 0x42, 0x6b, 0x32, 0xff, 0xb2, + 0xe2, 0xee, 0x03, 0x1f, 0xf4, 0xef, 0xdb, 0x53, + 0x79, 0xd5, 0x4e, 0xaf, 0x60, 0x8e, 0x02, 0xc2, + 0xcc, 0x39, 0x97, 0x7b, 0xfd, 0xa1, 0xf8, 0x7a, + 0x26, 0xe8, 0x55, 0xd6, 0xa4, 0x8b, 0xa0, 0x1b, + 0x2d, 0x63, 0xaa, 0x73, 0x71, 0x6e, 0xbf, 0x8b, + 0x3b, 0xe3, 0x1b, 0x0d, 0xbb, 0x2e, 0x44, 0x09, + 0x64, 0xac, 0xc7, 0x9e, 0xb5, 0xc6, 0x77, 0xb0, + 0x79, 0xb3, 0xaa, 0xfc, 0x67, 0x57, 0x9a, 0x50, + 0x81, 0x37, 0x14, 0x7c, 0xd7, 0xa0, 0xd4, 0x6a, + 0x79, 0x84, 0x51, 0x0e, 0x95, 0x0a, 0x30, 0xa3, + 0x60, 0x55, 0x48, 0x05, 0x16, 0xae, 0x43, 0x90, + 0xdc, 0x8e, 0x09, 0xbe, 0x79, 0xf6, 0x90, 0x74, + 0xf8, 0x20, 0x96, 0x4d, 0xa7, 0xf5, 0x1a, 0x2b, + 0xc7, 0x15, 0x9d, 0x18, 0xf7, 0x94, 0x87, 0xf7, + 0xf4, 0xfb, 0x0d, 0x61, 0xb6, 0xd7, 0xbe, 0x10, + 0x8e, 0x47, 0x3c, 0x10, 0x44, 0x90, 0x52, 0x21, + 0x83, 0xc0, 0xf5, 0x99, 0xaa, 0xbc, 0xf6, 0x55, + 0xae, 0xf5, 0xb2, 0xa4, 0xcd, 0x4d, 0xb9, 0x38, + 0x6c, 0xbc, 0x80, 0xc3, 0xad, 0xf4, 0x46, 0x31, + 0x01, 0x58, 0x2d, 0x88, 0x57, 0xc3, 0x23, 0xd1, + 0x64, 0xc9, 0xa3, 0x21, 0x6b, 0x8b, 0x8a, 0x23, + 0x2c, 0x4f, 0xa9, 0xcd, 0x67, 0xfa, 0x77, 0xad, + 0xa3, 0x16, 0xa2, 0xe5, 0x19, 0x14, 0x70, 0x41, + 0x5b, 0xda, 0x14, 0xde, 0xe3, 0xe5, 0xc1, 0x15, + 0xb4, 0x77, 0xa4, 0x9b, 0xb8, 0xb1, 0x28, 0x51, + 0x30, 0xb4, 0xf1, 0xf3, 0xf8, 0x6d, 0xd0, 0xc3, + 0x8c, 0x4c, 0x76, 0xb0, 0x9a, 0xdf, 0xc8, 0xbe, + 0xf8, 0x4a, 0x61, 0x6e, 0x3e, 0xd6, 0x3c, 0xe8, + 0xde, 0x56, 0xa0, 0x9c, 0x25, 0xbe, 0xce, 0x93, + 0x1f, 0x88, 0xfb, 0x9a, 0x1a, 0xe2, 0xff, 0x88, + 0xad, 0x10, 0xcb, 0x6c, 0xd6, 0xe7, 0x39, 0x0b, + 0xe5, 0x1a, 0x06, 0x05, 0x64, 0x5b, 0x0a, 0xdf, + 0x22, 0x58, 0xd7, 0xfb, 0x88, 0x12, 0xdd, 0xb7, + 0x52, 0x3a, 0xc9, 0xbf, 0x49, 0xdf, 0x8c, 0x87, + 0x9f, 0x84, 0xb5, 0x0a, 0xf6, 0x00, 0x52, 0xae, + 0x67, 0x12, 0x1a, 0x8c, 0x71, 0x15, 0xf5, 0xa1, + 0x13, 0x39, 0xf0, 0x91, 0x7e, 0x88, 0x7c, 0xb3, + 0x95, 0x50, 0x02, 0xa6, 0x63, 0xb5, 0x64, 0xfb, + 0x90, 0x87, 0x61, 0xe2, 0x27, 0xaf, 0x11, 0x0c, + 0x73, 0x83, 0xef, 0xa9, 0x28, 0xfe, 0xc8, 0x85, + 0x1a, 0x3a, 0xde, 0xf2, 0xe5, 0x25, 0x64, 0x6d, + 0xaa, 0x41, 0x4c, 0x80, 0x2e, 0x84, 0xff, 0xc1, + 0xc0, 0x54, 0x0c, 0x29, 0x1b, 0xa3, 0x07, 0x7c, + 0x33, 0x4c, 0x10, 0xf6, 0x6f, 0x79, 0xdf, 0xd3, + 0xf0, 0x24, 0x57, 0xf1, 0x60, 0xe1, 0xf0, 0xbd, + 0xc4, 0x1f, 0xf4, 0x67, 0xd2, 0xd3, 0xcc, 0x6a, + 0x07, 0x72, 0x44, 0x16, 0x85, 0x46, 0xd0, 0x73, + 0x87, 0xa9, 0xc7, 0x2f, 0xd1, 0xf5, 0xec, 0xe3, + 0x28, 0xa3, 0x93, 0x4f, 0xd7, 0x76, 0xc1, 0x3c, + 0x0d, 0x13, 0x33, 0xcf, 0x5b, 0xbd, 0x6a, 0x52, + 0x4e, 0xee, 0xc8, 0x5e, 0xa1, 0x58, 0x4a, 0x08, + 0x81, 0xd9, 0x23, 0xcc, 0xfb, 0x1c, 0xb2, 0xd8, + 0xa3, 0xe4, 0x53, 0xfe, 0xf4, 0x4b, 0x48, 0xc1, + 0x20, 0xa4, 0x97, 0xf8, 0x38, 0xa3, 0x69, 0xc1, + 0x11, 0xf0, 0xa1, 0x3b, 0xa9, 0x9a, 0x12, 0x61, + 0xe8, 0x8d, 0x99, 0x44, 0x3f, 0x94, 0x72, 0x82, + 0x19, 0x96, 0x62, 0xb0, 0xa6, 0x64, 0x05, 0x19, + 0x8f, 0xd6, 0x5d, 0x05, 0xbf, 0x79, 0x9e, 0x9d, + 0xe4, 0x93, 0x4c, 0xad, 0x61, 0x8c, 0x18, 0xda, + 0xb6, 0x2e, 0xb3, 0xca, 0x14, 0x4d, 0x53, 0xa4, + 0x97, 0x27, 0x10, 0x56, 0xa2, 0x67, 0x5a, 0x5a, + 0x5e, 0x13, 0xc0, 0xdb, 0xa7, 0x9f, 0x45, 0x5b, + 0xeb, 0x1a, 0x14, 0x0c, 0x8c, 0x38, 0x5e, 0x77, + 0x9a, 0xec, 0x75, 0x68, 0x93, 0x65, 0x02, 0x9c, + 0xfb, 0x62, 0x60, 0x49, 0xdd, 0xb2, 0x2a, 0x67, + 0x86, 0xe3, 0x8a, 0x7d, 0x8c, 0x46, 0x78, 0x81, + 0x60, 0x69, 0xf2, 0x3f, 0x74, 0x11, 0x35, 0xff, + 0x77, 0xa3, 0x66, 0x20, 0xfc, 0x98, 0x4a, 0x35, + 0x7a, 0x52, 0xe4, 0x90, 0x13, 0x80, 0xb9, 0xa6, + 0x73, 0x7a, 0x7d, 0x66, 0x6e, 0x6b, 0xb6, 0x43, + 0x10, 0xd5, 0x91, 0x2b, 0x66, 0xdd, 0x89, 0x87, + 0xe3, 0x8c, 0x58, 0x53, 0x2f, 0x40, 0x74, 0x45, + 0x1b, 0x77, 0x7a, 0xa4, 0x44, 0x19, 0x78, 0xba, + 0x87, 0x10, 0x41, 0x31, 0x32, 0x5f, 0x87, 0x68, + 0xde, 0x43, 0x4a, 0xef, 0x33, 0xb3, 0x11, 0x83, + 0xa9, 0xc2, 0x6f, 0x8d, 0x34, 0xe2, 0x95, 0x84, + 0x3a, 0x4f, 0x6f, 0x8c, 0x31, 0x1d, 0xb6, 0xf5, + 0x95, 0x0d, 0x01, 0x11, 0x20, 0xdf, 0x72, 0xf3, + 0x3f, 0x9a, 0x33, 0xaa, 0xb1, 0x06, 0x6a, 0x63, + 0x47, 0x91, 0x01, 0xdf, 0xb3, 0x54, 0x36, 0xfd, + 0x06, 0x2d, 0xb8, 0x08, 0xe3, 0xd3, 0x65, 0xac, + 0x66, 0x03, 0xee, 0xa4, 0x63, 0xbd, 0xd4, 0xce, + 0xbd, 0x79, 0xa7, 0x48, 0x38, 0xc5, 0x7d, 0xb5, + 0x71, 0x9a, 0x3c, 0x11, 0x7c, 0x6c, 0xe2, 0x54, + 0x02, 0x5d, 0x42, 0xab, 0x25, 0x93, 0x66, 0x01, + 0x37, 0x78, 0x35, 0x4a, 0x8c, 0x19, 0x4d, 0x00, + 0x75, 0x4f, 0xcc, 0xc0, 0x26, 0x82, 0xc1, 0x35, + 0x8c, 0xc7, 0xc2, 0x59, 0x01, 0x3e, 0x98, 0x22, + 0x88, 0x9c, 0x90, 0x75, 0x05, 0x33, 0x07, 0xb9, + 0x39, 0x81, 0x38, 0x58, 0x10, 0x29, 0xcf, 0xc8, + 0x98, 0xb2, 0x03, 0xd7, 0x5b, 0xb3, 0x18, 0xba, + 0x34, 0x0c, 0x9f, 0xab, 0xd7, 0xed, 0x29, 0x82, + 0x41, 0xe0, 0x20, 0x97, 0x57, 0x92, 0xb2, 0xb8, + 0x10, 0x2d, 0x0b, 0xa2, 0xc5, 0x8f, 0x90, 0x6f, + 0xed, 0x12, 0x56, 0x25, 0xbe, 0xfd, 0x75, 0xf7, + 0xb6, 0xf8, 0x40, 0x67, 0x39, 0x11, 0xfa, 0x15, + 0xae, 0x6a, 0x54, 0x5f, 0x32, 0x2b, 0xf8, 0x48, + 0x55, 0xbe, 0x86, 0x2f, 0x69, 0x48, 0x5b, 0x5d, + 0x4d, 0xb7, 0x35, 0xaa, 0xb6, 0x91, 0x88, 0x19, + 0x96, 0x1c, 0x68, 0xf6, 0x85, 0x9e, 0xb3, 0xb2, + 0xa3, 0x32, 0xd4, 0x52, 0x70, 0xb7, 0x62, 0xe3, + 0x14, 0xb6, 0x78, 0x5f, 0x1b, 0x1d, 0x04, 0x9c, + 0x26, 0x0c, 0x33, 0x94, 0xb1, 0x97, 0x08, 0xdb, + 0x0b, 0x39, 0x29, 0xd4, 0xbc, 0x6d, 0xdf, 0x02, + 0xc6, 0x99, 0xab, 0x99, 0x32, 0xe5, 0xce, 0x51, + 0x4f, 0xae, 0xb8, 0x8b, 0xe0, 0xaf, 0x07, 0xc4, + 0xf9, 0x41, 0x7c, 0x59, 0xa0, 0xac, 0x74, 0x4d, + 0x7e, 0x43, 0x77, 0x9c, 0x06, 0x49, 0x79, 0x8a, + 0x14, 0x73, 0x93, 0xa8, 0x5b, 0x1b, 0x34, 0x29, + 0x78, 0x04, 0x2f, 0xd7, 0x1f, 0x13, 0x90, 0xe0, + 0xdd, 0x3b, 0x42, 0x6b, 0x79, 0x6e, 0x52, 0xc7, + 0x0f, 0x38, 0xda, 0x01, 0x2c, 0x8d, 0xe6, 0x94, + 0x5d, 0x59, 0x27, 0x1d, 0x10, 0x4e, 0x11, 0x36, + 0xfb, 0x53, 0x16, 0x05, 0x25, 0xf2, 0x64, 0xd8, + 0xf9, 0xcd, 0x5c, 0xfe, 0xb4, 0x18, 0x44, 0x80, + 0x10, 0xbc, 0x3d, 0xf3, 0x1d, 0x5a, 0xf0, 0xc1, + 0xc3, 0x55, 0xff, 0x41, 0x3e, 0xe3, 0xef, 0x44, + 0xb2, 0xc0, 0x01, 0x18, 0xa2, 0x49, 0x88, 0x78, + 0x0d, 0x4c, 0xc8, 0x73, 0xcf, 0x30, 0x85, 0x3a, + 0x88, 0x90, 0x01, 0xcf, 0x69, 0x53, 0xa3, 0x18, + 0x3f, 0xd6, 0xe7, 0x94, 0x14, 0xa7, 0xae, 0xcd, + 0x6f, 0x11, 0x72, 0xfe, 0x2b, 0xb0, 0x81, 0x53, + 0xea, 0x67, 0xd6, 0xe4, 0xca, 0x42, 0xa0, 0xf9, + 0xb1, 0xd4, 0xb5, 0x3b, 0xc9, 0xf0, 0x36, 0xc1, + 0x1c, 0xf4, 0xb1, 0xf6, 0x84, 0xd0, 0x86, 0x6c, + 0x76, 0x9a, 0x03, 0xc2, 0xb6, 0x2e, 0x9a, 0x46, + 0xf5, 0x5f, 0x2c, 0x38, 0xac, 0xad, 0x6f, 0x2e, + 0x7a, 0x18, 0x2d, 0x22, 0x95, 0x5e, 0x5e, 0xc9, + 0x7a, 0x0a, 0x56, 0xe1, 0xc7, 0x15, 0xfd, 0xbf, + 0xff, 0xf7, 0x7e, 0x85, 0x20, 0xa9, 0x8a, 0x9c, + 0xa9, 0x7d, 0xe8, 0xed, 0xfc, 0x7f, 0xbb, 0xf0, + 0x05, 0x3f, 0xce, 0x4f, 0x4c, 0xee, 0xa4, 0xa0, + 0xcc, 0x9c, 0x62, 0x1e, 0xd6, 0xd0, 0x30, 0x37, + 0xb8, 0x98, 0x56, 0x1d, 0xaa, 0xd6, 0x5e, 0x73, + 0x12, 0xe4, 0x88, 0x82, 0x48, 0x64, 0x06, 0xd7, + 0x2a, 0x31, 0x50, 0x7b, 0x10, 0x17, 0xb8, 0x4c, + 0x5a, 0x8d, 0xf1, 0xfc, 0xf1, 0x33, 0x3b, 0x98, + 0x42, 0x18, 0x5b, 0x35, 0x78, 0xca, 0x8e, 0x41, + 0x52, 0xae, 0x6d, 0xe1, 0xa2, 0x9d, 0x5b, 0xbd, + 0xf3, 0x5f, 0x49, 0xc1, 0x27, 0x06, 0xc1, 0xaf, + 0xc0, 0xa3, 0x9d, 0xf3, 0x1c, 0x8e, 0x90, 0x8a, + 0xb0, 0x69, 0xb0, 0xc5, 0x11, 0x0c, 0x91, 0x14, + 0x1f, 0x5e, 0x10, 0xe1, 0x1d, 0x14, 0x30, 0x54, + 0x1e, 0x17, 0x3d, 0x31, 0x7b, 0xbf, 0x2f, 0x9d, + 0x6d, 0x63, 0x32, 0xf0, 0x9d, 0x9f, 0x95, 0x3d, + 0x0b, 0xd2, 0x4d, 0x10, 0xe2, 0x3f, 0x67, 0x69, + 0x43, 0x9a, 0x4a, 0x2c, 0x54, 0x71, 0xa8, 0xa0, + 0x9e, 0x9f, 0x10, 0xaf, 0x1b, 0xce, 0x99, 0xe3, + 0x25, 0x32, 0x10, 0x54, 0x80, 0xfe, 0xda, 0x57, + 0xd0, 0xb2, 0x92, 0x7f, 0xbb, 0x5f, 0xe7, 0x4d, + 0x1b, 0x3d, 0x46, 0x4d, 0xe4, 0x4c, 0xd6, 0xaf, + 0x1a, 0x32, 0x12, 0x40, 0xb8, 0x84, 0x8e, 0xe4, + 0x80, 0xce, 0x7e, 0xc1, 0x13, 0x8b, 0xb0, 0xb7, + 0x6f, 0x24, 0xba, 0x85, 0x50, 0x83, 0xc3, 0xcf, + 0x19, 0xb3, 0xf0, 0xc7, 0xee, 0x68, 0xbe, 0x9e, + 0x6d, 0xb9, 0xfb, 0xd5, 0x29, 0xce, 0x82, 0xcd, + 0x69, 0x16, 0x68, 0x6b, 0x6a, 0xf4, 0x02, 0x32, + 0xce, 0x60, 0x37, 0x0c, 0xb9, 0x38, 0x92, 0x9c, + 0x42, 0xa9, 0x0b, 0x53, 0x96, 0xfe, 0x39, 0xc1, + 0x24, 0x65, 0x9b, 0xcd, 0xe7, 0x8d, 0x36, 0x07, + 0x9f, 0x1d, 0x35, 0x8e, 0xdc, 0x4c, 0xb5, 0x68, + 0xc5, 0xfd, 0x44, 0x19, 0xf2, 0x6c, 0x59, 0x1c, + 0xb1, 0x0b, 0x35, 0x48, 0x86, 0x1a, 0x05, 0x22, + 0x03, 0x0c, 0x0c, 0xa2, 0x92, 0x90, 0x35, 0xfb, + 0x37, 0x94, 0xc7, 0x15, 0x84, 0xae, 0xe8, 0x05, + 0xa0, 0xf7, 0x30, 0x11, 0x5c, 0xe4, 0x5d, 0x3e, + 0x12, 0x54, 0x80, 0x54, 0x6b, 0x09, 0x8c, 0xce, + 0x80, 0x5e, 0xa7, 0xc8, 0x6a, 0x0c, 0x56, 0xe1, + 0x18, 0x7d, 0xc9, 0x39, 0xc1, 0xef, 0xe3, 0x25, + 0xa0, 0x8b, 0x2f, 0x60, 0x3a, 0x43, 0x39, 0xa6, + 0x28, 0x28, 0x7b, 0x4c, 0x77, 0xd4, 0x49, 0x61, + 0x46, 0xe9, 0x1b, 0x45, 0xd6, 0xb1, 0x56, 0xe1, + 0x7d, 0x34, 0xcd, 0x06, 0xb6, 0x67, 0x8d, 0x7d, + 0x7a, 0xe2, 0xbe, 0x68, 0x35, 0xa6, 0x78, 0xe5, + 0x47, 0x48, 0xb7, 0xc7, 0xde, 0xcd, 0xc9, 0x05, + 0xb4, 0xe7, 0x50, 0x48, 0xe1, 0x4b, 0xfe, 0x76, + 0x77, 0xc6, 0xf7, 0x5f, 0xcb, 0xc2, 0xa8, 0xd7, + 0xd6, 0x8a, 0xe5, 0x49, 0xd9, 0xca, 0x45, 0xf4, + 0xda, 0xcd, 0x33, 0xd1, 0x59, 0x2d, 0x9e, 0xc1, + 0x5c, 0xe6, 0x01, 0x18, 0xb8, 0xf0, 0x5e, 0xb1, + 0x69, 0x95, 0x2f, 0x02, 0x2a, 0xe7, 0x4a, 0xd7, + 0xd1, 0xc3, 0xd5, 0x6f, 0x15, 0xc8, 0xdc, 0x29, + 0xde, 0xb9, 0x3f, 0x8b, 0xa6, 0xbc, 0xdd, 0x25, + 0x84, 0x35, 0x3c, 0x90, 0x2d, 0xc2, 0x1e, 0x98, + 0x8a, 0x50, 0x09, 0x77, 0x42, 0xe9, 0x35, 0x8a, + 0x7c, 0x97, 0xbf, 0xe8, 0xbf, 0x56, 0xd0, 0x8b, + 0x65, 0xd3, 0xaf, 0x1e, 0x05, 0x94, 0xfa, 0xac, + 0xa8, 0x2b, 0x28, 0xcb, 0x37, 0x3e, 0xe8, 0xbb, + 0x66, 0x3a, 0xed, 0xb2, 0x48, 0x10, 0x0f, 0x3a, + 0x5a, 0xc5, 0xdb, 0x26, 0x0e, 0xaa, 0x5e, 0x69, + 0x15, 0xd6, 0x81, 0xae, 0xbd, 0xe6, 0x03, 0xf1, + 0xf6, 0x37, 0xc8, 0xde, 0x70, 0x1f, 0x64, 0xb9, + 0x5e, 0xbf, 0x2e, 0x4f, 0xb1, 0xea, 0xa0, 0x17, + 0xe6, 0x7c, 0xf9, 0x2f, 0x1e, 0xd8, 0x58, 0xde, + 0xa7, 0xf0, 0x46, 0x52, 0x95, 0xdf, 0xa4, 0x96, + 0xd0, 0xc4, 0x97, 0x2b, 0x95, 0xcd, 0x5e, 0x40, + 0x23, 0x5c, 0x10, 0xee, 0xba, 0x72, 0x9b, 0xcf, + 0x0b, 0xe8, 0x18, 0x3a, 0x70, 0xd2, 0x5e, 0x07, + 0x68, 0x93, 0xef, 0x4a, 0x5b, 0x8d, 0x72, 0x41, + 0x4e, 0xea, 0x33, 0x6a, 0x0a, 0x5e, 0xfb, 0x02, + 0x3f, 0xd4, 0xed, 0x5b, 0xe0, 0x42, 0x84, 0xd4, + 0xaa, 0x85, 0xdc, 0x5b, 0x67, 0xee, 0x71, 0x67, + 0xba, 0x8e, 0xd2, 0xbe, 0x61, 0xdf, 0x5a, 0x26, + 0xb9, 0xf0, 0x77, 0x81, 0x53, 0x24, 0x16, 0xcb, + 0x8c, 0xb8, 0x06, 0x6e, 0x68, 0xda, 0xc8, 0x2d, + 0x17, 0x54, 0xdb, 0x46, 0xcb, 0xfd, 0x1f, 0x3d, + 0x94, 0x81, 0x09, 0x4b, 0xfa, 0xb1, 0x46, 0xd9, + 0x11, 0xa3, 0xb7, 0x31, 0x9c, 0xd2, 0x38, 0xd6, + 0xba, 0x3d, 0xa3, 0x74, 0xd8, 0xf1, 0x24, 0xe8, + 0x9c, 0xcb, 0x1d, 0xf9, 0x4a, 0xf7, 0xc8, 0x4b, + 0xfe, 0x97, 0x7c, 0xa1, 0x02, 0xeb, 0x40, 0xc3, + 0x89, 0x71, 0x01, 0xcd, 0x33, 0x2a, 0xc2, 0x82, + 0xce, 0x62, 0x8d, 0x53, 0x7c, 0xdf, 0xce, 0xd7, + 0xf5, 0xa8, 0x4f, 0xf2, 0xf2, 0x2e, 0xc1, 0xeb, + 0x97, 0x99, 0x37, 0x3c, 0x53, 0xa6, 0xb4, 0x46, + 0x05, 0x64, 0x92, 0x87, 0x08, 0x3c, 0x23, 0x4b, + 0x9d, 0x67, 0x18, 0xf9, 0xe2, 0x0b, 0x1c, 0x39, + 0xd3, 0x87, 0x70, 0xc0, 0xb9, 0x1e, 0x52, 0x0a, + 0x0f, 0x48, 0xe2, 0xe7, 0x51, 0x72, 0x94, 0xf7, + 0xa3, 0xdc, 0xe5, 0x66, 0x33, 0x39, 0x54, 0x06, + 0x55, 0x93, 0x30, 0xf9, 0x5e, 0x76, 0x8f, 0xe0, + 0x59, 0x4d, 0x0d, 0xa7, 0xf5, 0xbe, 0xdb, 0x20, + 0xad, 0x0d, 0x76, 0x88, 0x5f, 0x9c, 0x7c, 0x75, + 0x2f, 0x2a, 0x0b, 0x79, 0x6e, 0xd3, 0xe2, 0x66, + 0xf5, 0x4a, 0x2d, 0x87, 0x87, 0x49, 0x84, 0x17, + 0xa2, 0x62, 0x4c, 0xbb, 0xe4, 0x6e, 0x98, 0x10, + 0xc9, 0xfb, 0x8a, 0x04, 0x68, 0x8d, 0x22, 0x66, + 0xad, 0xea, 0x2a, 0xc9, 0x97, 0x2d, 0x3c, 0xbc, + 0xd0, 0x77, 0x5f, 0xe6, 0xb8, 0x7f, 0xe6, 0xf6, + 0x39, 0xbf, 0x56, 0x0e, 0x26, 0x6d, 0xc5, 0x3e, + 0x53, 0x19, 0xd6, 0xb4, 0x57, 0x36, 0xa3, 0xc6, + 0xd3, 0x3d, 0x66, 0x79, 0x30, 0x5c, 0x14, 0x0c, + 0x0f, 0x3e, 0x96, 0xae, 0x90, 0x97, 0xab, 0x0d, + 0x9f, 0xc3, 0xe7, 0x66, 0x3e, 0xe0, 0x31, 0x43, + 0x4b, 0x01, 0xb3, 0x0e, 0x9e, 0x8c, 0x82, 0x4a, + 0x8c, 0xc7, 0x79, 0x85, 0xdf, 0x75, 0x0d, 0xb4, + 0x2b, 0x03, 0x14, 0xef, 0x72, 0x58, 0xfd, 0x64, + 0xc8, 0xe3, 0x0d, 0x9a, 0x14, 0x6f, 0x76, 0xf9, + 0x46, 0xd1, 0xd2, 0x81, 0xb3, 0x16, 0x6e, 0xc7, + 0x76, 0x82, 0xce, 0xf4, 0xee, 0x33, 0x00, 0xe6, + 0x77, 0xc4, 0xad, 0x4f, 0x06, 0xa7, 0x48, 0x80, + 0x9e, 0x21, 0x66, 0xca, 0x75, 0x69, 0x57, 0xcb, + 0xf0, 0x67, 0x6a, 0xaa, 0x8f, 0x88, 0x14, 0xbd, + 0x65, 0x62, 0xe2, 0xad, 0xcc, 0x22, 0x88, 0x7b, + 0x94, 0xbd, 0x0e, 0xcd, 0xb6, 0x69, 0xa2, 0xcb, + 0x7d, 0x57, 0x5c, 0xb4, 0x92, 0x80, 0x13, 0x99, + 0x84, 0xf3, 0x79, 0x0a, 0x2d, 0x70, 0xa4, 0xe0, + 0xde, 0xc6, 0x32, 0xb0, 0x8a, 0x62, 0xb5, 0xcf, + 0xfa, 0x5e, 0x5a, 0x92, 0x32, 0x7d, 0x34, 0x07, + 0xb5, 0x52, 0x3a, 0xb5, 0x7d, 0x0f, 0xa1, 0xba, + 0x56, 0xd0, 0x07, 0x76, 0x11, 0xf2, 0xc3, 0x33, + 0x9d, 0xbd, 0x12, 0x35, 0x5e, 0xf7, 0x05, 0x88, + 0x76, 0x94, 0xa6, 0xbf, 0xed, 0xb8, 0xa4, 0xa2, + 0x0c, 0xbe, 0x0f, 0x6a, 0xaf, 0xf3, 0x1b, 0x33, + 0x4a, 0xb7, 0x68, 0x3f, 0xbe, 0x95, 0x13, 0x97, + 0x0f, 0x15, 0x17, 0x1b, 0x23, 0xaa, 0x08, 0x78, + 0xa6, 0x5b, 0x08, 0xa2, 0x9d, 0x03, 0xa8, 0xa7, + 0x39, 0xdc, 0xbc, 0x9a, 0x85, 0xf5, 0xe5, 0x55, + 0x59, 0x3c, 0xef, 0xf9, 0x3f, 0x22, 0x8e, 0xf8, + 0xd8, 0x3e, 0x02, 0x0b, 0xd8, 0x78, 0x4b, 0x15, + 0x7f, 0xaa, 0x2c, 0xff, 0xbe, 0x77, 0x33, 0xc7, + 0x6a, 0x12, 0xaa, 0xa4, 0xbe, 0xc0, 0x3b, 0xcb, + 0x13, 0x9d, 0x9c, 0x5a, 0x9f, 0x8a, 0x57, 0x36, + 0x4f, 0x02, 0x5a, 0xf8, 0x1d, 0x97, 0x77, 0x43, + 0xc8, 0xa5, 0xb7, 0x9b, 0x10, 0x98, 0xfd, 0x58, + 0xbf, 0x42, 0xf6, 0xbf, 0xff, 0x6c, 0x40, 0x18, + 0x18, 0xdf, 0xac, 0x57, 0x71, 0xea, 0xcc, 0x8e, + 0xfd, 0xfe, 0x10, 0xfb, 0xb9, 0xfe, 0xbc, 0x9a, + 0x9c, 0x27, 0xe4, 0x10, 0x15, 0x94, 0x41, 0xa1, + 0xcc, 0xf6, 0x25, 0x49, 0x4f, 0x96, 0xc1, 0x8c, + 0x9e, 0x3e, 0x18, 0x29, 0x49, 0x92, 0xe7, 0xfe, + 0x22, 0xff, 0xed, 0x02, 0x16, 0x90, 0xef, 0xac, + 0xec, 0x95, 0x1d, 0x5b, 0x94, 0x9c, 0xf6, 0x7c, + 0x1b, 0x5a, 0x9d, 0xb0, 0x9b, 0x05, 0x36, 0xbf, + 0xef, 0xec, 0x63, 0x35, 0x40, 0x24, 0x45, 0x40, + 0x30, 0x1a, 0x9b, 0x90, 0xc3, 0xc2, 0xf7, 0x37, + 0xfb, 0x08, 0x8e, 0x48, 0x19, 0x48, 0xed, 0xa8, + 0xa8, 0x04, 0x6f, 0xd0, 0x33, 0xe9, 0xb8, 0x8d, + 0xe7, 0x1e, 0x5c, 0x47, 0x74, 0xc0, 0x66, 0x30, + 0x4e, 0xa7, 0x86, 0x73, 0xf1, 0xe5, 0x78, 0xa6, + 0xe0, 0xc1, 0xda, 0x13, 0x72, 0x07, 0x85, 0x34, + 0x63, 0x95, 0x49, 0x30, 0x4b, 0x9d, 0x03, 0xf1, + 0x7a, 0x6b, 0x91, 0xa2, 0x85, 0x41, 0xf9, 0x4a, + 0xd6, 0xff, 0xff, 0x86, 0xf7, 0xf0, 0xce, 0xb9, + 0x07, 0xf1, 0x88, 0x04, 0x33, 0xaa, 0xeb, 0x54, + 0xb2, 0x1c, 0x8e, 0x2e, 0x7b, 0x04, 0xa8, 0xcc, + 0x2c, 0x7a, 0xb3, 0xad, 0x1a, 0x89, 0x38, 0x89, + 0xd7, 0x11, 0x3a, 0x8c, 0xcf, 0xe3, 0xc5, 0xba, + 0xb0, 0xcc, 0xc4, 0xe3, 0x33, 0xf3, 0x18, 0xba, + 0xec, 0x56, 0xd9, 0x1c, 0x40, 0x70, 0x0d, 0x4e, + 0x97, 0x01, 0x23, 0xf3, 0x5a, 0xdc, 0xbf, 0x68, + 0x93, 0xc2, 0x1d, 0x8a, 0x96, 0xb7, 0xac, 0x18, + 0x6f, 0xf7, 0x84, 0x71, 0x0d, 0x3d, 0xf8, 0xba, + 0xdf, 0xb6, 0x89, 0x1d, 0x78, 0x19, 0xf2, 0x59, + 0xe9, 0x15, 0x55, 0x29, 0x73, 0x50, 0x59, 0x14, + 0x02, 0x21, 0x16, 0x8f, 0x0f, 0xdf, 0xa5, 0xf0, +}; + +static struct crc_test { + uint32_t crc; /* random starting crc */ + uint32_t start; /* random offset in buf */ + uint32_t length; /* random length of test */ + uint32_t crc_le; /* expected crc32_le result */ + uint32_t crc_be; /* expected crc32_be result */ +} test[] = { + {0xffffffff, 0x00000000, 0x00001000, 0x13934bef, 0x14f3b75f}, + {0xfe7328ea, 0x00000763, 0x00000717, 0xed2c0d70, 0x57531214}, + {0x4c40684e, 0x00000721, 0x0000011e, 0xd7f46ccc, 0xedf12ec3}, + {0x6b487f90, 0x00000264, 0x000007bc, 0x759e9939, 0x9af8e387}, + {0x9f5810db, 0x00000afa, 0x00000255, 0x2685197f, 0x716de6ed}, + {0xb15c4755, 0x00000d5b, 0x000002a4, 0xd8fadcb5, 0xfc34ae3f}, + {0x06518253, 0x00000ffb, 0x00000004, 0xabee2433, 0xfa30ac9e}, + {0xd9e71c55, 0x00000a2a, 0x00000259, 0x96682af2, 0xe5907ea3}, + {0x0c1ae843, 0x00000ce4, 0x0000031b, 0x7b637c43, 0xe7f71b04}, + {0xec3cd517, 0x000002ff, 0x00000566, 0x5d719a77, 0xed16e045}, + {0x77828e95, 0x0000067f, 0x0000038f, 0x43ee5b6c, 0x35999927}, + {0xec87b4e3, 0x00000d1c, 0x000002e3, 0x2ddd2eee, 0x9452d3f8}, + {0x412158bb, 0x00000eee, 0x00000111, 0x67b38ba2, 0x177976d0}, + {0x2e52de3e, 0x00000c4a, 0x000003b5, 0xbcc5d61d, 0xf60fee71}, + {0x6ddaae8b, 0x00000d99, 0x00000266, 0x8b535544, 0x1dab8596}, + {0x049b6cb1, 0x000009c5, 0x000000b0, 0xfc22cabc, 0x47ebc954}, + {0x77d4b954, 0x0000028a, 0x000007fa, 0x71d00923, 0x905585ef}, + {0x5e192355, 0x00000ac1, 0x000001fa, 0xb966b81a, 0x33c12903}, + {0x7d80b71d, 0x00000213, 0x000001e0, 0x2bba371a, 0x5f4bd8d9}, + {0x01f6f1e4, 0x000001d6, 0x00000395, 0xb7e8a647, 0x2a7943a1}, + {0x1dfabb13, 0x00000e14, 0x000001eb, 0x53917fba, 0x8dee1e5d}, + {0xb00a4449, 0x00000bf6, 0x00000409, 0xedecb577, 0x628e087d}, + {0x7ecd3981, 0x0000083f, 0x0000016b, 0xefef62b9, 0xda4f94e6}, + {0xf8f330d2, 0x000004be, 0x00000757, 0x9357c9f3, 0x8e2d5c2f}, + {0x03c38af2, 0x00000d23, 0x000002dc, 0x360fa8c0, 0x6294c0d6}, + {0x687bb79b, 0x00000f3d, 0x000000c2, 0x448d3be2, 0x08f48f3a}, + {0x6710f550, 0x000009e9, 0x00000603, 0xdbfd1998, 0xc950ac29}, + {0x873171d1, 0x00000787, 0x000004d5, 0xab7f1b62, 0xe66896ab}, + {0x373b1314, 0x00000f0f, 0x000000f0, 0x184098ab, 0x4038e674}, + {0x90fad9cd, 0x00000ead, 0x00000152, 0x23ce52ff, 0x9eff3974}, + {0x19676fe7, 0x0000007d, 0x0000070d, 0xf8a76f1e, 0xfbc5c8a9}, + {0x89facd45, 0x000005f3, 0x00000473, 0x4331a006, 0xb8f0f0cc}, + {0x6f173747, 0x00000fc3, 0x0000003c, 0xb012f08e, 0x5126e378}, + {0x4b44a106, 0x0000075a, 0x0000008b, 0xf6f7ac38, 0xf9b1781b}, + {0xb620ad06, 0x00000774, 0x0000017e, 0xd34558e6, 0xb175edd3}, + {0x976f21e9, 0x000008d7, 0x0000034a, 0xe533aa3a, 0x1e4367b9}, + {0x687628c0, 0x000006c5, 0x0000061b, 0x3a840b15, 0xfb5989a0}, + {0xe24ac108, 0x00000cd0, 0x0000032f, 0x51010ae8, 0xcdd8f182}, + {0x361c44a3, 0x00000304, 0x00000719, 0xfd7bd481, 0x12de540f}, + {0xd93ff95e, 0x00000db7, 0x0000008e, 0xcfbbc304, 0x42eecd5a}, + {0xed752d12, 0x00000883, 0x00000091, 0x65a6c868, 0x9ebfa578}, + {0xb4ff4b54, 0x000003d3, 0x000001c1, 0xf82597e7, 0xa8ad2b19}, + {0x111b520f, 0x00000708, 0x000000eb, 0xc3e109f3, 0x323ace17}, + {0x62c806f2, 0x00000ba3, 0x0000045c, 0x874d3a72, 0xaf1a1360}, + {0x40d97470, 0x000005e1, 0x0000058d, 0x87a9684f, 0x524244a8}, + {0x4312179c, 0x00000056, 0x0000070e, 0x809a00f5, 0xf9e940b0}, + {0x13d5f84c, 0x00000a2d, 0x00000104, 0xf3d27578, 0x5d33341c}, + {0x1f302cb2, 0x00000151, 0x00000014, 0x1e162693, 0x53c3cfc3}, + {0xe491db24, 0x00000600, 0x000006f6, 0x7ff09615, 0xa300ecf7}, + {0xf9a98069, 0x000002ba, 0x000002ad, 0x01af7387, 0x31c0911e}, + {0xe9c477ad, 0x0000015f, 0x00000778, 0x6facf9a0, 0x1993b688}, + {0x353f32b2, 0x0000087c, 0x00000783, 0x6cc964ea, 0x418db561}, + {0x78e1b24f, 0x00000650, 0x000006a8, 0xb3bb7c27, 0xf2aad006}, + {0x61aa400e, 0x00000049, 0x00000254, 0xb8cd1681, 0x79150b15}, + {0xb84b10b0, 0x00000f73, 0x0000008c, 0x406a6450, 0x0c705222}, + {0x9fa99c9c, 0x00000a7c, 0x000004d7, 0xfb3d21b4, 0xe4e789df}, + {0x3fc9ebe3, 0x00000cd9, 0x000000d6, 0x43803f9c, 0x5a152be5}, + {0x529879cd, 0x000002f2, 0x00000595, 0x78b4c6a6, 0xf7236ec4}, + {0x3a933019, 0x00000516, 0x00000266, 0xdcb45436, 0x2c7935f5}, + {0x887b4977, 0x00000227, 0x0000038d, 0xc5f7c3d9, 0x0d6d7df6}, + {0x770745de, 0x000008c6, 0x00000739, 0xf69145e8, 0x47d5efc9}, + {0x28be3b47, 0x00000c46, 0x0000032b, 0x764c028f, 0x1eb70d64}, + {0x5013a050, 0x00000cf6, 0x00000309, 0xea8fe164, 0x186affa4}, + {0x2ec4c9ba, 0x000006e8, 0x0000078d, 0xa35557a9, 0xb41f49ec}, + {0xa9f950c9, 0x00000d33, 0x000002cc, 0x41ea8618, 0xab8dfae3}, + {0x5b520229, 0x000007b2, 0x00000484, 0x44569f1f, 0x607a8052}, + {0xd8dcbbfc, 0x0000002f, 0x0000048c, 0xdb88ab8b, 0xf1c411f1}, + {0x25529792, 0x00000d1d, 0x000002e2, 0x20cda404, 0x32683a2d}, + {0x9f3f6d71, 0x00000238, 0x0000079a, 0x0720443e, 0x4b8ba2ff}, + {0x64121215, 0x000007ff, 0x0000038f, 0x6aacff2c, 0x3b84233b}, + {0xfb6cdde0, 0x00000ef8, 0x00000107, 0xbd43a0f1, 0x926624d0}, + {0x221c9d6f, 0x000007b6, 0x0000014f, 0xb67f834b, 0x2bdedda4}, + {0x030e1de4, 0x00000836, 0x000004b4, 0x0d67d26a, 0x75a73b73}, + {0xb56fa6cf, 0x00000c07, 0x000003f8, 0x60601ac1, 0x10a43f35}, + {0xb55c89f5, 0x0000098e, 0x000001d4, 0x2400efbe, 0x006e28eb}, + {0x5e90b6d5, 0x0000070b, 0x000003ea, 0x3bb5d6ea, 0xb175fa6b}, + {0x2a7045ae, 0x00000961, 0x00000633, 0xfca89e4b, 0x962cd6d2}, + {0x8b374ea9, 0x000006ba, 0x00000780, 0xbce036ed, 0x4dc8279b}, + {0x8bd90bc9, 0x00000562, 0x00000369, 0xcb26a24b, 0x50dee743}, + {0x5b1b1762, 0x000000fd, 0x0000051a, 0x33cdda07, 0xee75ff7b}, + {0xa4153555, 0x0000058f, 0x000005c7, 0xbe50eeca, 0xe73fffcc}, + {0x0be1f931, 0x00000651, 0x00000672, 0x95a25753, 0x4ad6270f}, + {0xb7e78618, 0x00000a7f, 0x000002bb, 0xe06bcc1c, 0x1a35ee59}, + {0x4a9bc41b, 0x00000e51, 0x000001ae, 0x709e8d2c, 0x75080ca8}, + {0xfc359d13, 0x00000440, 0x000002f8, 0x0a58451f, 0x6fa3cfbf}, + {0x5aa48619, 0x000006d1, 0x00000284, 0x928ead83, 0xbd600efc}, + {0xa609afa8, 0x0000053e, 0x00000272, 0xb048c141, 0x184f80bb}, + {0x3f108afb, 0x00000949, 0x00000150, 0x9a6bb5bc, 0x0ea02be1}, + {0x79bec2d3, 0x000008ed, 0x00000712, 0x32692d57, 0x2eb13289}, + {0x9429e067, 0x00000bc3, 0x0000043c, 0x5295ceff, 0x8a9014a7}, + {0xae58b96a, 0x0000082d, 0x000007d2, 0xc2a681ba, 0x6af94089}, + {0x95df24be, 0x00000985, 0x000004c1, 0x3a287765, 0x379fcb42}, + {0x5e94976f, 0x00000596, 0x000004ed, 0xff00c489, 0x991fc1f5}, + {0xf5e5f1de, 0x00000d31, 0x000002ce, 0x35f28e91, 0x543def1a}, + {0xa2c219cf, 0x00000a3c, 0x00000374, 0x707d21eb, 0xa6d28bc1}, + {0xf21b6ceb, 0x00000919, 0x00000135, 0x0847fb8b, 0x224468c2}, + {0xaa988728, 0x00000787, 0x00000771, 0x885aeaa4, 0x814db00b}, + {0xaa5dfaac, 0x000003e5, 0x0000051b, 0x52c48ab7, 0x725bef8a}, + {0x0a053968, 0x00000d2a, 0x000002d5, 0x7a90256d, 0xc53b9402}, + {0x1421dc20, 0x00000eef, 0x00000110, 0x97d6da24, 0x10846935}, + {0xb47c2166, 0x00000a6a, 0x00000209, 0xcfd6cc52, 0x46e2797e}, + {0x77dd1955, 0x000000de, 0x00000266, 0xba74bcaa, 0x4fa3fe9c}, + {0x68a03cc2, 0x0000082f, 0x000007b0, 0x752bd5d8, 0x4f760c63}, + {0x0226b0a3, 0x00000a5f, 0x000005a0, 0x82de4970, 0x8ee1310e}, + {0x637bf3b1, 0x00000d93, 0x0000026c, 0x5c7115cb, 0x9f6a0ced}, + {0x3b120edf, 0x00000c13, 0x000003ec, 0x80d7d20f, 0x241657d5}, + {0xe2456780, 0x000002eb, 0x00000641, 0xc0a5d289, 0x74df96b4}, + {0x9b2e7125, 0x00000c0c, 0x000003f3, 0xcc15f57e, 0x03e290bf}, + {0x153033ef, 0x00000787, 0x000006b6, 0x3cde443b, 0x7bf1d121}, + {0x18458b3f, 0x0000066c, 0x00000561, 0x9a2bd8c6, 0x9d564bef}, + {0x4ff9d4b9, 0x00000c8f, 0x0000033a, 0xd0ee6d6d, 0xee00aa0b}, + {0xdf84b5d9, 0x00000802, 0x0000029a, 0xdab0d74a, 0xd0cb63dc}, + {0x81ee15df, 0x000003ce, 0x00000725, 0x9942e2de, 0xe48fb26b}, + {0x5c768e04, 0x00000afd, 0x00000160, 0x36110831, 0x8dc74483}, + {0xe5e18094, 0x00000b4b, 0x000000a0, 0xffa3e4a7, 0xc0145e1b}, + {0xed7263b6, 0x00000d0d, 0x000002f2, 0xb0006a35, 0x5468ae3a}, + {0x5bfde7d7, 0x000006fb, 0x00000554, 0xa4193b76, 0xb73d34b2}, + {0x67f4a743, 0x00000b85, 0x0000047a, 0xf05c8d8f, 0x4f843e49}, + {0xf13bdf22, 0x00000ff7, 0x00000008, 0x816351eb, 0x41f537f6}, + {0x08ecc608, 0x00000d5d, 0x00000098, 0x90492772, 0xf5172204}, + {0x296f52ba, 0x000004f9, 0x00000788, 0x5e5a4896, 0xe01d5b46}, + {0xbe4624c2, 0x00000427, 0x000004ef, 0xcd267b94, 0x7b9069f4}, + {0x906f7c7c, 0x00000a05, 0x0000003f, 0x03fcfc33, 0x7b6ff563}, + {0x8f7b323e, 0x00000458, 0x000004c7, 0xcd4969c8, 0xd4c22ada}, + {0x88d6593d, 0x00000597, 0x000005b5, 0xf199cd3b, 0x5c3e8ca2}, + {0x978a7768, 0x00000268, 0x000001d3, 0xb28c95bd, 0x49a2cc67}, + {0x857a621e, 0x000007a7, 0x000003a8, 0xf4bf84ab, 0xde26f369}, + {0xb0e121ef, 0x000005be, 0x00000644, 0x28747c14, 0x61d4dc6b}, + {0, 0, 0, 0, 0}, +}; + +static int test_crc32c(void) +{ + struct crc_test *t = test; + int failures = 0; + + while (t->length) { + uint32_t be, le; + le = ext2fs_crc32c_le(t->crc, test_buf + t->start, t->length); + be = ext2fs_crc32c_be(t->crc, test_buf + t->start, t->length); + if (le != t->crc_le) { + printf("Test %d LE fails, %x != %x\n", + (t - test), le, t->crc_le); + failures++; + } + if (be != t->crc_be) { + printf("Test %d BE fails, %x != %x\n", + (t - test), be, t->crc_be); + failures++; + } + t++; + } + + return failures; +} + +int main(int argc, char *argv[]) +{ + int ret; + + ret = test_crc32c(); + if (!ret) + printf("No failures.\n"); + + return ret; +} +#endif /* UNITTEST */ diff --git a/portlibs/sources/libcustomext2fs/source/crc32c_defs.h b/portlibs/sources/libcustomext2fs/source/crc32c_defs.h new file mode 100644 index 00000000..023f2c01 --- /dev/null +++ b/portlibs/sources/libcustomext2fs/source/crc32c_defs.h @@ -0,0 +1,51 @@ +/* + * This is the CRC32c polynomial, as outlined by Castagnoli. + * x^32+x^28+x^27+x^26+x^25+x^23+x^22+x^20+x^19+x^18+x^14+x^13+x^11+x^10+x^9+ + * x^8+x^6+x^0 + */ +#define CRCPOLY_LE 0x82F63B78 +#define CRCPOLY_BE 0x1EDC6F41 + +/* How many bits at a time to use. Valid values are 1, 2, 4, 8, 32 and 64. */ +/* For less performance-sensitive, use 4 */ +#ifndef CRC_LE_BITS +# define CRC_LE_BITS 64 +#endif +#ifndef CRC_BE_BITS +# define CRC_BE_BITS 64 +#endif + +/* + * Little-endian CRC computation. Used with serial bit streams sent + * lsbit-first. Be sure to use cpu_to_le32() to append the computed CRC. + */ +#if CRC_LE_BITS > 64 || CRC_LE_BITS < 1 || CRC_LE_BITS == 16 || \ + CRC_LE_BITS & CRC_LE_BITS-1 +# error "CRC_LE_BITS must be one of {1, 2, 4, 8, 32, 64}" +#endif + +/* + * Big-endian CRC computation. Used with serial bit streams sent + * msbit-first. Be sure to use cpu_to_be32() to append the computed CRC. + */ +#if CRC_BE_BITS > 64 || CRC_BE_BITS < 1 || CRC_BE_BITS == 16 || \ + CRC_BE_BITS & CRC_BE_BITS-1 +# error "CRC_BE_BITS must be one of {1, 2, 4, 8, 32, 64}" +#endif + + +#define ___constant_swab32(x) \ + ((uint32_t)( \ + (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \ + (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \ + (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \ + (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24))) + + +#if (__GNUC__ >= 3) +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) +#else +#define likely(x) (x) +#define unlikely(x) (x) +#endif diff --git a/portlibs/sources/libcustomext2fs/source/crc32c_table.h b/portlibs/sources/libcustomext2fs/source/crc32c_table.h new file mode 100644 index 00000000..b3e2ed09 --- /dev/null +++ b/portlibs/sources/libcustomext2fs/source/crc32c_table.h @@ -0,0 +1,1065 @@ +/* + * crc32ctable.h - CRC32c tables + * this file is generated - do not edit + * # gen_crc32ctable > crc32c_table.h + * with + * CRC_LE_BITS = 64 + * CRC_BE_BITS = 64 + */ +#include +static const uint32_t t0_le[] = { +tole(0x00000000L), tole(0xf26b8303L), tole(0xe13b70f7L), tole(0x1350f3f4L), +tole(0xc79a971fL), tole(0x35f1141cL), tole(0x26a1e7e8L), tole(0xd4ca64ebL), +tole(0x8ad958cfL), tole(0x78b2dbccL), tole(0x6be22838L), tole(0x9989ab3bL), +tole(0x4d43cfd0L), tole(0xbf284cd3L), tole(0xac78bf27L), tole(0x5e133c24L), +tole(0x105ec76fL), tole(0xe235446cL), tole(0xf165b798L), tole(0x030e349bL), +tole(0xd7c45070L), tole(0x25afd373L), tole(0x36ff2087L), tole(0xc494a384L), +tole(0x9a879fa0L), tole(0x68ec1ca3L), tole(0x7bbcef57L), tole(0x89d76c54L), +tole(0x5d1d08bfL), tole(0xaf768bbcL), tole(0xbc267848L), tole(0x4e4dfb4bL), +tole(0x20bd8edeL), tole(0xd2d60dddL), tole(0xc186fe29L), tole(0x33ed7d2aL), +tole(0xe72719c1L), tole(0x154c9ac2L), tole(0x061c6936L), tole(0xf477ea35L), +tole(0xaa64d611L), tole(0x580f5512L), tole(0x4b5fa6e6L), tole(0xb93425e5L), +tole(0x6dfe410eL), tole(0x9f95c20dL), tole(0x8cc531f9L), tole(0x7eaeb2faL), +tole(0x30e349b1L), tole(0xc288cab2L), tole(0xd1d83946L), tole(0x23b3ba45L), +tole(0xf779deaeL), tole(0x05125dadL), tole(0x1642ae59L), tole(0xe4292d5aL), +tole(0xba3a117eL), tole(0x4851927dL), tole(0x5b016189L), tole(0xa96ae28aL), +tole(0x7da08661L), tole(0x8fcb0562L), tole(0x9c9bf696L), tole(0x6ef07595L), +tole(0x417b1dbcL), tole(0xb3109ebfL), tole(0xa0406d4bL), tole(0x522bee48L), +tole(0x86e18aa3L), tole(0x748a09a0L), tole(0x67dafa54L), tole(0x95b17957L), +tole(0xcba24573L), tole(0x39c9c670L), tole(0x2a993584L), tole(0xd8f2b687L), +tole(0x0c38d26cL), tole(0xfe53516fL), tole(0xed03a29bL), tole(0x1f682198L), +tole(0x5125dad3L), tole(0xa34e59d0L), tole(0xb01eaa24L), tole(0x42752927L), +tole(0x96bf4dccL), tole(0x64d4cecfL), tole(0x77843d3bL), tole(0x85efbe38L), +tole(0xdbfc821cL), tole(0x2997011fL), tole(0x3ac7f2ebL), tole(0xc8ac71e8L), +tole(0x1c661503L), tole(0xee0d9600L), tole(0xfd5d65f4L), tole(0x0f36e6f7L), +tole(0x61c69362L), tole(0x93ad1061L), tole(0x80fde395L), tole(0x72966096L), +tole(0xa65c047dL), tole(0x5437877eL), tole(0x4767748aL), tole(0xb50cf789L), +tole(0xeb1fcbadL), tole(0x197448aeL), tole(0x0a24bb5aL), tole(0xf84f3859L), +tole(0x2c855cb2L), tole(0xdeeedfb1L), tole(0xcdbe2c45L), tole(0x3fd5af46L), +tole(0x7198540dL), tole(0x83f3d70eL), tole(0x90a324faL), tole(0x62c8a7f9L), +tole(0xb602c312L), tole(0x44694011L), tole(0x5739b3e5L), tole(0xa55230e6L), +tole(0xfb410cc2L), tole(0x092a8fc1L), tole(0x1a7a7c35L), tole(0xe811ff36L), +tole(0x3cdb9bddL), tole(0xceb018deL), tole(0xdde0eb2aL), tole(0x2f8b6829L), +tole(0x82f63b78L), tole(0x709db87bL), tole(0x63cd4b8fL), tole(0x91a6c88cL), +tole(0x456cac67L), tole(0xb7072f64L), tole(0xa457dc90L), tole(0x563c5f93L), +tole(0x082f63b7L), tole(0xfa44e0b4L), tole(0xe9141340L), tole(0x1b7f9043L), +tole(0xcfb5f4a8L), tole(0x3dde77abL), tole(0x2e8e845fL), tole(0xdce5075cL), +tole(0x92a8fc17L), tole(0x60c37f14L), tole(0x73938ce0L), tole(0x81f80fe3L), +tole(0x55326b08L), tole(0xa759e80bL), tole(0xb4091bffL), tole(0x466298fcL), +tole(0x1871a4d8L), tole(0xea1a27dbL), tole(0xf94ad42fL), tole(0x0b21572cL), +tole(0xdfeb33c7L), tole(0x2d80b0c4L), tole(0x3ed04330L), tole(0xccbbc033L), +tole(0xa24bb5a6L), tole(0x502036a5L), tole(0x4370c551L), tole(0xb11b4652L), +tole(0x65d122b9L), tole(0x97baa1baL), tole(0x84ea524eL), tole(0x7681d14dL), +tole(0x2892ed69L), tole(0xdaf96e6aL), tole(0xc9a99d9eL), tole(0x3bc21e9dL), +tole(0xef087a76L), tole(0x1d63f975L), tole(0x0e330a81L), tole(0xfc588982L), +tole(0xb21572c9L), tole(0x407ef1caL), tole(0x532e023eL), tole(0xa145813dL), +tole(0x758fe5d6L), tole(0x87e466d5L), tole(0x94b49521L), tole(0x66df1622L), +tole(0x38cc2a06L), tole(0xcaa7a905L), tole(0xd9f75af1L), tole(0x2b9cd9f2L), +tole(0xff56bd19L), tole(0x0d3d3e1aL), tole(0x1e6dcdeeL), tole(0xec064eedL), +tole(0xc38d26c4L), tole(0x31e6a5c7L), tole(0x22b65633L), tole(0xd0ddd530L), +tole(0x0417b1dbL), tole(0xf67c32d8L), tole(0xe52cc12cL), tole(0x1747422fL), +tole(0x49547e0bL), tole(0xbb3ffd08L), tole(0xa86f0efcL), tole(0x5a048dffL), +tole(0x8ecee914L), tole(0x7ca56a17L), tole(0x6ff599e3L), tole(0x9d9e1ae0L), +tole(0xd3d3e1abL), tole(0x21b862a8L), tole(0x32e8915cL), tole(0xc083125fL), +tole(0x144976b4L), tole(0xe622f5b7L), tole(0xf5720643L), tole(0x07198540L), +tole(0x590ab964L), tole(0xab613a67L), tole(0xb831c993L), tole(0x4a5a4a90L), +tole(0x9e902e7bL), tole(0x6cfbad78L), tole(0x7fab5e8cL), tole(0x8dc0dd8fL), +tole(0xe330a81aL), tole(0x115b2b19L), tole(0x020bd8edL), tole(0xf0605beeL), +tole(0x24aa3f05L), tole(0xd6c1bc06L), tole(0xc5914ff2L), tole(0x37faccf1L), +tole(0x69e9f0d5L), tole(0x9b8273d6L), tole(0x88d28022L), tole(0x7ab90321L), +tole(0xae7367caL), tole(0x5c18e4c9L), tole(0x4f48173dL), tole(0xbd23943eL), +tole(0xf36e6f75L), tole(0x0105ec76L), tole(0x12551f82L), tole(0xe03e9c81L), +tole(0x34f4f86aL), tole(0xc69f7b69L), tole(0xd5cf889dL), tole(0x27a40b9eL), +tole(0x79b737baL), tole(0x8bdcb4b9L), tole(0x988c474dL), tole(0x6ae7c44eL), +tole(0xbe2da0a5L), tole(0x4c4623a6L), tole(0x5f16d052L), tole(0xad7d5351L)}; + +static const uint32_t t1_le[] = { +tole(0x00000000L), tole(0x13a29877L), tole(0x274530eeL), tole(0x34e7a899L), +tole(0x4e8a61dcL), tole(0x5d28f9abL), tole(0x69cf5132L), tole(0x7a6dc945L), +tole(0x9d14c3b8L), tole(0x8eb65bcfL), tole(0xba51f356L), tole(0xa9f36b21L), +tole(0xd39ea264L), tole(0xc03c3a13L), tole(0xf4db928aL), tole(0xe7790afdL), +tole(0x3fc5f181L), tole(0x2c6769f6L), tole(0x1880c16fL), tole(0x0b225918L), +tole(0x714f905dL), tole(0x62ed082aL), tole(0x560aa0b3L), tole(0x45a838c4L), +tole(0xa2d13239L), tole(0xb173aa4eL), tole(0x859402d7L), tole(0x96369aa0L), +tole(0xec5b53e5L), tole(0xfff9cb92L), tole(0xcb1e630bL), tole(0xd8bcfb7cL), +tole(0x7f8be302L), tole(0x6c297b75L), tole(0x58ced3ecL), tole(0x4b6c4b9bL), +tole(0x310182deL), tole(0x22a31aa9L), tole(0x1644b230L), tole(0x05e62a47L), +tole(0xe29f20baL), tole(0xf13db8cdL), tole(0xc5da1054L), tole(0xd6788823L), +tole(0xac154166L), tole(0xbfb7d911L), tole(0x8b507188L), tole(0x98f2e9ffL), +tole(0x404e1283L), tole(0x53ec8af4L), tole(0x670b226dL), tole(0x74a9ba1aL), +tole(0x0ec4735fL), tole(0x1d66eb28L), tole(0x298143b1L), tole(0x3a23dbc6L), +tole(0xdd5ad13bL), tole(0xcef8494cL), tole(0xfa1fe1d5L), tole(0xe9bd79a2L), +tole(0x93d0b0e7L), tole(0x80722890L), tole(0xb4958009L), tole(0xa737187eL), +tole(0xff17c604L), tole(0xecb55e73L), tole(0xd852f6eaL), tole(0xcbf06e9dL), +tole(0xb19da7d8L), tole(0xa23f3fafL), tole(0x96d89736L), tole(0x857a0f41L), +tole(0x620305bcL), tole(0x71a19dcbL), tole(0x45463552L), tole(0x56e4ad25L), +tole(0x2c896460L), tole(0x3f2bfc17L), tole(0x0bcc548eL), tole(0x186eccf9L), +tole(0xc0d23785L), tole(0xd370aff2L), tole(0xe797076bL), tole(0xf4359f1cL), +tole(0x8e585659L), tole(0x9dface2eL), tole(0xa91d66b7L), tole(0xbabffec0L), +tole(0x5dc6f43dL), tole(0x4e646c4aL), tole(0x7a83c4d3L), tole(0x69215ca4L), +tole(0x134c95e1L), tole(0x00ee0d96L), tole(0x3409a50fL), tole(0x27ab3d78L), +tole(0x809c2506L), tole(0x933ebd71L), tole(0xa7d915e8L), tole(0xb47b8d9fL), +tole(0xce1644daL), tole(0xddb4dcadL), tole(0xe9537434L), tole(0xfaf1ec43L), +tole(0x1d88e6beL), tole(0x0e2a7ec9L), tole(0x3acdd650L), tole(0x296f4e27L), +tole(0x53028762L), tole(0x40a01f15L), tole(0x7447b78cL), tole(0x67e52ffbL), +tole(0xbf59d487L), tole(0xacfb4cf0L), tole(0x981ce469L), tole(0x8bbe7c1eL), +tole(0xf1d3b55bL), tole(0xe2712d2cL), tole(0xd69685b5L), tole(0xc5341dc2L), +tole(0x224d173fL), tole(0x31ef8f48L), tole(0x050827d1L), tole(0x16aabfa6L), +tole(0x6cc776e3L), tole(0x7f65ee94L), tole(0x4b82460dL), tole(0x5820de7aL), +tole(0xfbc3faf9L), tole(0xe861628eL), tole(0xdc86ca17L), tole(0xcf245260L), +tole(0xb5499b25L), tole(0xa6eb0352L), tole(0x920cabcbL), tole(0x81ae33bcL), +tole(0x66d73941L), tole(0x7575a136L), tole(0x419209afL), tole(0x523091d8L), +tole(0x285d589dL), tole(0x3bffc0eaL), tole(0x0f186873L), tole(0x1cbaf004L), +tole(0xc4060b78L), tole(0xd7a4930fL), tole(0xe3433b96L), tole(0xf0e1a3e1L), +tole(0x8a8c6aa4L), tole(0x992ef2d3L), tole(0xadc95a4aL), tole(0xbe6bc23dL), +tole(0x5912c8c0L), tole(0x4ab050b7L), tole(0x7e57f82eL), tole(0x6df56059L), +tole(0x1798a91cL), tole(0x043a316bL), tole(0x30dd99f2L), tole(0x237f0185L), +tole(0x844819fbL), tole(0x97ea818cL), tole(0xa30d2915L), tole(0xb0afb162L), +tole(0xcac27827L), tole(0xd960e050L), tole(0xed8748c9L), tole(0xfe25d0beL), +tole(0x195cda43L), tole(0x0afe4234L), tole(0x3e19eaadL), tole(0x2dbb72daL), +tole(0x57d6bb9fL), tole(0x447423e8L), tole(0x70938b71L), tole(0x63311306L), +tole(0xbb8de87aL), tole(0xa82f700dL), tole(0x9cc8d894L), tole(0x8f6a40e3L), +tole(0xf50789a6L), tole(0xe6a511d1L), tole(0xd242b948L), tole(0xc1e0213fL), +tole(0x26992bc2L), tole(0x353bb3b5L), tole(0x01dc1b2cL), tole(0x127e835bL), +tole(0x68134a1eL), tole(0x7bb1d269L), tole(0x4f567af0L), tole(0x5cf4e287L), +tole(0x04d43cfdL), tole(0x1776a48aL), tole(0x23910c13L), tole(0x30339464L), +tole(0x4a5e5d21L), tole(0x59fcc556L), tole(0x6d1b6dcfL), tole(0x7eb9f5b8L), +tole(0x99c0ff45L), tole(0x8a626732L), tole(0xbe85cfabL), tole(0xad2757dcL), +tole(0xd74a9e99L), tole(0xc4e806eeL), tole(0xf00fae77L), tole(0xe3ad3600L), +tole(0x3b11cd7cL), tole(0x28b3550bL), tole(0x1c54fd92L), tole(0x0ff665e5L), +tole(0x759baca0L), tole(0x663934d7L), tole(0x52de9c4eL), tole(0x417c0439L), +tole(0xa6050ec4L), tole(0xb5a796b3L), tole(0x81403e2aL), tole(0x92e2a65dL), +tole(0xe88f6f18L), tole(0xfb2df76fL), tole(0xcfca5ff6L), tole(0xdc68c781L), +tole(0x7b5fdfffL), tole(0x68fd4788L), tole(0x5c1aef11L), tole(0x4fb87766L), +tole(0x35d5be23L), tole(0x26772654L), tole(0x12908ecdL), tole(0x013216baL), +tole(0xe64b1c47L), tole(0xf5e98430L), tole(0xc10e2ca9L), tole(0xd2acb4deL), +tole(0xa8c17d9bL), tole(0xbb63e5ecL), tole(0x8f844d75L), tole(0x9c26d502L), +tole(0x449a2e7eL), tole(0x5738b609L), tole(0x63df1e90L), tole(0x707d86e7L), +tole(0x0a104fa2L), tole(0x19b2d7d5L), tole(0x2d557f4cL), tole(0x3ef7e73bL), +tole(0xd98eedc6L), tole(0xca2c75b1L), tole(0xfecbdd28L), tole(0xed69455fL), +tole(0x97048c1aL), tole(0x84a6146dL), tole(0xb041bcf4L), tole(0xa3e32483L)}; + +static const uint32_t t2_le[] = { +tole(0x00000000L), tole(0xa541927eL), tole(0x4f6f520dL), tole(0xea2ec073L), +tole(0x9edea41aL), tole(0x3b9f3664L), tole(0xd1b1f617L), tole(0x74f06469L), +tole(0x38513ec5L), tole(0x9d10acbbL), tole(0x773e6cc8L), tole(0xd27ffeb6L), +tole(0xa68f9adfL), tole(0x03ce08a1L), tole(0xe9e0c8d2L), tole(0x4ca15aacL), +tole(0x70a27d8aL), tole(0xd5e3eff4L), tole(0x3fcd2f87L), tole(0x9a8cbdf9L), +tole(0xee7cd990L), tole(0x4b3d4beeL), tole(0xa1138b9dL), tole(0x045219e3L), +tole(0x48f3434fL), tole(0xedb2d131L), tole(0x079c1142L), tole(0xa2dd833cL), +tole(0xd62de755L), tole(0x736c752bL), tole(0x9942b558L), tole(0x3c032726L), +tole(0xe144fb14L), tole(0x4405696aL), tole(0xae2ba919L), tole(0x0b6a3b67L), +tole(0x7f9a5f0eL), tole(0xdadbcd70L), tole(0x30f50d03L), tole(0x95b49f7dL), +tole(0xd915c5d1L), tole(0x7c5457afL), tole(0x967a97dcL), tole(0x333b05a2L), +tole(0x47cb61cbL), tole(0xe28af3b5L), tole(0x08a433c6L), tole(0xade5a1b8L), +tole(0x91e6869eL), tole(0x34a714e0L), tole(0xde89d493L), tole(0x7bc846edL), +tole(0x0f382284L), tole(0xaa79b0faL), tole(0x40577089L), tole(0xe516e2f7L), +tole(0xa9b7b85bL), tole(0x0cf62a25L), tole(0xe6d8ea56L), tole(0x43997828L), +tole(0x37691c41L), tole(0x92288e3fL), tole(0x78064e4cL), tole(0xdd47dc32L), +tole(0xc76580d9L), tole(0x622412a7L), tole(0x880ad2d4L), tole(0x2d4b40aaL), +tole(0x59bb24c3L), tole(0xfcfab6bdL), tole(0x16d476ceL), tole(0xb395e4b0L), +tole(0xff34be1cL), tole(0x5a752c62L), tole(0xb05bec11L), tole(0x151a7e6fL), +tole(0x61ea1a06L), tole(0xc4ab8878L), tole(0x2e85480bL), tole(0x8bc4da75L), +tole(0xb7c7fd53L), tole(0x12866f2dL), tole(0xf8a8af5eL), tole(0x5de93d20L), +tole(0x29195949L), tole(0x8c58cb37L), tole(0x66760b44L), tole(0xc337993aL), +tole(0x8f96c396L), tole(0x2ad751e8L), tole(0xc0f9919bL), tole(0x65b803e5L), +tole(0x1148678cL), tole(0xb409f5f2L), tole(0x5e273581L), tole(0xfb66a7ffL), +tole(0x26217bcdL), tole(0x8360e9b3L), tole(0x694e29c0L), tole(0xcc0fbbbeL), +tole(0xb8ffdfd7L), tole(0x1dbe4da9L), tole(0xf7908ddaL), tole(0x52d11fa4L), +tole(0x1e704508L), tole(0xbb31d776L), tole(0x511f1705L), tole(0xf45e857bL), +tole(0x80aee112L), tole(0x25ef736cL), tole(0xcfc1b31fL), tole(0x6a802161L), +tole(0x56830647L), tole(0xf3c29439L), tole(0x19ec544aL), tole(0xbcadc634L), +tole(0xc85da25dL), tole(0x6d1c3023L), tole(0x8732f050L), tole(0x2273622eL), +tole(0x6ed23882L), tole(0xcb93aafcL), tole(0x21bd6a8fL), tole(0x84fcf8f1L), +tole(0xf00c9c98L), tole(0x554d0ee6L), tole(0xbf63ce95L), tole(0x1a225cebL), +tole(0x8b277743L), tole(0x2e66e53dL), tole(0xc448254eL), tole(0x6109b730L), +tole(0x15f9d359L), tole(0xb0b84127L), tole(0x5a968154L), tole(0xffd7132aL), +tole(0xb3764986L), tole(0x1637dbf8L), tole(0xfc191b8bL), tole(0x595889f5L), +tole(0x2da8ed9cL), tole(0x88e97fe2L), tole(0x62c7bf91L), tole(0xc7862defL), +tole(0xfb850ac9L), tole(0x5ec498b7L), tole(0xb4ea58c4L), tole(0x11abcabaL), +tole(0x655baed3L), tole(0xc01a3cadL), tole(0x2a34fcdeL), tole(0x8f756ea0L), +tole(0xc3d4340cL), tole(0x6695a672L), tole(0x8cbb6601L), tole(0x29faf47fL), +tole(0x5d0a9016L), tole(0xf84b0268L), tole(0x1265c21bL), tole(0xb7245065L), +tole(0x6a638c57L), tole(0xcf221e29L), tole(0x250cde5aL), tole(0x804d4c24L), +tole(0xf4bd284dL), tole(0x51fcba33L), tole(0xbbd27a40L), tole(0x1e93e83eL), +tole(0x5232b292L), tole(0xf77320ecL), tole(0x1d5de09fL), tole(0xb81c72e1L), +tole(0xccec1688L), tole(0x69ad84f6L), tole(0x83834485L), tole(0x26c2d6fbL), +tole(0x1ac1f1ddL), tole(0xbf8063a3L), tole(0x55aea3d0L), tole(0xf0ef31aeL), +tole(0x841f55c7L), tole(0x215ec7b9L), tole(0xcb7007caL), tole(0x6e3195b4L), +tole(0x2290cf18L), tole(0x87d15d66L), tole(0x6dff9d15L), tole(0xc8be0f6bL), +tole(0xbc4e6b02L), tole(0x190ff97cL), tole(0xf321390fL), tole(0x5660ab71L), +tole(0x4c42f79aL), tole(0xe90365e4L), tole(0x032da597L), tole(0xa66c37e9L), +tole(0xd29c5380L), tole(0x77ddc1feL), tole(0x9df3018dL), tole(0x38b293f3L), +tole(0x7413c95fL), tole(0xd1525b21L), tole(0x3b7c9b52L), tole(0x9e3d092cL), +tole(0xeacd6d45L), tole(0x4f8cff3bL), tole(0xa5a23f48L), tole(0x00e3ad36L), +tole(0x3ce08a10L), tole(0x99a1186eL), tole(0x738fd81dL), tole(0xd6ce4a63L), +tole(0xa23e2e0aL), tole(0x077fbc74L), tole(0xed517c07L), tole(0x4810ee79L), +tole(0x04b1b4d5L), tole(0xa1f026abL), tole(0x4bdee6d8L), tole(0xee9f74a6L), +tole(0x9a6f10cfL), tole(0x3f2e82b1L), tole(0xd50042c2L), tole(0x7041d0bcL), +tole(0xad060c8eL), tole(0x08479ef0L), tole(0xe2695e83L), tole(0x4728ccfdL), +tole(0x33d8a894L), tole(0x96993aeaL), tole(0x7cb7fa99L), tole(0xd9f668e7L), +tole(0x9557324bL), tole(0x3016a035L), tole(0xda386046L), tole(0x7f79f238L), +tole(0x0b899651L), tole(0xaec8042fL), tole(0x44e6c45cL), tole(0xe1a75622L), +tole(0xdda47104L), tole(0x78e5e37aL), tole(0x92cb2309L), tole(0x378ab177L), +tole(0x437ad51eL), tole(0xe63b4760L), tole(0x0c158713L), tole(0xa954156dL), +tole(0xe5f54fc1L), tole(0x40b4ddbfL), tole(0xaa9a1dccL), tole(0x0fdb8fb2L), +tole(0x7b2bebdbL), tole(0xde6a79a5L), tole(0x3444b9d6L), tole(0x91052ba8L)}; + +static const uint32_t t3_le[] = { +tole(0x00000000L), tole(0xdd45aab8L), tole(0xbf672381L), tole(0x62228939L), +tole(0x7b2231f3L), tole(0xa6679b4bL), tole(0xc4451272L), tole(0x1900b8caL), +tole(0xf64463e6L), tole(0x2b01c95eL), tole(0x49234067L), tole(0x9466eadfL), +tole(0x8d665215L), tole(0x5023f8adL), tole(0x32017194L), tole(0xef44db2cL), +tole(0xe964b13dL), tole(0x34211b85L), tole(0x560392bcL), tole(0x8b463804L), +tole(0x924680ceL), tole(0x4f032a76L), tole(0x2d21a34fL), tole(0xf06409f7L), +tole(0x1f20d2dbL), tole(0xc2657863L), tole(0xa047f15aL), tole(0x7d025be2L), +tole(0x6402e328L), tole(0xb9474990L), tole(0xdb65c0a9L), tole(0x06206a11L), +tole(0xd725148bL), tole(0x0a60be33L), tole(0x6842370aL), tole(0xb5079db2L), +tole(0xac072578L), tole(0x71428fc0L), tole(0x136006f9L), tole(0xce25ac41L), +tole(0x2161776dL), tole(0xfc24ddd5L), tole(0x9e0654ecL), tole(0x4343fe54L), +tole(0x5a43469eL), tole(0x8706ec26L), tole(0xe524651fL), tole(0x3861cfa7L), +tole(0x3e41a5b6L), tole(0xe3040f0eL), tole(0x81268637L), tole(0x5c632c8fL), +tole(0x45639445L), tole(0x98263efdL), tole(0xfa04b7c4L), tole(0x27411d7cL), +tole(0xc805c650L), tole(0x15406ce8L), tole(0x7762e5d1L), tole(0xaa274f69L), +tole(0xb327f7a3L), tole(0x6e625d1bL), tole(0x0c40d422L), tole(0xd1057e9aL), +tole(0xaba65fe7L), tole(0x76e3f55fL), tole(0x14c17c66L), tole(0xc984d6deL), +tole(0xd0846e14L), tole(0x0dc1c4acL), tole(0x6fe34d95L), tole(0xb2a6e72dL), +tole(0x5de23c01L), tole(0x80a796b9L), tole(0xe2851f80L), tole(0x3fc0b538L), +tole(0x26c00df2L), tole(0xfb85a74aL), tole(0x99a72e73L), tole(0x44e284cbL), +tole(0x42c2eedaL), tole(0x9f874462L), tole(0xfda5cd5bL), tole(0x20e067e3L), +tole(0x39e0df29L), tole(0xe4a57591L), tole(0x8687fca8L), tole(0x5bc25610L), +tole(0xb4868d3cL), tole(0x69c32784L), tole(0x0be1aebdL), tole(0xd6a40405L), +tole(0xcfa4bccfL), tole(0x12e11677L), tole(0x70c39f4eL), tole(0xad8635f6L), +tole(0x7c834b6cL), tole(0xa1c6e1d4L), tole(0xc3e468edL), tole(0x1ea1c255L), +tole(0x07a17a9fL), tole(0xdae4d027L), tole(0xb8c6591eL), tole(0x6583f3a6L), +tole(0x8ac7288aL), tole(0x57828232L), tole(0x35a00b0bL), tole(0xe8e5a1b3L), +tole(0xf1e51979L), tole(0x2ca0b3c1L), tole(0x4e823af8L), tole(0x93c79040L), +tole(0x95e7fa51L), tole(0x48a250e9L), tole(0x2a80d9d0L), tole(0xf7c57368L), +tole(0xeec5cba2L), tole(0x3380611aL), tole(0x51a2e823L), tole(0x8ce7429bL), +tole(0x63a399b7L), tole(0xbee6330fL), tole(0xdcc4ba36L), tole(0x0181108eL), +tole(0x1881a844L), tole(0xc5c402fcL), tole(0xa7e68bc5L), tole(0x7aa3217dL), +tole(0x52a0c93fL), tole(0x8fe56387L), tole(0xedc7eabeL), tole(0x30824006L), +tole(0x2982f8ccL), tole(0xf4c75274L), tole(0x96e5db4dL), tole(0x4ba071f5L), +tole(0xa4e4aad9L), tole(0x79a10061L), tole(0x1b838958L), tole(0xc6c623e0L), +tole(0xdfc69b2aL), tole(0x02833192L), tole(0x60a1b8abL), tole(0xbde41213L), +tole(0xbbc47802L), tole(0x6681d2baL), tole(0x04a35b83L), tole(0xd9e6f13bL), +tole(0xc0e649f1L), tole(0x1da3e349L), tole(0x7f816a70L), tole(0xa2c4c0c8L), +tole(0x4d801be4L), tole(0x90c5b15cL), tole(0xf2e73865L), tole(0x2fa292ddL), +tole(0x36a22a17L), tole(0xebe780afL), tole(0x89c50996L), tole(0x5480a32eL), +tole(0x8585ddb4L), tole(0x58c0770cL), tole(0x3ae2fe35L), tole(0xe7a7548dL), +tole(0xfea7ec47L), tole(0x23e246ffL), tole(0x41c0cfc6L), tole(0x9c85657eL), +tole(0x73c1be52L), tole(0xae8414eaL), tole(0xcca69dd3L), tole(0x11e3376bL), +tole(0x08e38fa1L), tole(0xd5a62519L), tole(0xb784ac20L), tole(0x6ac10698L), +tole(0x6ce16c89L), tole(0xb1a4c631L), tole(0xd3864f08L), tole(0x0ec3e5b0L), +tole(0x17c35d7aL), tole(0xca86f7c2L), tole(0xa8a47efbL), tole(0x75e1d443L), +tole(0x9aa50f6fL), tole(0x47e0a5d7L), tole(0x25c22ceeL), tole(0xf8878656L), +tole(0xe1873e9cL), tole(0x3cc29424L), tole(0x5ee01d1dL), tole(0x83a5b7a5L), +tole(0xf90696d8L), tole(0x24433c60L), tole(0x4661b559L), tole(0x9b241fe1L), +tole(0x8224a72bL), tole(0x5f610d93L), tole(0x3d4384aaL), tole(0xe0062e12L), +tole(0x0f42f53eL), tole(0xd2075f86L), tole(0xb025d6bfL), tole(0x6d607c07L), +tole(0x7460c4cdL), tole(0xa9256e75L), tole(0xcb07e74cL), tole(0x16424df4L), +tole(0x106227e5L), tole(0xcd278d5dL), tole(0xaf050464L), tole(0x7240aedcL), +tole(0x6b401616L), tole(0xb605bcaeL), tole(0xd4273597L), tole(0x09629f2fL), +tole(0xe6264403L), tole(0x3b63eebbL), tole(0x59416782L), tole(0x8404cd3aL), +tole(0x9d0475f0L), tole(0x4041df48L), tole(0x22635671L), tole(0xff26fcc9L), +tole(0x2e238253L), tole(0xf36628ebL), tole(0x9144a1d2L), tole(0x4c010b6aL), +tole(0x5501b3a0L), tole(0x88441918L), tole(0xea669021L), tole(0x37233a99L), +tole(0xd867e1b5L), tole(0x05224b0dL), tole(0x6700c234L), tole(0xba45688cL), +tole(0xa345d046L), tole(0x7e007afeL), tole(0x1c22f3c7L), tole(0xc167597fL), +tole(0xc747336eL), tole(0x1a0299d6L), tole(0x782010efL), tole(0xa565ba57L), +tole(0xbc65029dL), tole(0x6120a825L), tole(0x0302211cL), tole(0xde478ba4L), +tole(0x31035088L), tole(0xec46fa30L), tole(0x8e647309L), tole(0x5321d9b1L), +tole(0x4a21617bL), tole(0x9764cbc3L), tole(0xf54642faL), tole(0x2803e842L)}; + +static const uint32_t t4_le[] = { +tole(0x00000000L), tole(0x38116facL), tole(0x7022df58L), tole(0x4833b0f4L), +tole(0xe045beb0L), tole(0xd854d11cL), tole(0x906761e8L), tole(0xa8760e44L), +tole(0xc5670b91L), tole(0xfd76643dL), tole(0xb545d4c9L), tole(0x8d54bb65L), +tole(0x2522b521L), tole(0x1d33da8dL), tole(0x55006a79L), tole(0x6d1105d5L), +tole(0x8f2261d3L), tole(0xb7330e7fL), tole(0xff00be8bL), tole(0xc711d127L), +tole(0x6f67df63L), tole(0x5776b0cfL), tole(0x1f45003bL), tole(0x27546f97L), +tole(0x4a456a42L), tole(0x725405eeL), tole(0x3a67b51aL), tole(0x0276dab6L), +tole(0xaa00d4f2L), tole(0x9211bb5eL), tole(0xda220baaL), tole(0xe2336406L), +tole(0x1ba8b557L), tole(0x23b9dafbL), tole(0x6b8a6a0fL), tole(0x539b05a3L), +tole(0xfbed0be7L), tole(0xc3fc644bL), tole(0x8bcfd4bfL), tole(0xb3debb13L), +tole(0xdecfbec6L), tole(0xe6ded16aL), tole(0xaeed619eL), tole(0x96fc0e32L), +tole(0x3e8a0076L), tole(0x069b6fdaL), tole(0x4ea8df2eL), tole(0x76b9b082L), +tole(0x948ad484L), tole(0xac9bbb28L), tole(0xe4a80bdcL), tole(0xdcb96470L), +tole(0x74cf6a34L), tole(0x4cde0598L), tole(0x04edb56cL), tole(0x3cfcdac0L), +tole(0x51eddf15L), tole(0x69fcb0b9L), tole(0x21cf004dL), tole(0x19de6fe1L), +tole(0xb1a861a5L), tole(0x89b90e09L), tole(0xc18abefdL), tole(0xf99bd151L), +tole(0x37516aaeL), tole(0x0f400502L), tole(0x4773b5f6L), tole(0x7f62da5aL), +tole(0xd714d41eL), tole(0xef05bbb2L), tole(0xa7360b46L), tole(0x9f2764eaL), +tole(0xf236613fL), tole(0xca270e93L), tole(0x8214be67L), tole(0xba05d1cbL), +tole(0x1273df8fL), tole(0x2a62b023L), tole(0x625100d7L), tole(0x5a406f7bL), +tole(0xb8730b7dL), tole(0x806264d1L), tole(0xc851d425L), tole(0xf040bb89L), +tole(0x5836b5cdL), tole(0x6027da61L), tole(0x28146a95L), tole(0x10050539L), +tole(0x7d1400ecL), tole(0x45056f40L), tole(0x0d36dfb4L), tole(0x3527b018L), +tole(0x9d51be5cL), tole(0xa540d1f0L), tole(0xed736104L), tole(0xd5620ea8L), +tole(0x2cf9dff9L), tole(0x14e8b055L), tole(0x5cdb00a1L), tole(0x64ca6f0dL), +tole(0xccbc6149L), tole(0xf4ad0ee5L), tole(0xbc9ebe11L), tole(0x848fd1bdL), +tole(0xe99ed468L), tole(0xd18fbbc4L), tole(0x99bc0b30L), tole(0xa1ad649cL), +tole(0x09db6ad8L), tole(0x31ca0574L), tole(0x79f9b580L), tole(0x41e8da2cL), +tole(0xa3dbbe2aL), tole(0x9bcad186L), tole(0xd3f96172L), tole(0xebe80edeL), +tole(0x439e009aL), tole(0x7b8f6f36L), tole(0x33bcdfc2L), tole(0x0badb06eL), +tole(0x66bcb5bbL), tole(0x5eadda17L), tole(0x169e6ae3L), tole(0x2e8f054fL), +tole(0x86f90b0bL), tole(0xbee864a7L), tole(0xf6dbd453L), tole(0xcecabbffL), +tole(0x6ea2d55cL), tole(0x56b3baf0L), tole(0x1e800a04L), tole(0x269165a8L), +tole(0x8ee76becL), tole(0xb6f60440L), tole(0xfec5b4b4L), tole(0xc6d4db18L), +tole(0xabc5decdL), tole(0x93d4b161L), tole(0xdbe70195L), tole(0xe3f66e39L), +tole(0x4b80607dL), tole(0x73910fd1L), tole(0x3ba2bf25L), tole(0x03b3d089L), +tole(0xe180b48fL), tole(0xd991db23L), tole(0x91a26bd7L), tole(0xa9b3047bL), +tole(0x01c50a3fL), tole(0x39d46593L), tole(0x71e7d567L), tole(0x49f6bacbL), +tole(0x24e7bf1eL), tole(0x1cf6d0b2L), tole(0x54c56046L), tole(0x6cd40feaL), +tole(0xc4a201aeL), tole(0xfcb36e02L), tole(0xb480def6L), tole(0x8c91b15aL), +tole(0x750a600bL), tole(0x4d1b0fa7L), tole(0x0528bf53L), tole(0x3d39d0ffL), +tole(0x954fdebbL), tole(0xad5eb117L), tole(0xe56d01e3L), tole(0xdd7c6e4fL), +tole(0xb06d6b9aL), tole(0x887c0436L), tole(0xc04fb4c2L), tole(0xf85edb6eL), +tole(0x5028d52aL), tole(0x6839ba86L), tole(0x200a0a72L), tole(0x181b65deL), +tole(0xfa2801d8L), tole(0xc2396e74L), tole(0x8a0ade80L), tole(0xb21bb12cL), +tole(0x1a6dbf68L), tole(0x227cd0c4L), tole(0x6a4f6030L), tole(0x525e0f9cL), +tole(0x3f4f0a49L), tole(0x075e65e5L), tole(0x4f6dd511L), tole(0x777cbabdL), +tole(0xdf0ab4f9L), tole(0xe71bdb55L), tole(0xaf286ba1L), tole(0x9739040dL), +tole(0x59f3bff2L), tole(0x61e2d05eL), tole(0x29d160aaL), tole(0x11c00f06L), +tole(0xb9b60142L), tole(0x81a76eeeL), tole(0xc994de1aL), tole(0xf185b1b6L), +tole(0x9c94b463L), tole(0xa485dbcfL), tole(0xecb66b3bL), tole(0xd4a70497L), +tole(0x7cd10ad3L), tole(0x44c0657fL), tole(0x0cf3d58bL), tole(0x34e2ba27L), +tole(0xd6d1de21L), tole(0xeec0b18dL), tole(0xa6f30179L), tole(0x9ee26ed5L), +tole(0x36946091L), tole(0x0e850f3dL), tole(0x46b6bfc9L), tole(0x7ea7d065L), +tole(0x13b6d5b0L), tole(0x2ba7ba1cL), tole(0x63940ae8L), tole(0x5b856544L), +tole(0xf3f36b00L), tole(0xcbe204acL), tole(0x83d1b458L), tole(0xbbc0dbf4L), +tole(0x425b0aa5L), tole(0x7a4a6509L), tole(0x3279d5fdL), tole(0x0a68ba51L), +tole(0xa21eb415L), tole(0x9a0fdbb9L), tole(0xd23c6b4dL), tole(0xea2d04e1L), +tole(0x873c0134L), tole(0xbf2d6e98L), tole(0xf71ede6cL), tole(0xcf0fb1c0L), +tole(0x6779bf84L), tole(0x5f68d028L), tole(0x175b60dcL), tole(0x2f4a0f70L), +tole(0xcd796b76L), tole(0xf56804daL), tole(0xbd5bb42eL), tole(0x854adb82L), +tole(0x2d3cd5c6L), tole(0x152dba6aL), tole(0x5d1e0a9eL), tole(0x650f6532L), +tole(0x081e60e7L), tole(0x300f0f4bL), tole(0x783cbfbfL), tole(0x402dd013L), +tole(0xe85bde57L), tole(0xd04ab1fbL), tole(0x9879010fL), tole(0xa0686ea3L)}; + +static const uint32_t t5_le[] = { +tole(0x00000000L), tole(0xef306b19L), tole(0xdb8ca0c3L), tole(0x34bccbdaL), +tole(0xb2f53777L), tole(0x5dc55c6eL), tole(0x697997b4L), tole(0x8649fcadL), +tole(0x6006181fL), tole(0x8f367306L), tole(0xbb8ab8dcL), tole(0x54bad3c5L), +tole(0xd2f32f68L), tole(0x3dc34471L), tole(0x097f8fabL), tole(0xe64fe4b2L), +tole(0xc00c303eL), tole(0x2f3c5b27L), tole(0x1b8090fdL), tole(0xf4b0fbe4L), +tole(0x72f90749L), tole(0x9dc96c50L), tole(0xa975a78aL), tole(0x4645cc93L), +tole(0xa00a2821L), tole(0x4f3a4338L), tole(0x7b8688e2L), tole(0x94b6e3fbL), +tole(0x12ff1f56L), tole(0xfdcf744fL), tole(0xc973bf95L), tole(0x2643d48cL), +tole(0x85f4168dL), tole(0x6ac47d94L), tole(0x5e78b64eL), tole(0xb148dd57L), +tole(0x370121faL), tole(0xd8314ae3L), tole(0xec8d8139L), tole(0x03bdea20L), +tole(0xe5f20e92L), tole(0x0ac2658bL), tole(0x3e7eae51L), tole(0xd14ec548L), +tole(0x570739e5L), tole(0xb83752fcL), tole(0x8c8b9926L), tole(0x63bbf23fL), +tole(0x45f826b3L), tole(0xaac84daaL), tole(0x9e748670L), tole(0x7144ed69L), +tole(0xf70d11c4L), tole(0x183d7addL), tole(0x2c81b107L), tole(0xc3b1da1eL), +tole(0x25fe3eacL), tole(0xcace55b5L), tole(0xfe729e6fL), tole(0x1142f576L), +tole(0x970b09dbL), tole(0x783b62c2L), tole(0x4c87a918L), tole(0xa3b7c201L), +tole(0x0e045bebL), tole(0xe13430f2L), tole(0xd588fb28L), tole(0x3ab89031L), +tole(0xbcf16c9cL), tole(0x53c10785L), tole(0x677dcc5fL), tole(0x884da746L), +tole(0x6e0243f4L), tole(0x813228edL), tole(0xb58ee337L), tole(0x5abe882eL), +tole(0xdcf77483L), tole(0x33c71f9aL), tole(0x077bd440L), tole(0xe84bbf59L), +tole(0xce086bd5L), tole(0x213800ccL), tole(0x1584cb16L), tole(0xfab4a00fL), +tole(0x7cfd5ca2L), tole(0x93cd37bbL), tole(0xa771fc61L), tole(0x48419778L), +tole(0xae0e73caL), tole(0x413e18d3L), tole(0x7582d309L), tole(0x9ab2b810L), +tole(0x1cfb44bdL), tole(0xf3cb2fa4L), tole(0xc777e47eL), tole(0x28478f67L), +tole(0x8bf04d66L), tole(0x64c0267fL), tole(0x507ceda5L), tole(0xbf4c86bcL), +tole(0x39057a11L), tole(0xd6351108L), tole(0xe289dad2L), tole(0x0db9b1cbL), +tole(0xebf65579L), tole(0x04c63e60L), tole(0x307af5baL), tole(0xdf4a9ea3L), +tole(0x5903620eL), tole(0xb6330917L), tole(0x828fc2cdL), tole(0x6dbfa9d4L), +tole(0x4bfc7d58L), tole(0xa4cc1641L), tole(0x9070dd9bL), tole(0x7f40b682L), +tole(0xf9094a2fL), tole(0x16392136L), tole(0x2285eaecL), tole(0xcdb581f5L), +tole(0x2bfa6547L), tole(0xc4ca0e5eL), tole(0xf076c584L), tole(0x1f46ae9dL), +tole(0x990f5230L), tole(0x763f3929L), tole(0x4283f2f3L), tole(0xadb399eaL), +tole(0x1c08b7d6L), tole(0xf338dccfL), tole(0xc7841715L), tole(0x28b47c0cL), +tole(0xaefd80a1L), tole(0x41cdebb8L), tole(0x75712062L), tole(0x9a414b7bL), +tole(0x7c0eafc9L), tole(0x933ec4d0L), tole(0xa7820f0aL), tole(0x48b26413L), +tole(0xcefb98beL), tole(0x21cbf3a7L), tole(0x1577387dL), tole(0xfa475364L), +tole(0xdc0487e8L), tole(0x3334ecf1L), tole(0x0788272bL), tole(0xe8b84c32L), +tole(0x6ef1b09fL), tole(0x81c1db86L), tole(0xb57d105cL), tole(0x5a4d7b45L), +tole(0xbc029ff7L), tole(0x5332f4eeL), tole(0x678e3f34L), tole(0x88be542dL), +tole(0x0ef7a880L), tole(0xe1c7c399L), tole(0xd57b0843L), tole(0x3a4b635aL), +tole(0x99fca15bL), tole(0x76ccca42L), tole(0x42700198L), tole(0xad406a81L), +tole(0x2b09962cL), tole(0xc439fd35L), tole(0xf08536efL), tole(0x1fb55df6L), +tole(0xf9fab944L), tole(0x16cad25dL), tole(0x22761987L), tole(0xcd46729eL), +tole(0x4b0f8e33L), tole(0xa43fe52aL), tole(0x90832ef0L), tole(0x7fb345e9L), +tole(0x59f09165L), tole(0xb6c0fa7cL), tole(0x827c31a6L), tole(0x6d4c5abfL), +tole(0xeb05a612L), tole(0x0435cd0bL), tole(0x308906d1L), tole(0xdfb96dc8L), +tole(0x39f6897aL), tole(0xd6c6e263L), tole(0xe27a29b9L), tole(0x0d4a42a0L), +tole(0x8b03be0dL), tole(0x6433d514L), tole(0x508f1eceL), tole(0xbfbf75d7L), +tole(0x120cec3dL), tole(0xfd3c8724L), tole(0xc9804cfeL), tole(0x26b027e7L), +tole(0xa0f9db4aL), tole(0x4fc9b053L), tole(0x7b757b89L), tole(0x94451090L), +tole(0x720af422L), tole(0x9d3a9f3bL), tole(0xa98654e1L), tole(0x46b63ff8L), +tole(0xc0ffc355L), tole(0x2fcfa84cL), tole(0x1b736396L), tole(0xf443088fL), +tole(0xd200dc03L), tole(0x3d30b71aL), tole(0x098c7cc0L), tole(0xe6bc17d9L), +tole(0x60f5eb74L), tole(0x8fc5806dL), tole(0xbb794bb7L), tole(0x544920aeL), +tole(0xb206c41cL), tole(0x5d36af05L), tole(0x698a64dfL), tole(0x86ba0fc6L), +tole(0x00f3f36bL), tole(0xefc39872L), tole(0xdb7f53a8L), tole(0x344f38b1L), +tole(0x97f8fab0L), tole(0x78c891a9L), tole(0x4c745a73L), tole(0xa344316aL), +tole(0x250dcdc7L), tole(0xca3da6deL), tole(0xfe816d04L), tole(0x11b1061dL), +tole(0xf7fee2afL), tole(0x18ce89b6L), tole(0x2c72426cL), tole(0xc3422975L), +tole(0x450bd5d8L), tole(0xaa3bbec1L), tole(0x9e87751bL), tole(0x71b71e02L), +tole(0x57f4ca8eL), tole(0xb8c4a197L), tole(0x8c786a4dL), tole(0x63480154L), +tole(0xe501fdf9L), tole(0x0a3196e0L), tole(0x3e8d5d3aL), tole(0xd1bd3623L), +tole(0x37f2d291L), tole(0xd8c2b988L), tole(0xec7e7252L), tole(0x034e194bL), +tole(0x8507e5e6L), tole(0x6a378effL), tole(0x5e8b4525L), tole(0xb1bb2e3cL)}; + +static const uint32_t t6_le[] = { +tole(0x00000000L), tole(0x68032cc8L), tole(0xd0065990L), tole(0xb8057558L), +tole(0xa5e0c5d1L), tole(0xcde3e919L), tole(0x75e69c41L), tole(0x1de5b089L), +tole(0x4e2dfd53L), tole(0x262ed19bL), tole(0x9e2ba4c3L), tole(0xf628880bL), +tole(0xebcd3882L), tole(0x83ce144aL), tole(0x3bcb6112L), tole(0x53c84ddaL), +tole(0x9c5bfaa6L), tole(0xf458d66eL), tole(0x4c5da336L), tole(0x245e8ffeL), +tole(0x39bb3f77L), tole(0x51b813bfL), tole(0xe9bd66e7L), tole(0x81be4a2fL), +tole(0xd27607f5L), tole(0xba752b3dL), tole(0x02705e65L), tole(0x6a7372adL), +tole(0x7796c224L), tole(0x1f95eeecL), tole(0xa7909bb4L), tole(0xcf93b77cL), +tole(0x3d5b83bdL), tole(0x5558af75L), tole(0xed5dda2dL), tole(0x855ef6e5L), +tole(0x98bb466cL), tole(0xf0b86aa4L), tole(0x48bd1ffcL), tole(0x20be3334L), +tole(0x73767eeeL), tole(0x1b755226L), tole(0xa370277eL), tole(0xcb730bb6L), +tole(0xd696bb3fL), tole(0xbe9597f7L), tole(0x0690e2afL), tole(0x6e93ce67L), +tole(0xa100791bL), tole(0xc90355d3L), tole(0x7106208bL), tole(0x19050c43L), +tole(0x04e0bccaL), tole(0x6ce39002L), tole(0xd4e6e55aL), tole(0xbce5c992L), +tole(0xef2d8448L), tole(0x872ea880L), tole(0x3f2bddd8L), tole(0x5728f110L), +tole(0x4acd4199L), tole(0x22ce6d51L), tole(0x9acb1809L), tole(0xf2c834c1L), +tole(0x7ab7077aL), tole(0x12b42bb2L), tole(0xaab15eeaL), tole(0xc2b27222L), +tole(0xdf57c2abL), tole(0xb754ee63L), tole(0x0f519b3bL), tole(0x6752b7f3L), +tole(0x349afa29L), tole(0x5c99d6e1L), tole(0xe49ca3b9L), tole(0x8c9f8f71L), +tole(0x917a3ff8L), tole(0xf9791330L), tole(0x417c6668L), tole(0x297f4aa0L), +tole(0xe6ecfddcL), tole(0x8eefd114L), tole(0x36eaa44cL), tole(0x5ee98884L), +tole(0x430c380dL), tole(0x2b0f14c5L), tole(0x930a619dL), tole(0xfb094d55L), +tole(0xa8c1008fL), tole(0xc0c22c47L), tole(0x78c7591fL), tole(0x10c475d7L), +tole(0x0d21c55eL), tole(0x6522e996L), tole(0xdd279cceL), tole(0xb524b006L), +tole(0x47ec84c7L), tole(0x2fefa80fL), tole(0x97eadd57L), tole(0xffe9f19fL), +tole(0xe20c4116L), tole(0x8a0f6ddeL), tole(0x320a1886L), tole(0x5a09344eL), +tole(0x09c17994L), tole(0x61c2555cL), tole(0xd9c72004L), tole(0xb1c40cccL), +tole(0xac21bc45L), tole(0xc422908dL), tole(0x7c27e5d5L), tole(0x1424c91dL), +tole(0xdbb77e61L), tole(0xb3b452a9L), tole(0x0bb127f1L), tole(0x63b20b39L), +tole(0x7e57bbb0L), tole(0x16549778L), tole(0xae51e220L), tole(0xc652cee8L), +tole(0x959a8332L), tole(0xfd99affaL), tole(0x459cdaa2L), tole(0x2d9ff66aL), +tole(0x307a46e3L), tole(0x58796a2bL), tole(0xe07c1f73L), tole(0x887f33bbL), +tole(0xf56e0ef4L), tole(0x9d6d223cL), tole(0x25685764L), tole(0x4d6b7bacL), +tole(0x508ecb25L), tole(0x388de7edL), tole(0x808892b5L), tole(0xe88bbe7dL), +tole(0xbb43f3a7L), tole(0xd340df6fL), tole(0x6b45aa37L), tole(0x034686ffL), +tole(0x1ea33676L), tole(0x76a01abeL), tole(0xcea56fe6L), tole(0xa6a6432eL), +tole(0x6935f452L), tole(0x0136d89aL), tole(0xb933adc2L), tole(0xd130810aL), +tole(0xccd53183L), tole(0xa4d61d4bL), tole(0x1cd36813L), tole(0x74d044dbL), +tole(0x27180901L), tole(0x4f1b25c9L), tole(0xf71e5091L), tole(0x9f1d7c59L), +tole(0x82f8ccd0L), tole(0xeafbe018L), tole(0x52fe9540L), tole(0x3afdb988L), +tole(0xc8358d49L), tole(0xa036a181L), tole(0x1833d4d9L), tole(0x7030f811L), +tole(0x6dd54898L), tole(0x05d66450L), tole(0xbdd31108L), tole(0xd5d03dc0L), +tole(0x8618701aL), tole(0xee1b5cd2L), tole(0x561e298aL), tole(0x3e1d0542L), +tole(0x23f8b5cbL), tole(0x4bfb9903L), tole(0xf3feec5bL), tole(0x9bfdc093L), +tole(0x546e77efL), tole(0x3c6d5b27L), tole(0x84682e7fL), tole(0xec6b02b7L), +tole(0xf18eb23eL), tole(0x998d9ef6L), tole(0x2188ebaeL), tole(0x498bc766L), +tole(0x1a438abcL), tole(0x7240a674L), tole(0xca45d32cL), tole(0xa246ffe4L), +tole(0xbfa34f6dL), tole(0xd7a063a5L), tole(0x6fa516fdL), tole(0x07a63a35L), +tole(0x8fd9098eL), tole(0xe7da2546L), tole(0x5fdf501eL), tole(0x37dc7cd6L), +tole(0x2a39cc5fL), tole(0x423ae097L), tole(0xfa3f95cfL), tole(0x923cb907L), +tole(0xc1f4f4ddL), tole(0xa9f7d815L), tole(0x11f2ad4dL), tole(0x79f18185L), +tole(0x6414310cL), tole(0x0c171dc4L), tole(0xb412689cL), tole(0xdc114454L), +tole(0x1382f328L), tole(0x7b81dfe0L), tole(0xc384aab8L), tole(0xab878670L), +tole(0xb66236f9L), tole(0xde611a31L), tole(0x66646f69L), tole(0x0e6743a1L), +tole(0x5daf0e7bL), tole(0x35ac22b3L), tole(0x8da957ebL), tole(0xe5aa7b23L), +tole(0xf84fcbaaL), tole(0x904ce762L), tole(0x2849923aL), tole(0x404abef2L), +tole(0xb2828a33L), tole(0xda81a6fbL), tole(0x6284d3a3L), tole(0x0a87ff6bL), +tole(0x17624fe2L), tole(0x7f61632aL), tole(0xc7641672L), tole(0xaf673abaL), +tole(0xfcaf7760L), tole(0x94ac5ba8L), tole(0x2ca92ef0L), tole(0x44aa0238L), +tole(0x594fb2b1L), tole(0x314c9e79L), tole(0x8949eb21L), tole(0xe14ac7e9L), +tole(0x2ed97095L), tole(0x46da5c5dL), tole(0xfedf2905L), tole(0x96dc05cdL), +tole(0x8b39b544L), tole(0xe33a998cL), tole(0x5b3fecd4L), tole(0x333cc01cL), +tole(0x60f48dc6L), tole(0x08f7a10eL), tole(0xb0f2d456L), tole(0xd8f1f89eL), +tole(0xc5144817L), tole(0xad1764dfL), tole(0x15121187L), tole(0x7d113d4fL)}; + +static const uint32_t t7_le[] = { +tole(0x00000000L), tole(0x493c7d27L), tole(0x9278fa4eL), tole(0xdb448769L), +tole(0x211d826dL), tole(0x6821ff4aL), tole(0xb3657823L), tole(0xfa590504L), +tole(0x423b04daL), tole(0x0b0779fdL), tole(0xd043fe94L), tole(0x997f83b3L), +tole(0x632686b7L), tole(0x2a1afb90L), tole(0xf15e7cf9L), tole(0xb86201deL), +tole(0x847609b4L), tole(0xcd4a7493L), tole(0x160ef3faL), tole(0x5f328eddL), +tole(0xa56b8bd9L), tole(0xec57f6feL), tole(0x37137197L), tole(0x7e2f0cb0L), +tole(0xc64d0d6eL), tole(0x8f717049L), tole(0x5435f720L), tole(0x1d098a07L), +tole(0xe7508f03L), tole(0xae6cf224L), tole(0x7528754dL), tole(0x3c14086aL), +tole(0x0d006599L), tole(0x443c18beL), tole(0x9f789fd7L), tole(0xd644e2f0L), +tole(0x2c1de7f4L), tole(0x65219ad3L), tole(0xbe651dbaL), tole(0xf759609dL), +tole(0x4f3b6143L), tole(0x06071c64L), tole(0xdd439b0dL), tole(0x947fe62aL), +tole(0x6e26e32eL), tole(0x271a9e09L), tole(0xfc5e1960L), tole(0xb5626447L), +tole(0x89766c2dL), tole(0xc04a110aL), tole(0x1b0e9663L), tole(0x5232eb44L), +tole(0xa86bee40L), tole(0xe1579367L), tole(0x3a13140eL), tole(0x732f6929L), +tole(0xcb4d68f7L), tole(0x827115d0L), tole(0x593592b9L), tole(0x1009ef9eL), +tole(0xea50ea9aL), tole(0xa36c97bdL), tole(0x782810d4L), tole(0x31146df3L), +tole(0x1a00cb32L), tole(0x533cb615L), tole(0x8878317cL), tole(0xc1444c5bL), +tole(0x3b1d495fL), tole(0x72213478L), tole(0xa965b311L), tole(0xe059ce36L), +tole(0x583bcfe8L), tole(0x1107b2cfL), tole(0xca4335a6L), tole(0x837f4881L), +tole(0x79264d85L), tole(0x301a30a2L), tole(0xeb5eb7cbL), tole(0xa262caecL), +tole(0x9e76c286L), tole(0xd74abfa1L), tole(0x0c0e38c8L), tole(0x453245efL), +tole(0xbf6b40ebL), tole(0xf6573dccL), tole(0x2d13baa5L), tole(0x642fc782L), +tole(0xdc4dc65cL), tole(0x9571bb7bL), tole(0x4e353c12L), tole(0x07094135L), +tole(0xfd504431L), tole(0xb46c3916L), tole(0x6f28be7fL), tole(0x2614c358L), +tole(0x1700aeabL), tole(0x5e3cd38cL), tole(0x857854e5L), tole(0xcc4429c2L), +tole(0x361d2cc6L), tole(0x7f2151e1L), tole(0xa465d688L), tole(0xed59abafL), +tole(0x553baa71L), tole(0x1c07d756L), tole(0xc743503fL), tole(0x8e7f2d18L), +tole(0x7426281cL), tole(0x3d1a553bL), tole(0xe65ed252L), tole(0xaf62af75L), +tole(0x9376a71fL), tole(0xda4ada38L), tole(0x010e5d51L), tole(0x48322076L), +tole(0xb26b2572L), tole(0xfb575855L), tole(0x2013df3cL), tole(0x692fa21bL), +tole(0xd14da3c5L), tole(0x9871dee2L), tole(0x4335598bL), tole(0x0a0924acL), +tole(0xf05021a8L), tole(0xb96c5c8fL), tole(0x6228dbe6L), tole(0x2b14a6c1L), +tole(0x34019664L), tole(0x7d3deb43L), tole(0xa6796c2aL), tole(0xef45110dL), +tole(0x151c1409L), tole(0x5c20692eL), tole(0x8764ee47L), tole(0xce589360L), +tole(0x763a92beL), tole(0x3f06ef99L), tole(0xe44268f0L), tole(0xad7e15d7L), +tole(0x572710d3L), tole(0x1e1b6df4L), tole(0xc55fea9dL), tole(0x8c6397baL), +tole(0xb0779fd0L), tole(0xf94be2f7L), tole(0x220f659eL), tole(0x6b3318b9L), +tole(0x916a1dbdL), tole(0xd856609aL), tole(0x0312e7f3L), tole(0x4a2e9ad4L), +tole(0xf24c9b0aL), tole(0xbb70e62dL), tole(0x60346144L), tole(0x29081c63L), +tole(0xd3511967L), tole(0x9a6d6440L), tole(0x4129e329L), tole(0x08159e0eL), +tole(0x3901f3fdL), tole(0x703d8edaL), tole(0xab7909b3L), tole(0xe2457494L), +tole(0x181c7190L), tole(0x51200cb7L), tole(0x8a648bdeL), tole(0xc358f6f9L), +tole(0x7b3af727L), tole(0x32068a00L), tole(0xe9420d69L), tole(0xa07e704eL), +tole(0x5a27754aL), tole(0x131b086dL), tole(0xc85f8f04L), tole(0x8163f223L), +tole(0xbd77fa49L), tole(0xf44b876eL), tole(0x2f0f0007L), tole(0x66337d20L), +tole(0x9c6a7824L), tole(0xd5560503L), tole(0x0e12826aL), tole(0x472eff4dL), +tole(0xff4cfe93L), tole(0xb67083b4L), tole(0x6d3404ddL), tole(0x240879faL), +tole(0xde517cfeL), tole(0x976d01d9L), tole(0x4c2986b0L), tole(0x0515fb97L), +tole(0x2e015d56L), tole(0x673d2071L), tole(0xbc79a718L), tole(0xf545da3fL), +tole(0x0f1cdf3bL), tole(0x4620a21cL), tole(0x9d642575L), tole(0xd4585852L), +tole(0x6c3a598cL), tole(0x250624abL), tole(0xfe42a3c2L), tole(0xb77edee5L), +tole(0x4d27dbe1L), tole(0x041ba6c6L), tole(0xdf5f21afL), tole(0x96635c88L), +tole(0xaa7754e2L), tole(0xe34b29c5L), tole(0x380faeacL), tole(0x7133d38bL), +tole(0x8b6ad68fL), tole(0xc256aba8L), tole(0x19122cc1L), tole(0x502e51e6L), +tole(0xe84c5038L), tole(0xa1702d1fL), tole(0x7a34aa76L), tole(0x3308d751L), +tole(0xc951d255L), tole(0x806daf72L), tole(0x5b29281bL), tole(0x1215553cL), +tole(0x230138cfL), tole(0x6a3d45e8L), tole(0xb179c281L), tole(0xf845bfa6L), +tole(0x021cbaa2L), tole(0x4b20c785L), tole(0x906440ecL), tole(0xd9583dcbL), +tole(0x613a3c15L), tole(0x28064132L), tole(0xf342c65bL), tole(0xba7ebb7cL), +tole(0x4027be78L), tole(0x091bc35fL), tole(0xd25f4436L), tole(0x9b633911L), +tole(0xa777317bL), tole(0xee4b4c5cL), tole(0x350fcb35L), tole(0x7c33b612L), +tole(0x866ab316L), tole(0xcf56ce31L), tole(0x14124958L), tole(0x5d2e347fL), +tole(0xe54c35a1L), tole(0xac704886L), tole(0x7734cfefL), tole(0x3e08b2c8L), +tole(0xc451b7ccL), tole(0x8d6dcaebL), tole(0x56294d82L), tole(0x1f1530a5L)}; + +static const uint32_t t0_be[] = { +tobe(0x00000000L), tobe(0x1edc6f41L), tobe(0x3db8de82L), tobe(0x2364b1c3L), +tobe(0x7b71bd04L), tobe(0x65add245L), tobe(0x46c96386L), tobe(0x58150cc7L), +tobe(0xf6e37a08L), tobe(0xe83f1549L), tobe(0xcb5ba48aL), tobe(0xd587cbcbL), +tobe(0x8d92c70cL), tobe(0x934ea84dL), tobe(0xb02a198eL), tobe(0xaef676cfL), +tobe(0xf31a9b51L), tobe(0xedc6f410L), tobe(0xcea245d3L), tobe(0xd07e2a92L), +tobe(0x886b2655L), tobe(0x96b74914L), tobe(0xb5d3f8d7L), tobe(0xab0f9796L), +tobe(0x05f9e159L), tobe(0x1b258e18L), tobe(0x38413fdbL), tobe(0x269d509aL), +tobe(0x7e885c5dL), tobe(0x6054331cL), tobe(0x433082dfL), tobe(0x5deced9eL), +tobe(0xf8e959e3L), tobe(0xe63536a2L), tobe(0xc5518761L), tobe(0xdb8de820L), +tobe(0x8398e4e7L), tobe(0x9d448ba6L), tobe(0xbe203a65L), tobe(0xa0fc5524L), +tobe(0x0e0a23ebL), tobe(0x10d64caaL), tobe(0x33b2fd69L), tobe(0x2d6e9228L), +tobe(0x757b9eefL), tobe(0x6ba7f1aeL), tobe(0x48c3406dL), tobe(0x561f2f2cL), +tobe(0x0bf3c2b2L), tobe(0x152fadf3L), tobe(0x364b1c30L), tobe(0x28977371L), +tobe(0x70827fb6L), tobe(0x6e5e10f7L), tobe(0x4d3aa134L), tobe(0x53e6ce75L), +tobe(0xfd10b8baL), tobe(0xe3ccd7fbL), tobe(0xc0a86638L), tobe(0xde740979L), +tobe(0x866105beL), tobe(0x98bd6affL), tobe(0xbbd9db3cL), tobe(0xa505b47dL), +tobe(0xef0edc87L), tobe(0xf1d2b3c6L), tobe(0xd2b60205L), tobe(0xcc6a6d44L), +tobe(0x947f6183L), tobe(0x8aa30ec2L), tobe(0xa9c7bf01L), tobe(0xb71bd040L), +tobe(0x19eda68fL), tobe(0x0731c9ceL), tobe(0x2455780dL), tobe(0x3a89174cL), +tobe(0x629c1b8bL), tobe(0x7c4074caL), tobe(0x5f24c509L), tobe(0x41f8aa48L), +tobe(0x1c1447d6L), tobe(0x02c82897L), tobe(0x21ac9954L), tobe(0x3f70f615L), +tobe(0x6765fad2L), tobe(0x79b99593L), tobe(0x5add2450L), tobe(0x44014b11L), +tobe(0xeaf73ddeL), tobe(0xf42b529fL), tobe(0xd74fe35cL), tobe(0xc9938c1dL), +tobe(0x918680daL), tobe(0x8f5aef9bL), tobe(0xac3e5e58L), tobe(0xb2e23119L), +tobe(0x17e78564L), tobe(0x093bea25L), tobe(0x2a5f5be6L), tobe(0x348334a7L), +tobe(0x6c963860L), tobe(0x724a5721L), tobe(0x512ee6e2L), tobe(0x4ff289a3L), +tobe(0xe104ff6cL), tobe(0xffd8902dL), tobe(0xdcbc21eeL), tobe(0xc2604eafL), +tobe(0x9a754268L), tobe(0x84a92d29L), tobe(0xa7cd9ceaL), tobe(0xb911f3abL), +tobe(0xe4fd1e35L), tobe(0xfa217174L), tobe(0xd945c0b7L), tobe(0xc799aff6L), +tobe(0x9f8ca331L), tobe(0x8150cc70L), tobe(0xa2347db3L), tobe(0xbce812f2L), +tobe(0x121e643dL), tobe(0x0cc20b7cL), tobe(0x2fa6babfL), tobe(0x317ad5feL), +tobe(0x696fd939L), tobe(0x77b3b678L), tobe(0x54d707bbL), tobe(0x4a0b68faL), +tobe(0xc0c1d64fL), tobe(0xde1db90eL), tobe(0xfd7908cdL), tobe(0xe3a5678cL), +tobe(0xbbb06b4bL), tobe(0xa56c040aL), tobe(0x8608b5c9L), tobe(0x98d4da88L), +tobe(0x3622ac47L), tobe(0x28fec306L), tobe(0x0b9a72c5L), tobe(0x15461d84L), +tobe(0x4d531143L), tobe(0x538f7e02L), tobe(0x70ebcfc1L), tobe(0x6e37a080L), +tobe(0x33db4d1eL), tobe(0x2d07225fL), tobe(0x0e63939cL), tobe(0x10bffcddL), +tobe(0x48aaf01aL), tobe(0x56769f5bL), tobe(0x75122e98L), tobe(0x6bce41d9L), +tobe(0xc5383716L), tobe(0xdbe45857L), tobe(0xf880e994L), tobe(0xe65c86d5L), +tobe(0xbe498a12L), tobe(0xa095e553L), tobe(0x83f15490L), tobe(0x9d2d3bd1L), +tobe(0x38288facL), tobe(0x26f4e0edL), tobe(0x0590512eL), tobe(0x1b4c3e6fL), +tobe(0x435932a8L), tobe(0x5d855de9L), tobe(0x7ee1ec2aL), tobe(0x603d836bL), +tobe(0xcecbf5a4L), tobe(0xd0179ae5L), tobe(0xf3732b26L), tobe(0xedaf4467L), +tobe(0xb5ba48a0L), tobe(0xab6627e1L), tobe(0x88029622L), tobe(0x96def963L), +tobe(0xcb3214fdL), tobe(0xd5ee7bbcL), tobe(0xf68aca7fL), tobe(0xe856a53eL), +tobe(0xb043a9f9L), tobe(0xae9fc6b8L), tobe(0x8dfb777bL), tobe(0x9327183aL), +tobe(0x3dd16ef5L), tobe(0x230d01b4L), tobe(0x0069b077L), tobe(0x1eb5df36L), +tobe(0x46a0d3f1L), tobe(0x587cbcb0L), tobe(0x7b180d73L), tobe(0x65c46232L), +tobe(0x2fcf0ac8L), tobe(0x31136589L), tobe(0x1277d44aL), tobe(0x0cabbb0bL), +tobe(0x54beb7ccL), tobe(0x4a62d88dL), tobe(0x6906694eL), tobe(0x77da060fL), +tobe(0xd92c70c0L), tobe(0xc7f01f81L), tobe(0xe494ae42L), tobe(0xfa48c103L), +tobe(0xa25dcdc4L), tobe(0xbc81a285L), tobe(0x9fe51346L), tobe(0x81397c07L), +tobe(0xdcd59199L), tobe(0xc209fed8L), tobe(0xe16d4f1bL), tobe(0xffb1205aL), +tobe(0xa7a42c9dL), tobe(0xb97843dcL), tobe(0x9a1cf21fL), tobe(0x84c09d5eL), +tobe(0x2a36eb91L), tobe(0x34ea84d0L), tobe(0x178e3513L), tobe(0x09525a52L), +tobe(0x51475695L), tobe(0x4f9b39d4L), tobe(0x6cff8817L), tobe(0x7223e756L), +tobe(0xd726532bL), tobe(0xc9fa3c6aL), tobe(0xea9e8da9L), tobe(0xf442e2e8L), +tobe(0xac57ee2fL), tobe(0xb28b816eL), tobe(0x91ef30adL), tobe(0x8f335fecL), +tobe(0x21c52923L), tobe(0x3f194662L), tobe(0x1c7df7a1L), tobe(0x02a198e0L), +tobe(0x5ab49427L), tobe(0x4468fb66L), tobe(0x670c4aa5L), tobe(0x79d025e4L), +tobe(0x243cc87aL), tobe(0x3ae0a73bL), tobe(0x198416f8L), tobe(0x075879b9L), +tobe(0x5f4d757eL), tobe(0x41911a3fL), tobe(0x62f5abfcL), tobe(0x7c29c4bdL), +tobe(0xd2dfb272L), tobe(0xcc03dd33L), tobe(0xef676cf0L), tobe(0xf1bb03b1L), +tobe(0xa9ae0f76L), tobe(0xb7726037L), tobe(0x9416d1f4L), tobe(0x8acabeb5L)}; + +static const uint32_t t1_be[] = { +tobe(0x00000000L), tobe(0x9f5fc3dfL), tobe(0x2063e8ffL), tobe(0xbf3c2b20L), +tobe(0x40c7d1feL), tobe(0xdf981221L), tobe(0x60a43901L), tobe(0xfffbfadeL), +tobe(0x818fa3fcL), tobe(0x1ed06023L), tobe(0xa1ec4b03L), tobe(0x3eb388dcL), +tobe(0xc1487202L), tobe(0x5e17b1ddL), tobe(0xe12b9afdL), tobe(0x7e745922L), +tobe(0x1dc328b9L), tobe(0x829ceb66L), tobe(0x3da0c046L), tobe(0xa2ff0399L), +tobe(0x5d04f947L), tobe(0xc25b3a98L), tobe(0x7d6711b8L), tobe(0xe238d267L), +tobe(0x9c4c8b45L), tobe(0x0313489aL), tobe(0xbc2f63baL), tobe(0x2370a065L), +tobe(0xdc8b5abbL), tobe(0x43d49964L), tobe(0xfce8b244L), tobe(0x63b7719bL), +tobe(0x3b865172L), tobe(0xa4d992adL), tobe(0x1be5b98dL), tobe(0x84ba7a52L), +tobe(0x7b41808cL), tobe(0xe41e4353L), tobe(0x5b226873L), tobe(0xc47dabacL), +tobe(0xba09f28eL), tobe(0x25563151L), tobe(0x9a6a1a71L), tobe(0x0535d9aeL), +tobe(0xface2370L), tobe(0x6591e0afL), tobe(0xdaadcb8fL), tobe(0x45f20850L), +tobe(0x264579cbL), tobe(0xb91aba14L), tobe(0x06269134L), tobe(0x997952ebL), +tobe(0x6682a835L), tobe(0xf9dd6beaL), tobe(0x46e140caL), tobe(0xd9be8315L), +tobe(0xa7cada37L), tobe(0x389519e8L), tobe(0x87a932c8L), tobe(0x18f6f117L), +tobe(0xe70d0bc9L), tobe(0x7852c816L), tobe(0xc76ee336L), tobe(0x583120e9L), +tobe(0x770ca2e4L), tobe(0xe853613bL), tobe(0x576f4a1bL), tobe(0xc83089c4L), +tobe(0x37cb731aL), tobe(0xa894b0c5L), tobe(0x17a89be5L), tobe(0x88f7583aL), +tobe(0xf6830118L), tobe(0x69dcc2c7L), tobe(0xd6e0e9e7L), tobe(0x49bf2a38L), +tobe(0xb644d0e6L), tobe(0x291b1339L), tobe(0x96273819L), tobe(0x0978fbc6L), +tobe(0x6acf8a5dL), tobe(0xf5904982L), tobe(0x4aac62a2L), tobe(0xd5f3a17dL), +tobe(0x2a085ba3L), tobe(0xb557987cL), tobe(0x0a6bb35cL), tobe(0x95347083L), +tobe(0xeb4029a1L), tobe(0x741fea7eL), tobe(0xcb23c15eL), tobe(0x547c0281L), +tobe(0xab87f85fL), tobe(0x34d83b80L), tobe(0x8be410a0L), tobe(0x14bbd37fL), +tobe(0x4c8af396L), tobe(0xd3d53049L), tobe(0x6ce91b69L), tobe(0xf3b6d8b6L), +tobe(0x0c4d2268L), tobe(0x9312e1b7L), tobe(0x2c2eca97L), tobe(0xb3710948L), +tobe(0xcd05506aL), tobe(0x525a93b5L), tobe(0xed66b895L), tobe(0x72397b4aL), +tobe(0x8dc28194L), tobe(0x129d424bL), tobe(0xada1696bL), tobe(0x32feaab4L), +tobe(0x5149db2fL), tobe(0xce1618f0L), tobe(0x712a33d0L), tobe(0xee75f00fL), +tobe(0x118e0ad1L), tobe(0x8ed1c90eL), tobe(0x31ede22eL), tobe(0xaeb221f1L), +tobe(0xd0c678d3L), tobe(0x4f99bb0cL), tobe(0xf0a5902cL), tobe(0x6ffa53f3L), +tobe(0x9001a92dL), tobe(0x0f5e6af2L), tobe(0xb06241d2L), tobe(0x2f3d820dL), +tobe(0xee1945c8L), tobe(0x71468617L), tobe(0xce7aad37L), tobe(0x51256ee8L), +tobe(0xaede9436L), tobe(0x318157e9L), tobe(0x8ebd7cc9L), tobe(0x11e2bf16L), +tobe(0x6f96e634L), tobe(0xf0c925ebL), tobe(0x4ff50ecbL), tobe(0xd0aacd14L), +tobe(0x2f5137caL), tobe(0xb00ef415L), tobe(0x0f32df35L), tobe(0x906d1ceaL), +tobe(0xf3da6d71L), tobe(0x6c85aeaeL), tobe(0xd3b9858eL), tobe(0x4ce64651L), +tobe(0xb31dbc8fL), tobe(0x2c427f50L), tobe(0x937e5470L), tobe(0x0c2197afL), +tobe(0x7255ce8dL), tobe(0xed0a0d52L), tobe(0x52362672L), tobe(0xcd69e5adL), +tobe(0x32921f73L), tobe(0xadcddcacL), tobe(0x12f1f78cL), tobe(0x8dae3453L), +tobe(0xd59f14baL), tobe(0x4ac0d765L), tobe(0xf5fcfc45L), tobe(0x6aa33f9aL), +tobe(0x9558c544L), tobe(0x0a07069bL), tobe(0xb53b2dbbL), tobe(0x2a64ee64L), +tobe(0x5410b746L), tobe(0xcb4f7499L), tobe(0x74735fb9L), tobe(0xeb2c9c66L), +tobe(0x14d766b8L), tobe(0x8b88a567L), tobe(0x34b48e47L), tobe(0xabeb4d98L), +tobe(0xc85c3c03L), tobe(0x5703ffdcL), tobe(0xe83fd4fcL), tobe(0x77601723L), +tobe(0x889bedfdL), tobe(0x17c42e22L), tobe(0xa8f80502L), tobe(0x37a7c6ddL), +tobe(0x49d39fffL), tobe(0xd68c5c20L), tobe(0x69b07700L), tobe(0xf6efb4dfL), +tobe(0x09144e01L), tobe(0x964b8ddeL), tobe(0x2977a6feL), tobe(0xb6286521L), +tobe(0x9915e72cL), tobe(0x064a24f3L), tobe(0xb9760fd3L), tobe(0x2629cc0cL), +tobe(0xd9d236d2L), tobe(0x468df50dL), tobe(0xf9b1de2dL), tobe(0x66ee1df2L), +tobe(0x189a44d0L), tobe(0x87c5870fL), tobe(0x38f9ac2fL), tobe(0xa7a66ff0L), +tobe(0x585d952eL), tobe(0xc70256f1L), tobe(0x783e7dd1L), tobe(0xe761be0eL), +tobe(0x84d6cf95L), tobe(0x1b890c4aL), tobe(0xa4b5276aL), tobe(0x3beae4b5L), +tobe(0xc4111e6bL), tobe(0x5b4eddb4L), tobe(0xe472f694L), tobe(0x7b2d354bL), +tobe(0x05596c69L), tobe(0x9a06afb6L), tobe(0x253a8496L), tobe(0xba654749L), +tobe(0x459ebd97L), tobe(0xdac17e48L), tobe(0x65fd5568L), tobe(0xfaa296b7L), +tobe(0xa293b65eL), tobe(0x3dcc7581L), tobe(0x82f05ea1L), tobe(0x1daf9d7eL), +tobe(0xe25467a0L), tobe(0x7d0ba47fL), tobe(0xc2378f5fL), tobe(0x5d684c80L), +tobe(0x231c15a2L), tobe(0xbc43d67dL), tobe(0x037ffd5dL), tobe(0x9c203e82L), +tobe(0x63dbc45cL), tobe(0xfc840783L), tobe(0x43b82ca3L), tobe(0xdce7ef7cL), +tobe(0xbf509ee7L), tobe(0x200f5d38L), tobe(0x9f337618L), tobe(0x006cb5c7L), +tobe(0xff974f19L), tobe(0x60c88cc6L), tobe(0xdff4a7e6L), tobe(0x40ab6439L), +tobe(0x3edf3d1bL), tobe(0xa180fec4L), tobe(0x1ebcd5e4L), tobe(0x81e3163bL), +tobe(0x7e18ece5L), tobe(0xe1472f3aL), tobe(0x5e7b041aL), tobe(0xc124c7c5L)}; + +static const uint32_t t2_be[] = { +tobe(0x00000000L), tobe(0xc2eee4d1L), tobe(0x9b01a6e3L), tobe(0x59ef4232L), +tobe(0x28df2287L), tobe(0xea31c656L), tobe(0xb3de8464L), tobe(0x713060b5L), +tobe(0x51be450eL), tobe(0x9350a1dfL), tobe(0xcabfe3edL), tobe(0x0851073cL), +tobe(0x79616789L), tobe(0xbb8f8358L), tobe(0xe260c16aL), tobe(0x208e25bbL), +tobe(0xa37c8a1cL), tobe(0x61926ecdL), tobe(0x387d2cffL), tobe(0xfa93c82eL), +tobe(0x8ba3a89bL), tobe(0x494d4c4aL), tobe(0x10a20e78L), tobe(0xd24ceaa9L), +tobe(0xf2c2cf12L), tobe(0x302c2bc3L), tobe(0x69c369f1L), tobe(0xab2d8d20L), +tobe(0xda1ded95L), tobe(0x18f30944L), tobe(0x411c4b76L), tobe(0x83f2afa7L), +tobe(0x58257b79L), tobe(0x9acb9fa8L), tobe(0xc324dd9aL), tobe(0x01ca394bL), +tobe(0x70fa59feL), tobe(0xb214bd2fL), tobe(0xebfbff1dL), tobe(0x29151bccL), +tobe(0x099b3e77L), tobe(0xcb75daa6L), tobe(0x929a9894L), tobe(0x50747c45L), +tobe(0x21441cf0L), tobe(0xe3aaf821L), tobe(0xba45ba13L), tobe(0x78ab5ec2L), +tobe(0xfb59f165L), tobe(0x39b715b4L), tobe(0x60585786L), tobe(0xa2b6b357L), +tobe(0xd386d3e2L), tobe(0x11683733L), tobe(0x48877501L), tobe(0x8a6991d0L), +tobe(0xaae7b46bL), tobe(0x680950baL), tobe(0x31e61288L), tobe(0xf308f659L), +tobe(0x823896ecL), tobe(0x40d6723dL), tobe(0x1939300fL), tobe(0xdbd7d4deL), +tobe(0xb04af6f2L), tobe(0x72a41223L), tobe(0x2b4b5011L), tobe(0xe9a5b4c0L), +tobe(0x9895d475L), tobe(0x5a7b30a4L), tobe(0x03947296L), tobe(0xc17a9647L), +tobe(0xe1f4b3fcL), tobe(0x231a572dL), tobe(0x7af5151fL), tobe(0xb81bf1ceL), +tobe(0xc92b917bL), tobe(0x0bc575aaL), tobe(0x522a3798L), tobe(0x90c4d349L), +tobe(0x13367ceeL), tobe(0xd1d8983fL), tobe(0x8837da0dL), tobe(0x4ad93edcL), +tobe(0x3be95e69L), tobe(0xf907bab8L), tobe(0xa0e8f88aL), tobe(0x62061c5bL), +tobe(0x428839e0L), tobe(0x8066dd31L), tobe(0xd9899f03L), tobe(0x1b677bd2L), +tobe(0x6a571b67L), tobe(0xa8b9ffb6L), tobe(0xf156bd84L), tobe(0x33b85955L), +tobe(0xe86f8d8bL), tobe(0x2a81695aL), tobe(0x736e2b68L), tobe(0xb180cfb9L), +tobe(0xc0b0af0cL), tobe(0x025e4bddL), tobe(0x5bb109efL), tobe(0x995fed3eL), +tobe(0xb9d1c885L), tobe(0x7b3f2c54L), tobe(0x22d06e66L), tobe(0xe03e8ab7L), +tobe(0x910eea02L), tobe(0x53e00ed3L), tobe(0x0a0f4ce1L), tobe(0xc8e1a830L), +tobe(0x4b130797L), tobe(0x89fde346L), tobe(0xd012a174L), tobe(0x12fc45a5L), +tobe(0x63cc2510L), tobe(0xa122c1c1L), tobe(0xf8cd83f3L), tobe(0x3a236722L), +tobe(0x1aad4299L), tobe(0xd843a648L), tobe(0x81ace47aL), tobe(0x434200abL), +tobe(0x3272601eL), tobe(0xf09c84cfL), tobe(0xa973c6fdL), tobe(0x6b9d222cL), +tobe(0x7e4982a5L), tobe(0xbca76674L), tobe(0xe5482446L), tobe(0x27a6c097L), +tobe(0x5696a022L), tobe(0x947844f3L), tobe(0xcd9706c1L), tobe(0x0f79e210L), +tobe(0x2ff7c7abL), tobe(0xed19237aL), tobe(0xb4f66148L), tobe(0x76188599L), +tobe(0x0728e52cL), tobe(0xc5c601fdL), tobe(0x9c2943cfL), tobe(0x5ec7a71eL), +tobe(0xdd3508b9L), tobe(0x1fdbec68L), tobe(0x4634ae5aL), tobe(0x84da4a8bL), +tobe(0xf5ea2a3eL), tobe(0x3704ceefL), tobe(0x6eeb8cddL), tobe(0xac05680cL), +tobe(0x8c8b4db7L), tobe(0x4e65a966L), tobe(0x178aeb54L), tobe(0xd5640f85L), +tobe(0xa4546f30L), tobe(0x66ba8be1L), tobe(0x3f55c9d3L), tobe(0xfdbb2d02L), +tobe(0x266cf9dcL), tobe(0xe4821d0dL), tobe(0xbd6d5f3fL), tobe(0x7f83bbeeL), +tobe(0x0eb3db5bL), tobe(0xcc5d3f8aL), tobe(0x95b27db8L), tobe(0x575c9969L), +tobe(0x77d2bcd2L), tobe(0xb53c5803L), tobe(0xecd31a31L), tobe(0x2e3dfee0L), +tobe(0x5f0d9e55L), tobe(0x9de37a84L), tobe(0xc40c38b6L), tobe(0x06e2dc67L), +tobe(0x851073c0L), tobe(0x47fe9711L), tobe(0x1e11d523L), tobe(0xdcff31f2L), +tobe(0xadcf5147L), tobe(0x6f21b596L), tobe(0x36cef7a4L), tobe(0xf4201375L), +tobe(0xd4ae36ceL), tobe(0x1640d21fL), tobe(0x4faf902dL), tobe(0x8d4174fcL), +tobe(0xfc711449L), tobe(0x3e9ff098L), tobe(0x6770b2aaL), tobe(0xa59e567bL), +tobe(0xce037457L), tobe(0x0ced9086L), tobe(0x5502d2b4L), tobe(0x97ec3665L), +tobe(0xe6dc56d0L), tobe(0x2432b201L), tobe(0x7dddf033L), tobe(0xbf3314e2L), +tobe(0x9fbd3159L), tobe(0x5d53d588L), tobe(0x04bc97baL), tobe(0xc652736bL), +tobe(0xb76213deL), tobe(0x758cf70fL), tobe(0x2c63b53dL), tobe(0xee8d51ecL), +tobe(0x6d7ffe4bL), tobe(0xaf911a9aL), tobe(0xf67e58a8L), tobe(0x3490bc79L), +tobe(0x45a0dcccL), tobe(0x874e381dL), tobe(0xdea17a2fL), tobe(0x1c4f9efeL), +tobe(0x3cc1bb45L), tobe(0xfe2f5f94L), tobe(0xa7c01da6L), tobe(0x652ef977L), +tobe(0x141e99c2L), tobe(0xd6f07d13L), tobe(0x8f1f3f21L), tobe(0x4df1dbf0L), +tobe(0x96260f2eL), tobe(0x54c8ebffL), tobe(0x0d27a9cdL), tobe(0xcfc94d1cL), +tobe(0xbef92da9L), tobe(0x7c17c978L), tobe(0x25f88b4aL), tobe(0xe7166f9bL), +tobe(0xc7984a20L), tobe(0x0576aef1L), tobe(0x5c99ecc3L), tobe(0x9e770812L), +tobe(0xef4768a7L), tobe(0x2da98c76L), tobe(0x7446ce44L), tobe(0xb6a82a95L), +tobe(0x355a8532L), tobe(0xf7b461e3L), tobe(0xae5b23d1L), tobe(0x6cb5c700L), +tobe(0x1d85a7b5L), tobe(0xdf6b4364L), tobe(0x86840156L), tobe(0x446ae587L), +tobe(0x64e4c03cL), tobe(0xa60a24edL), tobe(0xffe566dfL), tobe(0x3d0b820eL), +tobe(0x4c3be2bbL), tobe(0x8ed5066aL), tobe(0xd73a4458L), tobe(0x15d4a089L)}; + +static const uint32_t t3_be[] = { +tobe(0x00000000L), tobe(0xfc93054aL), tobe(0xe7fa65d5L), tobe(0x1b69609fL), +tobe(0xd128a4ebL), tobe(0x2dbba1a1L), tobe(0x36d2c13eL), tobe(0xca41c474L), +tobe(0xbc8d2697L), tobe(0x401e23ddL), tobe(0x5b774342L), tobe(0xa7e44608L), +tobe(0x6da5827cL), tobe(0x91368736L), tobe(0x8a5fe7a9L), tobe(0x76cce2e3L), +tobe(0x67c6226fL), tobe(0x9b552725L), tobe(0x803c47baL), tobe(0x7caf42f0L), +tobe(0xb6ee8684L), tobe(0x4a7d83ceL), tobe(0x5114e351L), tobe(0xad87e61bL), +tobe(0xdb4b04f8L), tobe(0x27d801b2L), tobe(0x3cb1612dL), tobe(0xc0226467L), +tobe(0x0a63a013L), tobe(0xf6f0a559L), tobe(0xed99c5c6L), tobe(0x110ac08cL), +tobe(0xcf8c44deL), tobe(0x331f4194L), tobe(0x2876210bL), tobe(0xd4e52441L), +tobe(0x1ea4e035L), tobe(0xe237e57fL), tobe(0xf95e85e0L), tobe(0x05cd80aaL), +tobe(0x73016249L), tobe(0x8f926703L), tobe(0x94fb079cL), tobe(0x686802d6L), +tobe(0xa229c6a2L), tobe(0x5ebac3e8L), tobe(0x45d3a377L), tobe(0xb940a63dL), +tobe(0xa84a66b1L), tobe(0x54d963fbL), tobe(0x4fb00364L), tobe(0xb323062eL), +tobe(0x7962c25aL), tobe(0x85f1c710L), tobe(0x9e98a78fL), tobe(0x620ba2c5L), +tobe(0x14c74026L), tobe(0xe854456cL), tobe(0xf33d25f3L), tobe(0x0fae20b9L), +tobe(0xc5efe4cdL), tobe(0x397ce187L), tobe(0x22158118L), tobe(0xde868452L), +tobe(0x81c4e6fdL), tobe(0x7d57e3b7L), tobe(0x663e8328L), tobe(0x9aad8662L), +tobe(0x50ec4216L), tobe(0xac7f475cL), tobe(0xb71627c3L), tobe(0x4b852289L), +tobe(0x3d49c06aL), tobe(0xc1dac520L), tobe(0xdab3a5bfL), tobe(0x2620a0f5L), +tobe(0xec616481L), tobe(0x10f261cbL), tobe(0x0b9b0154L), tobe(0xf708041eL), +tobe(0xe602c492L), tobe(0x1a91c1d8L), tobe(0x01f8a147L), tobe(0xfd6ba40dL), +tobe(0x372a6079L), tobe(0xcbb96533L), tobe(0xd0d005acL), tobe(0x2c4300e6L), +tobe(0x5a8fe205L), tobe(0xa61ce74fL), tobe(0xbd7587d0L), tobe(0x41e6829aL), +tobe(0x8ba746eeL), tobe(0x773443a4L), tobe(0x6c5d233bL), tobe(0x90ce2671L), +tobe(0x4e48a223L), tobe(0xb2dba769L), tobe(0xa9b2c7f6L), tobe(0x5521c2bcL), +tobe(0x9f6006c8L), tobe(0x63f30382L), tobe(0x789a631dL), tobe(0x84096657L), +tobe(0xf2c584b4L), tobe(0x0e5681feL), tobe(0x153fe161L), tobe(0xe9ace42bL), +tobe(0x23ed205fL), tobe(0xdf7e2515L), tobe(0xc417458aL), tobe(0x388440c0L), +tobe(0x298e804cL), tobe(0xd51d8506L), tobe(0xce74e599L), tobe(0x32e7e0d3L), +tobe(0xf8a624a7L), tobe(0x043521edL), tobe(0x1f5c4172L), tobe(0xe3cf4438L), +tobe(0x9503a6dbL), tobe(0x6990a391L), tobe(0x72f9c30eL), tobe(0x8e6ac644L), +tobe(0x442b0230L), tobe(0xb8b8077aL), tobe(0xa3d167e5L), tobe(0x5f4262afL), +tobe(0x1d55a2bbL), tobe(0xe1c6a7f1L), tobe(0xfaafc76eL), tobe(0x063cc224L), +tobe(0xcc7d0650L), tobe(0x30ee031aL), tobe(0x2b876385L), tobe(0xd71466cfL), +tobe(0xa1d8842cL), tobe(0x5d4b8166L), tobe(0x4622e1f9L), tobe(0xbab1e4b3L), +tobe(0x70f020c7L), tobe(0x8c63258dL), tobe(0x970a4512L), tobe(0x6b994058L), +tobe(0x7a9380d4L), tobe(0x8600859eL), tobe(0x9d69e501L), tobe(0x61fae04bL), +tobe(0xabbb243fL), tobe(0x57282175L), tobe(0x4c4141eaL), tobe(0xb0d244a0L), +tobe(0xc61ea643L), tobe(0x3a8da309L), tobe(0x21e4c396L), tobe(0xdd77c6dcL), +tobe(0x173602a8L), tobe(0xeba507e2L), tobe(0xf0cc677dL), tobe(0x0c5f6237L), +tobe(0xd2d9e665L), tobe(0x2e4ae32fL), tobe(0x352383b0L), tobe(0xc9b086faL), +tobe(0x03f1428eL), tobe(0xff6247c4L), tobe(0xe40b275bL), tobe(0x18982211L), +tobe(0x6e54c0f2L), tobe(0x92c7c5b8L), tobe(0x89aea527L), tobe(0x753da06dL), +tobe(0xbf7c6419L), tobe(0x43ef6153L), tobe(0x588601ccL), tobe(0xa4150486L), +tobe(0xb51fc40aL), tobe(0x498cc140L), tobe(0x52e5a1dfL), tobe(0xae76a495L), +tobe(0x643760e1L), tobe(0x98a465abL), tobe(0x83cd0534L), tobe(0x7f5e007eL), +tobe(0x0992e29dL), tobe(0xf501e7d7L), tobe(0xee688748L), tobe(0x12fb8202L), +tobe(0xd8ba4676L), tobe(0x2429433cL), tobe(0x3f4023a3L), tobe(0xc3d326e9L), +tobe(0x9c914446L), tobe(0x6002410cL), tobe(0x7b6b2193L), tobe(0x87f824d9L), +tobe(0x4db9e0adL), tobe(0xb12ae5e7L), tobe(0xaa438578L), tobe(0x56d08032L), +tobe(0x201c62d1L), tobe(0xdc8f679bL), tobe(0xc7e60704L), tobe(0x3b75024eL), +tobe(0xf134c63aL), tobe(0x0da7c370L), tobe(0x16cea3efL), tobe(0xea5da6a5L), +tobe(0xfb576629L), tobe(0x07c46363L), tobe(0x1cad03fcL), tobe(0xe03e06b6L), +tobe(0x2a7fc2c2L), tobe(0xd6ecc788L), tobe(0xcd85a717L), tobe(0x3116a25dL), +tobe(0x47da40beL), tobe(0xbb4945f4L), tobe(0xa020256bL), tobe(0x5cb32021L), +tobe(0x96f2e455L), tobe(0x6a61e11fL), tobe(0x71088180L), tobe(0x8d9b84caL), +tobe(0x531d0098L), tobe(0xaf8e05d2L), tobe(0xb4e7654dL), tobe(0x48746007L), +tobe(0x8235a473L), tobe(0x7ea6a139L), tobe(0x65cfc1a6L), tobe(0x995cc4ecL), +tobe(0xef90260fL), tobe(0x13032345L), tobe(0x086a43daL), tobe(0xf4f94690L), +tobe(0x3eb882e4L), tobe(0xc22b87aeL), tobe(0xd942e731L), tobe(0x25d1e27bL), +tobe(0x34db22f7L), tobe(0xc84827bdL), tobe(0xd3214722L), tobe(0x2fb24268L), +tobe(0xe5f3861cL), tobe(0x19608356L), tobe(0x0209e3c9L), tobe(0xfe9ae683L), +tobe(0x88560460L), tobe(0x74c5012aL), tobe(0x6fac61b5L), tobe(0x933f64ffL), +tobe(0x597ea08bL), tobe(0xa5eda5c1L), tobe(0xbe84c55eL), tobe(0x4217c014L)}; + +static const uint32_t t4_be[] = { +tobe(0x00000000L), tobe(0x3aab4576L), tobe(0x75568aecL), tobe(0x4ffdcf9aL), +tobe(0xeaad15d8L), tobe(0xd00650aeL), tobe(0x9ffb9f34L), tobe(0xa550da42L), +tobe(0xcb8644f1L), tobe(0xf12d0187L), tobe(0xbed0ce1dL), tobe(0x847b8b6bL), +tobe(0x212b5129L), tobe(0x1b80145fL), tobe(0x547ddbc5L), tobe(0x6ed69eb3L), +tobe(0x89d0e6a3L), tobe(0xb37ba3d5L), tobe(0xfc866c4fL), tobe(0xc62d2939L), +tobe(0x637df37bL), tobe(0x59d6b60dL), tobe(0x162b7997L), tobe(0x2c803ce1L), +tobe(0x4256a252L), tobe(0x78fde724L), tobe(0x370028beL), tobe(0x0dab6dc8L), +tobe(0xa8fbb78aL), tobe(0x9250f2fcL), tobe(0xddad3d66L), tobe(0xe7067810L), +tobe(0x0d7da207L), tobe(0x37d6e771L), tobe(0x782b28ebL), tobe(0x42806d9dL), +tobe(0xe7d0b7dfL), tobe(0xdd7bf2a9L), tobe(0x92863d33L), tobe(0xa82d7845L), +tobe(0xc6fbe6f6L), tobe(0xfc50a380L), tobe(0xb3ad6c1aL), tobe(0x8906296cL), +tobe(0x2c56f32eL), tobe(0x16fdb658L), tobe(0x590079c2L), tobe(0x63ab3cb4L), +tobe(0x84ad44a4L), tobe(0xbe0601d2L), tobe(0xf1fbce48L), tobe(0xcb508b3eL), +tobe(0x6e00517cL), tobe(0x54ab140aL), tobe(0x1b56db90L), tobe(0x21fd9ee6L), +tobe(0x4f2b0055L), tobe(0x75804523L), tobe(0x3a7d8ab9L), tobe(0x00d6cfcfL), +tobe(0xa586158dL), tobe(0x9f2d50fbL), tobe(0xd0d09f61L), tobe(0xea7bda17L), +tobe(0x1afb440eL), tobe(0x20500178L), tobe(0x6fadcee2L), tobe(0x55068b94L), +tobe(0xf05651d6L), tobe(0xcafd14a0L), tobe(0x8500db3aL), tobe(0xbfab9e4cL), +tobe(0xd17d00ffL), tobe(0xebd64589L), tobe(0xa42b8a13L), tobe(0x9e80cf65L), +tobe(0x3bd01527L), tobe(0x017b5051L), tobe(0x4e869fcbL), tobe(0x742ddabdL), +tobe(0x932ba2adL), tobe(0xa980e7dbL), tobe(0xe67d2841L), tobe(0xdcd66d37L), +tobe(0x7986b775L), tobe(0x432df203L), tobe(0x0cd03d99L), tobe(0x367b78efL), +tobe(0x58ade65cL), tobe(0x6206a32aL), tobe(0x2dfb6cb0L), tobe(0x175029c6L), +tobe(0xb200f384L), tobe(0x88abb6f2L), tobe(0xc7567968L), tobe(0xfdfd3c1eL), +tobe(0x1786e609L), tobe(0x2d2da37fL), tobe(0x62d06ce5L), tobe(0x587b2993L), +tobe(0xfd2bf3d1L), tobe(0xc780b6a7L), tobe(0x887d793dL), tobe(0xb2d63c4bL), +tobe(0xdc00a2f8L), tobe(0xe6abe78eL), tobe(0xa9562814L), tobe(0x93fd6d62L), +tobe(0x36adb720L), tobe(0x0c06f256L), tobe(0x43fb3dccL), tobe(0x795078baL), +tobe(0x9e5600aaL), tobe(0xa4fd45dcL), tobe(0xeb008a46L), tobe(0xd1abcf30L), +tobe(0x74fb1572L), tobe(0x4e505004L), tobe(0x01ad9f9eL), tobe(0x3b06dae8L), +tobe(0x55d0445bL), tobe(0x6f7b012dL), tobe(0x2086ceb7L), tobe(0x1a2d8bc1L), +tobe(0xbf7d5183L), tobe(0x85d614f5L), tobe(0xca2bdb6fL), tobe(0xf0809e19L), +tobe(0x35f6881cL), tobe(0x0f5dcd6aL), tobe(0x40a002f0L), tobe(0x7a0b4786L), +tobe(0xdf5b9dc4L), tobe(0xe5f0d8b2L), tobe(0xaa0d1728L), tobe(0x90a6525eL), +tobe(0xfe70ccedL), tobe(0xc4db899bL), tobe(0x8b264601L), tobe(0xb18d0377L), +tobe(0x14ddd935L), tobe(0x2e769c43L), tobe(0x618b53d9L), tobe(0x5b2016afL), +tobe(0xbc266ebfL), tobe(0x868d2bc9L), tobe(0xc970e453L), tobe(0xf3dba125L), +tobe(0x568b7b67L), tobe(0x6c203e11L), tobe(0x23ddf18bL), tobe(0x1976b4fdL), +tobe(0x77a02a4eL), tobe(0x4d0b6f38L), tobe(0x02f6a0a2L), tobe(0x385de5d4L), +tobe(0x9d0d3f96L), tobe(0xa7a67ae0L), tobe(0xe85bb57aL), tobe(0xd2f0f00cL), +tobe(0x388b2a1bL), tobe(0x02206f6dL), tobe(0x4ddda0f7L), tobe(0x7776e581L), +tobe(0xd2263fc3L), tobe(0xe88d7ab5L), tobe(0xa770b52fL), tobe(0x9ddbf059L), +tobe(0xf30d6eeaL), tobe(0xc9a62b9cL), tobe(0x865be406L), tobe(0xbcf0a170L), +tobe(0x19a07b32L), tobe(0x230b3e44L), tobe(0x6cf6f1deL), tobe(0x565db4a8L), +tobe(0xb15bccb8L), tobe(0x8bf089ceL), tobe(0xc40d4654L), tobe(0xfea60322L), +tobe(0x5bf6d960L), tobe(0x615d9c16L), tobe(0x2ea0538cL), tobe(0x140b16faL), +tobe(0x7add8849L), tobe(0x4076cd3fL), tobe(0x0f8b02a5L), tobe(0x352047d3L), +tobe(0x90709d91L), tobe(0xaadbd8e7L), tobe(0xe526177dL), tobe(0xdf8d520bL), +tobe(0x2f0dcc12L), tobe(0x15a68964L), tobe(0x5a5b46feL), tobe(0x60f00388L), +tobe(0xc5a0d9caL), tobe(0xff0b9cbcL), tobe(0xb0f65326L), tobe(0x8a5d1650L), +tobe(0xe48b88e3L), tobe(0xde20cd95L), tobe(0x91dd020fL), tobe(0xab764779L), +tobe(0x0e269d3bL), tobe(0x348dd84dL), tobe(0x7b7017d7L), tobe(0x41db52a1L), +tobe(0xa6dd2ab1L), tobe(0x9c766fc7L), tobe(0xd38ba05dL), tobe(0xe920e52bL), +tobe(0x4c703f69L), tobe(0x76db7a1fL), tobe(0x3926b585L), tobe(0x038df0f3L), +tobe(0x6d5b6e40L), tobe(0x57f02b36L), tobe(0x180de4acL), tobe(0x22a6a1daL), +tobe(0x87f67b98L), tobe(0xbd5d3eeeL), tobe(0xf2a0f174L), tobe(0xc80bb402L), +tobe(0x22706e15L), tobe(0x18db2b63L), tobe(0x5726e4f9L), tobe(0x6d8da18fL), +tobe(0xc8dd7bcdL), tobe(0xf2763ebbL), tobe(0xbd8bf121L), tobe(0x8720b457L), +tobe(0xe9f62ae4L), tobe(0xd35d6f92L), tobe(0x9ca0a008L), tobe(0xa60be57eL), +tobe(0x035b3f3cL), tobe(0x39f07a4aL), tobe(0x760db5d0L), tobe(0x4ca6f0a6L), +tobe(0xaba088b6L), tobe(0x910bcdc0L), tobe(0xdef6025aL), tobe(0xe45d472cL), +tobe(0x410d9d6eL), tobe(0x7ba6d818L), tobe(0x345b1782L), tobe(0x0ef052f4L), +tobe(0x6026cc47L), tobe(0x5a8d8931L), tobe(0x157046abL), tobe(0x2fdb03ddL), +tobe(0x8a8bd99fL), tobe(0xb0209ce9L), tobe(0xffdd5373L), tobe(0xc5761605L)}; + +static const uint32_t t5_be[] = { +tobe(0x00000000L), tobe(0x6bed1038L), tobe(0xd7da2070L), tobe(0xbc373048L), +tobe(0xb1682fa1L), tobe(0xda853f99L), tobe(0x66b20fd1L), tobe(0x0d5f1fe9L), +tobe(0x7c0c3003L), tobe(0x17e1203bL), tobe(0xabd61073L), tobe(0xc03b004bL), +tobe(0xcd641fa2L), tobe(0xa6890f9aL), tobe(0x1abe3fd2L), tobe(0x71532feaL), +tobe(0xf8186006L), tobe(0x93f5703eL), tobe(0x2fc24076L), tobe(0x442f504eL), +tobe(0x49704fa7L), tobe(0x229d5f9fL), tobe(0x9eaa6fd7L), tobe(0xf5477fefL), +tobe(0x84145005L), tobe(0xeff9403dL), tobe(0x53ce7075L), tobe(0x3823604dL), +tobe(0x357c7fa4L), tobe(0x5e916f9cL), tobe(0xe2a65fd4L), tobe(0x894b4fecL), +tobe(0xeeecaf4dL), tobe(0x8501bf75L), tobe(0x39368f3dL), tobe(0x52db9f05L), +tobe(0x5f8480ecL), tobe(0x346990d4L), tobe(0x885ea09cL), tobe(0xe3b3b0a4L), +tobe(0x92e09f4eL), tobe(0xf90d8f76L), tobe(0x453abf3eL), tobe(0x2ed7af06L), +tobe(0x2388b0efL), tobe(0x4865a0d7L), tobe(0xf452909fL), tobe(0x9fbf80a7L), +tobe(0x16f4cf4bL), tobe(0x7d19df73L), tobe(0xc12eef3bL), tobe(0xaac3ff03L), +tobe(0xa79ce0eaL), tobe(0xcc71f0d2L), tobe(0x7046c09aL), tobe(0x1babd0a2L), +tobe(0x6af8ff48L), tobe(0x0115ef70L), tobe(0xbd22df38L), tobe(0xd6cfcf00L), +tobe(0xdb90d0e9L), tobe(0xb07dc0d1L), tobe(0x0c4af099L), tobe(0x67a7e0a1L), +tobe(0xc30531dbL), tobe(0xa8e821e3L), tobe(0x14df11abL), tobe(0x7f320193L), +tobe(0x726d1e7aL), tobe(0x19800e42L), tobe(0xa5b73e0aL), tobe(0xce5a2e32L), +tobe(0xbf0901d8L), tobe(0xd4e411e0L), tobe(0x68d321a8L), tobe(0x033e3190L), +tobe(0x0e612e79L), tobe(0x658c3e41L), tobe(0xd9bb0e09L), tobe(0xb2561e31L), +tobe(0x3b1d51ddL), tobe(0x50f041e5L), tobe(0xecc771adL), tobe(0x872a6195L), +tobe(0x8a757e7cL), tobe(0xe1986e44L), tobe(0x5daf5e0cL), tobe(0x36424e34L), +tobe(0x471161deL), tobe(0x2cfc71e6L), tobe(0x90cb41aeL), tobe(0xfb265196L), +tobe(0xf6794e7fL), tobe(0x9d945e47L), tobe(0x21a36e0fL), tobe(0x4a4e7e37L), +tobe(0x2de99e96L), tobe(0x46048eaeL), tobe(0xfa33bee6L), tobe(0x91deaedeL), +tobe(0x9c81b137L), tobe(0xf76ca10fL), tobe(0x4b5b9147L), tobe(0x20b6817fL), +tobe(0x51e5ae95L), tobe(0x3a08beadL), tobe(0x863f8ee5L), tobe(0xedd29eddL), +tobe(0xe08d8134L), tobe(0x8b60910cL), tobe(0x3757a144L), tobe(0x5cbab17cL), +tobe(0xd5f1fe90L), tobe(0xbe1ceea8L), tobe(0x022bdee0L), tobe(0x69c6ced8L), +tobe(0x6499d131L), tobe(0x0f74c109L), tobe(0xb343f141L), tobe(0xd8aee179L), +tobe(0xa9fdce93L), tobe(0xc210deabL), tobe(0x7e27eee3L), tobe(0x15cafedbL), +tobe(0x1895e132L), tobe(0x7378f10aL), tobe(0xcf4fc142L), tobe(0xa4a2d17aL), +tobe(0x98d60cf7L), tobe(0xf33b1ccfL), tobe(0x4f0c2c87L), tobe(0x24e13cbfL), +tobe(0x29be2356L), tobe(0x4253336eL), tobe(0xfe640326L), tobe(0x9589131eL), +tobe(0xe4da3cf4L), tobe(0x8f372cccL), tobe(0x33001c84L), tobe(0x58ed0cbcL), +tobe(0x55b21355L), tobe(0x3e5f036dL), tobe(0x82683325L), tobe(0xe985231dL), +tobe(0x60ce6cf1L), tobe(0x0b237cc9L), tobe(0xb7144c81L), tobe(0xdcf95cb9L), +tobe(0xd1a64350L), tobe(0xba4b5368L), tobe(0x067c6320L), tobe(0x6d917318L), +tobe(0x1cc25cf2L), tobe(0x772f4ccaL), tobe(0xcb187c82L), tobe(0xa0f56cbaL), +tobe(0xadaa7353L), tobe(0xc647636bL), tobe(0x7a705323L), tobe(0x119d431bL), +tobe(0x763aa3baL), tobe(0x1dd7b382L), tobe(0xa1e083caL), tobe(0xca0d93f2L), +tobe(0xc7528c1bL), tobe(0xacbf9c23L), tobe(0x1088ac6bL), tobe(0x7b65bc53L), +tobe(0x0a3693b9L), tobe(0x61db8381L), tobe(0xddecb3c9L), tobe(0xb601a3f1L), +tobe(0xbb5ebc18L), tobe(0xd0b3ac20L), tobe(0x6c849c68L), tobe(0x07698c50L), +tobe(0x8e22c3bcL), tobe(0xe5cfd384L), tobe(0x59f8e3ccL), tobe(0x3215f3f4L), +tobe(0x3f4aec1dL), tobe(0x54a7fc25L), tobe(0xe890cc6dL), tobe(0x837ddc55L), +tobe(0xf22ef3bfL), tobe(0x99c3e387L), tobe(0x25f4d3cfL), tobe(0x4e19c3f7L), +tobe(0x4346dc1eL), tobe(0x28abcc26L), tobe(0x949cfc6eL), tobe(0xff71ec56L), +tobe(0x5bd33d2cL), tobe(0x303e2d14L), tobe(0x8c091d5cL), tobe(0xe7e40d64L), +tobe(0xeabb128dL), tobe(0x815602b5L), tobe(0x3d6132fdL), tobe(0x568c22c5L), +tobe(0x27df0d2fL), tobe(0x4c321d17L), tobe(0xf0052d5fL), tobe(0x9be83d67L), +tobe(0x96b7228eL), tobe(0xfd5a32b6L), tobe(0x416d02feL), tobe(0x2a8012c6L), +tobe(0xa3cb5d2aL), tobe(0xc8264d12L), tobe(0x74117d5aL), tobe(0x1ffc6d62L), +tobe(0x12a3728bL), tobe(0x794e62b3L), tobe(0xc57952fbL), tobe(0xae9442c3L), +tobe(0xdfc76d29L), tobe(0xb42a7d11L), tobe(0x081d4d59L), tobe(0x63f05d61L), +tobe(0x6eaf4288L), tobe(0x054252b0L), tobe(0xb97562f8L), tobe(0xd29872c0L), +tobe(0xb53f9261L), tobe(0xded28259L), tobe(0x62e5b211L), tobe(0x0908a229L), +tobe(0x0457bdc0L), tobe(0x6fbaadf8L), tobe(0xd38d9db0L), tobe(0xb8608d88L), +tobe(0xc933a262L), tobe(0xa2deb25aL), tobe(0x1ee98212L), tobe(0x7504922aL), +tobe(0x785b8dc3L), tobe(0x13b69dfbL), tobe(0xaf81adb3L), tobe(0xc46cbd8bL), +tobe(0x4d27f267L), tobe(0x26cae25fL), tobe(0x9afdd217L), tobe(0xf110c22fL), +tobe(0xfc4fddc6L), tobe(0x97a2cdfeL), tobe(0x2b95fdb6L), tobe(0x4078ed8eL), +tobe(0x312bc264L), tobe(0x5ac6d25cL), tobe(0xe6f1e214L), tobe(0x8d1cf22cL), +tobe(0x8043edc5L), tobe(0xebaefdfdL), tobe(0x5799cdb5L), tobe(0x3c74dd8dL)}; + +static const uint32_t t6_be[] = { +tobe(0x00000000L), tobe(0x2f7076afL), tobe(0x5ee0ed5eL), tobe(0x71909bf1L), +tobe(0xbdc1dabcL), tobe(0x92b1ac13L), tobe(0xe32137e2L), tobe(0xcc51414dL), +tobe(0x655fda39L), tobe(0x4a2fac96L), tobe(0x3bbf3767L), tobe(0x14cf41c8L), +tobe(0xd89e0085L), tobe(0xf7ee762aL), tobe(0x867eeddbL), tobe(0xa90e9b74L), +tobe(0xcabfb472L), tobe(0xe5cfc2ddL), tobe(0x945f592cL), tobe(0xbb2f2f83L), +tobe(0x777e6eceL), tobe(0x580e1861L), tobe(0x299e8390L), tobe(0x06eef53fL), +tobe(0xafe06e4bL), tobe(0x809018e4L), tobe(0xf1008315L), tobe(0xde70f5baL), +tobe(0x1221b4f7L), tobe(0x3d51c258L), tobe(0x4cc159a9L), tobe(0x63b12f06L), +tobe(0x8ba307a5L), tobe(0xa4d3710aL), tobe(0xd543eafbL), tobe(0xfa339c54L), +tobe(0x3662dd19L), tobe(0x1912abb6L), tobe(0x68823047L), tobe(0x47f246e8L), +tobe(0xeefcdd9cL), tobe(0xc18cab33L), tobe(0xb01c30c2L), tobe(0x9f6c466dL), +tobe(0x533d0720L), tobe(0x7c4d718fL), tobe(0x0dddea7eL), tobe(0x22ad9cd1L), +tobe(0x411cb3d7L), tobe(0x6e6cc578L), tobe(0x1ffc5e89L), tobe(0x308c2826L), +tobe(0xfcdd696bL), tobe(0xd3ad1fc4L), tobe(0xa23d8435L), tobe(0x8d4df29aL), +tobe(0x244369eeL), tobe(0x0b331f41L), tobe(0x7aa384b0L), tobe(0x55d3f21fL), +tobe(0x9982b352L), tobe(0xb6f2c5fdL), tobe(0xc7625e0cL), tobe(0xe81228a3L), +tobe(0x099a600bL), tobe(0x26ea16a4L), tobe(0x577a8d55L), tobe(0x780afbfaL), +tobe(0xb45bbab7L), tobe(0x9b2bcc18L), tobe(0xeabb57e9L), tobe(0xc5cb2146L), +tobe(0x6cc5ba32L), tobe(0x43b5cc9dL), tobe(0x3225576cL), tobe(0x1d5521c3L), +tobe(0xd104608eL), tobe(0xfe741621L), tobe(0x8fe48dd0L), tobe(0xa094fb7fL), +tobe(0xc325d479L), tobe(0xec55a2d6L), tobe(0x9dc53927L), tobe(0xb2b54f88L), +tobe(0x7ee40ec5L), tobe(0x5194786aL), tobe(0x2004e39bL), tobe(0x0f749534L), +tobe(0xa67a0e40L), tobe(0x890a78efL), tobe(0xf89ae31eL), tobe(0xd7ea95b1L), +tobe(0x1bbbd4fcL), tobe(0x34cba253L), tobe(0x455b39a2L), tobe(0x6a2b4f0dL), +tobe(0x823967aeL), tobe(0xad491101L), tobe(0xdcd98af0L), tobe(0xf3a9fc5fL), +tobe(0x3ff8bd12L), tobe(0x1088cbbdL), tobe(0x6118504cL), tobe(0x4e6826e3L), +tobe(0xe766bd97L), tobe(0xc816cb38L), tobe(0xb98650c9L), tobe(0x96f62666L), +tobe(0x5aa7672bL), tobe(0x75d71184L), tobe(0x04478a75L), tobe(0x2b37fcdaL), +tobe(0x4886d3dcL), tobe(0x67f6a573L), tobe(0x16663e82L), tobe(0x3916482dL), +tobe(0xf5470960L), tobe(0xda377fcfL), tobe(0xaba7e43eL), tobe(0x84d79291L), +tobe(0x2dd909e5L), tobe(0x02a97f4aL), tobe(0x7339e4bbL), tobe(0x5c499214L), +tobe(0x9018d359L), tobe(0xbf68a5f6L), tobe(0xcef83e07L), tobe(0xe18848a8L), +tobe(0x1334c016L), tobe(0x3c44b6b9L), tobe(0x4dd42d48L), tobe(0x62a45be7L), +tobe(0xaef51aaaL), tobe(0x81856c05L), tobe(0xf015f7f4L), tobe(0xdf65815bL), +tobe(0x766b1a2fL), tobe(0x591b6c80L), tobe(0x288bf771L), tobe(0x07fb81deL), +tobe(0xcbaac093L), tobe(0xe4dab63cL), tobe(0x954a2dcdL), tobe(0xba3a5b62L), +tobe(0xd98b7464L), tobe(0xf6fb02cbL), tobe(0x876b993aL), tobe(0xa81bef95L), +tobe(0x644aaed8L), tobe(0x4b3ad877L), tobe(0x3aaa4386L), tobe(0x15da3529L), +tobe(0xbcd4ae5dL), tobe(0x93a4d8f2L), tobe(0xe2344303L), tobe(0xcd4435acL), +tobe(0x011574e1L), tobe(0x2e65024eL), tobe(0x5ff599bfL), tobe(0x7085ef10L), +tobe(0x9897c7b3L), tobe(0xb7e7b11cL), tobe(0xc6772aedL), tobe(0xe9075c42L), +tobe(0x25561d0fL), tobe(0x0a266ba0L), tobe(0x7bb6f051L), tobe(0x54c686feL), +tobe(0xfdc81d8aL), tobe(0xd2b86b25L), tobe(0xa328f0d4L), tobe(0x8c58867bL), +tobe(0x4009c736L), tobe(0x6f79b199L), tobe(0x1ee92a68L), tobe(0x31995cc7L), +tobe(0x522873c1L), tobe(0x7d58056eL), tobe(0x0cc89e9fL), tobe(0x23b8e830L), +tobe(0xefe9a97dL), tobe(0xc099dfd2L), tobe(0xb1094423L), tobe(0x9e79328cL), +tobe(0x3777a9f8L), tobe(0x1807df57L), tobe(0x699744a6L), tobe(0x46e73209L), +tobe(0x8ab67344L), tobe(0xa5c605ebL), tobe(0xd4569e1aL), tobe(0xfb26e8b5L), +tobe(0x1aaea01dL), tobe(0x35ded6b2L), tobe(0x444e4d43L), tobe(0x6b3e3becL), +tobe(0xa76f7aa1L), tobe(0x881f0c0eL), tobe(0xf98f97ffL), tobe(0xd6ffe150L), +tobe(0x7ff17a24L), tobe(0x50810c8bL), tobe(0x2111977aL), tobe(0x0e61e1d5L), +tobe(0xc230a098L), tobe(0xed40d637L), tobe(0x9cd04dc6L), tobe(0xb3a03b69L), +tobe(0xd011146fL), tobe(0xff6162c0L), tobe(0x8ef1f931L), tobe(0xa1818f9eL), +tobe(0x6dd0ced3L), tobe(0x42a0b87cL), tobe(0x3330238dL), tobe(0x1c405522L), +tobe(0xb54ece56L), tobe(0x9a3eb8f9L), tobe(0xebae2308L), tobe(0xc4de55a7L), +tobe(0x088f14eaL), tobe(0x27ff6245L), tobe(0x566ff9b4L), tobe(0x791f8f1bL), +tobe(0x910da7b8L), tobe(0xbe7dd117L), tobe(0xcfed4ae6L), tobe(0xe09d3c49L), +tobe(0x2ccc7d04L), tobe(0x03bc0babL), tobe(0x722c905aL), tobe(0x5d5ce6f5L), +tobe(0xf4527d81L), tobe(0xdb220b2eL), tobe(0xaab290dfL), tobe(0x85c2e670L), +tobe(0x4993a73dL), tobe(0x66e3d192L), tobe(0x17734a63L), tobe(0x38033cccL), +tobe(0x5bb213caL), tobe(0x74c26565L), tobe(0x0552fe94L), tobe(0x2a22883bL), +tobe(0xe673c976L), tobe(0xc903bfd9L), tobe(0xb8932428L), tobe(0x97e35287L), +tobe(0x3eedc9f3L), tobe(0x119dbf5cL), tobe(0x600d24adL), tobe(0x4f7d5202L), +tobe(0x832c134fL), tobe(0xac5c65e0L), tobe(0xddccfe11L), tobe(0xf2bc88beL)}; + +static const uint32_t t7_be[] = { +tobe(0x00000000L), tobe(0x2669802cL), tobe(0x4cd30058L), tobe(0x6aba8074L), +tobe(0x99a600b0L), tobe(0xbfcf809cL), tobe(0xd57500e8L), tobe(0xf31c80c4L), +tobe(0x2d906e21L), tobe(0x0bf9ee0dL), tobe(0x61436e79L), tobe(0x472aee55L), +tobe(0xb4366e91L), tobe(0x925feebdL), tobe(0xf8e56ec9L), tobe(0xde8ceee5L), +tobe(0x5b20dc42L), tobe(0x7d495c6eL), tobe(0x17f3dc1aL), tobe(0x319a5c36L), +tobe(0xc286dcf2L), tobe(0xe4ef5cdeL), tobe(0x8e55dcaaL), tobe(0xa83c5c86L), +tobe(0x76b0b263L), tobe(0x50d9324fL), tobe(0x3a63b23bL), tobe(0x1c0a3217L), +tobe(0xef16b2d3L), tobe(0xc97f32ffL), tobe(0xa3c5b28bL), tobe(0x85ac32a7L), +tobe(0xb641b884L), tobe(0x902838a8L), tobe(0xfa92b8dcL), tobe(0xdcfb38f0L), +tobe(0x2fe7b834L), tobe(0x098e3818L), tobe(0x6334b86cL), tobe(0x455d3840L), +tobe(0x9bd1d6a5L), tobe(0xbdb85689L), tobe(0xd702d6fdL), tobe(0xf16b56d1L), +tobe(0x0277d615L), tobe(0x241e5639L), tobe(0x4ea4d64dL), tobe(0x68cd5661L), +tobe(0xed6164c6L), tobe(0xcb08e4eaL), tobe(0xa1b2649eL), tobe(0x87dbe4b2L), +tobe(0x74c76476L), tobe(0x52aee45aL), tobe(0x3814642eL), tobe(0x1e7de402L), +tobe(0xc0f10ae7L), tobe(0xe6988acbL), tobe(0x8c220abfL), tobe(0xaa4b8a93L), +tobe(0x59570a57L), tobe(0x7f3e8a7bL), tobe(0x15840a0fL), tobe(0x33ed8a23L), +tobe(0x725f1e49L), tobe(0x54369e65L), tobe(0x3e8c1e11L), tobe(0x18e59e3dL), +tobe(0xebf91ef9L), tobe(0xcd909ed5L), tobe(0xa72a1ea1L), tobe(0x81439e8dL), +tobe(0x5fcf7068L), tobe(0x79a6f044L), tobe(0x131c7030L), tobe(0x3575f01cL), +tobe(0xc66970d8L), tobe(0xe000f0f4L), tobe(0x8aba7080L), tobe(0xacd3f0acL), +tobe(0x297fc20bL), tobe(0x0f164227L), tobe(0x65acc253L), tobe(0x43c5427fL), +tobe(0xb0d9c2bbL), tobe(0x96b04297L), tobe(0xfc0ac2e3L), tobe(0xda6342cfL), +tobe(0x04efac2aL), tobe(0x22862c06L), tobe(0x483cac72L), tobe(0x6e552c5eL), +tobe(0x9d49ac9aL), tobe(0xbb202cb6L), tobe(0xd19aacc2L), tobe(0xf7f32ceeL), +tobe(0xc41ea6cdL), tobe(0xe27726e1L), tobe(0x88cda695L), tobe(0xaea426b9L), +tobe(0x5db8a67dL), tobe(0x7bd12651L), tobe(0x116ba625L), tobe(0x37022609L), +tobe(0xe98ec8ecL), tobe(0xcfe748c0L), tobe(0xa55dc8b4L), tobe(0x83344898L), +tobe(0x7028c85cL), tobe(0x56414870L), tobe(0x3cfbc804L), tobe(0x1a924828L), +tobe(0x9f3e7a8fL), tobe(0xb957faa3L), tobe(0xd3ed7ad7L), tobe(0xf584fafbL), +tobe(0x06987a3fL), tobe(0x20f1fa13L), tobe(0x4a4b7a67L), tobe(0x6c22fa4bL), +tobe(0xb2ae14aeL), tobe(0x94c79482L), tobe(0xfe7d14f6L), tobe(0xd81494daL), +tobe(0x2b08141eL), tobe(0x0d619432L), tobe(0x67db1446L), tobe(0x41b2946aL), +tobe(0xe4be3c92L), tobe(0xc2d7bcbeL), tobe(0xa86d3ccaL), tobe(0x8e04bce6L), +tobe(0x7d183c22L), tobe(0x5b71bc0eL), tobe(0x31cb3c7aL), tobe(0x17a2bc56L), +tobe(0xc92e52b3L), tobe(0xef47d29fL), tobe(0x85fd52ebL), tobe(0xa394d2c7L), +tobe(0x50885203L), tobe(0x76e1d22fL), tobe(0x1c5b525bL), tobe(0x3a32d277L), +tobe(0xbf9ee0d0L), tobe(0x99f760fcL), tobe(0xf34de088L), tobe(0xd52460a4L), +tobe(0x2638e060L), tobe(0x0051604cL), tobe(0x6aebe038L), tobe(0x4c826014L), +tobe(0x920e8ef1L), tobe(0xb4670eddL), tobe(0xdedd8ea9L), tobe(0xf8b40e85L), +tobe(0x0ba88e41L), tobe(0x2dc10e6dL), tobe(0x477b8e19L), tobe(0x61120e35L), +tobe(0x52ff8416L), tobe(0x7496043aL), tobe(0x1e2c844eL), tobe(0x38450462L), +tobe(0xcb5984a6L), tobe(0xed30048aL), tobe(0x878a84feL), tobe(0xa1e304d2L), +tobe(0x7f6fea37L), tobe(0x59066a1bL), tobe(0x33bcea6fL), tobe(0x15d56a43L), +tobe(0xe6c9ea87L), tobe(0xc0a06aabL), tobe(0xaa1aeadfL), tobe(0x8c736af3L), +tobe(0x09df5854L), tobe(0x2fb6d878L), tobe(0x450c580cL), tobe(0x6365d820L), +tobe(0x907958e4L), tobe(0xb610d8c8L), tobe(0xdcaa58bcL), tobe(0xfac3d890L), +tobe(0x244f3675L), tobe(0x0226b659L), tobe(0x689c362dL), tobe(0x4ef5b601L), +tobe(0xbde936c5L), tobe(0x9b80b6e9L), tobe(0xf13a369dL), tobe(0xd753b6b1L), +tobe(0x96e122dbL), tobe(0xb088a2f7L), tobe(0xda322283L), tobe(0xfc5ba2afL), +tobe(0x0f47226bL), tobe(0x292ea247L), tobe(0x43942233L), tobe(0x65fda21fL), +tobe(0xbb714cfaL), tobe(0x9d18ccd6L), tobe(0xf7a24ca2L), tobe(0xd1cbcc8eL), +tobe(0x22d74c4aL), tobe(0x04becc66L), tobe(0x6e044c12L), tobe(0x486dcc3eL), +tobe(0xcdc1fe99L), tobe(0xeba87eb5L), tobe(0x8112fec1L), tobe(0xa77b7eedL), +tobe(0x5467fe29L), tobe(0x720e7e05L), tobe(0x18b4fe71L), tobe(0x3edd7e5dL), +tobe(0xe05190b8L), tobe(0xc6381094L), tobe(0xac8290e0L), tobe(0x8aeb10ccL), +tobe(0x79f79008L), tobe(0x5f9e1024L), tobe(0x35249050L), tobe(0x134d107cL), +tobe(0x20a09a5fL), tobe(0x06c91a73L), tobe(0x6c739a07L), tobe(0x4a1a1a2bL), +tobe(0xb9069aefL), tobe(0x9f6f1ac3L), tobe(0xf5d59ab7L), tobe(0xd3bc1a9bL), +tobe(0x0d30f47eL), tobe(0x2b597452L), tobe(0x41e3f426L), tobe(0x678a740aL), +tobe(0x9496f4ceL), tobe(0xb2ff74e2L), tobe(0xd845f496L), tobe(0xfe2c74baL), +tobe(0x7b80461dL), tobe(0x5de9c631L), tobe(0x37534645L), tobe(0x113ac669L), +tobe(0xe22646adL), tobe(0xc44fc681L), tobe(0xaef546f5L), tobe(0x889cc6d9L), +tobe(0x5610283cL), tobe(0x7079a810L), tobe(0x1ac32864L), tobe(0x3caaa848L), +tobe(0xcfb6288cL), tobe(0xe9dfa8a0L), tobe(0x836528d4L), tobe(0xa50ca8f8L)}; + diff --git a/portlibs/sources/libext2fs/source/csum.c b/portlibs/sources/libcustomext2fs/source/csum.c similarity index 96% rename from portlibs/sources/libext2fs/source/csum.c rename to portlibs/sources/libcustomext2fs/source/csum.c index 58e29710..596923e5 100644 --- a/portlibs/sources/libext2fs/source/csum.c +++ b/portlibs/sources/libcustomext2fs/source/csum.c @@ -10,6 +10,7 @@ * %End-Header% */ +#include "config.h" #if HAVE_SYS_TYPES_H #include #endif @@ -46,7 +47,7 @@ STATIC __u16 ext2fs_group_desc_csum(ext2_filsys fs, dgrp_t group) desc = ext2fs_group_desc(fs, fs->group_desc, group); if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) { - int offset = offsetof(struct ext2_group_desc, bg_checksum); + size_t offset = offsetof(struct ext2_group_desc, bg_checksum); #ifdef WORDS_BIGENDIAN struct ext4_group_desc swabdesc; @@ -127,10 +128,10 @@ errcode_t ext2fs_set_gdt_csum(ext2_filsys fs) return 0; for (i = 0; i < fs->group_desc_count; i++) { - unsigned int old_csum = ext2fs_bg_checksum(fs, i); - int old_unused = ext2fs_bg_itable_unused(fs, i); - unsigned int old_flags = ext2fs_bg_flags(fs, i); - int old_free_inodes_count = ext2fs_bg_free_inodes_count(fs, i); + __u32 old_csum = ext2fs_bg_checksum(fs, i); + __u32 old_unused = ext2fs_bg_itable_unused(fs, i); + __u32 old_flags = ext2fs_bg_flags(fs, i); + __u32 old_free_inodes_count = ext2fs_bg_free_inodes_count(fs, i); if (old_free_inodes_count == sb->s_inodes_per_group) { ext2fs_bg_flags_set(fs, i, EXT2_BG_INODE_UNINIT); diff --git a/portlibs/sources/libext2fs/source/dblist.c b/portlibs/sources/libcustomext2fs/source/dblist.c similarity index 98% rename from portlibs/sources/libext2fs/source/dblist.c rename to portlibs/sources/libcustomext2fs/source/dblist.c index 8ee61b4c..80017921 100644 --- a/portlibs/sources/libext2fs/source/dblist.c +++ b/portlibs/sources/libcustomext2fs/source/dblist.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #if HAVE_UNISTD_H #include @@ -60,7 +61,7 @@ static errcode_t make_dblist(ext2_filsys fs, ext2_ino_t size, struct ext2_db_entry2 *list, ext2_dblist *ret_dblist) { - ext2_dblist dblist; + ext2_dblist dblist = 0; errcode_t retval; ext2_ino_t num_dirs; size_t len; @@ -73,7 +74,7 @@ static errcode_t make_dblist(ext2_filsys fs, ext2_ino_t size, retval = ext2fs_get_mem(sizeof(struct ext2_struct_dblist), &dblist); if (retval) - return retval; + goto cleanup; memset(dblist, 0, sizeof(struct ext2_struct_dblist)); dblist->magic = EXT2_ET_MAGIC_DBLIST; @@ -172,7 +173,7 @@ errcode_t ext2fs_add_dir_block2(ext2_dblist dblist, ext2_ino_t ino, sizeof(struct ext2_db_entry2), &dblist->list); if (retval) { - dblist->size -= 100; + dblist->size = old_size / sizeof(struct ext2_db_entry2); return retval; } } diff --git a/portlibs/sources/libext2fs/source/dblist_dir.c b/portlibs/sources/libcustomext2fs/source/dblist_dir.c similarity index 98% rename from portlibs/sources/libext2fs/source/dblist_dir.c rename to portlibs/sources/libcustomext2fs/source/dblist_dir.c index 07ed8afa..d4d51114 100644 --- a/portlibs/sources/libext2fs/source/dblist_dir.c +++ b/portlibs/sources/libcustomext2fs/source/dblist_dir.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #if HAVE_UNISTD_H #include diff --git a/portlibs/sources/libext2fs/source/dir_iterate.c b/portlibs/sources/libcustomext2fs/source/dir_iterate.c similarity index 99% rename from portlibs/sources/libext2fs/source/dir_iterate.c rename to portlibs/sources/libcustomext2fs/source/dir_iterate.c index 88f6b476..5125d199 100644 --- a/portlibs/sources/libext2fs/source/dir_iterate.c +++ b/portlibs/sources/libcustomext2fs/source/dir_iterate.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H diff --git a/portlibs/sources/libext2fs/source/dirblock.c b/portlibs/sources/libcustomext2fs/source/dirblock.c similarity index 99% rename from portlibs/sources/libext2fs/source/dirblock.c rename to portlibs/sources/libcustomext2fs/source/dirblock.c index 73e1f0ab..cb3a104c 100644 --- a/portlibs/sources/libext2fs/source/dirblock.c +++ b/portlibs/sources/libcustomext2fs/source/dirblock.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #if HAVE_UNISTD_H #include diff --git a/portlibs/sources/libext2fs/source/dirhash.c b/portlibs/sources/libcustomext2fs/source/dirhash.c similarity index 98% rename from portlibs/sources/libext2fs/source/dirhash.c rename to portlibs/sources/libcustomext2fs/source/dirhash.c index a0697069..c4ac94e0 100644 --- a/portlibs/sources/libext2fs/source/dirhash.c +++ b/portlibs/sources/libcustomext2fs/source/dirhash.c @@ -11,6 +11,7 @@ * %End-Header% */ +#include "config.h" #include #include @@ -217,11 +218,13 @@ errcode_t ext2fs_dirhash(int version, const char *name, int len, switch (version) { case EXT2_HASH_LEGACY_UNSIGNED: unsigned_flag++; + /* fallthrough */ case EXT2_HASH_LEGACY: hash = dx_hack_hash(name, len, unsigned_flag); break; case EXT2_HASH_HALF_MD4_UNSIGNED: unsigned_flag++; + /* fallthrough */ case EXT2_HASH_HALF_MD4: p = name; while (len > 0) { @@ -235,6 +238,7 @@ errcode_t ext2fs_dirhash(int version, const char *name, int len, break; case EXT2_HASH_TEA_UNSIGNED: unsigned_flag++; + /* fallthrough */ case EXT2_HASH_TEA: p = name; while (len > 0) { diff --git a/portlibs/sources/libext2fs/source/disc_cache.c b/portlibs/sources/libcustomext2fs/source/disc_cache.c similarity index 99% rename from portlibs/sources/libext2fs/source/disc_cache.c rename to portlibs/sources/libcustomext2fs/source/disc_cache.c index 2a9ad05c..00fa53b4 100644 --- a/portlibs/sources/libext2fs/source/disc_cache.c +++ b/portlibs/sources/libcustomext2fs/source/disc_cache.c @@ -52,12 +52,12 @@ CACHE* cache_constructor (unsigned int numberOfPages, unsigned int sectorsPerPag if(numberOfPages==0 || sectorsPerPage==0) return NULL; - if (numberOfPages < 4) { - numberOfPages = 4; + if (numberOfPages < 32) { + numberOfPages = 32; } - if (sectorsPerPage < 32) { - sectorsPerPage = 32; + if (sectorsPerPage < 16) { + sectorsPerPage = 16; } cache = (CACHE*) mem_alloc (sizeof(CACHE)); diff --git a/portlibs/sources/libext2fs/source/disc_cache.h b/portlibs/sources/libcustomext2fs/source/disc_cache.h similarity index 100% rename from portlibs/sources/libext2fs/source/disc_cache.h rename to portlibs/sources/libcustomext2fs/source/disc_cache.h diff --git a/portlibs/sources/libext2fs/source/dupfs.c b/portlibs/sources/libcustomext2fs/source/dupfs.c similarity index 99% rename from portlibs/sources/libext2fs/source/dupfs.c rename to portlibs/sources/libcustomext2fs/source/dupfs.c index a9e2a976..64d31248 100644 --- a/portlibs/sources/libext2fs/source/dupfs.c +++ b/portlibs/sources/libcustomext2fs/source/dupfs.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #if HAVE_UNISTD_H #include diff --git a/portlibs/sources/libext2fs/source/e2image.h b/portlibs/sources/libcustomext2fs/source/e2image.h similarity index 88% rename from portlibs/sources/libext2fs/source/e2image.h rename to portlibs/sources/libcustomext2fs/source/e2image.h index 4de2c8d9..c918529e 100644 --- a/portlibs/sources/libext2fs/source/e2image.h +++ b/portlibs/sources/libcustomext2fs/source/e2image.h @@ -12,6 +12,14 @@ * %End-Header% */ +/* Image types */ +#define E2IMAGE_RAW 1 +#define E2IMAGE_QCOW2 2 + +/* Image flags */ +#define E2IMAGE_INSTALL_FLAG 1 +#define E2IMAGE_SCRAMBLE_FLAG 2 +#define E2IMAGE_IS_QCOW2_FLAG 3 struct ext2_image_hdr { __u32 magic_number; /* This must be EXT2_ET_MAGIC_E2IMAGE */ @@ -36,16 +44,3 @@ struct ext2_image_hdr { __u32 offset_blockmap; /* Byte offset of the inode bitmaps */ __u32 offset_reserved[8]; }; - - - - - - - - - - - - - diff --git a/portlibs/sources/libext2fs/source/expanddir.c b/portlibs/sources/libcustomext2fs/source/expanddir.c similarity index 85% rename from portlibs/sources/libext2fs/source/expanddir.c rename to portlibs/sources/libcustomext2fs/source/expanddir.c index 7673a3bd..41c40882 100644 --- a/portlibs/sources/libext2fs/source/expanddir.c +++ b/portlibs/sources/libcustomext2fs/source/expanddir.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -21,6 +22,7 @@ struct expand_dir_struct { int done; int newblocks; + blk64_t goal; errcode_t err; }; @@ -33,18 +35,25 @@ static int expand_dir_proc(ext2_filsys fs, { struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data; blk64_t new_blk; - static blk64_t last_blk = 0; char *block; errcode_t retval; if (*blocknr) { - last_blk = *blocknr; + if (blockcnt >= 0) + es->goal = *blocknr; return 0; } - retval = ext2fs_new_block2(fs, last_blk, 0, &new_blk); - if (retval) { - es->err = retval; - return BLOCK_ABORT; + if (blockcnt && + (EXT2FS_B2C(fs, es->goal) == EXT2FS_B2C(fs, es->goal+1))) + new_blk = es->goal+1; + else { + es->goal &= ~EXT2FS_CLUSTER_MASK(fs); + retval = ext2fs_new_block2(fs, es->goal, 0, &new_blk); + if (retval) { + es->err = retval; + return BLOCK_ABORT; + } + es->newblocks++; } if (blockcnt > 0) { retval = ext2fs_new_dir_block(fs, 0, 0, &block); @@ -63,6 +72,8 @@ static int expand_dir_proc(ext2_filsys fs, memset(block, 0, fs->blocksize); retval = io_channel_write_blk64(fs->io, new_blk, 1, block); } + if (blockcnt >= 0) + es->goal = new_blk; if (retval) { es->err = retval; return BLOCK_ABORT; @@ -70,7 +81,6 @@ static int expand_dir_proc(ext2_filsys fs, ext2fs_free_mem(&block); *blocknr = new_blk; ext2fs_block_alloc_stats2(fs, new_blk, +1); - es->newblocks++; if (es->done) return (BLOCK_CHANGED | BLOCK_ABORT); @@ -98,6 +108,7 @@ errcode_t ext2fs_expand_dir(ext2_filsys fs, ext2_ino_t dir) es.done = 0; es.err = 0; + es.goal = 0; es.newblocks = 0; retval = ext2fs_block_iterate3(fs, dir, BLOCK_FLAG_APPEND, diff --git a/portlibs/sources/libext2fs/source/ext2.c b/portlibs/sources/libcustomext2fs/source/ext2.c similarity index 94% rename from portlibs/sources/libext2fs/source/ext2.c rename to portlibs/sources/libcustomext2fs/source/ext2.c index 7cff7f3c..02b94702 100644 --- a/portlibs/sources/libext2fs/source/ext2.c +++ b/portlibs/sources/libcustomext2fs/source/ext2.c @@ -89,7 +89,7 @@ bool ext2Mount(const char *name, const DISC_INTERFACE *interface, sec_t startSec io_chan->private_data = fd; io_chan->flags = flags; - retval = ext2fs_open2(io_chan->name, 0, io_chan->flags, 0, 0, &io_chan, &fs); + retval = ext2fs_open2(io_chan->name, 0, io_chan->flags, 0, 0, io_chan, &fs); if(retval) { ext2_log_trace("error mounting %i\n", (int) retval); @@ -223,7 +223,7 @@ int ext2FindPartitions (const DISC_INTERFACE *interface, sec_t **out_partitions) int i; union { - u8 buffer[512]; + u8 buffer[MAX_SECTOR_SIZE]; MASTER_BOOT_RECORD mbr; EXTENDED_BOOT_RECORD ebr; } sector; @@ -249,27 +249,30 @@ int ext2FindPartitions (const DISC_INTERFACE *interface, sec_t **out_partitions) return 0; } - struct ext2_super_block * super = (struct ext2_super_block *) malloc(SUPERBLOCK_SIZE); //1024 bytes - if(!super) + // Allocate 4 x max sector size in case of 4096 sector size + u8 *buffer = (u8 *) mem_alloc(4 * MAX_SECTOR_SIZE); + if(!buffer) { ext2_log_trace("no memory for superblock"); errno = ENOMEM; return -1; } + // Super is always at offset SUPERBLOCK_OFFSET + struct ext2_super_block * super = (struct ext2_super_block *) (buffer + SUPERBLOCK_OFFSET); //1024 bytes partitions = (sec_t *) malloc(sizeof(sec_t)); if(!partitions) { ext2_log_trace("no memory for partitions"); errno = ENOMEM; - mem_free(super); + mem_free(buffer); return -1; } // Read the first sector on the device if (!interface->readSectors(0, 1, §or.buffer)) { errno = EIO; mem_free(partitions); - mem_free(super); + mem_free(buffer); return -1; } @@ -295,7 +298,7 @@ int ext2FindPartitions (const DISC_INTERFACE *interface, sec_t **out_partitions) case PARTITION_TYPE_LINUX: // Read and validate the EXT partition - if (interface->readSectors(part_lba+SUPERBLOCK_OFFSET/BYTES_PER_SECTOR, SUPERBLOCK_SIZE/BYTES_PER_SECTOR, super)) + if (interface->readSectors(part_lba, 4, buffer)) { if (ext2fs_le16_to_cpu(super->s_magic) == EXT2_SUPER_MAGIC) { @@ -334,7 +337,7 @@ int ext2FindPartitions (const DISC_INTERFACE *interface, sec_t **out_partitions) next_erb_lba = ext2fs_le32_to_cpu(sector.ebr.next_ebr.lba_start); // Check if this partition has a valid EXT boot record - if (interface->readSectors(part_lba+SUPERBLOCK_OFFSET/BYTES_PER_SECTOR, SUPERBLOCK_SIZE/BYTES_PER_SECTOR, super)) + if (interface->readSectors(part_lba, 4, buffer)) { if (ext2fs_le16_to_cpu(super->s_magic) == EXT2_SUPER_MAGIC) { @@ -361,7 +364,7 @@ int ext2FindPartitions (const DISC_INTERFACE *interface, sec_t **out_partitions) { // Check if this partition has a valid EXT boot record anyway, // it might be misrepresented due to a lazy partition editor - if (interface->readSectors(part_lba+SUPERBLOCK_OFFSET/BYTES_PER_SECTOR, SUPERBLOCK_SIZE/BYTES_PER_SECTOR, super)) + if (interface->readSectors(part_lba, 4, buffer)) { if (ext2fs_le16_to_cpu(super->s_magic) == EXT2_SUPER_MAGIC) { @@ -386,7 +389,7 @@ int ext2FindPartitions (const DISC_INTERFACE *interface, sec_t **out_partitions) // As a last-ditched effort, search the first 64 sectors of the device for stray EXT partitions for (i = 1; i < 64; i++) { - if (interface->readSectors(i+SUPERBLOCK_OFFSET/BYTES_PER_SECTOR, SUPERBLOCK_SIZE/BYTES_PER_SECTOR, super)) + if (interface->readSectors(i, 4, buffer)) { if (ext2fs_le16_to_cpu(super->s_magic) == EXT2_SUPER_MAGIC) { @@ -412,8 +415,8 @@ cleanup: if(partitions && partition_count == 0) mem_free(partitions); - if(super) - mem_free(super); + if(buffer) + mem_free(buffer); return ret; } diff --git a/portlibs/sources/libcustomext2fs/source/ext2_err.c b/portlibs/sources/libcustomext2fs/source/ext2_err.c new file mode 100644 index 00000000..a58b6866 --- /dev/null +++ b/portlibs/sources/libcustomext2fs/source/ext2_err.c @@ -0,0 +1,199 @@ +/* + * ext2_err.c: + * This file is automatically generated; please do not edit it. + */ + +#include + +#define N_(a) a + +static const char * const text[] = { + N_( "EXT2FS Library version 1.42"), + N_( "Wrong magic number for ext2_filsys structure"), + N_( "Wrong magic number for badblocks_list structure"), + N_( "Wrong magic number for badblocks_iterate structure"), + N_( "Wrong magic number for inode_scan structure"), + N_( "Wrong magic number for io_channel structure"), + N_( "Wrong magic number for unix io_channel structure"), + N_( "Wrong magic number for io_manager structure"), + N_( "Wrong magic number for block_bitmap structure"), + N_( "Wrong magic number for inode_bitmap structure"), + N_( "Wrong magic number for generic_bitmap structure"), + N_( "Wrong magic number for test io_channel structure"), + N_( "Wrong magic number for directory block list structure"), + N_( "Wrong magic number for icount structure"), + N_( "Wrong magic number for Powerquest io_channel structure"), + N_( "Wrong magic number for ext2 file structure"), + N_( "Wrong magic number for Ext2 Image Header"), + N_( "Wrong magic number for inode io_channel structure"), + N_( "Wrong magic number for ext4 extent handle"), + N_( "Bad magic number in super-block"), + N_( "Filesystem revision too high"), + N_( "Attempt to write to filesystem opened read-only"), + N_( "Can't read group descriptors"), + N_( "Can't write group descriptors"), + N_( "Corrupt group descriptor: bad block for block bitmap"), + N_( "Corrupt group descriptor: bad block for inode bitmap"), + N_( "Corrupt group descriptor: bad block for inode table"), + N_( "Can't write an inode bitmap"), + N_( "Can't read an inode bitmap"), + N_( "Can't write an block bitmap"), + N_( "Can't read an block bitmap"), + N_( "Can't write an inode table"), + N_( "Can't read an inode table"), + N_( "Can't read next inode"), + N_( "Filesystem has unexpected block size"), + N_( "EXT2 directory corrupted"), + N_( "Attempt to read block from filesystem resulted in short read"), + N_( "Attempt to write block to filesystem resulted in short write"), + N_( "No free space in the directory"), + N_( "Inode bitmap not loaded"), + N_( "Block bitmap not loaded"), + N_( "Illegal inode number"), + N_( "Illegal block number"), + N_( "Internal error in ext2fs_expand_dir"), + N_( "Not enough space to build proposed filesystem"), + N_( "Illegal block number passed to ext2fs_mark_block_bitmap"), + N_( "Illegal block number passed to ext2fs_unmark_block_bitmap"), + N_( "Illegal block number passed to ext2fs_test_block_bitmap"), + N_( "Illegal inode number passed to ext2fs_mark_inode_bitmap"), + N_( "Illegal inode number passed to ext2fs_unmark_inode_bitmap"), + N_( "Illegal inode number passed to ext2fs_test_inode_bitmap"), + N_( "Attempt to fudge end of block bitmap past the real end"), + N_( "Attempt to fudge end of inode bitmap past the real end"), + N_( "Illegal indirect block found" ), + N_( "Illegal doubly indirect block found" ), + N_( "Illegal triply indirect block found" ), + N_( "Block bitmaps are not the same"), + N_( "Inode bitmaps are not the same"), + N_( "Illegal or malformed device name"), + N_( "A block group is missing an inode table"), + N_( "The ext2 superblock is corrupt"), + N_( "Illegal generic bit number passed to ext2fs_mark_generic_bitmap"), + N_( "Illegal generic bit number passed to ext2fs_unmark_generic_bitmap"), + N_( "Illegal generic bit number passed to ext2fs_test_generic_bitmap"), + N_( "Too many symbolic links encountered."), + N_( "The callback function will not handle this case"), + N_( "The inode is from a bad block in the inode table"), + N_( "Filesystem has unsupported feature(s)"), + N_( "Filesystem has unsupported read-only feature(s)"), + N_( "IO Channel failed to seek on read or write"), + N_( "Memory allocation failed"), + N_( "Invalid argument passed to ext2 library"), + N_( "Could not allocate block in ext2 filesystem"), + N_( "Could not allocate inode in ext2 filesystem"), + N_( "Ext2 inode is not a directory"), + N_( "Too many references in table"), + N_( "File not found by ext2_lookup"), + N_( "File open read-only"), + N_( "Ext2 directory block not found"), + N_( "Ext2 directory already exists"), + N_( "Unimplemented ext2 library function"), + N_( "User cancel requested"), + N_( "Ext2 file too big"), + N_( "Supplied journal device not a block device"), + N_( "Journal superblock not found"), + N_( "Journal must be at least 1024 blocks"), + N_( "Unsupported journal version"), + N_( "Error loading external journal"), + N_( "Journal not found"), + N_( "Directory hash unsupported"), + N_( "Illegal extended attribute block number"), + N_( "Cannot create filesystem with requested number of inodes"), + N_( "E2image snapshot not in use"), + N_( "Too many reserved group descriptor blocks"), + N_( "Resize inode is corrupt"), + N_( "Tried to set block bmap with missing indirect block"), + N_( "TDB: Success"), + N_( "TDB: Corrupt database"), + N_( "TDB: IO Error"), + N_( "TDB: Locking error"), + N_( "TDB: Out of memory"), + N_( "TDB: Record exists"), + N_( "TDB: Lock exists on other keys"), + N_( "TDB: Invalid parameter"), + N_( "TDB: Record does not exist"), + N_( "TDB: Write not permitted"), + N_( "Ext2fs directory block list is empty"), + N_( "Attempt to modify a block mapping via a read-only block iterator"), + N_( "Wrong magic number for ext4 extent saved path"), + N_( "Wrong magic number for 64-bit generic bitmap"), + N_( "Wrong magic number for 64-bit block bitmap"), + N_( "Wrong magic number for 64-bit inode bitmap"), + N_( "Wrong magic number --- RESERVED_13"), + N_( "Wrong magic number --- RESERVED_14"), + N_( "Wrong magic number --- RESERVED_15"), + N_( "Wrong magic number --- RESERVED_16"), + N_( "Wrong magic number --- RESERVED_17"), + N_( "Wrong magic number --- RESERVED_18"), + N_( "Wrong magic number --- RESERVED_19"), + N_( "Corrupt extent header"), + N_( "Corrupt extent index"), + N_( "Corrupt extent"), + N_( "No free space in extent map"), + N_( "Inode does not use extents"), + N_( "No 'next' extent"), + N_( "No 'previous' extent"), + N_( "No 'up' extent"), + N_( "No 'down' extent"), + N_( "No current node"), + N_( "Ext2fs operation not supported"), + N_( "No room to insert extent in node"), + N_( "Splitting would result in empty node"), + N_( "Extent not found"), + N_( "Operation not supported for inodes containing extents"), + N_( "Extent length is invalid"), + N_( "I/O Channel does not support 64-bit block numbers"), + N_( "Can't check if filesystem is mounted due to missing mtab file"), + N_( "Filesystem too large to use legacy bitmaps"), + N_( "MMP: invalid magic number"), + N_( "MMP: device currently active"), + N_( "MMP: fsck being run"), + N_( "MMP: block number beyond filesystem range"), + N_( "MMP: undergoing an unknown operation"), + N_( "MMP: filesystem still in use"), + N_( "MMP: open with O_DIRECT failed"), + 0 +}; + +struct error_table { + char const * const * msgs; + long base; + int n_msgs; +}; +struct et_list { + struct et_list *next; + const struct error_table * table; +}; +extern struct et_list *_et_list; + +const struct error_table et_ext2_error_table = { text, 2133571328L, 145 }; + +static struct et_list link = { 0, 0 }; + +void initialize_ext2_error_table_r(struct et_list **list); +void initialize_ext2_error_table(void); + +void initialize_ext2_error_table(void) { + initialize_ext2_error_table_r(&_et_list); +} + +/* For Heimdal compatibility */ +void initialize_ext2_error_table_r(struct et_list **list) +{ + struct et_list *et, **end; + + for (end = list, et = *list; et; end = &et->next, et = et->next) + if (et->table->msgs == text) + return; + et = malloc(sizeof(struct et_list)); + if (et == 0) { + if (!link.table) + et = &link; + else + return; + } + et->table = &et_ext2_error_table; + et->next = 0; + *end = et; +} diff --git a/portlibs/sources/libcustomext2fs/source/ext2_err.h b/portlibs/sources/libcustomext2fs/source/ext2_err.h new file mode 100644 index 00000000..5d794d2b --- /dev/null +++ b/portlibs/sources/libcustomext2fs/source/ext2_err.h @@ -0,0 +1,169 @@ +/* + * ext2_err.h: + * This file is automatically generated; please do not edit it. + */ +#ifndef EXT2_ERR_H_ +#define EXT2_ERR_H_ + +#include "com_err.h" + +#define EXT2_ET_OK (0) +#define EXT2_ET_BASE (2133571328L) +#define EXT2_ET_MAGIC_EXT2FS_FILSYS (2133571329L) +#define EXT2_ET_MAGIC_BADBLOCKS_LIST (2133571330L) +#define EXT2_ET_MAGIC_BADBLOCKS_ITERATE (2133571331L) +#define EXT2_ET_MAGIC_INODE_SCAN (2133571332L) +#define EXT2_ET_MAGIC_IO_CHANNEL (2133571333L) +#define EXT2_ET_MAGIC_UNIX_IO_CHANNEL (2133571334L) +#define EXT2_ET_MAGIC_IO_MANAGER (2133571335L) +#define EXT2_ET_MAGIC_BLOCK_BITMAP (2133571336L) +#define EXT2_ET_MAGIC_INODE_BITMAP (2133571337L) +#define EXT2_ET_MAGIC_GENERIC_BITMAP (2133571338L) +#define EXT2_ET_MAGIC_TEST_IO_CHANNEL (2133571339L) +#define EXT2_ET_MAGIC_DBLIST (2133571340L) +#define EXT2_ET_MAGIC_ICOUNT (2133571341L) +#define EXT2_ET_MAGIC_PQ_IO_CHANNEL (2133571342L) +#define EXT2_ET_MAGIC_EXT2_FILE (2133571343L) +#define EXT2_ET_MAGIC_E2IMAGE (2133571344L) +#define EXT2_ET_MAGIC_INODE_IO_CHANNEL (2133571345L) +#define EXT2_ET_MAGIC_EXTENT_HANDLE (2133571346L) +#define EXT2_ET_BAD_MAGIC (2133571347L) +#define EXT2_ET_REV_TOO_HIGH (2133571348L) +#define EXT2_ET_RO_FILSYS (2133571349L) +#define EXT2_ET_GDESC_READ (2133571350L) +#define EXT2_ET_GDESC_WRITE (2133571351L) +#define EXT2_ET_GDESC_BAD_BLOCK_MAP (2133571352L) +#define EXT2_ET_GDESC_BAD_INODE_MAP (2133571353L) +#define EXT2_ET_GDESC_BAD_INODE_TABLE (2133571354L) +#define EXT2_ET_INODE_BITMAP_WRITE (2133571355L) +#define EXT2_ET_INODE_BITMAP_READ (2133571356L) +#define EXT2_ET_BLOCK_BITMAP_WRITE (2133571357L) +#define EXT2_ET_BLOCK_BITMAP_READ (2133571358L) +#define EXT2_ET_INODE_TABLE_WRITE (2133571359L) +#define EXT2_ET_INODE_TABLE_READ (2133571360L) +#define EXT2_ET_NEXT_INODE_READ (2133571361L) +#define EXT2_ET_UNEXPECTED_BLOCK_SIZE (2133571362L) +#define EXT2_ET_DIR_CORRUPTED (2133571363L) +#define EXT2_ET_SHORT_READ (2133571364L) +#define EXT2_ET_SHORT_WRITE (2133571365L) +#define EXT2_ET_DIR_NO_SPACE (2133571366L) +#define EXT2_ET_NO_INODE_BITMAP (2133571367L) +#define EXT2_ET_NO_BLOCK_BITMAP (2133571368L) +#define EXT2_ET_BAD_INODE_NUM (2133571369L) +#define EXT2_ET_BAD_BLOCK_NUM (2133571370L) +#define EXT2_ET_EXPAND_DIR_ERR (2133571371L) +#define EXT2_ET_TOOSMALL (2133571372L) +#define EXT2_ET_BAD_BLOCK_MARK (2133571373L) +#define EXT2_ET_BAD_BLOCK_UNMARK (2133571374L) +#define EXT2_ET_BAD_BLOCK_TEST (2133571375L) +#define EXT2_ET_BAD_INODE_MARK (2133571376L) +#define EXT2_ET_BAD_INODE_UNMARK (2133571377L) +#define EXT2_ET_BAD_INODE_TEST (2133571378L) +#define EXT2_ET_FUDGE_BLOCK_BITMAP_END (2133571379L) +#define EXT2_ET_FUDGE_INODE_BITMAP_END (2133571380L) +#define EXT2_ET_BAD_IND_BLOCK (2133571381L) +#define EXT2_ET_BAD_DIND_BLOCK (2133571382L) +#define EXT2_ET_BAD_TIND_BLOCK (2133571383L) +#define EXT2_ET_NEQ_BLOCK_BITMAP (2133571384L) +#define EXT2_ET_NEQ_INODE_BITMAP (2133571385L) +#define EXT2_ET_BAD_DEVICE_NAME (2133571386L) +#define EXT2_ET_MISSING_INODE_TABLE (2133571387L) +#define EXT2_ET_CORRUPT_SUPERBLOCK (2133571388L) +#define EXT2_ET_BAD_GENERIC_MARK (2133571389L) +#define EXT2_ET_BAD_GENERIC_UNMARK (2133571390L) +#define EXT2_ET_BAD_GENERIC_TEST (2133571391L) +#define EXT2_ET_SYMLINK_LOOP (2133571392L) +#define EXT2_ET_CALLBACK_NOTHANDLED (2133571393L) +#define EXT2_ET_BAD_BLOCK_IN_INODE_TABLE (2133571394L) +#define EXT2_ET_UNSUPP_FEATURE (2133571395L) +#define EXT2_ET_RO_UNSUPP_FEATURE (2133571396L) +#define EXT2_ET_LLSEEK_FAILED (2133571397L) +#define EXT2_ET_NO_MEMORY (2133571398L) +#define EXT2_ET_INVALID_ARGUMENT (2133571399L) +#define EXT2_ET_BLOCK_ALLOC_FAIL (2133571400L) +#define EXT2_ET_INODE_ALLOC_FAIL (2133571401L) +#define EXT2_ET_NO_DIRECTORY (2133571402L) +#define EXT2_ET_TOO_MANY_REFS (2133571403L) +#define EXT2_ET_FILE_NOT_FOUND (2133571404L) +#define EXT2_ET_FILE_RO (2133571405L) +#define EXT2_ET_DB_NOT_FOUND (2133571406L) +#define EXT2_ET_DIR_EXISTS (2133571407L) +#define EXT2_ET_UNIMPLEMENTED (2133571408L) +#define EXT2_ET_CANCEL_REQUESTED (2133571409L) +#define EXT2_ET_FILE_TOO_BIG (2133571410L) +#define EXT2_ET_JOURNAL_NOT_BLOCK (2133571411L) +#define EXT2_ET_NO_JOURNAL_SB (2133571412L) +#define EXT2_ET_JOURNAL_TOO_SMALL (2133571413L) +#define EXT2_ET_JOURNAL_UNSUPP_VERSION (2133571414L) +#define EXT2_ET_LOAD_EXT_JOURNAL (2133571415L) +#define EXT2_ET_NO_JOURNAL (2133571416L) +#define EXT2_ET_DIRHASH_UNSUPP (2133571417L) +#define EXT2_ET_BAD_EA_BLOCK_NUM (2133571418L) +#define EXT2_ET_TOO_MANY_INODES (2133571419L) +#define EXT2_ET_NOT_IMAGE_FILE (2133571420L) +#define EXT2_ET_RES_GDT_BLOCKS (2133571421L) +#define EXT2_ET_RESIZE_INODE_CORRUPT (2133571422L) +#define EXT2_ET_SET_BMAP_NO_IND (2133571423L) +#define EXT2_ET_TDB_SUCCESS (2133571424L) +#define EXT2_ET_TDB_ERR_CORRUPT (2133571425L) +#define EXT2_ET_TDB_ERR_IO (2133571426L) +#define EXT2_ET_TDB_ERR_LOCK (2133571427L) +#define EXT2_ET_TDB_ERR_OOM (2133571428L) +#define EXT2_ET_TDB_ERR_EXISTS (2133571429L) +#define EXT2_ET_TDB_ERR_NOLOCK (2133571430L) +#define EXT2_ET_TDB_ERR_EINVAL (2133571431L) +#define EXT2_ET_TDB_ERR_NOEXIST (2133571432L) +#define EXT2_ET_TDB_ERR_RDONLY (2133571433L) +#define EXT2_ET_DBLIST_EMPTY (2133571434L) +#define EXT2_ET_RO_BLOCK_ITERATE (2133571435L) +#define EXT2_ET_MAGIC_EXTENT_PATH (2133571436L) +#define EXT2_ET_MAGIC_GENERIC_BITMAP64 (2133571437L) +#define EXT2_ET_MAGIC_BLOCK_BITMAP64 (2133571438L) +#define EXT2_ET_MAGIC_INODE_BITMAP64 (2133571439L) +#define EXT2_ET_MAGIC_RESERVED_13 (2133571440L) +#define EXT2_ET_MAGIC_RESERVED_14 (2133571441L) +#define EXT2_ET_MAGIC_RESERVED_15 (2133571442L) +#define EXT2_ET_MAGIC_RESERVED_16 (2133571443L) +#define EXT2_ET_MAGIC_RESERVED_17 (2133571444L) +#define EXT2_ET_MAGIC_RESERVED_18 (2133571445L) +#define EXT2_ET_MAGIC_RESERVED_19 (2133571446L) +#define EXT2_ET_EXTENT_HEADER_BAD (2133571447L) +#define EXT2_ET_EXTENT_INDEX_BAD (2133571448L) +#define EXT2_ET_EXTENT_LEAF_BAD (2133571449L) +#define EXT2_ET_EXTENT_NO_SPACE (2133571450L) +#define EXT2_ET_INODE_NOT_EXTENT (2133571451L) +#define EXT2_ET_EXTENT_NO_NEXT (2133571452L) +#define EXT2_ET_EXTENT_NO_PREV (2133571453L) +#define EXT2_ET_EXTENT_NO_UP (2133571454L) +#define EXT2_ET_EXTENT_NO_DOWN (2133571455L) +#define EXT2_ET_NO_CURRENT_NODE (2133571456L) +#define EXT2_ET_OP_NOT_SUPPORTED (2133571457L) +#define EXT2_ET_CANT_INSERT_EXTENT (2133571458L) +#define EXT2_ET_CANT_SPLIT_EXTENT (2133571459L) +#define EXT2_ET_EXTENT_NOT_FOUND (2133571460L) +#define EXT2_ET_EXTENT_NOT_SUPPORTED (2133571461L) +#define EXT2_ET_EXTENT_INVALID_LENGTH (2133571462L) +#define EXT2_ET_IO_CHANNEL_NO_SUPPORT_64 (2133571463L) +#define EXT2_NO_MTAB_FILE (2133571464L) +#define EXT2_ET_CANT_USE_LEGACY_BITMAPS (2133571465L) +#define EXT2_ET_MMP_MAGIC_INVALID (2133571466L) +#define EXT2_ET_MMP_FAILED (2133571467L) +#define EXT2_ET_MMP_FSCK_ON (2133571468L) +#define EXT2_ET_MMP_BAD_BLOCK (2133571469L) +#define EXT2_ET_MMP_UNKNOWN_SEQ (2133571470L) +#define EXT2_ET_MMP_CHANGE_ABORT (2133571471L) +#define EXT2_ET_MMP_OPEN_DIRECT (2133571472L) +extern const struct error_table et_ext2_error_table; +extern void initialize_ext2_error_table(void); + +/* For compatibility with Heimdal */ +extern void initialize_ext2_error_table_r(struct et_list **list); + +#define ERROR_TABLE_BASE_ext2 (2133571328L) + +/* for compatibility with older versions... */ +#define init_ext2_err_tbl initialize_ext2_error_table +#define ext2_err_base ERROR_TABLE_BASE_ext2 + +#endif + diff --git a/portlibs/sources/libext2fs/source/ext2_ext_attr.h b/portlibs/sources/libcustomext2fs/source/ext2_ext_attr.h similarity index 100% rename from portlibs/sources/libext2fs/source/ext2_ext_attr.h rename to portlibs/sources/libcustomext2fs/source/ext2_ext_attr.h diff --git a/portlibs/sources/libext2fs/source/ext2_frag.c b/portlibs/sources/libcustomext2fs/source/ext2_frag.c similarity index 100% rename from portlibs/sources/libext2fs/source/ext2_frag.c rename to portlibs/sources/libcustomext2fs/source/ext2_frag.c diff --git a/portlibs/sources/libext2fs/source/ext2_frag.h b/portlibs/sources/libcustomext2fs/source/ext2_frag.h similarity index 100% rename from portlibs/sources/libext2fs/source/ext2_frag.h rename to portlibs/sources/libcustomext2fs/source/ext2_frag.h diff --git a/portlibs/sources/libext2fs/source/ext2_fs.h b/portlibs/sources/libcustomext2fs/source/ext2_fs.h similarity index 87% rename from portlibs/sources/libext2fs/source/ext2_fs.h rename to portlibs/sources/libcustomext2fs/source/ext2_fs.h index 8a58dd10..4d41992c 100644 --- a/portlibs/sources/libext2fs/source/ext2_fs.h +++ b/portlibs/sources/libcustomext2fs/source/ext2_fs.h @@ -108,6 +108,18 @@ (s)->s_log_cluster_size) #define EXT2_CLUSTER_SIZE_BITS(s) ((s)->s_log_cluster_size + 10) +/* + * Macro-instructions used to manage fragments + * + * Note: for backwards compatibility only, for the dump program. + * Ext2/3/4 will never support fragments.... + */ +#define EXT2_MIN_FRAG_SIZE EXT2_MIN_BLOCK_SIZE +#define EXT2_MAX_FRAG_SIZE EXT2_MAX_BLOCK_SIZE +#define EXT2_MIN_FRAG_LOG_SIZE EXT2_MIN_BLOCK_LOG_SIZE +#define EXT2_FRAG_SIZE(s) EXT2_BLOCK_SIZE(s) +#define EXT2_FRAGS_PER_BLOCK(s) 1 + /* * ACL structures */ @@ -142,7 +154,9 @@ struct ext2_group_desc __u16 bg_free_inodes_count; /* Free inodes count */ __u16 bg_used_dirs_count; /* Directories count */ __u16 bg_flags; - __u32 bg_reserved[2]; + __u32 bg_exclude_bitmap_lo; /* Exclude bitmap for snapshots */ + __u16 bg_block_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+bitmap) LSB */ + __u16 bg_inode_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+bitmap) LSB */ __u16 bg_itable_unused; /* Unused inodes count */ __u16 bg_checksum; /* crc16(s_uuid+grouo_num+group_desc)*/ }; @@ -159,7 +173,9 @@ struct ext4_group_desc __u16 bg_free_inodes_count; /* Free inodes count */ __u16 bg_used_dirs_count; /* Directories count */ __u16 bg_flags; /* EXT4_BG_flags (INODE_UNINIT, etc) */ - __u32 bg_reserved[2]; /* Likely block/inode bitmap checksum */ + __u32 bg_exclude_bitmap_lo; /* Exclude bitmap for snapshots */ + __u16 bg_block_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+bitmap) LSB */ + __u16 bg_inode_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+bitmap) LSB */ __u16 bg_itable_unused; /* Unused inodes count */ __u16 bg_checksum; /* crc16(sb_uuid+group+desc) */ __u32 bg_block_bitmap_hi; /* Blocks bitmap block MSB */ @@ -169,7 +185,10 @@ struct ext4_group_desc __u16 bg_free_inodes_count_hi;/* Free inodes count MSB */ __u16 bg_used_dirs_count_hi; /* Directories count MSB */ __u16 bg_itable_unused_hi; /* Unused inodes count MSB */ - __u32 bg_reserved2[3]; + __u32 bg_exclude_bitmap_hi; /* Exclude bitmap block MSB */ + __u16 bg_block_bitmap_csum_hi;/* crc32c(s_uuid+grp_num+bitmap) MSB */ + __u16 bg_inode_bitmap_csum_hi;/* crc32c(s_uuid+grp_num+bitmap) MSB */ + __u32 bg_reserved; }; #define EXT2_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not initialized */ @@ -228,10 +247,15 @@ struct ext2_dx_countlimit { #define EXT2_BLOCKS_PER_GROUP(s) (EXT2_SB(s)->s_blocks_per_group) #define EXT2_INODES_PER_GROUP(s) (EXT2_SB(s)->s_inodes_per_group) +#define EXT2_CLUSTERS_PER_GROUP(s) (EXT2_SB(s)->s_clusters_per_group) #define EXT2_INODES_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s)) /* limits imposed by 16-bit value gd_free_{blocks,inode}_count */ -#define EXT2_MAX_BLOCKS_PER_GROUP(s) ((1 << 16) - 8) -#define EXT2_MAX_INODES_PER_GROUP(s) ((1 << 16) - EXT2_INODES_PER_BLOCK(s)) +#define EXT2_MAX_BLOCKS_PER_GROUP(s) ((((unsigned) 1 << 16) - 8) * \ + (EXT2_CLUSTER_SIZE(s) / \ + EXT2_BLOCK_SIZE(s))) +#define EXT2_MAX_CLUSTERS_PER_GROUP(s) (((unsigned) 1 << 16) - 8) +#define EXT2_MAX_INODES_PER_GROUP(s) (((unsigned) 1 << 16) - \ + EXT2_INODES_PER_BLOCK(s)) #ifdef __KERNEL__ #define EXT2_DESC_PER_BLOCK(s) (EXT2_SB(s)->s_desc_per_block) #define EXT2_DESC_PER_BLOCK_BITS(s) (EXT2_SB(s)->s_desc_per_block_bits) @@ -322,6 +346,7 @@ struct ext4_new_group_input { #define EXT2_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long) #define EXT2_IOC_GROUP_ADD _IOW('f', 8,struct ext2_new_group_input) #define EXT4_IOC_GROUP_ADD _IOW('f', 8,struct ext4_new_group_input) +#define EXT4_IOC_RESIZE_FS _IOW('f', 16, __u64) /* * Structure of an inode on the disk @@ -357,7 +382,8 @@ struct ext2_inode { __u16 l_i_file_acl_high; __u16 l_i_uid_high; /* these 2 fields */ __u16 l_i_gid_high; /* were reserved2[0] */ - __u32 l_i_reserved2; + __u16 l_i_checksum_lo; /* crc32c(uuid+inum+inode) */ + __u16 l_i_reserved; } linux2; struct { __u8 h_i_frag; /* Fragment number */ @@ -404,7 +430,8 @@ struct ext2_inode_large { __u16 l_i_file_acl_high; __u16 l_i_uid_high; /* these 2 fields */ __u16 l_i_gid_high; /* were reserved2[0] */ - __u32 l_i_reserved2; + __u16 l_i_checksum_lo; /* crc32c(uuid+inum+inode) */ + __u16 l_i_reserved; } linux2; struct { __u8 h_i_frag; /* Fragment number */ @@ -416,7 +443,7 @@ struct ext2_inode_large { } hurd2; } osd2; /* OS dependent 2 */ __u16 i_extra_isize; - __u16 i_pad1; + __u16 i_checksum_hi; /* crc32c(uuid+inum+inode) */ __u32 i_ctime_extra; /* extra Change time (nsec << 2 | epoch) */ __u32 i_mtime_extra; /* extra Modification time (nsec << 2 | epoch) */ __u32 i_atime_extra; /* extra Access time (nsec << 2 | epoch) */ @@ -435,7 +462,6 @@ struct ext2_inode_large { #define i_gid_low i_gid #define i_uid_high osd2.linux2.l_i_uid_high #define i_gid_high osd2.linux2.l_i_gid_high -#define i_reserved2 osd2.linux2.l_i_reserved2 #else #if defined(__GNU__) @@ -588,7 +614,7 @@ struct ext2_super_block { __u16 s_want_extra_isize; /* New inodes should reserve # bytes */ __u32 s_flags; /* Miscellaneous flags */ __u16 s_raid_stride; /* RAID stride */ - __u16 s_mmp_interval; /* # seconds to wait in MMP checking */ + __u16 s_mmp_update_interval; /* # seconds to wait in MMP checking */ __u64 s_mmp_block; /* Block for multi-mount protection */ __u32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/ __u8 s_log_groups_per_flex; /* FLEX_BG group size */ @@ -617,7 +643,8 @@ struct ext2_super_block { __u32 s_usr_quota_inum; /* inode number of user quota file */ __u32 s_grp_quota_inum; /* inode number of group quota file */ __u32 s_overhead_blocks; /* overhead blocks/clusters in fs */ - __u32 s_reserved[109]; /* Padding to the end of the block */ + __u32 s_reserved[108]; /* Padding to the end of the block */ + __u32 s_checksum; /* crc32c(superblock) */ }; #define EXT4_S_ERR_LEN (EXT4_S_ERR_END - EXT4_S_ERR_START) @@ -665,7 +692,9 @@ struct ext2_super_block { #define EXT2_FEATURE_COMPAT_RESIZE_INODE 0x0010 #define EXT2_FEATURE_COMPAT_DIR_INDEX 0x0020 #define EXT2_FEATURE_COMPAT_LAZY_BG 0x0040 -#define EXT2_FEATURE_COMPAT_EXCLUDE_INODE 0x0080 +/* #define EXT2_FEATURE_COMPAT_EXCLUDE_INODE 0x0080 not used, legacy */ +#define EXT2_FEATURE_COMPAT_EXCLUDE_BITMAP 0x0100 + #define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 #define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 @@ -677,6 +706,7 @@ struct ext2_super_block { #define EXT4_FEATURE_RO_COMPAT_HAS_SNAPSHOT 0x0080 #define EXT4_FEATURE_RO_COMPAT_QUOTA 0x0100 #define EXT4_FEATURE_RO_COMPAT_BIGALLOC 0x0200 +#define EXT4_FEATURE_RO_COMPAT_METADATA_CSUM 0x0400 #define EXT2_FEATURE_INCOMPAT_COMPRESSION 0x0001 #define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002 @@ -691,7 +721,8 @@ struct ext2_super_block { #define EXT4_FEATURE_INCOMPAT_DIRDATA 0x1000 #define EXT2_FEATURE_COMPAT_SUPP 0 -#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE) +#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \ + EXT4_FEATURE_INCOMPAT_MMP) #define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \ EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \ EXT4_FEATURE_RO_COMPAT_DIR_NLINK| \ @@ -772,28 +803,52 @@ struct ext2_dir_entry_2 { ~EXT2_DIR_ROUND) /* - * This structure will be used for multiple mount protection. It will be - * written into the block number saved in the s_mmp_block field in the - * superblock. + * This structure is used for multiple mount protection. It is written + * into the block number saved in the s_mmp_block field in the superblock. + * Programs that check MMP should assume that if SEQ_FSCK (or any unknown + * code above SEQ_MAX) is present then it is NOT safe to use the filesystem, + * regardless of how old the timestamp is. + * + * The timestamp in the MMP structure will be updated by e2fsck at some + * arbitary intervals (start of passes, after every few groups of inodes + * in pass1 and pass1b). There is no guarantee that e2fsck is updating + * the MMP block in a timely manner, and the updates it does are purely + * for the convenience of the sysadmin and not for automatic validation. + * + * Note: Only the mmp_seq value is used to determine whether the MMP block + * is being updated. The mmp_time, mmp_nodename, and mmp_bdevname + * fields are only for informational purposes for the administrator, + * due to clock skew between nodes and hostname HA service takeover. */ -#define EXT2_MMP_MAGIC 0x004D4D50 /* ASCII for MMP */ -#define EXT2_MMP_CLEAN 0xFF4D4D50 /* Value of mmp_seq for clean unmount */ -#define EXT2_MMP_FSCK_ON 0xE24D4D50 /* Value of mmp_seq when being fscked */ +#define EXT4_MMP_MAGIC 0x004D4D50U /* ASCII for MMP */ +#define EXT4_MMP_SEQ_CLEAN 0xFF4D4D50U /* mmp_seq value for clean unmount */ +#define EXT4_MMP_SEQ_FSCK 0xE24D4D50U /* mmp_seq value when being fscked */ +#define EXT4_MMP_SEQ_MAX 0xE24D4D4FU /* maximum valid mmp_seq value */ struct mmp_struct { - __u32 mmp_magic; - __u32 mmp_seq; - __u64 mmp_time; - char mmp_nodename[64]; - char mmp_bdevname[32]; - __u16 mmp_interval; + __u32 mmp_magic; /* Magic number for MMP */ + __u32 mmp_seq; /* Sequence no. updated periodically */ + __u64 mmp_time; /* Time last updated */ + char mmp_nodename[64]; /* Node which last updated MMP block */ + char mmp_bdevname[32]; /* Bdev which last updated MMP block */ + __u16 mmp_check_interval; /* Changed mmp_check_interval */ __u16 mmp_pad1; - __u32 mmp_pad2; + __u32 mmp_pad2[227]; }; /* - * Interval in number of seconds to update the MMP sequence number. + * Default interval for MMP update in seconds. */ -#define EXT2_MMP_DEF_INTERVAL 5 +#define EXT4_MMP_UPDATE_INTERVAL 5 + +/* + * Maximum interval for MMP update in seconds. + */ +#define EXT4_MMP_MAX_UPDATE_INTERVAL 300 + +/* + * Minimum interval for MMP checking in seconds. + */ +#define EXT4_MMP_MIN_CHECK_INTERVAL 5 #endif /* _LINUX_EXT2_FS_H */ diff --git a/portlibs/sources/libext2fs/source/ext2_internal.c b/portlibs/sources/libcustomext2fs/source/ext2_internal.c similarity index 99% rename from portlibs/sources/libext2fs/source/ext2_internal.c rename to portlibs/sources/libcustomext2fs/source/ext2_internal.c index d75133a7..ddb5f2a4 100644 --- a/portlibs/sources/libext2fs/source/ext2_internal.c +++ b/portlibs/sources/libcustomext2fs/source/ext2_internal.c @@ -249,7 +249,7 @@ static ext2_ino_t ext2PathToInode(ext2_vd *vd, const char * path) filename[i] = '\0'; - errorcode = ext2fs_namei(vd->fs, vd->root, parent, filename, &ino); + errorcode = ext2fs_namei_follow(vd->fs, vd->root, parent, filename, &ino); if(errorcode != EXT2_ET_OK) return 0; @@ -389,7 +389,7 @@ static ext2_ino_t ext2CreateSymlink(ext2_vd *vd, const char *path, const char * if (!err) { inode.i_block[0] = blk; - inode.i_blocks = vd->fs->blocksize / BYTES_PER_SECTOR; + inode.i_blocks = vd->fs->blocksize / 512; vd->fs->io->manager->write_blk(vd->fs->io, blk, 1, buffer); ext2fs_block_alloc_stats(vd->fs, blk, +1); } diff --git a/portlibs/sources/libext2fs/source/ext2_internal.h b/portlibs/sources/libcustomext2fs/source/ext2_internal.h similarity index 100% rename from portlibs/sources/libext2fs/source/ext2_internal.h rename to portlibs/sources/libcustomext2fs/source/ext2_internal.h diff --git a/portlibs/sources/libext2fs/source/ext2_io.h b/portlibs/sources/libcustomext2fs/source/ext2_io.h similarity index 98% rename from portlibs/sources/libext2fs/source/ext2_io.h rename to portlibs/sources/libcustomext2fs/source/ext2_io.h index 9f84d996..289a34f9 100644 --- a/portlibs/sources/libext2fs/source/ext2_io.h +++ b/portlibs/sources/libcustomext2fs/source/ext2_io.h @@ -26,8 +26,9 @@ typedef struct struct_io_manager *io_manager; typedef struct struct_io_channel *io_channel; typedef struct struct_io_stats *io_stats; -#define CHANNEL_FLAGS_WRITETHROUGH 0x01 +#define CHANNEL_FLAGS_WRITETHROUGH 0x01 #define CHANNEL_FLAGS_DISCARD_ZEROES 0x02 +#define CHANNEL_FLAGS_BLOCK_DEVICE 0x04 #define io_channel_discard_zeroes_data(i) (i->flags & CHANNEL_FLAGS_DISCARD_ZEROES) diff --git a/portlibs/sources/libcustomext2fs/source/ext2_types.h b/portlibs/sources/libcustomext2fs/source/ext2_types.h new file mode 100644 index 00000000..0912c4bc --- /dev/null +++ b/portlibs/sources/libcustomext2fs/source/ext2_types.h @@ -0,0 +1,143 @@ +/* + * If linux/types.h is already been included, assume it has defined + * everything we need. (cross fingers) Other header files may have + * also defined the types that we need. + */ +#ifndef _EXT2_TYPES_H +#define _EXT2_TYPES_H + +#define __S8_TYPEDEF __signed__ char +#define __U8_TYPEDEF unsigned char +#define __S16_TYPEDEF __signed__ short +#define __U16_TYPEDEF unsigned short +#define __S32_TYPEDEF __signed__ int +#define __U32_TYPEDEF unsigned int +#define __S64_TYPEDEF __signed__ long long +#define __U64_TYPEDEF unsigned long long + +#ifdef __U8_TYPEDEF +typedef __U8_TYPEDEF __u8; +#else +typedef unsigned char __u8; +#endif + +#ifdef __S8_TYPEDEF +typedef __S8_TYPEDEF __s8; +#else +typedef signed char __s8; +#endif + +#ifdef __U16_TYPEDEF +typedef __U16_TYPEDEF __u16; +#else +#if (4 == 2) +typedef unsigned int __u16; +#else +#if (2 == 2) +typedef unsigned short __u16; +#else + ?==error: undefined 16 bit type +#endif /* SIZEOF_SHORT == 2 */ +#endif /* SIZEOF_INT == 2 */ +#endif /* __U16_TYPEDEF */ + +#ifdef __S16_TYPEDEF +typedef __S16_TYPEDEF __s16; +#else +#if (4 == 2) +typedef int __s16; +#else +#if (2 == 2) +typedef short __s16; +#else + ?==error: undefined 16 bit type +#endif /* SIZEOF_SHORT == 2 */ +#endif /* SIZEOF_INT == 2 */ +#endif /* __S16_TYPEDEF */ + + +#ifdef __U32_TYPEDEF +typedef __U32_TYPEDEF __u32; +#else +#if (4 == 4) +typedef unsigned int __u32; +#else +#if (4 == 4) +typedef unsigned long __u32; +#else +#if (2 == 4) +typedef unsigned short __u32; +#else + ?== error: undefined 32 bit type +#endif /* SIZEOF_SHORT == 4 */ +#endif /* SIZEOF_LONG == 4 */ +#endif /* SIZEOF_INT == 4 */ +#endif /* __U32_TYPEDEF */ + +#ifdef __S32_TYPEDEF +typedef __S32_TYPEDEF __s32; +#else +#if (4 == 4) +typedef int __s32; +#else +#if (4 == 4) +typedef long __s32; +#else +#if (2 == 4) +typedef short __s32; +#else + ?== error: undefined 32 bit type +#endif /* SIZEOF_SHORT == 4 */ +#endif /* SIZEOF_LONG == 4 */ +#endif /* SIZEOF_INT == 4 */ +#endif /* __S32_TYPEDEF */ + +#ifdef __U64_TYPEDEF +typedef __U64_TYPEDEF __u64; +#else +#if (4 == 8) +typedef unsigned int __u64; +#else +#if (4 == 8) +typedef unsigned long __u64; +#else +#if (8 == 8) +typedef unsigned long long __u64; +#endif /* SIZEOF_LONG_LONG == 8 */ +#endif /* SIZEOF_LONG == 8 */ +#endif /* SIZEOF_INT == 8 */ +#endif /* __U64_TYPEDEF */ + +#ifdef __S64_TYPEDEF +typedef __S64_TYPEDEF __s64; +#else +#if (4 == 8) +typedef int __s64; +#else +#if (4 == 8) +typedef long __s64; +#else +#if (8 == 8) +#if defined(__GNUC__) +typedef __signed__ long long __s64; +#else +typedef signed long long __s64; +#endif /* __GNUC__ */ +#endif /* SIZEOF_LONG_LONG == 8 */ +#endif /* SIZEOF_LONG == 8 */ +#endif /* SIZEOF_INT == 8 */ +#endif /* __S64_TYPEDEF */ + +#undef __S8_TYPEDEF +#undef __U8_TYPEDEF +#undef __S16_TYPEDEF +#undef __U16_TYPEDEF +#undef __S32_TYPEDEF +#undef __U32_TYPEDEF +#undef __S64_TYPEDEF +#undef __U64_TYPEDEF + +#endif /* _*_TYPES_H */ + +/* These defines are needed for the public ext2fs.h header file */ +#define HAVE_SYS_TYPES_H 1 diff --git a/portlibs/sources/libext2fs/source/ext2dir.c b/portlibs/sources/libcustomext2fs/source/ext2dir.c similarity index 100% rename from portlibs/sources/libext2fs/source/ext2dir.c rename to portlibs/sources/libcustomext2fs/source/ext2dir.c diff --git a/portlibs/sources/libext2fs/source/ext2dir.h b/portlibs/sources/libcustomext2fs/source/ext2dir.h similarity index 100% rename from portlibs/sources/libext2fs/source/ext2dir.h rename to portlibs/sources/libcustomext2fs/source/ext2dir.h diff --git a/portlibs/sources/libext2fs/source/ext2file.c b/portlibs/sources/libcustomext2fs/source/ext2file.c similarity index 96% rename from portlibs/sources/libext2fs/source/ext2file.c rename to portlibs/sources/libcustomext2fs/source/ext2file.c index 6647466f..f2b77c19 100644 --- a/portlibs/sources/libext2fs/source/ext2file.c +++ b/portlibs/sources/libcustomext2fs/source/ext2file.c @@ -41,11 +41,7 @@ void ext2CloseFile (ext2_file_state *file) // Sync the file (and its attributes) to disc if(file->write) - { - // Read in node changes before writing them - ext2fs_read_inode(file->vd->fs, file->ni->ino, &file->ni->ni); ext2UpdateTimes(file->vd, file->ni, EXT2_UPDATE_ACTIME); - } if (file->read) ext2UpdateTimes(file->vd, file->ni, EXT2_UPDATE_ATIME); @@ -243,11 +239,25 @@ ssize_t ext2_write_r (struct _reent *r, int fd, const char *ptr, size_t len) // Lock ext2Lock(file->vd); - u32 writen = 0; + errcode_t err = 0; + u32 written = 0; // Write to the files data atrribute - errcode_t err = ext2fs_file_write(file->fd, ptr, len, &writen); - if (writen <= 0 || err) { + while (len > 0) + { + u32 wrote = 0; + + err = ext2fs_file_write(file->fd, ptr, len, &wrote); + if (err) + break; + + len -= wrote; + ptr += wrote; + written += wrote; + } + + // Check for errors + if (err) { ext2Unlock(file->vd); r->_errno = errno; return (err ? err : -1); @@ -256,7 +266,7 @@ ssize_t ext2_write_r (struct _reent *r, int fd, const char *ptr, size_t len) // Unlock ext2Unlock(file->vd); - return (writen == 0 ? -1 : writen); + return (written == 0 ? -1 : written); } ssize_t ext2_read_r (struct _reent *r, int fd, char *ptr, size_t len) diff --git a/portlibs/sources/libext2fs/source/ext2file.h b/portlibs/sources/libcustomext2fs/source/ext2file.h similarity index 100% rename from portlibs/sources/libext2fs/source/ext2file.h rename to portlibs/sources/libcustomext2fs/source/ext2file.h diff --git a/portlibs/sources/libext2fs/source/ext2fs.h b/portlibs/sources/libcustomext2fs/source/ext2fs.h similarity index 90% rename from portlibs/sources/libext2fs/source/ext2fs.h rename to portlibs/sources/libcustomext2fs/source/ext2fs.h index 7016486c..85ac7a2b 100644 --- a/portlibs/sources/libext2fs/source/ext2fs.h +++ b/portlibs/sources/libcustomext2fs/source/ext2fs.h @@ -29,6 +29,10 @@ extern "C" { #define NO_INLINE_FUNCS #endif +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 600 /* for posix_memalign() */ +#endif + /* * Where the master copy of the superblock is located, and how big * superblocks are supposed to be. We define SUPERBLOCK_SIZE because @@ -37,7 +41,7 @@ extern "C" { * 1032 bytes long). */ #define SUPERBLOCK_OFFSET 1024 -#define SUPERBLOCK_SIZE 1024 +#define SUPERBLOCK_SIZE 1024 /* * The last ext2fs revision level that this version of the library is @@ -53,9 +57,18 @@ extern "C" { #include #include #include +#include +#include +#include + +#ifndef __USE_XOPEN2K +/* If the "#define _XOPEN_SOURCE 600" didn't succeed in declaring + * posix_memalign(), maybe due to or included beforej + * _XOPEN_SOURCE, declare it here to avoid compiler warnings. */ +extern int posix_memalign(void **__memptr, size_t __alignment, size_t __size); +#endif #include "ext2_types.h" -#include "com_err.h" #include "ext2_fs.h" #include "ext3_extents.h" @@ -68,6 +81,7 @@ typedef __u64 ext2_off64_t; typedef __s64 e2_blkcnt_t; typedef __u32 ext2_dirhash_t; +#include "com_err.h" #include "ext2_io.h" #include "ext2_err.h" #include "ext2_ext_attr.h" @@ -171,6 +185,7 @@ typedef struct ext2_file *ext2_file_t; #define EXT2_FLAG_64BITS 0x20000 #define EXT2_FLAG_PRINT_PROGRESS 0x40000 #define EXT2_FLAG_DIRECT_IO 0x80000 +#define EXT2_FLAG_SKIP_MMP 0x100000 /* * Special flag in the ext2 inode i_flag field that means that this is @@ -180,10 +195,9 @@ typedef struct ext2_file *ext2_file_t; /* * Flags for mkjournal - * - * EXT2_MKJOURNAL_V1_SUPER Make a (deprecated) V1 journal superblock */ -#define EXT2_MKJOURNAL_V1_SUPER 0x0000001 +#define EXT2_MKJOURNAL_V1_SUPER 0x0000001 /* create V1 superblock (deprecated) */ +#define EXT2_MKJOURNAL_LAZYINIT 0x0000002 /* don't zero journal inode before use*/ struct opaque_ext2_group_desc; @@ -194,11 +208,11 @@ struct struct_ext2_filsys { char * device_name; struct ext2_super_block * super; unsigned int blocksize; - int clustersize; + int fragsize; dgrp_t group_desc_count; unsigned long desc_blocks; struct opaque_ext2_group_desc * group_desc; - int inode_blocks_per_group; + unsigned int inode_blocks_per_group; ext2fs_inode_bitmap inode_map; ext2fs_block_bitmap block_map; /* XXX FIXME-64: not 64-bit safe, but not used? */ @@ -216,10 +230,11 @@ struct struct_ext2_filsys { struct ext2_image_hdr * image_header; __u32 umask; time_t now; + int cluster_ratio_bits; /* * Reserved for future expansion */ - __u32 reserved[7]; + __u32 reserved[6]; /* * Reserved for the use of the calling application. @@ -238,6 +253,18 @@ struct struct_ext2_filsys { errcode_t (*get_alloc_block)(ext2_filsys fs, blk64_t goal, blk64_t *ret); void (*block_alloc_stats)(ext2_filsys fs, blk64_t blk, int inuse); + + /* + * Buffers for Multiple mount protection(MMP) block. + */ + void *mmp_buf; + void *mmp_cmp; + int mmp_fd; + + /* + * Time at which e2fsck last updated the MMP block. + */ + long mmp_last_written; }; #include "bitops.h" @@ -519,6 +546,7 @@ typedef struct ext2_icount *ext2_icount_t; EXT3_FEATURE_INCOMPAT_RECOVER|\ EXT3_FEATURE_INCOMPAT_EXTENTS|\ EXT4_FEATURE_INCOMPAT_FLEX_BG|\ + EXT4_FEATURE_INCOMPAT_MMP|\ EXT4_FEATURE_INCOMPAT_64BIT) #else #define EXT2_LIB_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE|\ @@ -527,14 +555,27 @@ typedef struct ext2_icount *ext2_icount_t; EXT3_FEATURE_INCOMPAT_RECOVER|\ EXT3_FEATURE_INCOMPAT_EXTENTS|\ EXT4_FEATURE_INCOMPAT_FLEX_BG|\ + EXT4_FEATURE_INCOMPAT_MMP|\ EXT4_FEATURE_INCOMPAT_64BIT) #endif +#ifdef CONFIG_QUOTA #define EXT2_LIB_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\ EXT4_FEATURE_RO_COMPAT_HUGE_FILE|\ EXT2_FEATURE_RO_COMPAT_LARGE_FILE|\ EXT4_FEATURE_RO_COMPAT_DIR_NLINK|\ EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE|\ - EXT4_FEATURE_RO_COMPAT_GDT_CSUM) + EXT4_FEATURE_RO_COMPAT_GDT_CSUM|\ + EXT4_FEATURE_RO_COMPAT_BIGALLOC|\ + EXT4_FEATURE_RO_COMPAT_QUOTA) +#else +#define EXT2_LIB_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\ + EXT4_FEATURE_RO_COMPAT_HUGE_FILE|\ + EXT2_FEATURE_RO_COMPAT_LARGE_FILE|\ + EXT4_FEATURE_RO_COMPAT_DIR_NLINK|\ + EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE|\ + EXT4_FEATURE_RO_COMPAT_GDT_CSUM|\ + EXT4_FEATURE_RO_COMPAT_BIGALLOC) +#endif /* * These features are only allowed if EXT2_FLAG_SOFTSUPP_FEATURES is passed @@ -543,6 +584,29 @@ typedef struct ext2_icount *ext2_icount_t; #define EXT2_LIB_SOFTSUPP_INCOMPAT (0) #define EXT2_LIB_SOFTSUPP_RO_COMPAT (EXT4_FEATURE_RO_COMPAT_BIGALLOC) + +/* Translate a block number to a cluster number */ +#define EXT2FS_CLUSTER_RATIO(fs) (1 << (fs)->cluster_ratio_bits) +#define EXT2FS_CLUSTER_MASK(fs) (EXT2FS_CLUSTER_RATIO(fs) - 1) +#define EXT2FS_B2C(fs, blk) ((blk) >> (fs)->cluster_ratio_bits) +/* Translate a cluster number to a block number */ +#define EXT2FS_C2B(fs, cluster) ((cluster) << (fs)->cluster_ratio_bits) +/* Translate # of blks to # of clusters */ +#define EXT2FS_NUM_B2C(fs, blks) (((blks) + EXT2FS_CLUSTER_MASK(fs)) >> \ + (fs)->cluster_ratio_bits) + +#if defined(HAVE_FSTAT64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED) +typedef struct stat64 ext2fs_struct_stat; +#else +typedef struct stat ext2fs_struct_stat; +#endif + +/* + * For ext2fs_close2() and ext2fs_flush2(), this flag allows you to + * avoid the fsync call. + */ +#define EXT2_FLAG_FLUSH_NO_SYNC 1 + /* * function prototypes */ @@ -656,6 +720,10 @@ extern errcode_t ext2fs_read_block_bitmap(ext2_filsys fs); extern errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs, const char *descr, ext2fs_block_bitmap *ret); +extern errcode_t ext2fs_allocate_subcluster_bitmap(ext2_filsys fs, + const char *descr, + ext2fs_block_bitmap *ret); +extern int ext2fs_get_bitmap_granularity(ext2fs_block_bitmap bitmap); extern errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs, const char *descr, ext2fs_inode_bitmap *ret); @@ -712,6 +780,7 @@ extern errcode_t ext2fs_get_block_bitmap_range2(ext2fs_block_bitmap bmap, extern dgrp_t ext2fs_group_of_blk2(ext2_filsys fs, blk64_t); extern blk64_t ext2fs_group_first_block2(ext2_filsys fs, dgrp_t group); extern blk64_t ext2fs_group_last_block2(ext2_filsys fs, dgrp_t group); +extern int ext2fs_group_blocks_count(ext2_filsys fs, dgrp_t group); extern blk64_t ext2fs_inode_data_blocks2(ext2_filsys fs, struct ext2_inode *inode); extern blk64_t ext2fs_inode_i_blocks(ext2_filsys fs, @@ -763,8 +832,10 @@ extern void ext2fs_bg_flags_set(ext2_filsys fs, dgrp_t group, __u16 bg_flags); extern void ext2fs_bg_flags_clear(ext2_filsys fs, dgrp_t group, __u16 bg_flags); extern __u16 ext2fs_bg_checksum(ext2_filsys fs, dgrp_t group); extern void ext2fs_bg_checksum_set(ext2_filsys fs, dgrp_t group, __u16 checksum); -extern blk64_t ext2fs_file_acl_block(const struct ext2_inode *inode); -extern void ext2fs_file_acl_block_set(struct ext2_inode *inode, blk64_t blk); +extern blk64_t ext2fs_file_acl_block(ext2_filsys fs, + const struct ext2_inode *inode); +extern void ext2fs_file_acl_block_set(ext2_filsys fs, + struct ext2_inode *inode, blk64_t blk); /* block.c */ extern errcode_t ext2fs_block_iterate(ext2_filsys fs, @@ -822,7 +893,9 @@ extern errcode_t ext2fs_check_desc(ext2_filsys fs); /* closefs.c */ extern errcode_t ext2fs_close(ext2_filsys fs); +extern errcode_t ext2fs_close2(ext2_filsys fs, int flags); extern errcode_t ext2fs_flush(ext2_filsys fs); +extern errcode_t ext2fs_flush2(ext2_filsys fs, int flags); extern int ext2fs_bg_has_super(ext2_filsys fs, int group_block); extern errcode_t ext2fs_super_and_bgd_loc2(ext2_filsys fs, dgrp_t group, @@ -838,6 +911,10 @@ extern int ext2fs_super_and_bgd_loc(ext2_filsys fs, int *ret_meta_bg); extern void ext2fs_update_dynamic_rev(ext2_filsys fs); +/* crc32c.c */ +extern __u32 ext2fs_crc32c_be(__u32 crc, unsigned char const *p, size_t len); +extern __u32 ext2fs_crc32c_le(__u32 crc, unsigned char const *p, size_t len); + /* csum.c */ extern void ext2fs_group_desc_csum_set(ext2_filsys fs, dgrp_t group); extern int ext2fs_group_desc_csum_verify(ext2_filsys fs, dgrp_t group); @@ -1088,6 +1165,8 @@ errcode_t ext2fs_get_generic_bmap_range(ext2fs_generic_bitmap bmap, errcode_t ext2fs_set_generic_bmap_range(ext2fs_generic_bitmap bmap, __u64 start, unsigned int num, void *in); +errcode_t ext2fs_convert_subcluster_bitmap(ext2_filsys fs, + ext2fs_block_bitmap *bitmap); /* getsize.c */ extern errcode_t ext2fs_get_device_size(const char *file, int blocksize, @@ -1227,21 +1306,21 @@ extern errcode_t ext2fs_zero_blocks(ext2_filsys fs, blk_t blk, int num, extern errcode_t ext2fs_zero_blocks2(ext2_filsys fs, blk64_t blk, int num, blk64_t *ret_blk, int *ret_count); extern errcode_t ext2fs_create_journal_superblock(ext2_filsys fs, - __u32 size, int flags, + __u32 num_blocks, int flags, char **ret_jsb); extern errcode_t ext2fs_add_journal_device(ext2_filsys fs, ext2_filsys journal_dev); -extern errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t size, +extern errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t num_blocks, int flags); -extern int ext2fs_default_journal_size(__u64 blocks); +extern int ext2fs_default_journal_size(__u64 num_blocks); /* openfs.c */ extern errcode_t ext2fs_open(const char *name, int flags, int superblock, - unsigned int block_size, io_channel * chan, + unsigned int block_size, io_channel chan, ext2_filsys *ret_fs); extern errcode_t ext2fs_open2(const char *name, const char *io_options, int flags, int superblock, - unsigned int block_size, io_channel * chan, + unsigned int block_size, io_channel chan, ext2_filsys *ret_fs); extern blk64_t ext2fs_descriptor_block_loc2(ext2_filsys fs, blk64_t group_block, dgrp_t i); @@ -1261,6 +1340,16 @@ errcode_t ext2fs_link(ext2_filsys fs, ext2_ino_t dir, const char *name, errcode_t ext2fs_unlink(ext2_filsys fs, ext2_ino_t dir, const char *name, ext2_ino_t ino, int flags); +/* mmp.c */ +errcode_t ext2fs_mmp_read(ext2_filsys fs, blk64_t mmp_blk, void *buf); +errcode_t ext2fs_mmp_write(ext2_filsys fs, blk64_t mmp_blk, void *buf); +errcode_t ext2fs_mmp_clear(ext2_filsys fs); +errcode_t ext2fs_mmp_init(ext2_filsys fs); +errcode_t ext2fs_mmp_start(ext2_filsys fs); +errcode_t ext2fs_mmp_update(ext2_filsys fs); +errcode_t ext2fs_mmp_stop(ext2_filsys fs); +unsigned ext2fs_mmp_new_seq(void); + /* read_bb.c */ extern errcode_t ext2fs_read_bb_inode(ext2_filsys fs, ext2_badblocks_list *bb_list); @@ -1296,9 +1385,12 @@ extern void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t, int bufsize); extern void ext2fs_swap_inode(ext2_filsys fs,struct ext2_inode *t, struct ext2_inode *f, int hostorder); +extern void ext2fs_swap_mmp(struct mmp_struct *mmp); /* valid_blk.c */ extern int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode); +extern int ext2fs_inode_has_valid_blocks2(ext2_filsys fs, + struct ext2_inode *inode); /* version.c */ extern int ext2fs_parse_version_string(const char *ver_string); @@ -1315,6 +1407,11 @@ extern errcode_t ext2fs_write_bb_FILE(ext2_badblocks_list bb_list, extern errcode_t ext2fs_get_mem(unsigned long size, void *ptr); extern errcode_t ext2fs_get_memalign(unsigned long size, unsigned long align, void *ptr); +extern errcode_t ext2fs_get_memzero(unsigned long size, void *ptr); +extern errcode_t ext2fs_get_array(unsigned long count, + unsigned long size, void *ptr); +extern errcode_t ext2fs_get_arrayzero(unsigned long count, + unsigned long size, void *ptr); extern errcode_t ext2fs_free_mem(void *ptr); extern errcode_t ext2fs_resize_mem(unsigned long old_size, unsigned long size, void *ptr); @@ -1336,6 +1433,9 @@ extern blk_t ext2fs_inode_data_blocks(ext2_filsys fs, struct ext2_inode *inode); extern unsigned int ext2fs_div_ceil(unsigned int a, unsigned int b); extern __u64 ext2fs_div64_ceil(__u64 a, __u64 b); +extern int ext2fs_open_file(const char *pathname, int flags, mode_t mode); +extern int ext2fs_stat(const char *path, ext2fs_struct_stat *buf); +extern int ext2fs_fstat(int fd, ext2fs_struct_stat *buf); /* * The actual inlined functions definitions themselves... @@ -1371,30 +1471,39 @@ _INLINE_ errcode_t ext2fs_get_mem(unsigned long size, void *ptr) return 0; } -_INLINE_ errcode_t ext2fs_get_memalign(unsigned long size, - unsigned long align, void *ptr) +_INLINE_ errcode_t ext2fs_get_memzero(unsigned long size, void *ptr) { void *pp; - #ifdef HWRVL - pp = mem_align(32, size); - #else pp = mem_alloc(size); - #endif if (!pp) return EXT2_ET_NO_MEMORY; - - memcpy(ptr, &pp, sizeof (pp)); + memset(pp, 0, size); + memcpy(ptr, &pp, sizeof(pp)); return 0; } _INLINE_ errcode_t ext2fs_get_array(unsigned long count, unsigned long size, void *ptr) { if (count && (-1UL)/count #if HAVE_UNISTD_H #include @@ -82,9 +83,9 @@ errcode_t ext2fs_write_ext_attr2(ext2_filsys fs, blk64_t block, void *inbuf) { errcode_t retval; char *write_buf; +#ifdef WORDS_BIGENDIAN char *buf = NULL; -#ifdef WORDS_BIGENDIAN retval = ext2fs_get_mem(fs->blocksize, &buf); if (retval) return retval; @@ -94,8 +95,9 @@ errcode_t ext2fs_write_ext_attr2(ext2_filsys fs, blk64_t block, void *inbuf) write_buf = (char *) inbuf; #endif retval = io_channel_write_blk64(fs->io, block, 1, write_buf); - if (buf) - ext2fs_free_mem(&buf); +#ifdef WORDS_BIGENDIAN + ext2fs_free_mem(&buf); +#endif if (!retval) ext2fs_mark_changed(fs); return retval; diff --git a/portlibs/sources/libext2fs/source/extent.c b/portlibs/sources/libcustomext2fs/source/extent.c similarity index 99% rename from portlibs/sources/libext2fs/source/extent.c rename to portlibs/sources/libcustomext2fs/source/extent.c index 5e070925..eb096d6a 100644 --- a/portlibs/sources/libext2fs/source/extent.c +++ b/portlibs/sources/libcustomext2fs/source/extent.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -253,9 +254,8 @@ extern errcode_t ext2fs_extent_open2(ext2_filsys fs, ext2_ino_t ino, handle->path[0].max_entries = ext2fs_le16_to_cpu(eh->eh_max); handle->path[0].curr = 0; handle->path[0].end_blk = - ((((__u64) handle->inode->i_size_high << 32) + - handle->inode->i_size + (fs->blocksize - 1)) - >> EXT2_BLOCK_SIZE_BITS(fs->super)); + (EXT2_I_SIZE(handle->inode) + fs->blocksize - 1) >> + EXT2_BLOCK_SIZE_BITS(fs->super); handle->path[0].visit_num = 1; handle->level = 0; handle->magic = EXT2_ET_MAGIC_EXTENT_HANDLE; @@ -374,9 +374,11 @@ retry: case EXT2_EXTENT_ROOT: handle->level = 0; path = handle->path + handle->level; + /* fallthrough */ case EXT2_EXTENT_FIRST_SIB: path->left = path->entries; path->curr = 0; + /* fallthrough */ case EXT2_EXTENT_NEXT_SIB: if (path->left <= 0) return EXT2_ET_EXTENT_NO_NEXT; diff --git a/portlibs/sources/libext2fs/source/fiemap.h b/portlibs/sources/libcustomext2fs/source/fiemap.h similarity index 100% rename from portlibs/sources/libext2fs/source/fiemap.h rename to portlibs/sources/libcustomext2fs/source/fiemap.h diff --git a/portlibs/sources/libext2fs/source/fileio.c b/portlibs/sources/libcustomext2fs/source/fileio.c similarity index 87% rename from portlibs/sources/libext2fs/source/fileio.c rename to portlibs/sources/libcustomext2fs/source/fileio.c index 44c859b9..193f72e5 100644 --- a/portlibs/sources/libext2fs/source/fileio.c +++ b/portlibs/sources/libcustomext2fs/source/fileio.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -22,7 +23,7 @@ struct ext2_file { errcode_t magic; ext2_filsys fs; ext2_ino_t ino; - struct ext2_inode inode; + struct ext2_inode *inode; int flags; __u64 pos; blk64_t blockno; @@ -56,13 +57,9 @@ errcode_t ext2fs_file_open2(ext2_filsys fs, ext2_ino_t ino, file->fs = fs; file->ino = ino; file->flags = flags & EXT2_FILE_MASK; - - if (inode) { - memcpy(&file->inode, inode, sizeof(struct ext2_inode)); - } else { - retval = ext2fs_read_inode(fs, ino, &file->inode); - if (retval) - goto fail; + file->inode = inode; + if (!inode) { + goto fail; } retval = ext2fs_get_array(3, fs->blocksize, &file->buf); @@ -102,7 +99,7 @@ struct ext2_inode *ext2fs_file_get_inode(ext2_file_t file) { if (file->magic != EXT2_ET_MAGIC_EXT2_FILE) return NULL; - return &file->inode; + return file->inode; } /* @@ -121,15 +118,12 @@ errcode_t ext2fs_file_flush(ext2_file_t file) !(file->flags & EXT2_FILE_BUF_DIRTY)) return 0; - // Flushing out the new size - Dimok - ext2fs_write_inode(file->fs, file->ino, &file->inode); - /* * OK, the physical block hasn't been allocated yet. * Allocate it. */ if (!file->physblock) { - retval = ext2fs_bmap2(fs, file->ino, &file->inode, + retval = ext2fs_bmap2(fs, file->ino, file->inode, BMAP_BUFFER, file->ino ? BMAP_ALLOC : 0, file->blockno, 0, &file->physblock); if (retval) @@ -181,7 +175,7 @@ static errcode_t load_buffer(ext2_file_t file, int dontfill) errcode_t retval; if (!(file->flags & EXT2_FILE_BUF_VALID)) { - retval = ext2fs_bmap2(fs, file->ino, &file->inode, + retval = ext2fs_bmap2(fs, file->ino, file->inode, BMAP_BUFFER, 0, file->blockno, 0, &file->physblock); if (retval) @@ -230,7 +224,7 @@ errcode_t ext2fs_file_read(ext2_file_t file, void *buf, EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE); fs = file->fs; - while ((file->pos < EXT2_I_SIZE(&file->inode)) && (wanted > 0)) { + while ((file->pos < EXT2_I_SIZE(file->inode)) && (wanted > 0)) { retval = sync_buffer_position(file); if (retval) goto fail; @@ -242,7 +236,7 @@ errcode_t ext2fs_file_read(ext2_file_t file, void *buf, c = fs->blocksize - start; if (c > wanted) c = wanted; - left = EXT2_I_SIZE(&file->inode) - file->pos ; + left = EXT2_I_SIZE(file->inode) - file->pos ; if (c > left) c = left; @@ -300,11 +294,11 @@ errcode_t ext2fs_file_write(ext2_file_t file, const void *buf, nbytes -= c; } - // I don't see why changing size is my duty - Dimok - if(EXT2_I_SIZE(&file->inode) < file->pos) + // Modify file size in inode if required + if(EXT2_I_SIZE(file->inode) < file->pos) { - file->inode.i_size = file->pos & 0xFFFFFFFF; - file->inode.i_size_high = (file->pos >> 32) & 0xFFFFFFFF; + file->inode->i_size = file->pos & 0xFFFFFFFF; + file->inode->i_size_high = (file->pos >> 32) & 0xFFFFFFFF; } fail: @@ -323,7 +317,7 @@ errcode_t ext2fs_file_llseek(ext2_file_t file, __u64 offset, else if (whence == EXT2_SEEK_CUR) file->pos += offset; else if (whence == EXT2_SEEK_END) - file->pos = EXT2_I_SIZE(&file->inode) + offset; + file->pos = EXT2_I_SIZE(file->inode) + offset; else return EXT2_ET_INVALID_ARGUMENT; @@ -336,7 +330,7 @@ errcode_t ext2fs_file_llseek(ext2_file_t file, __u64 offset, errcode_t ext2fs_file_lseek(ext2_file_t file, ext2_off_t offset, int whence, ext2_off_t *ret_pos) { - __u64 loffset, ret_loffset = 0; + __u64 loffset, ret_loffset; errcode_t retval; loffset = offset; @@ -354,7 +348,7 @@ errcode_t ext2fs_file_get_lsize(ext2_file_t file, __u64 *ret_size) { if (file->magic != EXT2_ET_MAGIC_EXT2_FILE) return EXT2_ET_MAGIC_EXT2_FILE; - *ret_size = EXT2_I_SIZE(&file->inode); + *ret_size = EXT2_I_SIZE(file->inode); return 0; } @@ -386,15 +380,14 @@ errcode_t ext2fs_file_set_size2(ext2_file_t file, ext2_off64_t size) truncate_block = ((size + file->fs->blocksize - 1) >> EXT2_BLOCK_SIZE_BITS(file->fs->super)) + 1; - old_size = file->inode.i_size + - (((blk64_t) file->inode.i_size_high) << 32); + old_size = EXT2_I_SIZE(file->inode); old_truncate = ((old_size + file->fs->blocksize - 1) >> EXT2_BLOCK_SIZE_BITS(file->fs->super)) + 1; - file->inode.i_size = size & 0xffffffff; - file->inode.i_size_high = (size >> 32); + file->inode->i_size = size & 0xffffffff; + file->inode->i_size_high = (size >> 32); if (file->ino) { - retval = ext2fs_write_inode(file->fs, file->ino, &file->inode); + retval = ext2fs_write_inode(file->fs, file->ino, file->inode); if (retval) return retval; } @@ -402,7 +395,7 @@ errcode_t ext2fs_file_set_size2(ext2_file_t file, ext2_off64_t size) if (truncate_block <= old_truncate) return 0; - return ext2fs_punch(file->fs, file->ino, &file->inode, 0, + return ext2fs_punch(file->fs, file->ino, file->inode, 0, truncate_block, ~0ULL); } diff --git a/portlibs/sources/libext2fs/source/finddev.c b/portlibs/sources/libcustomext2fs/source/finddev.c similarity index 96% rename from portlibs/sources/libext2fs/source/finddev.c rename to portlibs/sources/libcustomext2fs/source/finddev.c index cc2029f2..311608de 100644 --- a/portlibs/sources/libext2fs/source/finddev.c +++ b/portlibs/sources/libcustomext2fs/source/finddev.c @@ -10,6 +10,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -33,6 +34,7 @@ #include "ext2_fs.h" #include "ext2fs.h" +#include "ext2fsP.h" struct dir_list { char *name; @@ -127,6 +129,7 @@ char *ext2fs_find_block_device(dev_t device) struct dir_list *list = 0, *new_list = 0; struct dir_list *current; char *ret_path = 0; + int level = 0; /* * Add the starting directories to search... @@ -153,6 +156,9 @@ char *ext2fs_find_block_device(dev_t device) if (list == 0) { list = new_list; new_list = 0; + /* Avoid infinite loop */ + if (++level >= EXT2FS_MAX_NESTED_LINKS) + break; } } free_dirlist(&list); diff --git a/portlibs/sources/libext2fs/source/flushb.c b/portlibs/sources/libcustomext2fs/source/flushb.c similarity index 93% rename from portlibs/sources/libext2fs/source/flushb.c rename to portlibs/sources/libcustomext2fs/source/flushb.c index b6f161b6..ac8923cb 100644 --- a/portlibs/sources/libext2fs/source/flushb.c +++ b/portlibs/sources/libcustomext2fs/source/flushb.c @@ -10,6 +10,7 @@ * %End-Header% */ +#include "config.h" #include #if HAVE_ERRNO_H #include @@ -65,9 +66,13 @@ errcode_t ext2fs_sync_device(int fd, int flushb) #ifdef BLKFLSBUF if (ioctl (fd, BLKFLSBUF, 0) == 0) return 0; +#elif defined(__linux__) +#warning BLKFLSBUF not defined #endif #ifdef FDFLUSH ioctl (fd, FDFLUSH, 0); /* In case this is a floppy */ +#elif defined(__linux__) +#warning FDFLUSH not defined #endif } return 0; diff --git a/portlibs/sources/libext2fs/source/freefs.c b/portlibs/sources/libcustomext2fs/source/freefs.c similarity index 94% rename from portlibs/sources/libext2fs/source/freefs.c rename to portlibs/sources/libcustomext2fs/source/freefs.c index 5c35bb68..28c4132f 100644 --- a/portlibs/sources/libext2fs/source/freefs.c +++ b/portlibs/sources/libcustomext2fs/source/freefs.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #if HAVE_UNISTD_H #include @@ -53,6 +54,11 @@ void ext2fs_free(ext2_filsys fs) if (fs->icache) ext2fs_free_inode_cache(fs->icache); + if (fs->mmp_buf) + ext2fs_free_mem(&fs->mmp_buf); + if (fs->mmp_cmp) + ext2fs_free_mem(&fs->mmp_cmp); + fs->magic = 0; ext2fs_free_mem(&fs); diff --git a/portlibs/sources/libext2fs/source/gekko_io.c b/portlibs/sources/libcustomext2fs/source/gekko_io.c similarity index 89% rename from portlibs/sources/libext2fs/source/gekko_io.c rename to portlibs/sources/libcustomext2fs/source/gekko_io.c index 97da1d9f..ec6d93d2 100644 --- a/portlibs/sources/libext2fs/source/gekko_io.c +++ b/portlibs/sources/libcustomext2fs/source/gekko_io.c @@ -47,6 +47,59 @@ static bool device_gekko_io_readsectors(io_channel dev, sec_t sector, sec_t numS static s64 device_gekko_io_writebytes(io_channel dev, s64 offset, s64 count, const void *buf); static bool device_gekko_io_writesectors(io_channel dev, sec_t sector, sec_t numSectors, const void* buffer); +/** + * Get the sector size of the device + */ +static int readSectorSize(const DISC_INTERFACE* interace) +{ + int counter1 = 0; + int counter2 = 0; + int i; + + u8 *memblock = (u8 *) mem_alloc(MAX_SECTOR_SIZE); + if(!memblock) + return 512; + + memset(memblock, 0x00, MAX_SECTOR_SIZE); + + if(!interace->readSectors(0, 1, memblock)) { + mem_free(memblock); + return 512; + } + + for(i = 0; i < MAX_SECTOR_SIZE; ++i) + { + if(memblock[i] != 0x00) + counter1++; + } + + memset(memblock, 0xFF, MAX_SECTOR_SIZE); + + if(!interace->readSectors(0, 1, memblock)) { + mem_free(memblock); + return 512; + } + + for(i = 0; i < MAX_SECTOR_SIZE; ++i) + { + if(memblock[i] != 0xFF) + counter2++; + } + + mem_free(memblock); + + if(counter1 <= 512 && counter2 <= 512) + return 512; + + if(counter1 <= 1024 && counter2 <= 1024) + return 1024; + + if(counter1 <= 2048 && counter2 <= 2048) + return 2048; + + return 4096; +} + /** * */ @@ -78,8 +131,9 @@ static errcode_t device_gekko_io_open(const char *name, int flags, io_channel *d return -1; } - struct ext2_super_block * super = (struct ext2_super_block *) mem_alloc(SUPERBLOCK_SIZE); //1024 bytes - if(!super) + // Allocate 4 x max sector size in case of 4096 sector size + u8 *buffer = (u8 *) mem_alloc(4 * MAX_SECTOR_SIZE); + if(!buffer) { ext2_log_trace("no memory for superblock"); errno = ENOMEM; @@ -87,44 +141,49 @@ static errcode_t device_gekko_io_open(const char *name, int flags, io_channel *d } // Check that there is a valid EXT boot sector at the start of the device - if (!interface->readSectors(fd->startSector+SUPERBLOCK_OFFSET/BYTES_PER_SECTOR, SUPERBLOCK_SIZE/BYTES_PER_SECTOR, super)) + if (!interface->readSectors(fd->startSector, 4, buffer)) { ext2_log_trace("read failure @ sector %d\n", fd->startSector); errno = EROFS; - mem_free(super); + mem_free(buffer); return -1; } + struct ext2_super_block * super = (struct ext2_super_block *) (buffer + SUPERBLOCK_OFFSET); + if(ext2fs_le16_to_cpu(super->s_magic) != EXT2_SUPER_MAGIC) { - mem_free(super); + ext2_log_trace("super mismatch: read %04X - expected %04X\n", ext2fs_le16_to_cpu(super->s_magic), EXT2_SUPER_MAGIC); + mem_free(buffer); errno = EROFS; return -1; } - // Parse the boot sector - fd->sectorSize = BYTES_PER_SECTOR; - fd->offset = 0; - fd->sectorCount = 0; - switch(ext2fs_le32_to_cpu(super->s_log_block_size)) { case 1: - fd->sectorCount = (sec_t) ((u64) ext2fs_le32_to_cpu(super->s_blocks_count) * (u64) 2048 / (u64) BYTES_PER_SECTOR); + (*dev)->block_size = 2048; break; case 2: - fd->sectorCount = (sec_t) ((u64) ext2fs_le32_to_cpu(super->s_blocks_count) * (u64) 4096 / (u64) BYTES_PER_SECTOR); + (*dev)->block_size = 4096; break; case 3: - fd->sectorCount = (sec_t) ((u64) ext2fs_le32_to_cpu(super->s_blocks_count) * (u64) 8192 / (u64) BYTES_PER_SECTOR); + (*dev)->block_size = 8192; break; default: case 0: - fd->sectorCount = (sec_t) ((u64) ext2fs_le32_to_cpu(super->s_blocks_count) * (u64) 1024 / (u64) BYTES_PER_SECTOR); + (*dev)->block_size = 1024; break; } - mem_free(super); + + // Parse the boot sector + fd->sectorSize = readSectorSize(interface); + fd->offset = 0; + fd->sectorCount = 0; + fd->sectorCount = (sec_t) ((u64) ext2fs_le32_to_cpu(super->s_blocks_count) * (u64) ((*dev)->block_size) / (u64) fd->sectorSize); + + mem_free(buffer); // Create the cache fd->cache = cache_constructor(fd->cachePageCount, fd->cachePageSize, interface, fd->startSector + fd->sectorCount, fd->sectorSize); diff --git a/portlibs/sources/libext2fs/source/gekko_io.h b/portlibs/sources/libcustomext2fs/source/gekko_io.h similarity index 98% rename from portlibs/sources/libext2fs/source/gekko_io.h rename to portlibs/sources/libcustomext2fs/source/gekko_io.h index 16786c7c..6d5b4fb1 100644 --- a/portlibs/sources/libext2fs/source/gekko_io.h +++ b/portlibs/sources/libcustomext2fs/source/gekko_io.h @@ -27,7 +27,7 @@ #include "disc_cache.h" #include "ext2fs.h" -#define BYTES_PER_SECTOR 512 +#define MAX_SECTOR_SIZE (4096) /** * gekko_fd - Gekko device driver descriptor diff --git a/portlibs/sources/libext2fs/source/gen_bitmap.c b/portlibs/sources/libcustomext2fs/source/gen_bitmap.c similarity index 99% rename from portlibs/sources/libext2fs/source/gen_bitmap.c rename to portlibs/sources/libcustomext2fs/source/gen_bitmap.c index 2ef1d826..6679bffa 100644 --- a/portlibs/sources/libext2fs/source/gen_bitmap.c +++ b/portlibs/sources/libcustomext2fs/source/gen_bitmap.c @@ -10,6 +10,7 @@ */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -25,7 +26,6 @@ #endif #include "ext2_fs.h" -#include "ext2fs.h" #include "ext2fsP.h" struct ext2fs_struct_generic_bitmap { @@ -179,8 +179,8 @@ int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap, #ifndef OMIT_COM_ERR com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP, "test_bitmap(%lu)", (unsigned long) bitno); - return 0; #endif + return 0; } if ((bitno < bitmap->start) || (bitno > bitmap->end)) { @@ -201,8 +201,8 @@ int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap, #ifndef OMIT_COM_ERR com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP, "mark_bitmap(%lu)", (unsigned long) bitno); - return 0; #endif + return 0; } if ((bitno < bitmap->start) || (bitno > bitmap->end)) { @@ -223,8 +223,8 @@ int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap, #ifndef OMIT_COM_ERR com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP, "mark_bitmap(%lu)", (unsigned long) bitno); - return 0; #endif + return 0; } if ((bitno < bitmap->start) || (bitno > bitmap->end)) { @@ -244,8 +244,8 @@ __u32 ext2fs_get_generic_bitmap_start(ext2fs_generic_bitmap bitmap) #ifndef OMIT_COM_ERR com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP, "get_bitmap_start"); - return 0; #endif + return 0; } return bitmap->start; @@ -261,8 +261,8 @@ __u32 ext2fs_get_generic_bitmap_end(ext2fs_generic_bitmap bitmap) #ifndef OMIT_COM_ERR com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP, "get_bitmap_end"); - return 0; #endif + return 0; } return bitmap->end; } @@ -278,8 +278,8 @@ void ext2fs_clear_generic_bitmap(ext2fs_generic_bitmap bitmap) #ifndef OMIT_COM_ERR com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP, "clear_generic_bitmap"); - return; #endif + return; } memset(bitmap->bitmap, 0, diff --git a/portlibs/sources/libext2fs/source/gen_bitmap64.c b/portlibs/sources/libcustomext2fs/source/gen_bitmap64.c similarity index 90% rename from portlibs/sources/libext2fs/source/gen_bitmap64.c rename to portlibs/sources/libcustomext2fs/source/gen_bitmap64.c index 9e7b2983..9dbbf9fb 100644 --- a/portlibs/sources/libext2fs/source/gen_bitmap64.c +++ b/portlibs/sources/libcustomext2fs/source/gen_bitmap64.c @@ -10,6 +10,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -107,12 +108,14 @@ errcode_t ext2fs_alloc_generic_bmap(ext2_filsys fs, errcode_t magic, bitmap->end = end; bitmap->real_end = real_end; bitmap->bitmap_ops = ops; + bitmap->cluster_bits = 0; switch (magic) { case EXT2_ET_MAGIC_INODE_BITMAP64: bitmap->base_error_code = EXT2_ET_BAD_INODE_MARK; break; case EXT2_ET_MAGIC_BLOCK_BITMAP64: bitmap->base_error_code = EXT2_ET_BAD_BLOCK_MARK; + bitmap->cluster_bits = fs->cluster_ratio_bits; break; default: bitmap->base_error_code = EXT2_ET_BAD_GENERIC_MARK; @@ -191,6 +194,7 @@ errcode_t ext2fs_copy_generic_bmap(ext2fs_generic_bitmap src, new_bmap->real_end = src->real_end; new_bmap->bitmap_ops = src->bitmap_ops; new_bmap->base_error_code = src->base_error_code; + new_bmap->cluster_bits = src->cluster_bits; descr = src->description; if (descr) { @@ -315,6 +319,8 @@ int ext2fs_mark_generic_bmap(ext2fs_generic_bitmap bitmap, if (!EXT2FS_IS_64_BITMAP(bitmap)) return 0; + arg >>= bitmap->cluster_bits; + if ((arg < bitmap->start) || (arg > bitmap->end)) { warn_bitmap(bitmap, EXT2FS_MARK_ERROR, arg); return 0; @@ -341,6 +347,8 @@ int ext2fs_unmark_generic_bmap(ext2fs_generic_bitmap bitmap, if (!EXT2FS_IS_64_BITMAP(bitmap)) return 0; + arg >>= bitmap->cluster_bits; + if ((arg < bitmap->start) || (arg > bitmap->end)) { warn_bitmap(bitmap, EXT2FS_UNMARK_ERROR, arg); return 0; @@ -367,6 +375,8 @@ int ext2fs_test_generic_bmap(ext2fs_generic_bitmap bitmap, if (!EXT2FS_IS_64_BITMAP(bitmap)) return 0; + arg >>= bitmap->cluster_bits; + if ((arg < bitmap->start) || (arg > bitmap->end)) { warn_bitmap(bitmap, EXT2FS_TEST_ERROR, arg); return 0; @@ -383,7 +393,7 @@ errcode_t ext2fs_set_generic_bmap_range(ext2fs_generic_bitmap bmap, return EINVAL; if (EXT2FS_IS_32_BITMAP(bmap)) { - if ((start+num) & ~0xffffffffULL) { + if ((start+num-1) & ~0xffffffffULL) { ext2fs_warn_bitmap2(bmap, EXT2FS_UNMARK_ERROR, 0xffffffff); return EINVAL; @@ -406,7 +416,7 @@ errcode_t ext2fs_get_generic_bmap_range(ext2fs_generic_bitmap bmap, return EINVAL; if (EXT2FS_IS_32_BITMAP(bmap)) { - if ((start+num) & ~0xffffffffULL) { + if ((start+num-1) & ~0xffffffffULL) { ext2fs_warn_bitmap2(bmap, EXT2FS_UNMARK_ERROR, 0xffffffff); return EINVAL; @@ -477,7 +487,7 @@ int ext2fs_test_block_bitmap_range2(ext2fs_block_bitmap bmap, bmap, block); if (EXT2FS_IS_32_BITMAP(bmap)) { - if ((block+num) & ~0xffffffffULL) { + if ((block+num-1) & ~0xffffffffULL) { ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap, EXT2FS_UNMARK_ERROR, 0xffffffff); return EINVAL; @@ -499,7 +509,7 @@ void ext2fs_mark_block_bitmap_range2(ext2fs_block_bitmap bmap, return; if (EXT2FS_IS_32_BITMAP(bmap)) { - if ((block+num) & ~0xffffffffULL) { + if ((block+num-1) & ~0xffffffffULL) { ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap, EXT2FS_UNMARK_ERROR, 0xffffffff); return; @@ -527,7 +537,7 @@ void ext2fs_unmark_block_bitmap_range2(ext2fs_block_bitmap bmap, return; if (EXT2FS_IS_32_BITMAP(bmap)) { - if ((block+num) & ~0xffffffffULL) { + if ((block+num-1) & ~0xffffffffULL) { ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap, EXT2FS_UNMARK_ERROR, 0xffffffff); return; @@ -548,7 +558,7 @@ void ext2fs_unmark_block_bitmap_range2(ext2fs_block_bitmap bmap, bmap->bitmap_ops->unmark_bmap_extent(bmap, block, num); } -int ext2fs_warn_bitmap32(ext2fs_generic_bitmap bitmap, const char *func) +void ext2fs_warn_bitmap32(ext2fs_generic_bitmap bitmap, const char *func) { #ifndef OMIT_COM_ERR if (bitmap && bitmap->description) @@ -559,5 +569,47 @@ int ext2fs_warn_bitmap32(ext2fs_generic_bitmap bitmap, const char *func) com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP, "called %s with 64-bit bitmap", func); #endif - return 0; +} + +errcode_t ext2fs_convert_subcluster_bitmap(ext2_filsys fs, + ext2fs_block_bitmap *bitmap) +{ + ext2fs_block_bitmap cmap, bmap; + errcode_t retval; + blk64_t i, b_end, c_end; + int n, ratio; + + bmap = *bitmap; + + if (fs->cluster_ratio_bits == ext2fs_get_bitmap_granularity(bmap)) + return 0; /* Nothing to do */ + + retval = ext2fs_allocate_block_bitmap(fs, "converted cluster bitmap", + &cmap); + if (retval) + return retval; + + i = bmap->start; + b_end = bmap->end; + bmap->end = bmap->real_end; + c_end = cmap->end; + cmap->end = cmap->real_end; + n = 0; + ratio = 1 << fs->cluster_ratio_bits; + while (i < bmap->real_end) { + if (ext2fs_test_block_bitmap2(bmap, i)) { + ext2fs_mark_block_bitmap2(cmap, i); + i += ratio - n; + n = 0; + continue; + } + i++; n++; + if (n >= ratio) + n = 0; + } + bmap->end = b_end; + cmap->end = c_end; + ext2fs_free_block_bitmap(bmap); + *bitmap = cmap; + return 0; } diff --git a/portlibs/sources/libext2fs/source/get_pathname.c b/portlibs/sources/libcustomext2fs/source/get_pathname.c similarity index 99% rename from portlibs/sources/libext2fs/source/get_pathname.c rename to portlibs/sources/libcustomext2fs/source/get_pathname.c index 7ac14db2..e259eee7 100644 --- a/portlibs/sources/libext2fs/source/get_pathname.c +++ b/portlibs/sources/libcustomext2fs/source/get_pathname.c @@ -21,6 +21,7 @@ * */ +#include "config.h" #include #include #if HAVE_UNISTD_H diff --git a/portlibs/sources/libext2fs/source/getsectsize.c b/portlibs/sources/libcustomext2fs/source/getsectsize.c similarity index 88% rename from portlibs/sources/libext2fs/source/getsectsize.c rename to portlibs/sources/libcustomext2fs/source/getsectsize.c index 64f42a62..30faecc7 100644 --- a/portlibs/sources/libext2fs/source/getsectsize.c +++ b/portlibs/sources/libcustomext2fs/source/getsectsize.c @@ -13,6 +13,7 @@ #define _LARGEFILE_SOURCE #define _LARGEFILE64_SOURCE +#include "config.h" #include #if HAVE_UNISTD_H #include @@ -45,11 +46,7 @@ errcode_t ext2fs_get_device_sectsize(const char *file, int *sectsize) { int fd; -#ifdef HAVE_OPEN64 - fd = open64(file, O_RDONLY); -#else - fd = open(file, O_RDONLY); -#endif + fd = ext2fs_open_file(file, O_RDONLY, 0); if (fd < 0) return errno; @@ -71,11 +68,7 @@ errcode_t ext2fs_get_device_phys_sectsize(const char *file, int *sectsize) { int fd; -#ifdef HAVE_OPEN64 - fd = open64(file, O_RDONLY); -#else - fd = open(file, O_RDONLY); -#endif + fd = ext2fs_open_file(file, O_RDONLY, 0); if (fd < 0) return errno; diff --git a/portlibs/sources/libext2fs/source/getsize.c b/portlibs/sources/libcustomext2fs/source/getsize.c similarity index 96% rename from portlibs/sources/libext2fs/source/getsize.c rename to portlibs/sources/libcustomext2fs/source/getsize.c index 56ec4b69..1e0ed16f 100644 --- a/portlibs/sources/libext2fs/source/getsize.c +++ b/portlibs/sources/libcustomext2fs/source/getsize.c @@ -15,6 +15,7 @@ #define _LARGEFILE_SOURCE #define _LARGEFILE64_SOURCE +#include "config.h" #include #if HAVE_UNISTD_H #include @@ -142,10 +143,12 @@ errcode_t ext2fs_get_device_size2(const char *file, int blocksize, blk64_t *retblocks) { int fd, rc = 0; + int valid_blkgetsize64 = 1; #ifdef __linux__ struct utsname ut; #endif unsigned long long size64; + unsigned long size; ext2_loff_t high, low; #ifdef FDGETPRM struct floppy_struct this_floppy; @@ -157,11 +160,7 @@ errcode_t ext2fs_get_device_size2(const char *file, int blocksize, char ch; #endif /* HAVE_SYS_DISKLABEL_H */ -#ifdef HAVE_OPEN64 - fd = open64(file, O_RDONLY); -#else - fd = open(file, O_RDONLY); -#endif + fd = ext2fs_open_file(file, O_RDONLY, 0); if (fd < 0) return errno; @@ -233,13 +232,9 @@ errcode_t ext2fs_get_device_size2(const char *file, int blocksize, #endif /* HAVE_SYS_DISKLABEL_H */ { -#ifdef HAVE_FSTAT64 - struct stat64 st; - if (fstat64(fd, &st) == 0) -#else - struct stat st; - if (fstat(fd, &st) == 0) -#endif + ext2fs_struct_stat st; + + if (ext2fs_fstat(fd, &st) == 0) if (S_ISREG(st.st_mode)) { *retblocks = st.st_size / blocksize; goto out; diff --git a/portlibs/sources/libext2fs/source/i_block.c b/portlibs/sources/libcustomext2fs/source/i_block.c similarity index 94% rename from portlibs/sources/libext2fs/source/i_block.c rename to portlibs/sources/libcustomext2fs/source/i_block.c index 39d93eec..5ca57e49 100644 --- a/portlibs/sources/libext2fs/source/i_block.c +++ b/portlibs/sources/libcustomext2fs/source/i_block.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #if HAVE_UNISTD_H #include @@ -38,6 +39,7 @@ errcode_t ext2fs_iblk_add_blocks(ext2_filsys fs, struct ext2_inode *inode, EXT4_FEATURE_RO_COMPAT_HUGE_FILE) || !(inode->i_flags & EXT4_HUGE_FILE_FL)) num_blocks *= fs->blocksize / 512; + num_blocks *= EXT2FS_CLUSTER_RATIO(fs); b += num_blocks; @@ -61,6 +63,7 @@ errcode_t ext2fs_iblk_sub_blocks(ext2_filsys fs, struct ext2_inode *inode, EXT4_FEATURE_RO_COMPAT_HUGE_FILE) || !(inode->i_flags & EXT4_HUGE_FILE_FL)) num_blocks *= fs->blocksize / 512; + num_blocks *= EXT2FS_CLUSTER_RATIO(fs); if (num_blocks > b) return EOVERFLOW; @@ -79,6 +82,7 @@ errcode_t ext2fs_iblk_set(ext2_filsys fs, struct ext2_inode *inode, blk64_t b) EXT4_FEATURE_RO_COMPAT_HUGE_FILE) || !(inode->i_flags & EXT4_HUGE_FILE_FL)) b *= fs->blocksize / 512; + b *= EXT2FS_CLUSTER_RATIO(fs); inode->i_blocks = b & 0xFFFFFFFF; if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE) diff --git a/portlibs/sources/libext2fs/source/icount.c b/portlibs/sources/libcustomext2fs/source/icount.c similarity index 97% rename from portlibs/sources/libext2fs/source/icount.c rename to portlibs/sources/libcustomext2fs/source/icount.c index 43cc53e1..5d64ac43 100644 --- a/portlibs/sources/libext2fs/source/icount.c +++ b/portlibs/sources/libcustomext2fs/source/icount.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #if HAVE_UNISTD_H #include #endif @@ -179,6 +180,7 @@ errcode_t ext2fs_create_icount_tdb(ext2_filsys fs, char *tdb_dir, ext2_icount_t icount; errcode_t retval; char *fn, uuid[40]; + ext2_ino_t num_inodes; int fd; retval = alloc_icount(fs, flags, &icount); @@ -192,8 +194,18 @@ errcode_t ext2fs_create_icount_tdb(ext2_filsys fs, char *tdb_dir, sprintf(fn, "%s/%s-icount-XXXXXX", tdb_dir, uuid); fd = mkstemp(fn); + /* + * This is an overestimate of the size that we will need; the + * ideal value is the number of used inodes with a count + * greater than 1. OTOH the times when we really need this is + * with the backup programs that use lots of hard links, in + * which case the number of inodes in use approaches the ideal + * value. + */ + num_inodes = fs->super->s_inodes_count - fs->super->s_free_inodes_count; + icount->tdb_fn = fn; - icount->tdb = tdb_open(fn, 0, TDB_CLEAR_IF_FIRST, + icount->tdb = tdb_open(fn, num_inodes, TDB_NOLOCK | TDB_NOSYNC, O_RDWR | O_CREAT | O_TRUNC, 0600); if (icount->tdb) { close(fd); @@ -363,31 +375,7 @@ static struct ext2_icount_el *get_icount_el(ext2_icount_t icount, low = 0; high = (int) icount->count-1; while (low <= high) { -#if 0 - mid = (low+high)/2; -#else - if (low == high) - mid = low; - else { - /* Interpolate for efficiency */ - lowval = icount->list[low].ino; - highval = icount->list[high].ino; - - if (ino < lowval) - range = 0; - else if (ino > highval) - range = 1; - else { - range = ((float) (ino - lowval)) / - (highval - lowval); - if (range > 0.9) - range = 0.9; - if (range < 0.1) - range = 0.1; - } - mid = low + ((int) (range * (high-low))); - } -#endif + mid = ((unsigned)low + (unsigned)high) >> 1; if (ino == icount->list[mid].ino) { icount->cursor = mid+1; return &icount->list[mid]; diff --git a/portlibs/sources/libext2fs/source/imager.c b/portlibs/sources/libcustomext2fs/source/imager.c similarity index 99% rename from portlibs/sources/libext2fs/source/imager.c rename to portlibs/sources/libcustomext2fs/source/imager.c index 5a6d0b95..a0fb81e4 100644 --- a/portlibs/sources/libext2fs/source/imager.c +++ b/portlibs/sources/libcustomext2fs/source/imager.c @@ -13,6 +13,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H diff --git a/portlibs/sources/libext2fs/source/ind_block.c b/portlibs/sources/libcustomext2fs/source/ind_block.c similarity index 98% rename from portlibs/sources/libext2fs/source/ind_block.c rename to portlibs/sources/libcustomext2fs/source/ind_block.c index 722d3bdc..aa82ae6b 100644 --- a/portlibs/sources/libext2fs/source/ind_block.c +++ b/portlibs/sources/libcustomext2fs/source/ind_block.c @@ -10,6 +10,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H diff --git a/portlibs/sources/libext2fs/source/initialize.c b/portlibs/sources/libcustomext2fs/source/initialize.c similarity index 85% rename from portlibs/sources/libext2fs/source/initialize.c rename to portlibs/sources/libcustomext2fs/source/initialize.c index 4706773a..b050a0a9 100644 --- a/portlibs/sources/libext2fs/source/initialize.c +++ b/portlibs/sources/libcustomext2fs/source/initialize.c @@ -10,6 +10,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -91,9 +92,11 @@ errcode_t ext2fs_initialize(const char *name, int flags, unsigned int overhead = 0; unsigned int ipg; dgrp_t i; + blk64_t free_blocks; blk_t numblocks; int rsv_gdt; int csum_flag; + int bigalloc_flag; int io_flags; char *buf = 0; char c; @@ -134,13 +137,26 @@ errcode_t ext2fs_initialize(const char *name, int flags, #define set_field(field, default) (super->field = param->field ? \ param->field : (default)) +#define assign_field(field) (super->field = param->field) super->s_magic = EXT2_SUPER_MAGIC; super->s_state = EXT2_VALID_FS; - set_field(s_log_block_size, 0); /* default blocksize: 1024 bytes */ - set_field(s_log_cluster_size, 0); - set_field(s_first_data_block, super->s_log_block_size ? 0 : 1); + bigalloc_flag = EXT2_HAS_RO_COMPAT_FEATURE(param, + EXT4_FEATURE_RO_COMPAT_BIGALLOC); + + assign_field(s_log_block_size); + + if (bigalloc_flag) { + set_field(s_log_cluster_size, super->s_log_block_size+4); + if (super->s_log_block_size > super->s_log_cluster_size) { + retval = EXT2_ET_INVALID_ARGUMENT; + goto cleanup; + } + } else + super->s_log_cluster_size = super->s_log_block_size; + + set_field(s_first_data_block, super->s_log_cluster_size ? 0 : 1); set_field(s_max_mnt_count, 0); set_field(s_errors, EXT2_ERRORS_DEFAULT); set_field(s_feature_compat, 0); @@ -181,16 +197,39 @@ errcode_t ext2fs_initialize(const char *name, int flags, super->s_creator_os = CREATOR_OS; - fs->blocksize = EXT2_BLOCK_SIZE(super); - fs->clustersize = EXT2_CLUSTER_SIZE(super); + fs->fragsize = fs->blocksize = EXT2_BLOCK_SIZE(super); + fs->cluster_ratio_bits = super->s_log_cluster_size - + super->s_log_block_size; - /* default: (fs->blocksize*8) blocks/group, up to 2^16 (GDT limit) */ - set_field(s_blocks_per_group, fs->blocksize * 8); - if (super->s_blocks_per_group > EXT2_MAX_BLOCKS_PER_GROUP(super)) - super->s_blocks_per_group = EXT2_MAX_BLOCKS_PER_GROUP(super); - super->s_clusters_per_group = super->s_blocks_per_group; + if (bigalloc_flag) { + if (param->s_blocks_per_group && + param->s_clusters_per_group && + ((param->s_clusters_per_group * EXT2FS_CLUSTER_RATIO(fs)) != + param->s_blocks_per_group)) { + retval = EXT2_ET_INVALID_ARGUMENT; + goto cleanup; + } + if (param->s_clusters_per_group) + assign_field(s_clusters_per_group); + else if (param->s_blocks_per_group) + super->s_clusters_per_group = + param->s_blocks_per_group / + EXT2FS_CLUSTER_RATIO(fs); + else + super->s_clusters_per_group = fs->blocksize * 8; + if (super->s_clusters_per_group > EXT2_MAX_CLUSTERS_PER_GROUP(super)) + super->s_clusters_per_group = EXT2_MAX_CLUSTERS_PER_GROUP(super); + super->s_blocks_per_group = EXT2FS_C2B(fs, + super->s_clusters_per_group); + } else { + set_field(s_blocks_per_group, fs->blocksize * 8); + if (super->s_blocks_per_group > EXT2_MAX_BLOCKS_PER_GROUP(super)) + super->s_blocks_per_group = EXT2_MAX_BLOCKS_PER_GROUP(super); + super->s_clusters_per_group = super->s_blocks_per_group; + } - ext2fs_blocks_count_set(super, ext2fs_blocks_count(param)); + ext2fs_blocks_count_set(super, ext2fs_blocks_count(param) & + ~((blk64_t) EXT2FS_CLUSTER_MASK(fs))); ext2fs_r_blocks_count_set(super, ext2fs_r_blocks_count(param)); if (ext2fs_r_blocks_count(super) >= ext2fs_blocks_count(param)) { retval = EXT2_ET_INVALID_ARGUMENT; @@ -209,7 +248,7 @@ errcode_t ext2fs_initialize(const char *name, int flags, } retry: - fs->group_desc_count = (blk_t) ext2fs_div64_ceil( + fs->group_desc_count = (dgrp_t) ext2fs_div64_ceil( ext2fs_blocks_count(super) - super->s_first_data_block, EXT2_BLOCKS_PER_GROUP(super)); if (fs->group_desc_count == 0) { @@ -246,7 +285,7 @@ retry: */ ipg = ext2fs_div_ceil(super->s_inodes_count, fs->group_desc_count); if (ipg > fs->blocksize * 8) { - if (super->s_blocks_per_group >= 256) { + if (!bigalloc_flag && super->s_blocks_per_group >= 256) { /* Try again with slightly different parameters */ super->s_blocks_per_group -= 8; ext2fs_blocks_count_set(super, @@ -364,7 +403,7 @@ ipg_retry: strcpy(buf, "block bitmap for "); strcat(buf, fs->device_name); - retval = ext2fs_allocate_block_bitmap(fs, buf, &fs->block_map); + retval = ext2fs_allocate_subcluster_bitmap(fs, buf, &fs->block_map); if (retval) goto cleanup; @@ -394,7 +433,7 @@ ipg_retry: * superblock and group descriptors (the inode tables and * bitmaps will be accounted for when allocated). */ - ext2fs_free_blocks_count_set(super, 0); + free_blocks = 0; csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(fs->super, EXT4_FEATURE_RO_COMPAT_GDT_CSUM); for (i = 0; i < fs->group_desc_count; i++) { @@ -416,14 +455,14 @@ ipg_retry: if (fs->super->s_log_groups_per_flex) numblocks += 2 + fs->inode_blocks_per_group; - ext2fs_free_blocks_count_set(super, - ext2fs_free_blocks_count(super) + - numblocks); + free_blocks += numblocks; ext2fs_bg_free_blocks_count_set(fs, i, numblocks); ext2fs_bg_free_inodes_count_set(fs, i, fs->super->s_inodes_per_group); ext2fs_bg_used_dirs_count_set(fs, i, 0); ext2fs_group_desc_csum_set(fs, i); } + free_blocks &= ~EXT2FS_CLUSTER_MASK(fs); + ext2fs_free_blocks_count_set(super, free_blocks); c = (char) 255; if (((int) c) == -1) { diff --git a/portlibs/sources/libcustomext2fs/source/inline.c b/portlibs/sources/libcustomext2fs/source/inline.c new file mode 100644 index 00000000..556e0d67 --- /dev/null +++ b/portlibs/sources/libcustomext2fs/source/inline.c @@ -0,0 +1,72 @@ +/* + * inline.c --- Includes the inlined functions defined in the header + * files as standalone functions, in case the application program + * is compiled with inlining turned off. + * + * Copyright (C) 1993, 1994 Theodore Ts'o. + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Library + * General Public License, version 2. + * %End-Header% + */ + + +#include "config.h" +#include +#include +#if HAVE_UNISTD_H +#include +#endif +#include +#include +#if HAVE_SYS_STAT_H +#include +#endif +#if HAVE_SYS_TYPES_H +#include +#endif + +#include "ext2_fs.h" +#define INCLUDE_INLINE_FUNCS +#include "ext2fs.h" + +#include "mem_allocate.h" + +/* + * We used to define this as an inline, but since we are now using + * autoconf-defined #ifdef's, we need to export this as a + * library-provided function exclusively. + */ +errcode_t ext2fs_get_memalign(unsigned long size, + unsigned long align, void *ptr) +{ + errcode_t retval; + + if (align == 0) + align = 8; +#ifdef HAVE_POSIX_MEMALIGN + retval = posix_memalign((void **) ptr, align, size); + if (retval) { + if (retval == ENOMEM) + return EXT2_ET_NO_MEMORY; + return retval; + } +#else +#ifdef HAVE_MEMALIGN + void *pp; + pp = mem_align(align, size); + if (pp == NULL) { + if (errno) + return errno; + else + return EXT2_ET_NO_MEMORY; + } + memcpy(ptr, &pp, sizeof (pp)); +#else +#error memalign or posix_memalign must be defined! +#endif +#endif + return 0; +} + diff --git a/portlibs/sources/libext2fs/source/inode.c b/portlibs/sources/libcustomext2fs/source/inode.c similarity index 99% rename from portlibs/sources/libext2fs/source/inode.c rename to portlibs/sources/libcustomext2fs/source/inode.c index a762dbce..6c524ff2 100644 --- a/portlibs/sources/libext2fs/source/inode.c +++ b/portlibs/sources/libcustomext2fs/source/inode.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -522,7 +523,8 @@ errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ext2_ino_t *ino, errcode_t ext2fs_read_inode_full(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode * inode, int bufsize) { - unsigned long group, block, block_nr, offset; + blk64_t block_nr; + unsigned long group, block, offset; char *ptr; errcode_t retval; int clen, i, inodes_per_block, length; @@ -628,7 +630,8 @@ errcode_t ext2fs_read_inode(ext2_filsys fs, ext2_ino_t ino, errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode * inode, int bufsize) { - unsigned long group, block, block_nr, offset; + blk64_t block_nr; + unsigned long group, block, offset; errcode_t retval = 0; struct ext2_inode_large temp_inode, *w_inode; char *ptr; @@ -669,8 +672,10 @@ errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino, if (length > (int) sizeof(struct ext2_inode_large)) { w_inode = malloc(length); - if (!w_inode) - return ENOMEM; + if (!w_inode) { + retval = ENOMEM; + goto errout; + } } else w_inode = &temp_inode; memset(w_inode, 0, length); diff --git a/portlibs/sources/libext2fs/source/inode_io.c b/portlibs/sources/libcustomext2fs/source/inode_io.c similarity index 99% rename from portlibs/sources/libext2fs/source/inode_io.c rename to portlibs/sources/libcustomext2fs/source/inode_io.c index b3e7ce51..8e0944ef 100644 --- a/portlibs/sources/libext2fs/source/inode_io.c +++ b/portlibs/sources/libcustomext2fs/source/inode_io.c @@ -10,6 +10,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -163,7 +164,7 @@ static errcode_t inode_open(const char *name, int flags, io_channel *channel) return 0; cleanup: - if (io->name) + if (io && io->name) ext2fs_free_mem(&io->name); if (data) ext2fs_free_mem(&data); diff --git a/portlibs/sources/libext2fs/source/io_manager.c b/portlibs/sources/libcustomext2fs/source/io_manager.c similarity index 99% rename from portlibs/sources/libext2fs/source/io_manager.c rename to portlibs/sources/libcustomext2fs/source/io_manager.c index 80f9dfcb..25df59ec 100644 --- a/portlibs/sources/libext2fs/source/io_manager.c +++ b/portlibs/sources/libcustomext2fs/source/io_manager.c @@ -2,6 +2,7 @@ * io_manager.c --- the I/O manager abstraction */ +#include "config.h" #include #include #if HAVE_UNISTD_H diff --git a/portlibs/sources/libext2fs/source/irel.h b/portlibs/sources/libcustomext2fs/source/irel.h similarity index 100% rename from portlibs/sources/libext2fs/source/irel.h rename to portlibs/sources/libcustomext2fs/source/irel.h diff --git a/portlibs/sources/libext2fs/source/irel_ma.c b/portlibs/sources/libcustomext2fs/source/irel_ma.c similarity index 99% rename from portlibs/sources/libext2fs/source/irel_ma.c rename to portlibs/sources/libcustomext2fs/source/irel_ma.c index b7eaf6b5..4cef0ac1 100644 --- a/portlibs/sources/libext2fs/source/irel_ma.c +++ b/portlibs/sources/libcustomext2fs/source/irel_ma.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #include diff --git a/portlibs/sources/libext2fs/source/ismounted.c b/portlibs/sources/libcustomext2fs/source/ismounted.c similarity index 99% rename from portlibs/sources/libext2fs/source/ismounted.c rename to portlibs/sources/libcustomext2fs/source/ismounted.c index bc1134fc..89d0d9a0 100644 --- a/portlibs/sources/libext2fs/source/ismounted.c +++ b/portlibs/sources/libcustomext2fs/source/ismounted.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #if HAVE_UNISTD_H #include diff --git a/portlibs/sources/libext2fs/source/jfs_compat.h b/portlibs/sources/libcustomext2fs/source/jfs_compat.h similarity index 100% rename from portlibs/sources/libext2fs/source/jfs_compat.h rename to portlibs/sources/libcustomext2fs/source/jfs_compat.h diff --git a/portlibs/sources/libext2fs/source/jfs_dat.h b/portlibs/sources/libcustomext2fs/source/jfs_dat.h similarity index 100% rename from portlibs/sources/libext2fs/source/jfs_dat.h rename to portlibs/sources/libcustomext2fs/source/jfs_dat.h diff --git a/portlibs/sources/libext2fs/source/jfs_user.h b/portlibs/sources/libcustomext2fs/source/jfs_user.h similarity index 100% rename from portlibs/sources/libext2fs/source/jfs_user.h rename to portlibs/sources/libcustomext2fs/source/jfs_user.h diff --git a/portlibs/sources/libext2fs/source/kernel-jbd.h b/portlibs/sources/libcustomext2fs/source/kernel-jbd.h similarity index 100% rename from portlibs/sources/libext2fs/source/kernel-jbd.h rename to portlibs/sources/libcustomext2fs/source/kernel-jbd.h diff --git a/portlibs/sources/libext2fs/source/kernel-list.h b/portlibs/sources/libcustomext2fs/source/kernel-list.h similarity index 100% rename from portlibs/sources/libext2fs/source/kernel-list.h rename to portlibs/sources/libcustomext2fs/source/kernel-list.h diff --git a/portlibs/sources/libext2fs/source/link.c b/portlibs/sources/libcustomext2fs/source/link.c similarity index 96% rename from portlibs/sources/libext2fs/source/link.c rename to portlibs/sources/libcustomext2fs/source/link.c index 4cc8426a..2d03b573 100644 --- a/portlibs/sources/libext2fs/source/link.c +++ b/portlibs/sources/libcustomext2fs/source/link.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -52,9 +53,9 @@ static int link_proc(struct ext2_dir_entry *dirent, * if so, absorb it into this one. */ next = (struct ext2_dir_entry *) (buf + offset + curr_rec_len); - if ((offset + curr_rec_len < blocksize - 8) && + if ((offset + (int) curr_rec_len < blocksize - 8) && (next->inode == 0) && - (offset + curr_rec_len + next->rec_len <= blocksize)) { + (offset + (int) curr_rec_len + (int) next->rec_len <= blocksize)) { curr_rec_len += next->rec_len; ls->err = ext2fs_set_rec_len(ls->fs, curr_rec_len, dirent); if (ls->err) diff --git a/portlibs/sources/libext2fs/source/llseek.c b/portlibs/sources/libcustomext2fs/source/llseek.c similarity index 99% rename from portlibs/sources/libext2fs/source/llseek.c rename to portlibs/sources/libcustomext2fs/source/llseek.c index 3b919bef..6cf81b3e 100644 --- a/portlibs/sources/libext2fs/source/llseek.c +++ b/portlibs/sources/libcustomext2fs/source/llseek.c @@ -12,6 +12,7 @@ #define _LARGEFILE_SOURCE #define _LARGEFILE64_SOURCE +#include "config.h" #if HAVE_SYS_TYPES_H #include #endif diff --git a/portlibs/sources/libext2fs/source/lookup.c b/portlibs/sources/libcustomext2fs/source/lookup.c similarity index 98% rename from portlibs/sources/libext2fs/source/lookup.c rename to portlibs/sources/libcustomext2fs/source/lookup.c index 97aa0887..0e66e712 100644 --- a/portlibs/sources/libext2fs/source/lookup.c +++ b/portlibs/sources/libcustomext2fs/source/lookup.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H diff --git a/portlibs/sources/libext2fs/source/mem2.h b/portlibs/sources/libcustomext2fs/source/mem2.h similarity index 100% rename from portlibs/sources/libext2fs/source/mem2.h rename to portlibs/sources/libcustomext2fs/source/mem2.h diff --git a/portlibs/sources/libext2fs/source/mem_allocate.h b/portlibs/sources/libcustomext2fs/source/mem_allocate.h similarity index 77% rename from portlibs/sources/libext2fs/source/mem_allocate.h rename to portlibs/sources/libcustomext2fs/source/mem_allocate.h index 4554b8b4..750ef0d3 100644 --- a/portlibs/sources/libext2fs/source/mem_allocate.h +++ b/portlibs/sources/libcustomext2fs/source/mem_allocate.h @@ -8,6 +8,14 @@ extern __inline__ void* mem_alloc (size_t size) { return MEM2_alloc(size); } +extern __inline__ void* mem_calloc (size_t count, size_t size) { + void *p = MEM2_alloc(count * size); + if(p) { + memset(p, 0, count * size); + } + return p; +} + extern __inline__ void* mem_realloc (void *p, size_t size) { return MEM2_realloc(p, size); } diff --git a/portlibs/sources/libext2fs/source/mkdir.c b/portlibs/sources/libcustomext2fs/source/mkdir.c similarity index 85% rename from portlibs/sources/libext2fs/source/mkdir.c rename to portlibs/sources/libcustomext2fs/source/mkdir.c index 86c65da9..b12bf2dd 100644 --- a/portlibs/sources/libext2fs/source/mkdir.c +++ b/portlibs/sources/libcustomext2fs/source/mkdir.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -33,6 +34,7 @@ errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum, const char *name) { + ext2_extent_handle_t handle; errcode_t retval; struct ext2_inode parent_inode, inode; ext2_ino_t ino = inum; @@ -83,8 +85,10 @@ errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum, inode.i_mode = LINUX_S_IFDIR | (0777 & ~fs->umask); inode.i_uid = inode.i_gid = 0; ext2fs_iblk_set(fs, &inode, 1); - /* FIXME-64 */ - inode.i_block[0] = blk; + if (fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS) + inode.i_flags |= EXT4_EXTENTS_FL; + else + inode.i_block[0] = blk; inode.i_links_count = 2; inode.i_size = fs->blocksize; @@ -98,6 +102,16 @@ errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum, if (retval) goto cleanup; + if (fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS) { + retval = ext2fs_extent_open2(fs, ino, &inode, &handle); + if (retval) + goto cleanup; + retval = ext2fs_extent_set_bmap(handle, 0, blk, 0); + ext2fs_extent_free(handle); + if (retval) + goto cleanup; + } + /* * Link the directory into the filesystem hierarchy */ diff --git a/portlibs/sources/libext2fs/source/mkjournal.c b/portlibs/sources/libcustomext2fs/source/mkjournal.c similarity index 86% rename from portlibs/sources/libext2fs/source/mkjournal.c rename to portlibs/sources/libcustomext2fs/source/mkjournal.c index 47fb92c2..81639ac6 100644 --- a/portlibs/sources/libext2fs/source/mkjournal.c +++ b/portlibs/sources/libcustomext2fs/source/mkjournal.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -44,13 +45,13 @@ * returns it as an allocated block. */ errcode_t ext2fs_create_journal_superblock(ext2_filsys fs, - __u32 size, int flags, + __u32 num_blocks, int flags, char **ret_jsb) { errcode_t retval; journal_superblock_t *jsb; - if (size < 1024) + if (num_blocks < 1024) return EXT2_ET_JOURNAL_TOO_SMALL; if ((retval = ext2fs_get_mem(fs->blocksize, &jsb))) @@ -64,7 +65,7 @@ errcode_t ext2fs_create_journal_superblock(ext2_filsys fs, else jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2); jsb->s_blocksize = htonl(fs->blocksize); - jsb->s_maxlen = htonl(size); + jsb->s_maxlen = htonl(num_blocks); jsb->s_nr_users = htonl(1); jsb->s_first = htonl(1); jsb->s_sequence = htonl(1); @@ -92,20 +93,21 @@ errcode_t ext2fs_create_journal_superblock(ext2_filsys fs, * filesystems. */ static errcode_t write_journal_file(ext2_filsys fs, char *filename, - blk_t size, int flags) + blk_t num_blocks, int flags) { errcode_t retval; char *buf = 0; int fd, ret_size; blk_t i; - if ((retval = ext2fs_create_journal_superblock(fs, size, flags, &buf))) + if ((retval = ext2fs_create_journal_superblock(fs, num_blocks, flags, + &buf))) return retval; /* Open the device or journal file */ if ((fd = open(filename, O_WRONLY)) < 0) { retval = errno; - goto errout; + goto errfree; } /* Write the superblock out */ @@ -119,7 +121,10 @@ static errcode_t write_journal_file(ext2_filsys fs, char *filename, goto errout; memset(buf, 0, fs->blocksize); - for (i = 1; i < size; i++) { + if (flags & EXT2_MKJOURNAL_LAZYINIT) + goto success; + + for (i = 1; i < num_blocks; i++) { ret_size = write(fd, buf, fs->blocksize); if (ret_size < 0) { retval = errno; @@ -128,10 +133,12 @@ static errcode_t write_journal_file(ext2_filsys fs, char *filename, if (ret_size != (int) fs->blocksize) goto errout; } - close(fd); +success: retval = 0; errout: + close(fd); +errfree: ext2fs_free_mem(&buf); return retval; } @@ -215,6 +222,7 @@ struct mkjournal_struct { blk64_t goal; blk64_t blk_to_zero; int zero_count; + int flags; char *buf; errcode_t err; }; @@ -234,19 +242,25 @@ static int mkjournal_proc(ext2_filsys fs, es->goal = *blocknr; return 0; } - retval = ext2fs_new_block2(fs, es->goal, 0, &new_blk); - if (retval) { - es->err = retval; - return BLOCK_ABORT; + if (blockcnt && + (EXT2FS_B2C(fs, es->goal) == EXT2FS_B2C(fs, es->goal+1))) + new_blk = es->goal+1; + else { + es->goal &= ~EXT2FS_CLUSTER_MASK(fs); + retval = ext2fs_new_block2(fs, es->goal, 0, &new_blk); + if (retval) { + es->err = retval; + return BLOCK_ABORT; + } + es->newblocks++; } if (blockcnt >= 0) es->num_blocks--; - es->newblocks++; retval = 0; if (blockcnt <= 0) retval = io_channel_write_blk64(fs->io, new_blk, 1, es->buf); - else { + else if (!(es->flags & EXT2_MKJOURNAL_LAZYINIT)) { if (es->zero_count) { if ((es->blk_to_zero + es->zero_count == new_blk) && (es->zero_count < 1024)) @@ -286,15 +300,17 @@ static int mkjournal_proc(ext2_filsys fs, * This function creates a journal using direct I/O routines. */ static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino, - blk64_t size, int flags) + blk_t num_blocks, int flags) { char *buf; dgrp_t group, start, end, i, log_flex; errcode_t retval; struct ext2_inode inode; + unsigned long long inode_size; struct mkjournal_struct es; - if ((retval = ext2fs_create_journal_superblock(fs, size, flags, &buf))) + if ((retval = ext2fs_create_journal_superblock(fs, num_blocks, flags, + &buf))) return retval; if ((retval = ext2fs_read_bitmaps(fs))) @@ -306,10 +322,11 @@ static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino, if (inode.i_blocks > 0) return EEXIST; - es.num_blocks = size; + es.num_blocks = num_blocks; es.newblocks = 0; es.buf = buf; es.err = 0; + es.flags = flags; es.zero_count = 0; if (fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS) { @@ -362,7 +379,12 @@ static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino, if ((retval = ext2fs_read_inode(fs, journal_ino, &inode))) goto errout; - inode.i_size += fs->blocksize * size; + inode_size = (unsigned long long)fs->blocksize * num_blocks; + inode.i_size = inode_size & 0xFFFFFFFF; + inode.i_size_high = (inode_size >> 32) & 0xFFFFFFFF; + if (inode.i_size_high) + fs->super->s_feature_ro_compat |= + EXT2_FEATURE_RO_COMPAT_LARGE_FILE; ext2fs_iblk_add_blocks(fs, &inode, es.newblocks); inode.i_mtime = inode.i_ctime = fs->now ? fs->now : time(0); inode.i_links_count = 1; @@ -373,12 +395,13 @@ static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino, retval = 0; memcpy(fs->super->s_jnl_blocks, inode.i_block, EXT2_N_BLOCKS*4); + fs->super->s_jnl_blocks[15] = inode.i_size_high; fs->super->s_jnl_blocks[16] = inode.i_size; fs->super->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS; ext2fs_mark_super_dirty(fs); errout: - ext2fs_zero_blocks2(0, 0, 0, 0, 0); + ext2fs_zero_blocks2(0, 0, 0, 0, 0); ext2fs_free_mem(&buf); return retval; } @@ -388,17 +411,17 @@ errout: * in the filesystem. For very small filesystems, it is not reasonable to * have a journal that fills more than half of the filesystem. */ -int ext2fs_default_journal_size(__u64 blocks) +int ext2fs_default_journal_size(__u64 num_blocks) { - if (blocks < 2048) + if (num_blocks < 2048) return -1; - if (blocks < 32768) + if (num_blocks < 32768) return (1024); - if (blocks < 256*1024) + if (num_blocks < 256*1024) return (4096); - if (blocks < 512*1024) + if (num_blocks < 512*1024) return (8192); - if (blocks < 1024*1024) + if (num_blocks < 1024*1024) return (16384); return 32768; } @@ -469,13 +492,13 @@ errcode_t ext2fs_add_journal_device(ext2_filsys fs, ext2_filsys journal_dev) * POSIX routines if the filesystem is mounted, or using direct I/O * functions if it is not. */ -errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t size, int flags) +errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t num_blocks, int flags) { errcode_t retval; ext2_ino_t journal_ino; struct stat st; char jfile[1024]; - int mount_flags; + int mount_flags, f; int fd = -1; if ((retval = ext2fs_check_mount_point(fs->device_name, &mount_flags, @@ -506,7 +529,14 @@ errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t size, int flags) if ((fd = open(jfile, O_CREAT|O_WRONLY, 0600)) < 0) return errno; - if ((retval = write_journal_file(fs, jfile, size, flags))) + /* Note that we can't do lazy journal initialization for mounted + * filesystems, since the zero writing is also allocating the + * journal blocks. We could use fallocate, but not all kernels + * support that, and creating a journal on a mounted ext2 + * filesystems is extremely rare these days... Ignore it. */ + flags &= ~EXT2_MKJOURNAL_LAZYINIT; + + if ((retval = write_journal_file(fs, jfile, num_blocks, flags))) goto errout; /* Get inode number of the journal file */ @@ -546,7 +576,7 @@ errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t size, int flags) } journal_ino = EXT2_JOURNAL_INO; if ((retval = write_journal_inode(fs, journal_ino, - size, flags))) + num_blocks, flags))) return retval; } @@ -569,7 +599,7 @@ main(int argc, char **argv) { errcode_t retval; char *device_name; - ext2_filsys fs; + ext2_filsys fs; if (argc < 2) { fprintf(stderr, "Usage: %s filesystem\n", argv[0]); diff --git a/portlibs/sources/libcustomext2fs/source/mmp.c b/portlibs/sources/libcustomext2fs/source/mmp.c new file mode 100644 index 00000000..dbbbdb2b --- /dev/null +++ b/portlibs/sources/libcustomext2fs/source/mmp.c @@ -0,0 +1,417 @@ +/* + * Helper functions for multiple mount protection (MMP). + * + * Copyright (C) 2011 Whamcloud, Inc. + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Public + * License. + * %End-Header% + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include "config.h" +#if HAVE_UNISTD_H +#include +#endif +#include + +#include +#include +#include + +#include "ext2_fs.h" +#include "ext2fs.h" + +#undef _SC_PAGESIZE + +static int mmp_pagesize(void) +{ +#ifdef _SC_PAGESIZE + int sysval = sysconf(_SC_PAGESIZE); + if (sysval > 0) + return sysval; +#endif /* _SC_PAGESIZE */ +#ifdef HAVE_GETPAGESIZE + return getpagesize(); +#else + return 4096; +#endif +} + +#ifndef O_DIRECT +#define O_DIRECT 0 +#endif + +errcode_t ext2fs_mmp_read(ext2_filsys fs, blk64_t mmp_blk, void *buf) +{ + struct mmp_struct *mmp_cmp; + errcode_t retval = 0; + + if ((mmp_blk <= fs->super->s_first_data_block) || + (mmp_blk >= fs->super->s_blocks_count)) + return EXT2_ET_MMP_BAD_BLOCK; + + if (fs->mmp_cmp == NULL) { + /* O_DIRECT in linux 2.4: page aligned + * O_DIRECT in linux 2.6: sector aligned + * A filesystem cannot be created with blocksize < sector size, + * or with blocksize > page_size. */ + int bufsize = fs->blocksize; + + if (bufsize < mmp_pagesize()) + bufsize = mmp_pagesize(); + retval = ext2fs_get_memalign(bufsize, bufsize, &fs->mmp_cmp); + if (retval) + return retval; + } + + /* ext2fs_open() reserves fd0,1,2 to avoid stdio collision, so checking + * mmp_fd <= 0 is OK to validate that the fd is valid. This opens its + * own fd to read the MMP block to ensure that it is using O_DIRECT, + * regardless of how the io_manager is doing reads, to avoid caching of + * the MMP block by the io_manager or the VM. It needs to be fresh. */ + if (fs->mmp_fd <= 0) { + fs->mmp_fd = open(fs->device_name, O_RDWR | O_DIRECT); + if (fs->mmp_fd < 0) { + retval = EXT2_ET_MMP_OPEN_DIRECT; + goto out; + } + } + + if (ext2fs_llseek(fs->mmp_fd, mmp_blk * fs->blocksize, SEEK_SET) != + mmp_blk * fs->blocksize) { + retval = EXT2_ET_LLSEEK_FAILED; + goto out; + } + + if (read(fs->mmp_fd, fs->mmp_cmp, fs->blocksize) != fs->blocksize) { + retval = EXT2_ET_SHORT_READ; + goto out; + } + + mmp_cmp = fs->mmp_cmp; +#ifdef WORDS_BIGENDIAN + ext2fs_swap_mmp(mmp_cmp); +#endif + + if (buf != NULL && buf != fs->mmp_cmp) + memcpy(buf, fs->mmp_cmp, fs->blocksize); + + if (mmp_cmp->mmp_magic != EXT4_MMP_MAGIC) { + retval = EXT2_ET_MMP_MAGIC_INVALID; + goto out; + } + +out: + return retval; +} + +errcode_t ext2fs_mmp_write(ext2_filsys fs, blk64_t mmp_blk, void *buf) +{ + struct mmp_struct *mmp_s = buf; + struct timeval tv; + errcode_t retval = 0; + + gettimeofday(&tv, 0); + mmp_s->mmp_time = tv.tv_sec; + fs->mmp_last_written = tv.tv_sec; + + if (fs->super->s_mmp_block < fs->super->s_first_data_block || + fs->super->s_mmp_block > ext2fs_blocks_count(fs->super)) + return EXT2_ET_MMP_BAD_BLOCK; + +#ifdef WORDS_BIGENDIAN + ext2fs_swap_mmp(mmp_s); +#endif + + /* I was tempted to make this use O_DIRECT and the mmp_fd, but + * this caused no end of grief, while leaving it as-is works. */ + retval = io_channel_write_blk64(fs->io, mmp_blk, -(int)sizeof(struct mmp_struct), buf); + +#ifdef WORDS_BIGENDIAN + ext2fs_swap_mmp(mmp_s); +#endif + + /* Make sure the block gets to disk quickly */ + io_channel_flush(fs->io); + return retval; +} + +#ifdef HAVE_SRANDOM +#define srand(x) srandom(x) +#define rand() random() +#endif + +unsigned ext2fs_mmp_new_seq() +{ + unsigned new_seq; + struct timeval tv; + + gettimeofday(&tv, 0); + srand((getpid() << 16) /*^ getuid()*/ ^ tv.tv_sec ^ tv.tv_usec); + + gettimeofday(&tv, 0); + /* Crank the random number generator a few times */ + for (new_seq = (tv.tv_sec ^ tv.tv_usec) & 0x1F; new_seq > 0; new_seq--) + rand(); + + do { + new_seq = rand(); + } while (new_seq > EXT4_MMP_SEQ_MAX); + + return new_seq; +} + +static errcode_t ext2fs_mmp_reset(ext2_filsys fs) +{ + struct mmp_struct *mmp_s = NULL; + errcode_t retval = 0; + + if (fs->mmp_buf == NULL) { + retval = ext2fs_get_mem(fs->blocksize, &fs->mmp_buf); + if (retval) + goto out; + } + + memset(fs->mmp_buf, 0, fs->blocksize); + mmp_s = fs->mmp_buf; + + mmp_s->mmp_magic = EXT4_MMP_MAGIC; + mmp_s->mmp_seq = EXT4_MMP_SEQ_CLEAN; + mmp_s->mmp_time = 0; +#if (0 && (_BSD_SOURCE || _XOPEN_SOURCE >= 500)) + gethostname(mmp_s->mmp_nodename, sizeof(mmp_s->mmp_nodename)); +#else + mmp_s->mmp_nodename[0] = '\0'; +#endif + strncpy(mmp_s->mmp_bdevname, fs->device_name, + sizeof(mmp_s->mmp_bdevname)); + + mmp_s->mmp_check_interval = fs->super->s_mmp_update_interval; + if (mmp_s->mmp_check_interval < EXT4_MMP_MIN_CHECK_INTERVAL) + mmp_s->mmp_check_interval = EXT4_MMP_MIN_CHECK_INTERVAL; + + retval = ext2fs_mmp_write(fs, fs->super->s_mmp_block, fs->mmp_buf); +out: + return retval; +} + +errcode_t ext2fs_mmp_clear(ext2_filsys fs) +{ + errcode_t retval = 0; + + if (!(fs->flags & EXT2_FLAG_RW)) + return EXT2_ET_RO_FILSYS; + + retval = ext2fs_mmp_reset(fs); + + return retval; +} + +errcode_t ext2fs_mmp_init(ext2_filsys fs) +{ + struct ext2_super_block *sb = fs->super; + blk64_t mmp_block; + errcode_t retval; + + if (sb->s_mmp_update_interval == 0) + sb->s_mmp_update_interval = EXT4_MMP_UPDATE_INTERVAL; + /* This is probably excessively large, but who knows? */ + else if (sb->s_mmp_update_interval > EXT4_MMP_MAX_UPDATE_INTERVAL) + return EXT2_ET_INVALID_ARGUMENT; + + if (fs->mmp_buf == NULL) { + retval = ext2fs_get_mem(fs->blocksize, &fs->mmp_buf); + if (retval) + goto out; + } + + retval = ext2fs_alloc_block2(fs, 0, fs->mmp_buf, &mmp_block); + if (retval) + goto out; + + sb->s_mmp_block = mmp_block; + + retval = ext2fs_mmp_reset(fs); + if (retval) + goto out; + +out: + return retval; +} + +/* + * Make sure that the fs is not mounted or being fsck'ed while opening the fs. + */ +errcode_t ext2fs_mmp_start(ext2_filsys fs) +{ + struct mmp_struct *mmp_s; + unsigned seq; + unsigned int mmp_check_interval; + errcode_t retval = 0; + + if (fs->mmp_buf == NULL) { + retval = ext2fs_get_mem(fs->blocksize, &fs->mmp_buf); + if (retval) + goto mmp_error; + } + + retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, fs->mmp_buf); + if (retval) + goto mmp_error; + + mmp_s = fs->mmp_buf; + + mmp_check_interval = fs->super->s_mmp_update_interval; + if (mmp_check_interval < EXT4_MMP_MIN_CHECK_INTERVAL) + mmp_check_interval = EXT4_MMP_MIN_CHECK_INTERVAL; + + seq = mmp_s->mmp_seq; + if (seq == EXT4_MMP_SEQ_CLEAN) + goto clean_seq; + if (seq == EXT4_MMP_SEQ_FSCK) { + retval = EXT2_ET_MMP_FSCK_ON; + goto mmp_error; + } + + if (seq > EXT4_MMP_SEQ_FSCK) { + retval = EXT2_ET_MMP_UNKNOWN_SEQ; + goto mmp_error; + } + + /* + * If check_interval in MMP block is larger, use that instead of + * check_interval from the superblock. + */ + if (mmp_s->mmp_check_interval > mmp_check_interval) + mmp_check_interval = mmp_s->mmp_check_interval; + + sleep(2 * mmp_check_interval + 1); + + retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, fs->mmp_buf); + if (retval) + goto mmp_error; + + if (seq != mmp_s->mmp_seq) { + retval = EXT2_ET_MMP_FAILED; + goto mmp_error; + } + +clean_seq: + if (!(fs->flags & EXT2_FLAG_RW)) + goto mmp_error; + + mmp_s->mmp_seq = seq = ext2fs_mmp_new_seq(); +#if (0 && (_BSD_SOURCE || _XOPEN_SOURCE >= 500)) + gethostname(mmp_s->mmp_nodename, sizeof(mmp_s->mmp_nodename)); +#else + strcpy(mmp_s->mmp_nodename, "unknown host"); +#endif + strncpy(mmp_s->mmp_bdevname, fs->device_name, + sizeof(mmp_s->mmp_bdevname)); + + retval = ext2fs_mmp_write(fs, fs->super->s_mmp_block, fs->mmp_buf); + if (retval) + goto mmp_error; + + sleep(2 * mmp_check_interval + 1); + + retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, fs->mmp_buf); + if (retval) + goto mmp_error; + + if (seq != mmp_s->mmp_seq) { + retval = EXT2_ET_MMP_FAILED; + goto mmp_error; + } + + mmp_s->mmp_seq = EXT4_MMP_SEQ_FSCK; + retval = ext2fs_mmp_write(fs, fs->super->s_mmp_block, fs->mmp_buf); + if (retval) + goto mmp_error; + + return 0; + +mmp_error: + return retval; +} + +/* + * Clear the MMP usage in the filesystem. If this function returns an + * error EXT2_ET_MMP_CHANGE_ABORT it means the filesystem was modified + * by some other process while in use, and changes should be dropped, or + * risk filesystem corruption. + */ +errcode_t ext2fs_mmp_stop(ext2_filsys fs) +{ + struct mmp_struct *mmp, *mmp_cmp; + errcode_t retval = 0; + + if (!(fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) || + !(fs->flags & EXT2_FLAG_RW) || (fs->flags & EXT2_FLAG_SKIP_MMP)) + goto mmp_error; + + retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, fs->mmp_buf); + if (retval) + goto mmp_error; + + /* Check if the MMP block is not changed. */ + mmp = fs->mmp_buf; + mmp_cmp = fs->mmp_cmp; + if (memcmp(mmp, mmp_cmp, sizeof(*mmp_cmp))) { + retval = EXT2_ET_MMP_CHANGE_ABORT; + goto mmp_error; + } + + mmp_cmp->mmp_seq = EXT4_MMP_SEQ_CLEAN; + retval = ext2fs_mmp_write(fs, fs->super->s_mmp_block, fs->mmp_cmp); + +mmp_error: + if (fs->mmp_fd > 0) { + close(fs->mmp_fd); + fs->mmp_fd = -1; + } + + return retval; +} + +#define EXT2_MIN_MMP_UPDATE_INTERVAL 60 + +/* + * Update the on-disk mmp buffer, after checking that it hasn't been changed. + */ +errcode_t ext2fs_mmp_update(ext2_filsys fs) +{ + struct mmp_struct *mmp, *mmp_cmp; + struct timeval tv; + errcode_t retval = 0; + + if (!(fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) || + !(fs->flags & EXT2_FLAG_RW) || (fs->flags & EXT2_FLAG_SKIP_MMP)) + return 0; + + gettimeofday(&tv, 0); + if (tv.tv_sec - fs->mmp_last_written < EXT2_MIN_MMP_UPDATE_INTERVAL) + return 0; + + retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, NULL); + if (retval) + goto mmp_error; + + mmp = fs->mmp_buf; + mmp_cmp = fs->mmp_cmp; + + if (memcmp(mmp, mmp_cmp, sizeof(*mmp_cmp))) + return EXT2_ET_MMP_CHANGE_ABORT; + + mmp->mmp_time = tv.tv_sec; + mmp->mmp_seq = EXT4_MMP_SEQ_FSCK; + retval = ext2fs_mmp_write(fs, fs->super->s_mmp_block, fs->mmp_buf); + +mmp_error: + return retval; +} diff --git a/portlibs/sources/libext2fs/source/namei.c b/portlibs/sources/libcustomext2fs/source/namei.c similarity index 98% rename from portlibs/sources/libext2fs/source/namei.c rename to portlibs/sources/libcustomext2fs/source/namei.c index bc0ae61d..efcc02b7 100644 --- a/portlibs/sources/libext2fs/source/namei.c +++ b/portlibs/sources/libcustomext2fs/source/namei.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -19,6 +20,7 @@ #include "ext2_fs.h" #include "ext2fs.h" +#include "ext2fsP.h" static errcode_t open_namei(ext2_filsys fs, ext2_ino_t root, ext2_ino_t base, const char *pathname, size_t pathlen, int follow, @@ -44,9 +46,9 @@ static errcode_t follow_link(ext2_filsys fs, ext2_ino_t root, ext2_ino_t dir, *res_inode = inode; return 0; } - if (link_count++ > 5) { + if (link_count++ >= EXT2FS_MAX_NESTED_LINKS) return EXT2_ET_SYMLINK_LOOP; - } + /* FIXME-64: Actually, this is FIXME EXTENTS */ if (ext2fs_inode_data_blocks(fs,&ei)) { retval = ext2fs_get_mem(fs->blocksize, &buffer); diff --git a/portlibs/sources/libext2fs/source/native.c b/portlibs/sources/libcustomext2fs/source/native.c similarity index 95% rename from portlibs/sources/libext2fs/source/native.c rename to portlibs/sources/libcustomext2fs/source/native.c index c71a95ee..ba3e0c8e 100644 --- a/portlibs/sources/libext2fs/source/native.c +++ b/portlibs/sources/libcustomext2fs/source/native.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include "ext2_fs.h" diff --git a/portlibs/sources/libext2fs/source/newdir.c b/portlibs/sources/libcustomext2fs/source/newdir.c similarity index 98% rename from portlibs/sources/libext2fs/source/newdir.c rename to portlibs/sources/libcustomext2fs/source/newdir.c index 6bc57194..b0a1e476 100644 --- a/portlibs/sources/libext2fs/source/newdir.c +++ b/portlibs/sources/libcustomext2fs/source/newdir.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H diff --git a/portlibs/sources/libext2fs/source/openfs.c b/portlibs/sources/libcustomext2fs/source/openfs.c similarity index 88% rename from portlibs/sources/libext2fs/source/openfs.c rename to portlibs/sources/libcustomext2fs/source/openfs.c index eb04d025..f5c736ff 100644 --- a/portlibs/sources/libext2fs/source/openfs.c +++ b/portlibs/sources/libcustomext2fs/source/openfs.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -22,6 +23,9 @@ #if HAVE_SYS_TYPES_H #include #endif +#ifdef HAVE_ERRNO_H +#include +#endif #include "ext2_fs.h" @@ -65,7 +69,7 @@ blk_t ext2fs_descriptor_block_loc(ext2_filsys fs, blk_t group_block, dgrp_t i) } errcode_t ext2fs_open(const char *name, int flags, int superblock, - unsigned int block_size, io_channel * io, + unsigned int block_size, io_channel io, ext2_filsys *ret_fs) { return ext2fs_open2(name, 0, flags, superblock, block_size, @@ -82,18 +86,19 @@ errcode_t ext2fs_open(const char *name, int flags, int superblock, * EXT2_FLAG_FORCE - Open the filesystem even if some of the * features aren't supported. * EXT2_FLAG_JOURNAL_DEV_OK - Open an ext3 journal device + * EXT2_FLAG_SKIP_MMP - Open without multi-mount protection check. */ errcode_t ext2fs_open2(const char *name, const char *io_options, int flags, int superblock, - unsigned int block_size, io_channel * io, + unsigned int block_size, io_channel io, ext2_filsys *ret_fs) { ext2_filsys fs; - io_manager manager = (*io)->manager; + io_manager manager = io->manager; errcode_t retval; unsigned long i, first_meta_bg; __u32 features; - int groups_per_block, blocks_per_group, io_flags; + unsigned int groups_per_block, blocks_per_group, io_flags; blk64_t group_block, blk; char *dest, *cp; #ifdef WORDS_BIGENDIAN @@ -109,7 +114,7 @@ errcode_t ext2fs_open2(const char *name, const char *io_options, memset(fs, 0, sizeof(struct struct_ext2_filsys)); fs->magic = EXT2_ET_MAGIC_EXT2FS_FILSYS; - fs->io = *io; + fs->io = io; fs->flags = flags; /* don't overwrite sb backups unless flag is explicitly cleared */ fs->flags |= EXT2_FLAG_MASTER_SB_ONLY; @@ -216,7 +221,7 @@ errcode_t ext2fs_open2(const char *name, const char *io_options, features = fs->super->s_feature_incompat; #ifdef EXT2_LIB_SOFTSUPP_INCOMPAT if (flags & EXT2_FLAG_SOFTSUPP_FEATURES) - features &= !EXT2_LIB_SOFTSUPP_INCOMPAT; + features &= ~EXT2_LIB_SOFTSUPP_INCOMPAT; #endif if (features & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP) { retval = EXT2_ET_UNSUPP_FEATURE; @@ -226,7 +231,7 @@ errcode_t ext2fs_open2(const char *name, const char *io_options, features = fs->super->s_feature_ro_compat; #ifdef EXT2_LIB_SOFTSUPP_RO_COMPAT if (flags & EXT2_FLAG_SOFTSUPP_FEATURES) - features &= !EXT2_LIB_SOFTSUPP_RO_COMPAT; + features &= ~EXT2_LIB_SOFTSUPP_RO_COMPAT; #endif if ((flags & EXT2_FLAG_RW) && (features & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP)) { @@ -247,12 +252,24 @@ errcode_t ext2fs_open2(const char *name, const char *io_options, retval = EXT2_ET_CORRUPT_SUPERBLOCK; goto cleanup; } - fs->blocksize = EXT2_BLOCK_SIZE(fs->super); + if (!EXT2_HAS_RO_COMPAT_FEATURE(fs->super, + EXT4_FEATURE_RO_COMPAT_BIGALLOC) && + (fs->super->s_log_block_size != fs->super->s_log_cluster_size)) { + retval = EXT2_ET_CORRUPT_SUPERBLOCK; + goto cleanup; + } + fs->fragsize = fs->blocksize = EXT2_BLOCK_SIZE(fs->super); if (EXT2_INODE_SIZE(fs->super) < EXT2_GOOD_OLD_INODE_SIZE) { retval = EXT2_ET_CORRUPT_SUPERBLOCK; goto cleanup; } - fs->clustersize = EXT2_CLUSTER_SIZE(fs->super); + fs->cluster_ratio_bits = fs->super->s_log_cluster_size - + fs->super->s_log_block_size; + if (EXT2_BLOCKS_PER_GROUP(fs->super) != + EXT2_CLUSTERS_PER_GROUP(fs->super) << fs->cluster_ratio_bits) { + retval = EXT2_ET_CORRUPT_SUPERBLOCK; + goto cleanup; + } fs->inode_blocks_per_group = ((EXT2_INODES_PER_GROUP(fs->super) * EXT2_INODE_SIZE(fs->super) + EXT2_BLOCK_SIZE(fs->super) - 1) / @@ -312,6 +329,8 @@ errcode_t ext2fs_open2(const char *name, const char *io_options, goto cleanup; if (!group_block) group_block = fs->super->s_first_data_block; + if (group_block == 0 && fs->blocksize == 1024) + group_block = 1; /* Deal with 1024 blocksize && bigalloc */ dest = (char *) fs->group_desc; groups_per_block = EXT2_DESC_PER_BLOCK(fs->super); if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) @@ -339,8 +358,8 @@ errcode_t ext2fs_open2(const char *name, const char *io_options, goto cleanup; #ifdef WORDS_BIGENDIAN for (j=0; j < groups_per_block; j++) { - /* The below happens to work... be careful. */ - gdp = ext2fs_group_desc(fs, fs->group_desc, j); + gdp = ext2fs_group_desc(fs, fs->group_desc, + i * groups_per_block + j); ext2fs_swap_group_desc2(fs, gdp); } #endif @@ -367,6 +386,18 @@ errcode_t ext2fs_open2(const char *name, const char *io_options, fs->flags &= ~EXT2_FLAG_NOFREE_ON_ERROR; *ret_fs = fs; + + if ((fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) && + !(flags & EXT2_FLAG_SKIP_MMP) && + (flags & (EXT2_FLAG_RW | EXT2_FLAG_EXCLUSIVE))) { + retval = ext2fs_mmp_start(fs); + if (retval) { + fs->flags |= EXT2_FLAG_SKIP_MMP; /* just do cleanup */ + ext2fs_mmp_stop(fs); + goto cleanup; + } + } + return 0; cleanup: if (flags & EXT2_FLAG_NOFREE_ON_ERROR) diff --git a/portlibs/sources/libext2fs/source/partitions.h b/portlibs/sources/libcustomext2fs/source/partitions.h similarity index 100% rename from portlibs/sources/libext2fs/source/partitions.h rename to portlibs/sources/libcustomext2fs/source/partitions.h diff --git a/portlibs/sources/libext2fs/source/progress.c b/portlibs/sources/libcustomext2fs/source/progress.c similarity index 96% rename from portlibs/sources/libext2fs/source/progress.c rename to portlibs/sources/libcustomext2fs/source/progress.c index 335b98b5..37d15096 100644 --- a/portlibs/sources/libext2fs/source/progress.c +++ b/portlibs/sources/libcustomext2fs/source/progress.c @@ -10,6 +10,7 @@ * %End-Header% */ +#include "config.h" #include "ext2fs.h" #include "ext2fsP.h" @@ -68,7 +69,7 @@ void ext2fs_numeric_progress_update(ext2_filsys fs, if (progress->skip_progress) return; - fprintf(stdout, "%*llu/%*llu", progress->log_max, val, + printf("%*llu/%*llu", progress->log_max, val, progress->log_max, progress->max); fprintf(stdout, "%.*s", (2*progress->log_max)+1, backspaces); } diff --git a/portlibs/sources/libext2fs/source/punch.c b/portlibs/sources/libcustomext2fs/source/punch.c similarity index 97% rename from portlibs/sources/libext2fs/source/punch.c rename to portlibs/sources/libcustomext2fs/source/punch.c index 8c6ec549..b53653a0 100644 --- a/portlibs/sources/libext2fs/source/punch.c +++ b/portlibs/sources/libcustomext2fs/source/punch.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -203,7 +204,7 @@ static errcode_t ext2fs_punch_extent(ext2_filsys fs, ext2_ino_t ino, if (start <= extent.e_lblk) { if (end < extent.e_lblk) goto next_extent; - dbg_printf("Case #1\n"); + dbg_printf("Case #%d\n", 1); /* Start of deleted region before extent; adjust beginning of extent */ free_start = extent.e_pblk; @@ -219,7 +220,7 @@ static errcode_t ext2fs_punch_extent(ext2_filsys fs, ext2_ino_t ino, break; /* End of deleted region after extent; adjust end of extent */ - dbg_printf("Case #2\n"); + dbg_printf("Case #%d\n", 2); newlen = start - extent.e_lblk; free_start = extent.e_pblk + newlen; free_count = extent.e_len - newlen; @@ -227,7 +228,7 @@ static errcode_t ext2fs_punch_extent(ext2_filsys fs, ext2_ino_t ino, } else { struct ext2fs_extent newex; - dbg_printf("Case #3\n"); + dbg_printf("Case #%d\n", 3); /* The hard case; we need to split the extent */ newex.e_pblk = extent.e_pblk + (end + 1 - extent.e_lblk); @@ -255,7 +256,7 @@ static errcode_t ext2fs_punch_extent(ext2_filsys fs, ext2_ino_t ino, dbg_print_extent("replacing", &extent); retval = ext2fs_extent_replace(handle, 0, &extent); } else { - dbg_printf("deleting current extent\n"); + dbg_printf("deleting current extent%s\n", ""); retval = ext2fs_extent_delete(handle, 0); } if (retval) diff --git a/portlibs/sources/libext2fs/source/read_bb.c b/portlibs/sources/libcustomext2fs/source/read_bb.c similarity index 99% rename from portlibs/sources/libext2fs/source/read_bb.c rename to portlibs/sources/libcustomext2fs/source/read_bb.c index e5d63227..b5a0d7b4 100644 --- a/portlibs/sources/libext2fs/source/read_bb.c +++ b/portlibs/sources/libcustomext2fs/source/read_bb.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H diff --git a/portlibs/sources/libext2fs/source/read_bb_file.c b/portlibs/sources/libcustomext2fs/source/read_bb_file.c similarity index 99% rename from portlibs/sources/libext2fs/source/read_bb_file.c rename to portlibs/sources/libcustomext2fs/source/read_bb_file.c index 25454a87..7d7bb7aa 100644 --- a/portlibs/sources/libext2fs/source/read_bb_file.c +++ b/portlibs/sources/libcustomext2fs/source/read_bb_file.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H diff --git a/portlibs/sources/libext2fs/source/res_gdt.c b/portlibs/sources/libcustomext2fs/source/res_gdt.c similarity index 92% rename from portlibs/sources/libext2fs/source/res_gdt.c rename to portlibs/sources/libcustomext2fs/source/res_gdt.c index 0d988428..6449228c 100644 --- a/portlibs/sources/libext2fs/source/res_gdt.c +++ b/portlibs/sources/libcustomext2fs/source/res_gdt.c @@ -10,6 +10,7 @@ * %End-Header% */ +#include "config.h" #include #include #include @@ -63,11 +64,11 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs) errcode_t retval, retval2; struct ext2_super_block *sb; struct ext2_inode inode; - __u32 *dindir_buf = 0, *gdt_buf = 0; + __u32 *dindir_buf, *gdt_buf; unsigned long long apb, inode_size; /* FIXME-64 - can't deal with extents */ blk_t dindir_blk, rsv_off, gdt_off, gdt_blk; - int dindir_dirty = 0, inode_dirty = 0; + int dindir_dirty = 0, inode_dirty = 0, sb_blk = 0; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); @@ -75,13 +76,22 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs) retval = ext2fs_get_array(2, fs->blocksize, &dindir_buf); if (retval) - goto out_free; + return retval; gdt_buf = (__u32 *)((char *)dindir_buf + fs->blocksize); retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode); if (retval) goto out_free; + /* + * File systems with a blocksize of 1024 and bigalloc have + * sb->s_first_data_block of 0; yet the superblock is still at + * block #1. We compensate for it here. + */ + sb_blk = sb->s_first_data_block; + if (fs->blocksize == 1024 && sb_blk == 0) + sb_blk = 1; + /* Maximum possible file size (we donly use the dindirect blocks) */ apb = EXT2_ADDR_PER_BLOCK(sb); if ((dindir_blk = inode.i_block[EXT2_DIND_BLOCK])) { @@ -92,7 +102,7 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs) if (retval) goto out_inode; } else { - blk_t goal = sb->s_first_data_block + fs->desc_blocks + + blk_t goal = sb_blk + fs->desc_blocks + sb->s_reserved_gdt_blocks + 2 + fs->inode_blocks_per_group; @@ -120,7 +130,7 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs) } for (rsv_off = 0, gdt_off = fs->desc_blocks, - gdt_blk = sb->s_first_data_block + 1 + fs->desc_blocks; + gdt_blk = sb_blk + 1 + fs->desc_blocks; rsv_off < sb->s_reserved_gdt_blocks; rsv_off++, gdt_off++, gdt_blk++) { unsigned int three = 1, five = 5, seven = 7; diff --git a/portlibs/sources/libext2fs/source/rw_bitmaps.c b/portlibs/sources/libcustomext2fs/source/rw_bitmaps.c similarity index 90% rename from portlibs/sources/libext2fs/source/rw_bitmaps.c rename to portlibs/sources/libcustomext2fs/source/rw_bitmaps.c index 7b74b421..1d5f7b2b 100644 --- a/portlibs/sources/libext2fs/source/rw_bitmaps.c +++ b/portlibs/sources/libcustomext2fs/source/rw_bitmaps.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -34,10 +35,10 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block) int block_nbytes, inode_nbytes; unsigned int nbits; errcode_t retval; - char *block_buf = 0, *inode_buf = 0; + char *block_buf = NULL, *inode_buf = NULL; int csum_flag = 0; blk64_t blk; - blk64_t blk_itr = fs->super->s_first_data_block; + blk64_t blk_itr = EXT2FS_B2C(fs, fs->super->s_first_data_block); ext2_ino_t ino_itr = 1; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); @@ -51,11 +52,11 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block) inode_nbytes = block_nbytes = 0; if (do_block) { - block_nbytes = EXT2_BLOCKS_PER_GROUP(fs->super) / 8; + block_nbytes = EXT2_CLUSTERS_PER_GROUP(fs->super) / 8; retval = ext2fs_get_memalign(fs->blocksize, fs->blocksize, &block_buf); if (retval) - return retval; + goto errout; memset(block_buf, 0xff, fs->blocksize); } if (do_inode) { @@ -64,7 +65,7 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block) retval = ext2fs_get_memalign(fs->blocksize, fs->blocksize, &inode_buf); if (retval) - return retval; + goto errout; memset(inode_buf, 0xff, fs->blocksize); } @@ -79,13 +80,14 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block) retval = ext2fs_get_block_bitmap_range2(fs->block_map, blk_itr, block_nbytes << 3, block_buf); if (retval) - return retval; + goto errout; if (i == fs->group_desc_count - 1) { /* Force bitmap padding for the last group */ - nbits = ((ext2fs_blocks_count(fs->super) + nbits = EXT2FS_NUM_B2C(fs, + ((ext2fs_blocks_count(fs->super) - (__u64) fs->super->s_first_data_block) - % (__u64) EXT2_BLOCKS_PER_GROUP(fs->super)); + % (__u64) EXT2_BLOCKS_PER_GROUP(fs->super))); if (nbits) for (j = nbits; j < fs->blocksize * 8; j++) ext2fs_set_bit(j, block_buf); @@ -94,8 +96,10 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block) if (blk) { retval = io_channel_write_blk64(fs->io, blk, 1, block_buf); - if (retval) - return EXT2_ET_BLOCK_BITMAP_WRITE; + if (retval) { + retval = EXT2_ET_BLOCK_BITMAP_WRITE; + goto errout; + } } skip_this_block_bitmap: blk_itr += block_nbytes << 3; @@ -111,14 +115,16 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block) retval = ext2fs_get_inode_bitmap_range2(fs->inode_map, ino_itr, inode_nbytes << 3, inode_buf); if (retval) - return retval; + goto errout; blk = ext2fs_inode_bitmap_loc(fs, i); if (blk) { retval = io_channel_write_blk64(fs->io, blk, 1, inode_buf); - if (retval) - return EXT2_ET_INODE_BITMAP_WRITE; + if (retval) { + retval = EXT2_ET_INODE_BITMAP_WRITE; + goto errout; + } } skip_this_inode_bitmap: ino_itr += inode_nbytes << 3; @@ -133,6 +139,12 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block) ext2fs_free_mem(&inode_buf); } return 0; +errout: + if (inode_buf) + ext2fs_free_mem(&inode_buf); + if (block_buf) + ext2fs_free_mem(&block_buf); + return retval; } static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block) @@ -141,13 +153,13 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block) char *block_bitmap = 0, *inode_bitmap = 0; char *buf; errcode_t retval; - int block_nbytes = EXT2_BLOCKS_PER_GROUP(fs->super) / 8; + int block_nbytes = EXT2_CLUSTERS_PER_GROUP(fs->super) / 8; int inode_nbytes = EXT2_INODES_PER_GROUP(fs->super) / 8; int csum_flag = 0; int do_image = fs->flags & EXT2_FLAG_IMAGE_FILE; unsigned int cnt; blk64_t blk; - blk64_t blk_itr = fs->super->s_first_data_block; + blk64_t blk_itr = EXT2FS_B2C(fs, fs->super->s_first_data_block); blk64_t blk_cnt; ext2_ino_t ino_itr = 1; ext2_ino_t ino_cnt; @@ -219,7 +231,7 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block) } blk = (fs->image_header->offset_blockmap / fs->blocksize); - blk_cnt = (blk64_t)EXT2_BLOCKS_PER_GROUP(fs->super) * + blk_cnt = (blk64_t)EXT2_CLUSTERS_PER_GROUP(fs->super) * fs->group_desc_count; while (block_nbytes > 0) { retval = io_channel_read_blk64(fs->image_io, blk++, diff --git a/portlibs/sources/libext2fs/source/sparse.c b/portlibs/sources/libcustomext2fs/source/sparse.c similarity index 98% rename from portlibs/sources/libext2fs/source/sparse.c rename to portlibs/sources/libcustomext2fs/source/sparse.c index 15ded0ae..96b24178 100644 --- a/portlibs/sources/libext2fs/source/sparse.c +++ b/portlibs/sources/libcustomext2fs/source/sparse.c @@ -10,6 +10,7 @@ * %End-Header% */ +#include "config.h" #include #include "ext2_fs.h" diff --git a/portlibs/sources/libext2fs/source/swapfs.c b/portlibs/sources/libcustomext2fs/source/swapfs.c similarity index 85% rename from portlibs/sources/libext2fs/source/swapfs.c rename to portlibs/sources/libcustomext2fs/source/swapfs.c index b856a097..24441e0c 100644 --- a/portlibs/sources/libext2fs/source/swapfs.c +++ b/portlibs/sources/libcustomext2fs/source/swapfs.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #if HAVE_UNISTD_H #include @@ -70,6 +71,8 @@ void ext2fs_swap_super(struct ext2_super_block * sb) sb->s_min_extra_isize = ext2fs_swab16(sb->s_min_extra_isize); sb->s_want_extra_isize = ext2fs_swab16(sb->s_want_extra_isize); sb->s_flags = ext2fs_swab32(sb->s_flags); + sb->s_mmp_update_interval = ext2fs_swab16(sb->s_mmp_update_interval); + sb->s_mmp_block = ext2fs_swab64(sb->s_mmp_block); sb->s_kbytes_written = ext2fs_swab64(sb->s_kbytes_written); sb->s_snapshot_inum = ext2fs_swab32(sb->s_snapshot_inum); sb->s_snapshot_id = ext2fs_swab32(sb->s_snapshot_id); @@ -78,21 +81,23 @@ void ext2fs_swap_super(struct ext2_super_block * sb) sb->s_snapshot_list = ext2fs_swab32(sb->s_snapshot_list); sb->s_usr_quota_inum = ext2fs_swab32(sb->s_usr_quota_inum); sb->s_grp_quota_inum = ext2fs_swab32(sb->s_grp_quota_inum); + sb->s_overhead_blocks = ext2fs_swab32(sb->s_overhead_blocks); + sb->s_checksum = ext2fs_swab32(sb->s_checksum); for (i=0; i < 4; i++) sb->s_hash_seed[i] = ext2fs_swab32(sb->s_hash_seed[i]); /* if journal backup is for a valid extent-based journal... */ - if (!ext2fs_extent_header_verify(sb->s_jnl_blocks, - sizeof(sb->s_jnl_blocks))) { - /* ... swap only the journal i_size */ - sb->s_jnl_blocks[16] = ext2fs_swab32(sb->s_jnl_blocks[16]); - /* and the extent data is not swapped on read */ - return; + if (ext2fs_extent_header_verify(sb->s_jnl_blocks, + sizeof(sb->s_jnl_blocks)) == 0) { + /* ... swap only the journal i_size and i_size_high, + * and the extent data is not swapped on read */ + i = 15; + } else { + /* direct/indirect journal: swap it all */ + i = 0; } - - /* direct/indirect journal: swap it all */ - for (i=0; i < 17; i++) + for (; i < 17; i++) sb->s_jnl_blocks[i] = ext2fs_swab32(sb->s_jnl_blocks[i]); } @@ -106,6 +111,11 @@ void ext2fs_swap_group_desc2(ext2_filsys fs, struct ext2_group_desc *gdp) gdp->bg_free_inodes_count = ext2fs_swab16(gdp->bg_free_inodes_count); gdp->bg_used_dirs_count = ext2fs_swab16(gdp->bg_used_dirs_count); gdp->bg_flags = ext2fs_swab16(gdp->bg_flags); + gdp->bg_exclude_bitmap_lo = ext2fs_swab32(gdp->bg_exclude_bitmap_lo); + gdp->bg_block_bitmap_csum_lo = + ext2fs_swab16(gdp->bg_block_bitmap_csum_lo); + gdp->bg_inode_bitmap_csum_lo = + ext2fs_swab16(gdp->bg_inode_bitmap_csum_lo); gdp->bg_itable_unused = ext2fs_swab16(gdp->bg_itable_unused); gdp->bg_checksum = ext2fs_swab16(gdp->bg_checksum); /* If we're 32-bit, we're done */ @@ -125,11 +135,16 @@ void ext2fs_swap_group_desc2(ext2_filsys fs, struct ext2_group_desc *gdp) gdp4->bg_used_dirs_count_hi = ext2fs_swab16(gdp4->bg_used_dirs_count_hi); gdp4->bg_itable_unused_hi = ext2fs_swab16(gdp4->bg_itable_unused_hi); + gdp4->bg_exclude_bitmap_hi = ext2fs_swab16(gdp4->bg_exclude_bitmap_hi); + gdp4->bg_block_bitmap_csum_hi = + ext2fs_swab16(gdp4->bg_block_bitmap_csum_hi); + gdp4->bg_inode_bitmap_csum_hi = + ext2fs_swab16(gdp4->bg_inode_bitmap_csum_hi); } void ext2fs_swap_group_desc(struct ext2_group_desc *gdp) { - return ext2fs_swap_group_desc2(0, gdp); + ext2fs_swap_group_desc2(0, gdp); } @@ -244,8 +259,8 @@ void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t, ext2fs_swab16 (f->osd2.linux2.l_i_uid_high); t->osd2.linux2.l_i_gid_high = ext2fs_swab16 (f->osd2.linux2.l_i_gid_high); - t->osd2.linux2.l_i_reserved2 = - ext2fs_swab32(f->osd2.linux2.l_i_reserved2); + t->osd2.linux2.l_i_checksum_lo = + ext2fs_swab16(f->osd2.linux2.l_i_checksum_lo); break; case EXT2_OS_HURD: t->osd1.hurd1.h_i_translator = @@ -279,6 +294,21 @@ void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t, return; } + if (extra_isize >= 4) + t->i_checksum_hi = ext2fs_swab16(f->i_checksum_hi); + if (extra_isize >= 8) + t->i_ctime_extra = ext2fs_swab32(f->i_ctime_extra); + if (extra_isize >= 12) + t->i_mtime_extra = ext2fs_swab32(f->i_mtime_extra); + if (extra_isize >= 16) + t->i_atime_extra = ext2fs_swab32(f->i_atime_extra); + if (extra_isize >= 20) + t->i_crtime = ext2fs_swab32(f->i_crtime); + if (extra_isize >= 24) + t->i_crtime_extra = ext2fs_swab32(f->i_crtime_extra); + if (extra_isize >= 28) + t->i_version_hi = ext2fs_swab32(f->i_version_hi); + i = sizeof(struct ext2_inode) + extra_isize + sizeof(__u32); if (bufsize < (int) i) return; /* no space for EA magic */ @@ -312,4 +342,12 @@ void ext2fs_swap_inode(ext2_filsys fs, struct ext2_inode *t, sizeof(struct ext2_inode)); } +void ext2fs_swap_mmp(struct mmp_struct *mmp) +{ + mmp->mmp_magic = ext2fs_swab32(mmp->mmp_magic); + mmp->mmp_seq = ext2fs_swab32(mmp->mmp_seq); + mmp->mmp_time = ext2fs_swab64(mmp->mmp_time); + mmp->mmp_check_interval = ext2fs_swab16(mmp->mmp_check_interval); +} + #endif diff --git a/portlibs/sources/libext2fs/source/tdb.c b/portlibs/sources/libcustomext2fs/source/tdb.c similarity index 99% rename from portlibs/sources/libext2fs/source/tdb.c rename to portlibs/sources/libcustomext2fs/source/tdb.c index 0550f468..73d54b6b 100644 --- a/portlibs/sources/libext2fs/source/tdb.c +++ b/portlibs/sources/libcustomext2fs/source/tdb.c @@ -38,6 +38,7 @@ Last Changed Date: 2007-06-22 13:36:10 -0400 (Fri, 22 Jun 2007) #endif #define _XOPEN_SOURCE 600 +#include "config.h" #include #include #include @@ -107,6 +108,8 @@ typedef int bool; #include "tdb.h" +static TDB_DATA tdb_null; + #ifndef u32 #define u32 unsigned #endif @@ -1751,7 +1754,7 @@ static int transaction_sync(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction: fsync failed\n")); return -1; } -#ifdef MS_SYNC +#if defined(HAVE_MSYNC) && defined(MS_SYNC) if (tdb->map_ptr) { tdb_off_t moffset = offset & ~(tdb->page_size-1); if (msync(moffset + (char *)tdb->map_ptr, @@ -3059,8 +3062,6 @@ int tdb_printfreelist(struct tdb_context *tdb) /* file: tdb.c */ -TDB_DATA tdb_null; - /* non-blocking increment of the tdb sequence number if the tdb has been opened using the TDB_SEQNUM flag @@ -3712,17 +3713,17 @@ void tdb_enable_seqnum(struct tdb_context *tdb) static struct tdb_context *tdbs = NULL; -/* This is based on the hash algorithm from gdbm */ +/* This is from a hash algorithm suggested by Rogier Wolff */ static unsigned int default_tdb_hash(TDB_DATA *key) { u32 value; /* Used to compute the hash value. */ u32 i; /* Used to cycle through random values. */ /* Set the initial value from the key size. */ - for (value = 0x238F13AF * key->dsize, i=0; i < key->dsize; i++) - value = (value + (key->dptr[i] << (i*5 % 24))); + for (value = 0, i=0; i < key->dsize; i++) + value = value * 256 + key->dptr[i] + (value >> 24) * 241; - return (1103515243 * value + 12345); + return value; } diff --git a/portlibs/sources/libext2fs/source/tdb.h b/portlibs/sources/libcustomext2fs/source/tdb.h similarity index 99% rename from portlibs/sources/libext2fs/source/tdb.h rename to portlibs/sources/libcustomext2fs/source/tdb.h index bfcd9436..732ef0ec 100644 --- a/portlibs/sources/libext2fs/source/tdb.h +++ b/portlibs/sources/libcustomext2fs/source/tdb.h @@ -206,8 +206,6 @@ void tdb_dump_all(struct tdb_context *tdb); int tdb_printfreelist(struct tdb_context *tdb); int tdb_validate_freelist(struct tdb_context *tdb, int *pnum_entries); -extern TDB_DATA tdb_null; - #ifdef __cplusplus } #endif diff --git a/portlibs/sources/libext2fs/source/unlink.c b/portlibs/sources/libcustomext2fs/source/unlink.c similarity index 98% rename from portlibs/sources/libext2fs/source/unlink.c rename to portlibs/sources/libcustomext2fs/source/unlink.c index 7ffeb9e8..d2d31cc4 100644 --- a/portlibs/sources/libext2fs/source/unlink.c +++ b/portlibs/sources/libcustomext2fs/source/unlink.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H diff --git a/portlibs/sources/libext2fs/source/valid_blk.c b/portlibs/sources/libcustomext2fs/source/valid_blk.c similarity index 86% rename from portlibs/sources/libext2fs/source/valid_blk.c rename to portlibs/sources/libcustomext2fs/source/valid_blk.c index ec3edd88..895e36ef 100644 --- a/portlibs/sources/libext2fs/source/valid_blk.c +++ b/portlibs/sources/libcustomext2fs/source/valid_blk.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #if HAVE_UNISTD_H #include @@ -23,7 +24,7 @@ * This function returns 1 if the inode's block entries actually * contain block entries. */ -int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode) +int ext2fs_inode_has_valid_blocks2(ext2_filsys fs, struct ext2_inode *inode) { /* * Only directories, regular files, and some symbolic links @@ -38,7 +39,7 @@ int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode) * target is stored in the block entries. */ if (LINUX_S_ISLNK (inode->i_mode)) { - if (ext2fs_file_acl_block(inode) == 0) { + if (ext2fs_file_acl_block(fs, inode) == 0) { /* With no EA block, we can rely on i_blocks */ if (inode->i_blocks == 0) return 0; @@ -53,3 +54,8 @@ int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode) } return 1; } + +int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode) +{ + return ext2fs_inode_has_valid_blocks2(NULL, inode); +} diff --git a/portlibs/sources/libext2fs/source/version.c b/portlibs/sources/libcustomext2fs/source/version.c similarity index 87% rename from portlibs/sources/libext2fs/source/version.c rename to portlibs/sources/libcustomext2fs/source/version.c index e7f223bf..3acfe3f9 100644 --- a/portlibs/sources/libext2fs/source/version.c +++ b/portlibs/sources/libcustomext2fs/source/version.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #if HAVE_UNISTD_H #include #endif @@ -19,8 +20,10 @@ #include "ext2_fs.h" #include "ext2fs.h" -static const char *lib_version = ""; -static const char *lib_date = ""; +#include "version.h" + +static const char *lib_version = E2FSPROGS_VERSION; +static const char *lib_date = E2FSPROGS_DATE; int ext2fs_parse_version_string(const char *ver_string) { diff --git a/portlibs/sources/libcustomext2fs/source/version.h b/portlibs/sources/libcustomext2fs/source/version.h new file mode 100644 index 00000000..10c4d84b --- /dev/null +++ b/portlibs/sources/libcustomext2fs/source/version.h @@ -0,0 +1,11 @@ +/* + * version.h --- controls the version number printed by the e2fs + * programs. + * + * Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, + * 2004, 2005, 2006, 2007, 2008, 2009, 2010 by Theodore Ts'o. This + * file may be redistributed under the GNU Public License v2. + */ + +#define E2FSPROGS_VERSION "1.42" +#define E2FSPROGS_DATE "29-Nov-2011" diff --git a/portlibs/sources/libext2fs/source/write_bb_file.c b/portlibs/sources/libcustomext2fs/source/write_bb_file.c similarity index 97% rename from portlibs/sources/libext2fs/source/write_bb_file.c rename to portlibs/sources/libcustomext2fs/source/write_bb_file.c index 70bcf08e..58343408 100644 --- a/portlibs/sources/libext2fs/source/write_bb_file.c +++ b/portlibs/sources/libcustomext2fs/source/write_bb_file.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include "ext2_fs.h" diff --git a/portlibs/sources/libcustomfat/Makefile b/portlibs/sources/libcustomfat/Makefile new file mode 100644 index 00000000..d909ca3b --- /dev/null +++ b/portlibs/sources/libcustomfat/Makefile @@ -0,0 +1,31 @@ +ifeq ($(strip $(DEVKITPRO)),) +$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPro) +endif + +export TOPDIR := $(CURDIR) + +export LIBFAT_MAJOR := 1 +export LIBFAT_MINOR := 0 +export LIBFAT_PATCH := 10 + +export VERSTRING := $(LIBFAT_MAJOR).$(LIBFAT_MINOR).$(LIBFAT_PATCH) + + +default: release + +all: release + +release: include/libfatversion.h wii-release + +wii-release: + $(MAKE) -C libogc PLATFORM=wii BUILD=wii_release + +clean: ogc-clean + +ogc-clean: + $(MAKE) -C libogc clean + +install: ogc-install + +ogc-install: cube-release wii-release + $(MAKE) -C libogc install diff --git a/portlibs/sources/libfat/fat.h b/portlibs/sources/libcustomfat/include/fat.h similarity index 99% rename from portlibs/sources/libfat/fat.h rename to portlibs/sources/libcustomfat/include/fat.h index 82c973d3..b0ffc13a 100644 --- a/portlibs/sources/libfat/fat.h +++ b/portlibs/sources/libcustomfat/include/fat.h @@ -1,7 +1,7 @@ /* fat.h Simple functionality for startup, mounting and unmounting of FAT-based devices. - + Copyright (c) 2006 - 2009 Michael "Chishm" Chisholm Dave "WinterMute" Murphy @@ -71,7 +71,7 @@ extern bool fatInitDefault (void); /* Mount the device pointed to by interface, and set up a devoptab entry for it as "name:". You can then access the filesystem using "name:/". -This will mount the active partition or the first valid partition on the disc, +This will mount the active partition or the first valid partition on the disc, and will use a cache size optimized for the host system. */ extern bool fatMountSimple (const char* name, const DISC_INTERFACE* interface); diff --git a/portlibs/sources/libfat/libfatversion.h b/portlibs/sources/libcustomfat/include/libfatversion.h similarity index 65% rename from portlibs/sources/libfat/libfatversion.h rename to portlibs/sources/libcustomfat/include/libfatversion.h index 40c50463..82c3187b 100644 --- a/portlibs/sources/libfat/libfatversion.h +++ b/portlibs/sources/libcustomfat/include/libfatversion.h @@ -3,8 +3,8 @@ #define _LIBFAT_MAJOR_ 1 #define _LIBFAT_MINOR_ 0 -#define _LIBFAT_PATCH_ 7 +#define _LIBFAT_PATCH_ 10 -#define _LIBFAT_STRING "libFAT Release 1.0.7" +#define _LIBFAT_STRING "libFAT Release 1.0.10" #endif // __LIBFATVERSION_H__ diff --git a/portlibs/sources/libcustomfat/libfat.pnproj b/portlibs/sources/libcustomfat/libfat.pnproj new file mode 100644 index 00000000..9b35658d --- /dev/null +++ b/portlibs/sources/libcustomfat/libfat.pnproj @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/portlibs/sources/libcustomfat/libfat.pnps b/portlibs/sources/libcustomfat/libfat.pnps new file mode 100644 index 00000000..bb191eba --- /dev/null +++ b/portlibs/sources/libcustomfat/libfat.pnps @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/portlibs/sources/libcustomfat/libogc/Makefile b/portlibs/sources/libcustomfat/libogc/Makefile new file mode 100644 index 00000000..30a396b8 --- /dev/null +++ b/portlibs/sources/libcustomfat/libogc/Makefile @@ -0,0 +1,132 @@ +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- +ifeq ($(strip $(DEVKITPPC)),) +$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC) +endif + +ifeq ($(PLATFORM),wii) +include $(DEVKITPPC)/wii_rules +endif + +ifeq ($(PLATFORM),cube) +include $(DEVKITPPC)/gamecube_rules +endif + +#--------------------------------------------------------------------------------- +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# INCLUDES is a list of directories containing extra header files +# DATA is a list of directories containing binary files +# LIBDIR is where the built library will be placed +# all directories are relative to this makefile +#--------------------------------------------------------------------------------- +BUILD ?= wii_release +SOURCES := ../source +INCLUDES := ../include +DATA := +LIBDIR := $(TOPDIR)/libogc/lib + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE) +CXXFLAGS = $(CFLAGS) + +ASFLAGS := -g + +ifneq ($(BUILD),debug) +export CUBEBIN := $(LIBDIR)/$(PLATFORM)/libfat.a +else +export CUBEBIN := $(LIBDIR)/$(PLATFORM)/libfatd.a +CFLAGS += -DFAT_DEBUG +endif + +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +LIBS := + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +export TOPDIR ?= $(CURDIR)/.. + + +export DEPSDIR := $(CURDIR)/$(BUILD) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) + + +export OFILES := $(addsuffix .o,$(BINFILES)) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) + +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) \ + -I$(LIBOGC_INC) + +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ + -L$(LIBOGC_LIB) + +.PHONY: $(BUILD) clean + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr wii_debug wii_release cube_debug cube_release $(LIBDIR) + +all: $(CUBEBIN) + +dist-bin: + @tar --exclude=.svn --exclude=*CVS* -cvjf $(TOPDIR)/distribute/$(VERSTRING)/libfat-ogc-$(VERSTRING).tar.bz2 include lib + +install: + cp lib/wii/libfat.a $(DEVKITPRO)/libogc/lib/wii + cp lib/cube/libfat.a $(DEVKITPRO)/libogc/lib/cube + cp include/fat.h $(DEVKITPRO)/libogc/include + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(CUBEBIN) : $(OFILES) $(LIBDIR)/$(PLATFORM) + @rm -f "$(CUBEBIN)" + @$(AR) rcs "$(CUBEBIN)" $(OFILES) + @echo built ... $(notdir $@) + +$(LIBDIR)/$(PLATFORM): + mkdir -p $(LIBDIR)/$(PLATFORM) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- + diff --git a/portlibs/sources/libcustomfat/libogc/include/fat.h b/portlibs/sources/libcustomfat/libogc/include/fat.h new file mode 100644 index 00000000..31efbe02 --- /dev/null +++ b/portlibs/sources/libcustomfat/libogc/include/fat.h @@ -0,0 +1,86 @@ +/* + fat.h + Simple functionality for startup, mounting and unmounting of FAT-based devices. + + Copyright (c) 2006 Michael "Chishm" Chisholm + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + 3. The name of the author may not be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifndef _LIBFAT_H +#define _LIBFAT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* +Initialise any inserted block-devices. +Add the fat device driver to the devoptab, making it available for standard file functions. +cacheSize: The number of pages to allocate for each inserted block-device +setAsDefaultDevice: if true, make this the default device driver for file operations +*/ +extern bool fatInit (uint32_t cacheSize, bool setAsDefaultDevice); + +/* +Calls fatInit with setAsDefaultDevice = true and cacheSize optimised for the host system. +*/ +extern bool fatInitDefault (void); + +/* +Mount the device pointed to by interface, and set up a devoptab entry for it as "name:". +You can then access the filesystem using "name:/". +This will mount the active partition or the first valid partition on the disc, +and will use a cache size optimized for the host system. +*/ +extern bool fatMountSimple (const char* name, const DISC_INTERFACE* interface); + +/* +Mount the device pointed to by interface, and set up a devoptab entry for it as "name:". +You can then access the filesystem using "name:/". +If startSector = 0, it will mount the active partition of the first valid partition on +the disc. Otherwise it will try to mount the partition starting at startSector. +cacheSize specifies the number of pages to allocate for the cache. +This will not startup the disc, so you need to call interface->startup(); first. +*/ +extern bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSector, uint32_t cacheSize, uint32_t SectorsPerPage); + +/* +Unmount the partition specified by name. +If there are open files, it will attempt to synchronise them to disc. +*/ +extern void fatUnmount (const char* name); + +/* +Get Volume Label +*/ +extern void fatGetVolumeLabel (const char* name, char *label); + +#ifdef __cplusplus +} +#endif + +#endif // _LIBFAT_H diff --git a/portlibs/sources/libfat/bit_ops.h b/portlibs/sources/libcustomfat/source/bit_ops.h similarity index 100% rename from portlibs/sources/libfat/bit_ops.h rename to portlibs/sources/libcustomfat/source/bit_ops.h diff --git a/portlibs/sources/libfat/cache.c b/portlibs/sources/libcustomfat/source/cache.c similarity index 100% rename from portlibs/sources/libfat/cache.c rename to portlibs/sources/libcustomfat/source/cache.c diff --git a/portlibs/sources/libfat/cache.h b/portlibs/sources/libcustomfat/source/cache.h similarity index 100% rename from portlibs/sources/libfat/cache.h rename to portlibs/sources/libcustomfat/source/cache.h diff --git a/portlibs/sources/libfat/common.h b/portlibs/sources/libcustomfat/source/common.h similarity index 100% rename from portlibs/sources/libfat/common.h rename to portlibs/sources/libcustomfat/source/common.h diff --git a/portlibs/sources/libfat/directory.c b/portlibs/sources/libcustomfat/source/directory.c similarity index 98% rename from portlibs/sources/libfat/directory.c rename to portlibs/sources/libcustomfat/source/directory.c index 55de3bb9..c09debe6 100644 --- a/portlibs/sources/libfat/directory.c +++ b/portlibs/sources/libcustomfat/source/directory.c @@ -204,8 +204,10 @@ static int _FAT_directory_mbsncasecmp (const char* s1, const char* s2, size_t le static bool _FAT_directory_entryGetAlias (const u8* entryData, char* destName) { - int i=0; - int j=0; + char c; + bool caseInfo; + int i = 0; + int j = 0; destName[0] = '\0'; if (entryData[0] != DIR_ENTRY_FREE) { @@ -219,14 +221,18 @@ static bool _FAT_directory_entryGetAlias (const u8* entryData, char* destName) { } } else { // Copy the filename from the dirEntry to the string + caseInfo = entryData[DIR_ENTRY_caseInfo] & CASE_LOWER_BASE; for (i = 0; (i < 8) && (entryData[DIR_ENTRY_name + i] != ' '); i++) { - destName[i] = entryData[DIR_ENTRY_name + i]; + c = entryData[DIR_ENTRY_name + i]; + destName[i] = (caseInfo ? tolower((unsigned char)c) : c); } // Copy the extension from the dirEntry to the string if (entryData[DIR_ENTRY_extension] != ' ') { destName[i++] = '.'; + caseInfo = entryData[DIR_ENTRY_caseInfo] & CASE_LOWER_EXT; for ( j = 0; (j < 3) && (entryData[DIR_ENTRY_extension + j] != ' '); j++) { - destName[i++] = entryData[DIR_ENTRY_extension + j]; + c = entryData[DIR_ENTRY_extension + j]; + destName[i++] = (caseInfo ? tolower((unsigned char)c) : c); } } destName[i] = '\0'; diff --git a/portlibs/sources/libfat/directory.h b/portlibs/sources/libcustomfat/source/directory.h similarity index 97% rename from portlibs/sources/libfat/directory.h rename to portlibs/sources/libcustomfat/source/directory.h index 93429217..ac66c781 100644 --- a/portlibs/sources/libfat/directory.h +++ b/portlibs/sources/libcustomfat/source/directory.h @@ -57,6 +57,9 @@ #define ATTRIB_HID 0x02 // Hidden #define ATTRIB_RO 0x01 // Read only +#define CASE_LOWER_EXT 0x10 // WinNT lowercase extension +#define CASE_LOWER_BASE 0x08 // WinNT lowercase basename + typedef enum {FT_DIRECTORY, FT_FILE} FILE_TYPE; typedef struct { @@ -77,7 +80,7 @@ enum DIR_ENTRY_offset { DIR_ENTRY_name = 0x00, DIR_ENTRY_extension = 0x08, DIR_ENTRY_attributes = 0x0B, - DIR_ENTRY_reserved = 0x0C, + DIR_ENTRY_caseInfo = 0x0C, DIR_ENTRY_cTime_ms = 0x0D, DIR_ENTRY_cTime = 0x0E, DIR_ENTRY_cDate = 0x10, diff --git a/portlibs/sources/libfat/disc.c b/portlibs/sources/libcustomfat/source/disc.c similarity index 100% rename from portlibs/sources/libfat/disc.c rename to portlibs/sources/libcustomfat/source/disc.c diff --git a/portlibs/sources/libfat/disc.h b/portlibs/sources/libcustomfat/source/disc.h similarity index 100% rename from portlibs/sources/libfat/disc.h rename to portlibs/sources/libcustomfat/source/disc.h diff --git a/portlibs/sources/libfat/fatdir.c b/portlibs/sources/libcustomfat/source/fatdir.c similarity index 98% rename from portlibs/sources/libfat/fatdir.c rename to portlibs/sources/libcustomfat/source/fatdir.c index 52a6fb51..fe0e781e 100644 --- a/portlibs/sources/libfat/fatdir.c +++ b/portlibs/sources/libcustomfat/source/fatdir.c @@ -465,16 +465,16 @@ int _FAT_statvfs_r (struct _reent *r, const char *path, struct statvfs *buf) _FAT_lock(&partition->lock); - if(memcmp(&buf->f_flag, "SCAN", 4) == 0) - { - //Special command was given to sync the numberFreeCluster - _FAT_partition_createFSinfo(partition); - } + if(memcmp(&buf->f_flag, "SCAN", 4) == 0) + { + //Special command was given to sync the numberFreeCluster + _FAT_partition_createFSinfo(partition); + } - if(partition->filesysType == FS_FAT32) - freeClusterCount = partition->fat.numberFreeCluster; - else - freeClusterCount = _FAT_fat_freeClusterCount (partition); + if(partition->filesysType == FS_FAT32) + freeClusterCount = partition->fat.numberFreeCluster; + else + freeClusterCount = _FAT_fat_freeClusterCount (partition); // FAT clusters = POSIX blocks buf->f_bsize = partition->bytesPerCluster; // File system block size. diff --git a/portlibs/sources/libfat/fatdir.h b/portlibs/sources/libcustomfat/source/fatdir.h similarity index 100% rename from portlibs/sources/libfat/fatdir.h rename to portlibs/sources/libcustomfat/source/fatdir.h diff --git a/portlibs/sources/libfat/fatfile.c b/portlibs/sources/libcustomfat/source/fatfile.c similarity index 97% rename from portlibs/sources/libfat/fatfile.c rename to portlibs/sources/libcustomfat/source/fatfile.c index e2a99f6a..f1e6d43e 100644 --- a/portlibs/sources/libfat/fatfile.c +++ b/portlibs/sources/libcustomfat/source/fatfile.c @@ -45,6 +45,37 @@ #include "filetime.h" #include "lock.h" +bool _FAT_findEntry(const char *path, DIR_ENTRY *dirEntry) { + PARTITION *partition = _FAT_partition_getPartitionFromPath(path); + + // Move the path pointer to the start of the actual path + if (strchr (path, ':') != NULL) { + path = strchr (path, ':') + 1; + } + if (strchr (path, ':') != NULL) { + return false; + } + + // Search for the file on the disc + return _FAT_directory_entryFromPath (partition, dirEntry, path, NULL); + +} + +int FAT_getAttr(const char *file) { + DIR_ENTRY dirEntry; + if (!_FAT_findEntry(file,&dirEntry)) return -1; + + return dirEntry.entryData[DIR_ENTRY_attributes]; +} + +int FAT_setAttr(const char *file, int attr) { + DIR_ENTRY dirEntry; + if (!_FAT_findEntry(file,&dirEntry)) return -1; + + return 0; +} + + int _FAT_open_r (struct _reent *r, void *fileStruct, const char *path, int flags, int mode) { PARTITION* partition = NULL; bool fileExists; diff --git a/portlibs/sources/libfat/fatfile.h b/portlibs/sources/libcustomfat/source/fatfile.h similarity index 100% rename from portlibs/sources/libfat/fatfile.h rename to portlibs/sources/libcustomfat/source/fatfile.h diff --git a/portlibs/sources/libfat/fatfile_frag.c b/portlibs/sources/libcustomfat/source/fatfile_frag.c similarity index 100% rename from portlibs/sources/libfat/fatfile_frag.c rename to portlibs/sources/libcustomfat/source/fatfile_frag.c diff --git a/portlibs/sources/libfat/fatfile_frag.h b/portlibs/sources/libcustomfat/source/fatfile_frag.h similarity index 100% rename from portlibs/sources/libfat/fatfile_frag.h rename to portlibs/sources/libcustomfat/source/fatfile_frag.h diff --git a/portlibs/sources/libfat/file_allocation_table.c b/portlibs/sources/libcustomfat/source/file_allocation_table.c similarity index 97% rename from portlibs/sources/libfat/file_allocation_table.c rename to portlibs/sources/libcustomfat/source/file_allocation_table.c index 9a3cc884..72f8aa74 100644 --- a/portlibs/sources/libfat/file_allocation_table.c +++ b/portlibs/sources/libcustomfat/source/file_allocation_table.c @@ -247,7 +247,7 @@ uint32_t _FAT_fat_linkFreeCluster(PARTITION* partition, uint32_t cluster) { } partition->fat.firstFree = firstFree; if(partition->fat.numberFreeCluster) - partition->fat.numberFreeCluster--; + partition->fat.numberFreeCluster--; partition->fat.numberLastAllocCluster = firstFree; if ((cluster >= CLUSTER_FIRST) && (cluster <= lastCluster)) @@ -279,7 +279,7 @@ uint32_t _FAT_fat_linkFreeClusterCleared (PARTITION* partition, uint32_t cluster return CLUSTER_ERROR; } - emptySector = (uint8_t*) _FAT_mem_allocate(partition->bytesPerSector); + emptySector = (uint8_t*) _FAT_mem_allocate(partition->bytesPerSector); // Clear all the sectors within the cluster memset (emptySector, 0, partition->bytesPerSector); @@ -317,8 +317,8 @@ bool _FAT_fat_clearLinks (PARTITION* partition, uint32_t cluster) { // Erase the link _FAT_fat_writeFatEntry (partition, cluster, CLUSTER_FREE); - if(partition->fat.numberFreeCluster < (partition->numberOfSectors/partition->sectorsPerCluster)) - partition->fat.numberFreeCluster++; + if(partition->fat.numberFreeCluster < (partition->numberOfSectors/partition->sectorsPerCluster)) + partition->fat.numberFreeCluster++; // Move onto next cluster cluster = nextCluster; } diff --git a/portlibs/sources/libfat/file_allocation_table.h b/portlibs/sources/libcustomfat/source/file_allocation_table.h similarity index 100% rename from portlibs/sources/libfat/file_allocation_table.h rename to portlibs/sources/libcustomfat/source/file_allocation_table.h diff --git a/portlibs/sources/libfat/filetime.c b/portlibs/sources/libcustomfat/source/filetime.c similarity index 100% rename from portlibs/sources/libfat/filetime.c rename to portlibs/sources/libcustomfat/source/filetime.c diff --git a/portlibs/sources/libfat/filetime.h b/portlibs/sources/libcustomfat/source/filetime.h similarity index 100% rename from portlibs/sources/libfat/filetime.h rename to portlibs/sources/libcustomfat/source/filetime.h diff --git a/portlibs/sources/libfat/libfat.c b/portlibs/sources/libcustomfat/source/libfat.c similarity index 100% rename from portlibs/sources/libfat/libfat.c rename to portlibs/sources/libcustomfat/source/libfat.c diff --git a/portlibs/sources/libfat/lock.c b/portlibs/sources/libcustomfat/source/lock.c similarity index 100% rename from portlibs/sources/libfat/lock.c rename to portlibs/sources/libcustomfat/source/lock.c diff --git a/portlibs/sources/libfat/lock.h b/portlibs/sources/libcustomfat/source/lock.h similarity index 100% rename from portlibs/sources/libfat/lock.h rename to portlibs/sources/libcustomfat/source/lock.h diff --git a/portlibs/sources/libfat/mem2.h b/portlibs/sources/libcustomfat/source/mem2.h similarity index 100% rename from portlibs/sources/libfat/mem2.h rename to portlibs/sources/libcustomfat/source/mem2.h diff --git a/portlibs/sources/libfat/mem_allocate.h b/portlibs/sources/libcustomfat/source/mem_allocate.h similarity index 100% rename from portlibs/sources/libfat/mem_allocate.h rename to portlibs/sources/libcustomfat/source/mem_allocate.h diff --git a/portlibs/sources/libfat/partition.c b/portlibs/sources/libcustomfat/source/partition.c similarity index 72% rename from portlibs/sources/libfat/partition.c rename to portlibs/sources/libcustomfat/source/partition.c index 41b9d761..9d220413 100644 --- a/portlibs/sources/libfat/partition.c +++ b/portlibs/sources/libcustomfat/source/partition.c @@ -38,8 +38,6 @@ #include #include -sec_t _FAT_startSector; - /* Data offsets */ @@ -93,10 +91,10 @@ enum BPB { // File system information block offsets enum FSIB { - FSIB_SIG1 = 0x00, - FSIB_SIG2 = 0x1e4, - FSIB_numberOfFreeCluster = 0x1e8, - FSIB_numberLastAllocCluster = 0x1ec, + FSIB_SIG1 = 0x00, + FSIB_SIG2 = 0x1e4, + FSIB_numberOfFreeCluster = 0x1e8, + FSIB_numberLastAllocCluster = 0x1ec, FSIB_bootSig_55 = 0x1FE, FSIB_bootSig_AA = 0x1FF }; @@ -105,20 +103,14 @@ static const char FAT_SIG[3] = {'F', 'A', 'T'}; static const char FS_INFO_SIG1[4] = {'R', 'R', 'a', 'A'}; static const char FS_INFO_SIG2[4] = {'r', 'r', 'A', 'a'}; -sec_t FindFirstValidPartition(const DISC_INTERFACE* disc) +sec_t FindFirstValidPartition_buf(const DISC_INTERFACE* disc, uint8_t *sectorBuffer) { uint8_t part_table[16*4]; uint8_t *ptr; int i; - uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(MAX_SECTOR_SIZE); - if(!sectorBuffer) { - return 0; - } - // Read first sector of disc if (!_FAT_disc_readSectors (disc, 0, 1, sectorBuffer)) { - _FAT_mem_free(sectorBuffer); return 0; } @@ -130,7 +122,6 @@ sec_t FindFirstValidPartition(const DISC_INTERFACE* disc) if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) || !memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) { - _FAT_mem_free(sectorBuffer); return part_lba; } @@ -143,61 +134,53 @@ sec_t FindFirstValidPartition(const DISC_INTERFACE* disc) for(n=0;n<8;n++) // max 8 logic partitions { - if(!_FAT_disc_readSectors (disc, part_lba+next_lba2, 1, sectorBuffer)) { - _FAT_mem_free(sectorBuffer); - return 0; - } + if(!_FAT_disc_readSectors (disc, part_lba+next_lba2, 1, sectorBuffer)) return 0; part_lba2 = part_lba + next_lba2 + u8array_to_u32(sectorBuffer, 0x1C6) ; next_lba2 = u8array_to_u32(sectorBuffer, 0x1D6); - if(!_FAT_disc_readSectors (disc, part_lba2, 1, sectorBuffer)) { - _FAT_mem_free(sectorBuffer); - return 0; - } + if(!_FAT_disc_readSectors (disc, part_lba2, 1, sectorBuffer)) return 0; if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) || - !memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) { - _FAT_mem_free(sectorBuffer); + !memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) + { return part_lba2; } if(next_lba2==0) break; } } else { - if(!_FAT_disc_readSectors (disc, part_lba, 1, sectorBuffer)) { - _FAT_mem_free(sectorBuffer); - return 0; - } + if(!_FAT_disc_readSectors (disc, part_lba, 1, sectorBuffer)) return 0; if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) || !memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) { - _FAT_mem_free(sectorBuffer); return part_lba; } } } - _FAT_mem_free(sectorBuffer); return 0; } +sec_t FindFirstValidPartition(const DISC_INTERFACE* disc) +{ + uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_align(MAX_SECTOR_SIZE); + if (!sectorBuffer) return 0; + sec_t ret = FindFirstValidPartition_buf(disc, sectorBuffer); + _FAT_mem_free(sectorBuffer); + return ret; +} -PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cacheSize, uint32_t sectorsPerPage, sec_t startSector) { + +PARTITION* _FAT_partition_constructor_buf (const DISC_INTERFACE* disc, uint32_t cacheSize, uint32_t sectorsPerPage, sec_t startSector, uint8_t *sectorBuffer) +{ PARTITION* partition; - uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(MAX_SECTOR_SIZE); - if(!sectorBuffer) { - return NULL; - } - // Read first sector of disc if (!_FAT_disc_readSectors (disc, startSector, 1, sectorBuffer)) { - _FAT_mem_free(sectorBuffer); return NULL; } // Make sure it is a valid MBR or boot sector if ( (sectorBuffer[BPB_bootSig_55] != 0x55) || (sectorBuffer[BPB_bootSig_AA] != 0xAA)) { - _FAT_mem_free(sectorBuffer); return NULL; } @@ -210,25 +193,21 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach // Check for FAT32 startSector = 0; } else { - startSector = FindFirstValidPartition(disc); + startSector = FindFirstValidPartition_buf(disc, sectorBuffer); if (!_FAT_disc_readSectors (disc, startSector, 1, sectorBuffer)) { - _FAT_mem_free(sectorBuffer); return NULL; } } - _FAT_startSector = startSector; - // Now verify that this is indeed a FAT partition if (memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) && - memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) { - _FAT_mem_free(sectorBuffer); + memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) + { return NULL; } partition = (PARTITION*) _FAT_mem_allocate (sizeof(PARTITION)); if (partition == NULL) { - _FAT_mem_free(sectorBuffer); return NULL; } @@ -255,19 +234,14 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach partition->numberOfSectors = u8array_to_u32( sectorBuffer, BPB_numSectors); } - if(disc->features & FEATURE_WII_USB) - partition->bytesPerSector = u8array_to_u16(sectorBuffer, BPB_bytesPerSector); - else - partition->bytesPerSector = MIN_SECTOR_SIZE; - + partition->bytesPerSector = u8array_to_u16(sectorBuffer, BPB_bytesPerSector); if(partition->bytesPerSector < MIN_SECTOR_SIZE || partition->bytesPerSector > MAX_SECTOR_SIZE) { - // Unsupported sector size - _FAT_mem_free(sectorBuffer); - _FAT_mem_free(partition); - return NULL; - } + // Unsupported sector size + _FAT_mem_free(partition); + return NULL; + } - partition->sectorsPerCluster = sectorBuffer[BPB_sectorsPerCluster] * u8array_to_u16(sectorBuffer, BPB_bytesPerSector) / partition->bytesPerSector; + partition->sectorsPerCluster = sectorBuffer[BPB_sectorsPerCluster]; partition->bytesPerCluster = partition->bytesPerSector * partition->sectorsPerCluster; partition->fat.fatStart = startSector + u8array_to_u16(sectorBuffer, BPB_reservedSectors); @@ -277,14 +251,14 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach partition->totalSize = ((uint64_t)partition->numberOfSectors - (partition->dataStart - startSector)) * (uint64_t)partition->bytesPerSector; - //FS info sector - partition->fsInfoSector = startSector + (u8array_to_u16(sectorBuffer, BPB_FAT32_fsInfo) ? u8array_to_u16(sectorBuffer, BPB_FAT32_fsInfo) : 1); + //FS info sector + partition->fsInfoSector = startSector + (u8array_to_u16(sectorBuffer, BPB_FAT32_fsInfo) ? u8array_to_u16(sectorBuffer, BPB_FAT32_fsInfo) : 1); // Store info about FAT uint32_t clusterCount = (partition->numberOfSectors - (uint32_t)(partition->dataStart - startSector)) / partition->sectorsPerCluster; partition->fat.lastCluster = clusterCount + CLUSTER_FIRST - 1; partition->fat.firstFree = CLUSTER_FIRST; - partition->fat.numberFreeCluster = 0; + partition->fat.numberFreeCluster = 0; partition->fat.numberLastAllocCluster = 0; if (clusterCount < CLUSTERS_PER_FAT12) { @@ -322,11 +296,20 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach _FAT_partition_readFSinfo(partition); - _FAT_mem_free(sectorBuffer); - return partition; } +PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cacheSize, uint32_t sectorsPerPage, sec_t startSector) +{ + uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_align(MAX_SECTOR_SIZE); + if (!sectorBuffer) return NULL; + PARTITION *ret = _FAT_partition_constructor_buf(disc, cacheSize, + sectorsPerPage, startSector, sectorBuffer); + _FAT_mem_free(sectorBuffer); + return ret; +} + + void _FAT_partition_destructor (PARTITION* partition) { FILE_STRUCT* nextFile; @@ -339,8 +322,8 @@ void _FAT_partition_destructor (PARTITION* partition) { nextFile = nextFile->nextOpenFile; } - // Write out the fs info sector - _FAT_partition_writeFSinfo(partition); + // Write out the fs info sector + _FAT_partition_writeFSinfo(partition); // Free memory used by the cache, writing it to disc at the same time _FAT_cache_destructor (partition->cache); @@ -367,89 +350,82 @@ PARTITION* _FAT_partition_getPartitionFromPath (const char* path) { void _FAT_partition_createFSinfo(PARTITION * partition) { - if(partition->readOnly || partition->filesysType != FS_FAT32) - return; + if(partition->readOnly || partition->filesysType != FS_FAT32) + return; - uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(partition->bytesPerSector); - if(!sectorBuffer) { - return; + uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_align(partition->bytesPerSector); + if (!sectorBuffer) return; + memset(sectorBuffer, 0, partition->bytesPerSector); + + int i; + for(i = 0; i < 4; ++i) + { + sectorBuffer[FSIB_SIG1+i] = FS_INFO_SIG1[i]; + sectorBuffer[FSIB_SIG2+i] = FS_INFO_SIG2[i]; } - memset(sectorBuffer, 0, partition->bytesPerSector); - int i; - for(i = 0; i < 4; ++i) - { - sectorBuffer[FSIB_SIG1+i] = FS_INFO_SIG1[i]; - sectorBuffer[FSIB_SIG2+i] = FS_INFO_SIG2[i]; - } + partition->fat.numberFreeCluster = _FAT_fat_freeClusterCount(partition); + u32_to_u8array(sectorBuffer, FSIB_numberOfFreeCluster, partition->fat.numberFreeCluster); + u32_to_u8array(sectorBuffer, FSIB_numberLastAllocCluster, partition->fat.numberLastAllocCluster); - partition->fat.numberFreeCluster = _FAT_fat_freeClusterCount(partition); - u32_to_u8array(sectorBuffer, FSIB_numberOfFreeCluster, partition->fat.numberFreeCluster); - u32_to_u8array(sectorBuffer, FSIB_numberLastAllocCluster, partition->fat.numberLastAllocCluster); + sectorBuffer[FSIB_bootSig_55] = 0x55; + sectorBuffer[FSIB_bootSig_AA] = 0xAA; - sectorBuffer[FSIB_bootSig_55] = 0x55; - sectorBuffer[FSIB_bootSig_AA] = 0xAA; + _FAT_disc_writeSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer); - _FAT_disc_writeSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer); - - _FAT_mem_free(sectorBuffer); + _FAT_mem_free(sectorBuffer); } void _FAT_partition_readFSinfo(PARTITION * partition) { - if(partition->filesysType != FS_FAT32) - return; + if(partition->filesysType != FS_FAT32) + return; - uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(partition->bytesPerSector); - if(!sectorBuffer) { - return; - } - memset(sectorBuffer, 0, partition->bytesPerSector); + uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_align(partition->bytesPerSector); + if (!sectorBuffer) return; + memset(sectorBuffer, 0, partition->bytesPerSector); // Read first sector of disc if (!_FAT_disc_readSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer)) { - _FAT_mem_free(sectorBuffer); + _FAT_mem_free(sectorBuffer); return; } - if(memcmp(sectorBuffer+FSIB_SIG1, FS_INFO_SIG1, 4) != 0 || - memcmp(sectorBuffer+FSIB_SIG2, FS_INFO_SIG2, 4) != 0 || - u8array_to_u32(sectorBuffer, FSIB_numberOfFreeCluster) == 0) { - //sector does not yet exist, create one! - _FAT_partition_createFSinfo(partition); - _FAT_mem_free(sectorBuffer); - return; - } - - partition->fat.numberFreeCluster = u8array_to_u32(sectorBuffer, FSIB_numberOfFreeCluster); - partition->fat.numberLastAllocCluster = u8array_to_u32(sectorBuffer, FSIB_numberLastAllocCluster); - _FAT_mem_free(sectorBuffer); + if(memcmp(sectorBuffer+FSIB_SIG1, FS_INFO_SIG1, 4) != 0 || + memcmp(sectorBuffer+FSIB_SIG2, FS_INFO_SIG2, 4) != 0 || + u8array_to_u32(sectorBuffer, FSIB_numberOfFreeCluster) == 0) + { + //sector does not yet exist, create one! + _FAT_partition_createFSinfo(partition); + } else { + partition->fat.numberFreeCluster = u8array_to_u32(sectorBuffer, FSIB_numberOfFreeCluster); + partition->fat.numberLastAllocCluster = u8array_to_u32(sectorBuffer, FSIB_numberLastAllocCluster); + } + _FAT_mem_free(sectorBuffer); } void _FAT_partition_writeFSinfo(PARTITION * partition) { - if(partition->filesysType != FS_FAT32) - return; + if(partition->filesysType != FS_FAT32) + return; - uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(partition->bytesPerSector); - if(!sectorBuffer) { - return; - } - memset(sectorBuffer, 0, partition->bytesPerSector); + uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_align(partition->bytesPerSector); + if (!sectorBuffer) return; + memset(sectorBuffer, 0, partition->bytesPerSector); // Read first sector of disc if (!_FAT_disc_readSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer)) { - _FAT_mem_free(sectorBuffer); + _FAT_mem_free(sectorBuffer); return; } if(memcmp(sectorBuffer+FSIB_SIG1, FS_INFO_SIG1, 4) || memcmp(sectorBuffer+FSIB_SIG2, FS_INFO_SIG2, 4)) { - _FAT_mem_free(sectorBuffer); - return; + _FAT_mem_free(sectorBuffer); + return; } - u32_to_u8array(sectorBuffer, FSIB_numberOfFreeCluster, partition->fat.numberFreeCluster); - u32_to_u8array(sectorBuffer, FSIB_numberLastAllocCluster, partition->fat.numberLastAllocCluster); + u32_to_u8array(sectorBuffer, FSIB_numberOfFreeCluster, partition->fat.numberFreeCluster); + u32_to_u8array(sectorBuffer, FSIB_numberLastAllocCluster, partition->fat.numberLastAllocCluster); - // Read first sector of disc + // Write first sector of disc _FAT_disc_writeSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer); _FAT_mem_free(sectorBuffer); } diff --git a/portlibs/sources/libfat/partition.h b/portlibs/sources/libcustomfat/source/partition.h similarity index 100% rename from portlibs/sources/libfat/partition.h rename to portlibs/sources/libcustomfat/source/partition.h diff --git a/portlibs/sources/libcustomntfs/AUTHORS b/portlibs/sources/libcustomntfs/AUTHORS new file mode 100644 index 00000000..b0ae639f --- /dev/null +++ b/portlibs/sources/libcustomntfs/AUTHORS @@ -0,0 +1,27 @@ + +Present authors of ntfs-3g in alphabetical order: + +Jean-Pierre Andre +Alon Bar-Lev +Dominique L Bouix +Csaba Henk +Bernhard Kaindl +Erik Larsson +Alejandro Pulver +Szabolcs Szakacsits +Miklos Szeredi + + +Past authors in alphabetical order: + +Anton Altaparmakov +Mario Emmenlauer +Yuval Fledel +Yura Pakhuchiy +Richard Russon + + +Nintendo GameCube/Wii port authors in alphabetical order: + +Rhys "Shareese" Koedijk +Dimok diff --git a/portlibs/sources/libcustomntfs/CREDITS b/portlibs/sources/libcustomntfs/CREDITS new file mode 100644 index 00000000..3c1bc7c3 --- /dev/null +++ b/portlibs/sources/libcustomntfs/CREDITS @@ -0,0 +1,50 @@ +The following people have contributed directly or indirectly +to the ntfs-3g project. + +Please let ntfs-3g-devel@lists.sf.net know if you believe +someone is missing, or if you prefer not to be listed. + +Dominique L Bouix +Csaba Henk +Max Khon +Auri Hautam�ki +Gergely Erdelyi +Anton Altaparmakov +Peter Boross +Don Bright +Mario Emmenlauer +Yuval Fledel +Kano from Kanotix +Roland Kletzing +Maarten Lankhorst +Gergely Madarasz +Patrick McLean +Florent Mertens +Yura Pakhuchiy +Miklos Szeredi +Bartosz Taudul +Zhanglinbao +Wade Fitzpatrick +Carsten Einig +Adam Cecile +Bruno Damour +Ales Fruman +Curt McDowell +Thomas Franken +Jonatan Lambert +Klaus Knopper +Zhanglinbao +Ismail Donmez +Laszlo Dvornik +Pallaghy Ajtony +Szabolcs Szakacsits +Jean-Pierre Andre +Alejandro Pulver +Erik Larsson +Alon Bar-Lev + +The following people have contributed directly or indirectly +to the Nintendo GameCube/Wii port of ntfs-3g. + +Michael "Chishm" Chisholm +rodries diff --git a/portlibs/sources/libcustomntfs/LICENSE b/portlibs/sources/libcustomntfs/LICENSE new file mode 100644 index 00000000..623b6258 --- /dev/null +++ b/portlibs/sources/libcustomntfs/LICENSE @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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. + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/portlibs/sources/libext2fs/Makefile b/portlibs/sources/libcustomntfs/Makefile similarity index 50% rename from portlibs/sources/libext2fs/Makefile rename to portlibs/sources/libcustomntfs/Makefile index d424b9af..8745416d 100644 --- a/portlibs/sources/libext2fs/Makefile +++ b/portlibs/sources/libcustomntfs/Makefile @@ -1,22 +1,28 @@ -default: wii-release +default: cube-release wii-release all: debug release -debug: wii-debug +debug: cube-debug wii-debug -release: wii-release +release: cube-release wii-release + +cube-debug: + $(MAKE) -C source PLATFORM=cube BUILD=cube_debug wii-debug: $(MAKE) -C source PLATFORM=wii BUILD=wii_debug +cube-release: + $(MAKE) -C source PLATFORM=cube BUILD=cube_release + wii-release: $(MAKE) -C source PLATFORM=wii BUILD=wii_release clean: $(MAKE) -C source clean -install: wii-release +install: cube-release wii-release $(MAKE) -C source install run: install diff --git a/portlibs/sources/libcustomntfs/READMII b/portlibs/sources/libcustomntfs/READMII new file mode 100644 index 00000000..ca8f1abe --- /dev/null +++ b/portlibs/sources/libcustomntfs/READMII @@ -0,0 +1,54 @@ + +INTRODUCTION +============ + +The NTFS-3G driver is an open source, freely available read/write NTFS driver +for Linux, FreeBSD, Mac OS X, NetBSD, Solaris and Haiku. It provides safe and +fast handling of the Windows XP, Windows Server 2003, Windows 2000, Windows +Vista, and Windows Server 2008 file systems. + +The purpose of the project is to develop, continuously quality test and +support a trustable, featureful and high performance solution for hardware +platforms and operating systems whose users need to reliably interoperate +with NTFS. Besides this practical goal, the project also aims to explore +the limits of the hybrid, kernel/user space filesystem driver approach, +performance, reliability and feature richness per invested effort wise. + +The driver is in STABLE status. The test methods, the test suites used +can be found at + + http://ntfs-3g.org/quality.html + +News, support answers, problem submission instructions, support and discussion +forums, performance numbers and other information are available on the project +web site at + + http://ntfs-3g.org + +For more details on the NTFS-3G project see the 'original' folder included +with this package. + +COMPILING AND INSTALLATION +========================== + +Make sure you have devKitPPC and the latest libogc installed. Then type: + + make + make install # or 'sudo make install' if you aren't root. + + +USAGE +===== + +NTFS related routines can be accessed by adding the following line to your +source file(s). + + #include + +When compiling you must also link against the libntfs. To do this add -lntfs +to the LIBS section of your application Makefile. For example: + + LIBS := -lwiiuse -lbte -lntfs -lfat -logc -lm + +For a more practical example of using NTFS in your application, +see the included 'example' folder. diff --git a/portlibs/sources/libcustomntfs/include/ntfs.h b/portlibs/sources/libcustomntfs/include/ntfs.h new file mode 100644 index 00000000..62f2f719 --- /dev/null +++ b/portlibs/sources/libcustomntfs/include/ntfs.h @@ -0,0 +1,148 @@ +/** + * ntfs.h - Simple functionality for startup, mounting and unmounting of NTFS-based devices. + * + * Copyright (c) 2010 Dimok + * Copyright (c) 2009 Rhys "Shareese" Koedijk + * Copyright (c) 2006 Michael "Chishm" Chisholm + * + * This program/include file 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. + * + * This program/include file 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _LIBNTFS_H +#define _LIBNTFS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* NTFS errno values */ +#define ENOPART 3000 /* No partition was found */ +#define EINVALPART 3001 /* Specified partition is invalid or not supported */ +#define EDIRTY 3002 /* Volume is dirty and NTFS_RECOVER was not specified during mount */ +#define EHIBERNATED 3003 /* Volume is hibernated and NTFS_IGNORE_HIBERFILE was not specified during mount */ + +/* NTFS cache options */ +#define CACHE_DEFAULT_PAGE_COUNT 8 /* The default number of pages in the cache */ +#define CACHE_DEFAULT_PAGE_SIZE 128 /* The default number of sectors per cache page */ + +/* NTFS mount flags */ +#define NTFS_DEFAULT 0x00000000 /* Standard mount, expects a clean, non-hibernated volume */ +#define NTFS_SHOW_HIDDEN_FILES 0x00000001 /* Display hidden files when enumerating directories */ +#define NTFS_SHOW_SYSTEM_FILES 0x00000002 /* Display system files when enumerating directories */ +#define NTFS_UPDATE_ACCESS_TIMES 0x00000004 /* Update file and directory access times */ +#define NTFS_RECOVER 0x00000008 /* Reset $LogFile if dirty (i.e. from unclean disconnect) */ +#define NTFS_IGNORE_HIBERFILE 0x00000010 /* Mount even if volume is hibernated */ +#define NTFS_READ_ONLY 0x00000020 /* Mount in read only mode */ +#define NTFS_IGNORE_CASE 0x00000040 /* Ignore case sensitivity. Everything must be and will be provided in lowercase. */ +#define NTFS_SU NTFS_SHOW_HIDDEN_FILES | NTFS_SHOW_SYSTEM_FILES +#define NTFS_FORCE NTFS_RECOVER | NTFS_IGNORE_HIBERFILE + +/** + * ntfs_md - NTFS mount descriptor + */ +typedef struct _ntfs_md { + char name[32]; /* Mount name (can be accessed as "name:/") */ + const DISC_INTERFACE *interface; /* Block device containing the mounted partition */ + sec_t startSector; /* Local block address to first sector of partition */ +} ntfs_md; + +/** + * Find all NTFS partitions on a block device. + * + * @param INTERFACE The block device to search + * @param PARTITIONS (out) A pointer to receive the array of partition start sectors + * + * @return The number of entries in PARTITIONS or -1 if an error occurred (see errno) + * @note The caller is responsible for freeing PARTITIONS when finished with it + */ +extern int ntfsFindPartitions (const DISC_INTERFACE *interface, sec_t **partitions); + +/** + * Mount all NTFS partitions on all inserted block devices. + * + * @param MOUNTS (out) A pointer to receive the array of mount descriptors + * @param FLAGS Additional mounting flags. (see above) + * + * @return The number of entries in MOUNTS or -1 if an error occurred (see errno) + * @note The caller is responsible for freeing MOUNTS when finished with it + * @note All device caches are setup using default values (see above) + */ +extern int ntfsMountAll (ntfs_md **mounts, u32 flags); + +/** + * Mount all NTFS partitions on a block devices. + * + * @param INTERFACE The block device to mount. + * @param MOUNTS (out) A pointer to receive the array of mount descriptors + * @param FLAGS Additional mounting flags. (see above) + * + * @return The number of entries in MOUNTS or -1 if an error occurred (see errno) + * @note The caller is responsible for freeing MOUNTS when finished with it + * @note The device cache is setup using default values (see above) + */ +extern int ntfsMountDevice (const DISC_INTERFACE* interface, ntfs_md **mounts, u32 flags); + +/** + * Mount a NTFS partition from a specific sector on a block device. + * + * @param NAME The name to mount the device under (can then be accessed as "NAME:/") + * @param INTERFACE The block device to mount + * @param STARTSECTOR The sector the partition begins at (see @ntfsFindPartitions) + * @param CACHEPAGECOUNT The total number of pages in the device cache + * @param CACHEPAGESIZE The number of sectors per cache page + * @param FLAGS Additional mounting flags (see above) + * + * @return True if mount was successful, false if no partition was found or an error occurred (see errno) + * @note ntfsFindPartitions should be used first to locate the partitions start sector + */ +extern bool ntfsMount (const char *name, const DISC_INTERFACE *interface, sec_t startSector, u32 cachePageCount, u32 cachePageSize, u32 flags); + +/** + * Unmount a NTFS partition. + * + * @param NAME The name of mount used in ntfsMountSimple() and ntfsMount() + * @param FORCE If true unmount even if the device is busy (may lead to data lose) + */ +extern void ntfsUnmount (const char *name, bool force); + +/** + * Get the volume name of a mounted NTFS partition. + * + * @param NAME The name of mount (see @ntfsMountAll, @ntfsMountDevice, and @ntfsMount) + * + * @return The volumes name if successful or NULL if an error occurred (see errno) + */ +extern const char *ntfsGetVolumeName (const char *name); + +/** + * Set the volume name of a mounted NTFS partition. + * + * @param NAME The name of mount (see @ntfsMountAll, @ntfsMountDevice, and @ntfsMount) + * @param VOLUMENAME The new volume name + * + * @return True if mount was successful, false if an error occurred (see errno) + * @note The mount must be write-enabled else this will fail + */ +extern bool ntfsSetVolumeName (const char *name, const char *volumeName); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBNTFS_H */ diff --git a/portlibs/sources/libcustomntfs/source/Makefile b/portlibs/sources/libcustomntfs/source/Makefile new file mode 100644 index 00000000..f922254d --- /dev/null +++ b/portlibs/sources/libcustomntfs/source/Makefile @@ -0,0 +1,130 @@ +#--------------------------------------------------------------------------------- +# Clear the implicit built in rules +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- +ifeq ($(strip $(DEVKITPPC)),) +$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") +endif + +ifeq ($(PLATFORM),wii) +include $(DEVKITPPC)/wii_rules +endif + +ifeq ($(PLATFORM),cube) +include $(DEVKITPPC)/gamecube_rules +endif + +#--------------------------------------------------------------------------------- +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# INCLUDES is a list of directories containing extra header files +#--------------------------------------------------------------------------------- +BUILD ?= wii_release +SOURCES := . +INCLUDES := ../include +LIBDIR := ../lib + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +CFLAGS = -O2 -Wall -ffast-math -pipe $(MACHDEP) $(INCLUDE) -DHAVE_CONFIG_H +CXXFLAGS = $(CFLAGS) +ASFLAGS := -g +export NTFSBIN := $(LIBDIR)/$(PLATFORM)/libntfs.a + +ifeq ($(BUILD),cube_debug) +CFLAGS += -DDEBUG +CXXFLAGS += -DDEBUG +endif +ifeq ($(BUILD),wii_debug) +CFLAGS += -DDEBUG +CXXFLAGS += -DDEBUG +endif + +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +LIBS := + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +export DEPSDIR := $(CURDIR)/$(BUILD) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) + + +export OFILES := $(addsuffix .o,$(BINFILES)) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) + +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) \ + -I$(LIBOGC_INC) + +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ + -L$(LIBOGC_LIB) + +.PHONY: $(BUILD) clean + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr wii_debug wii_release cube_debug cube_release $(LIBDIR) + +all: $(NTFSBIN) + +install: + cp ../include/ntfs.h $(DEVKITPRO)/libogc/include + cp ../lib/wii/libntfs.a $(DEVKITPRO)/libogc/lib/wii + cp ../lib/cube/libntfs.a $(DEVKITPRO)/libogc/lib/cube + +wii-install: + cp ../include/ntfs.h $(DEVKITPRO)/libogc/include + cp ../lib/wii/libntfs.a $(DEVKITPRO)/libogc/lib/wii + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(NTFSBIN): $(OFILES) $(LIBDIR)/$(PLATFORM) + @rm -f "../$(NTFSBIN)" + @$(AR) rcs "../$(NTFSBIN)" $(OFILES) + @echo built ... $(notdir $@) + +$(LIBDIR)/$(PLATFORM): + mkdir -p ../$(LIBDIR)/$(PLATFORM) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- + diff --git a/portlibs/sources/libntfs/acls.c b/portlibs/sources/libcustomntfs/source/acls.c similarity index 99% rename from portlibs/sources/libntfs/acls.c rename to portlibs/sources/libcustomntfs/source/acls.c index 2a58eeaf..070d7575 100644 --- a/portlibs/sources/libntfs/acls.c +++ b/portlibs/sources/libcustomntfs/source/acls.c @@ -522,9 +522,7 @@ gid_t ntfs_find_group(const struct MAPPING* groupmapping, const SID * gsid) { gid_t gid; const struct MAPPING *p; - int gsidsz; - gsidsz = ntfs_sid_size(gsid); p = groupmapping; while (p && p->xid && !ntfs_same_sid(gsid, p->sid)) p = p->next; @@ -880,7 +878,7 @@ BOOL ntfs_valid_posix(const struct POSIX_SECURITY *pxdesc) } } if ((pxdesc->acccnt > 0) - && ((checks[0].owners != 1) || (checks[0].groups != 1) + && ((checks[0].owners != 1) || (checks[0].groups != 1) || (checks[0].others != 1))) ok = FALSE; /* do not check owner, group or other are present in */ @@ -1806,7 +1804,7 @@ static BOOL build_group_denials_grant(ACL *pacl, * - grants to owner (always present - first grant) * + grants to designated user * + mask denial to group (unless mask allows all) - * - denials to group (preventing grants to world to apply) + * - denials to group (preventing grants to world to apply) * - grants to group (unless group has no more than world rights) * + mask denials to designated group (unless mask allows all) * + grants to designated group @@ -1901,7 +1899,6 @@ static int buildacls_posix(struct MAPPING* const mapping[], const SID *sid; int acecnt; int usidsz; - int gsidsz; int wsidsz; int asidsz; int ssidsz; @@ -1909,7 +1906,6 @@ static int buildacls_posix(struct MAPPING* const mapping[], le32 grants; usidsz = ntfs_sid_size(usid); - gsidsz = ntfs_sid_size(gsid); wsidsz = ntfs_sid_size(worldsid); asidsz = ntfs_sid_size(adminsid); ssidsz = ntfs_sid_size(systemsid); @@ -3132,7 +3128,6 @@ static int norm_ownadmin_permissions_posix(struct POSIX_SECURITY *posix_desc, u16 tag; u16 tagsset; struct POSIX_ACE *pxace; - int acccnt; mode_t denywrld; mode_t allow; mode_t deny; @@ -3141,7 +3136,6 @@ static int norm_ownadmin_permissions_posix(struct POSIX_SECURITY *posix_desc, mode = 0; pxace = posix_desc->acl.ace; - acccnt = posix_desc->acccnt; tagsset = 0; denywrld = 0; /* @@ -3881,12 +3875,10 @@ struct POSIX_SECURITY *ntfs_build_permissions_posix( int ntfs_build_permissions(const char *securattr, const SID *usid, const SID *gsid, BOOL isdir) { - const SECURITY_DESCRIPTOR_RELATIVE *phead; int perm; BOOL adminowns; BOOL groupowns; - phead = (const SECURITY_DESCRIPTOR_RELATIVE*)securattr; adminowns = ntfs_same_sid(usid,adminsid) || ntfs_same_sid(gsid,adminsid); groupowns = !adminowns && ntfs_same_sid(gsid,usid); @@ -3969,7 +3961,6 @@ static struct MAPLIST *getmappingitem(FILEREADER reader, void *fileid, { int src; int dst; - char *p; char *q; char *pu; char *pg; @@ -4003,7 +3994,6 @@ static struct MAPLIST *getmappingitem(FILEREADER reader, void *fileid, if (gotend) { pu = pg = (char*)NULL; /* decompose into uid, gid and sid */ - p = item->maptext; item->uidstr = item->maptext; item->gidstr = strchr(item->uidstr, ':'); if (item->gidstr) { diff --git a/portlibs/sources/libntfs/acls.h b/portlibs/sources/libcustomntfs/source/acls.h similarity index 100% rename from portlibs/sources/libntfs/acls.h rename to portlibs/sources/libcustomntfs/source/acls.h diff --git a/portlibs/sources/libntfs/attrib.c b/portlibs/sources/libcustomntfs/source/attrib.c similarity index 99% rename from portlibs/sources/libntfs/attrib.c rename to portlibs/sources/libcustomntfs/source/attrib.c index e6f614f0..281a6205 100644 --- a/portlibs/sources/libntfs/attrib.c +++ b/portlibs/sources/libcustomntfs/source/attrib.c @@ -475,9 +475,10 @@ ntfs_attr *ntfs_attr_open(ntfs_inode *ni, const ATTR_TYPES type, } cs = a->flags & (ATTR_IS_COMPRESSED | ATTR_IS_SPARSE); - + + /* a file may be sparse though its unnamed data is not (cf $UsnJrnl) */ if (na->type == AT_DATA && na->name == AT_UNNAMED && - ((!(a->flags & ATTR_IS_SPARSE) != !NAttrSparse(na)) || + (((a->flags & ATTR_IS_SPARSE) && !NAttrSparse(na)) || (!(a->flags & ATTR_IS_ENCRYPTED) != !NAttrEncrypted(na)))) { errno = EIO; ntfs_log_perror("Inode %lld has corrupt attribute flags " @@ -1774,7 +1775,6 @@ s64 ntfs_attr_pwrite(ntfs_attr *na, const s64 pos, s64 count, const void *b) } need_to = { 0, 0 }; BOOL wasnonresident = FALSE; BOOL compressed; - BOOL sparse; BOOL updatemap; ntfs_log_enter("Entering for inode %lld, attr 0x%x, pos 0x%llx, count " @@ -1850,7 +1850,7 @@ s64 ntfs_attr_pwrite(ntfs_attr *na, const s64 pos, s64 count, const void *b) goto errno_set; } #else - if (ntfs_attr_truncate(na, pos + count)) { + if (ntfs_attr_truncate_i(na, pos + count, HOLES_OK)) { ntfs_log_perror("Failed to enlarge attribute"); goto errno_set; } @@ -1860,7 +1860,6 @@ s64 ntfs_attr_pwrite(ntfs_attr *na, const s64 pos, s64 count, const void *b) != const_cpu_to_le16(0); need_to.undo_data_size = 1; } - sparse = (na->data_flags & ATTR_IS_SPARSE) != const_cpu_to_le16(0); /* * For compressed data, a single full block was allocated * to deal with compression, possibly in a previous call. @@ -2221,7 +2220,7 @@ done: updatemap = (compressed ? NAttrFullyMapped(na) != 0 : update_from != -1); #endif - if (updatemap) + if (updatemap) { if (ntfs_attr_update_mapping_pairs(na, (update_from < 0 ? 0 : update_from))) { /* @@ -2231,6 +2230,10 @@ done: total = -1; goto out; } + if (!wasnonresident) + NAttrClearBeingNonResident(na); + NAttrClearDataAppending(na); + } out: ntfs_log_leave("\n"); return total; @@ -2292,7 +2295,8 @@ err_out: if (updatemap) ntfs_attr_update_mapping_pairs(na, 0); /* Restore original data_size if needed. */ - if (need_to.undo_data_size && ntfs_attr_truncate(na, old_data_size)) + if (need_to.undo_data_size + && ntfs_attr_truncate_i(na, old_data_size, HOLES_OK)) ntfs_log_perror("Failed to restore data_size"); errno = eo; errno_set: @@ -2310,7 +2314,6 @@ int ntfs_attr_pclose(ntfs_attr *na) ntfs_attr_search_ctx *ctx = NULL; runlist_element *rl; int eo; - s64 hole; int compressed_part; BOOL compressed; @@ -2422,7 +2425,6 @@ int ntfs_attr_pclose(ntfs_attr *na) goto rl_err_out; } if (rl->lcn < (LCN)0) { - hole = rl->vcn + rl->length; if (rl->lcn != (LCN)LCN_HOLE) { errno = EIO; ntfs_log_perror("%s: Unexpected LCN (%lld)", @@ -2475,6 +2477,7 @@ retry: goto out; } out: + NAttrClearComprClosing(na); ntfs_log_leave("\n"); return (!ok); rl_err_out: @@ -2531,6 +2534,7 @@ s64 ntfs_attr_mst_pread(ntfs_attr *na, const s64 pos, const s64 bk_cnt, { s64 br; u8 *end; + BOOL warn; ntfs_log_trace("Entering for inode 0x%llx, attr type 0x%x, pos 0x%llx.\n", (unsigned long long)na->ni->mft_no, na->type, @@ -2544,9 +2548,11 @@ s64 ntfs_attr_mst_pread(ntfs_attr *na, const s64 pos, const s64 bk_cnt, if (br <= 0) return br; br /= bk_size; + /* log errors unless silenced */ + warn = !na->ni || !na->ni->vol || !NVolNoFixupWarn(na->ni->vol); for (end = (u8*)dst + br * bk_size; (u8*)dst < end; dst = (u8*)dst + bk_size) - ntfs_mst_post_read_fixup((NTFS_RECORD*)dst, bk_size); + ntfs_mst_post_read_fixup_warn((NTFS_RECORD*)dst, bk_size, warn); /* Finally, return the number of blocks read. */ return br; } @@ -3544,6 +3550,14 @@ int ntfs_attr_size_bounds_check(const ntfs_volume *vol, const ATTR_TYPES type, min_size = sle64_to_cpu(ad->min_size); max_size = sle64_to_cpu(ad->max_size); + + /* The $AttrDef generated by Windows specifies 2 as min_size for the + * volume name attribute, but in reality Windows sets it to 0 when + * clearing the volume name. If we want to be able to clear the volume + * name we must also accept 0 as min_size, despite the $AttrDef + * definition. */ + if(type == AT_VOLUME_NAME) + min_size = 0; if ((min_size && (size < min_size)) || ((max_size > 0) && (size > max_size))) { @@ -4296,7 +4310,7 @@ add_non_resident: goto rm_attr_err_out; } /* Resize and set attribute value. */ - if (ntfs_attr_truncate(na, size) || + if (ntfs_attr_truncate_i(na, size, HOLES_OK) || (val && (ntfs_attr_pwrite(na, 0, size, val) != size))) { err = errno; ntfs_log_perror("Failed to initialize just added attribute"); @@ -4877,6 +4891,7 @@ cluster_free_err_out: ntfs_log_trace("Eeek! Failed to release allocated clusters in error " "code path. Leaving inconsistent metadata...\n"); NAttrClearNonResident(na); + NAttrClearFullyMapped(na); na->allocated_size = na->data_size; na->rl = NULL; free(rl); @@ -5000,7 +5015,7 @@ static int ntfs_resident_attr_resize_i(ntfs_attr *na, const s64 newsize, return (ret); } /* Resize non-resident attribute */ - return ntfs_attr_truncate(na, newsize); + return ntfs_attr_truncate_i(na, newsize, HOLES_OK); } else if (errno != ENOSPC && errno != EPERM) { err = errno; ntfs_log_perror("Failed to make attribute non-resident"); @@ -5348,7 +5363,6 @@ static int ntfs_attr_make_resident(ntfs_attr *na, ntfs_attr_search_ctx *ctx) * record is in a transiently corrupted state at this moment in time. */ if (ntfs_cluster_free(vol, na, 0, -1) < 0) { - err = errno; ntfs_log_perror("Eeek! Failed to release allocated clusters"); ntfs_log_trace("Ignoring error and leaving behind wasted " "clusters.\n"); @@ -5360,6 +5374,7 @@ static int ntfs_attr_make_resident(ntfs_attr *na, ntfs_attr_search_ctx *ctx) /* Update in-memory struct ntfs_attr. */ NAttrClearNonResident(na); + NAttrClearFullyMapped(na); NAttrClearSparse(na); NAttrClearEncrypted(na); na->initialized_size = na->data_size; @@ -5453,6 +5468,7 @@ static int ntfs_attr_update_meta(ATTR_RECORD *a, ntfs_attr *na, MFT_RECORD *m, NAttrClearSparse(na); a->flags &= ~ATTR_IS_SPARSE; + na->data_flags = a->flags; a->compression_unit = 0; memmove((u8*)a + le16_to_cpu(a->name_offset) - 8, @@ -6422,7 +6438,12 @@ out: int ntfs_attr_truncate(ntfs_attr *na, const s64 newsize) { - return (ntfs_attr_truncate_i(na, newsize, HOLES_OK)); + int r; + + r = ntfs_attr_truncate_i(na, newsize, HOLES_OK); + NAttrClearDataAppending(na); + NAttrClearBeingNonResident(na); + return (r); } /* diff --git a/portlibs/sources/libntfs/attrib.h b/portlibs/sources/libcustomntfs/source/attrib.h similarity index 100% rename from portlibs/sources/libntfs/attrib.h rename to portlibs/sources/libcustomntfs/source/attrib.h diff --git a/portlibs/sources/libntfs/attrib_frag.c b/portlibs/sources/libcustomntfs/source/attrib_frag.c similarity index 100% rename from portlibs/sources/libntfs/attrib_frag.c rename to portlibs/sources/libcustomntfs/source/attrib_frag.c diff --git a/portlibs/sources/libntfs/attrlist.c b/portlibs/sources/libcustomntfs/source/attrlist.c similarity index 100% rename from portlibs/sources/libntfs/attrlist.c rename to portlibs/sources/libcustomntfs/source/attrlist.c diff --git a/portlibs/sources/libntfs/attrlist.h b/portlibs/sources/libcustomntfs/source/attrlist.h similarity index 100% rename from portlibs/sources/libntfs/attrlist.h rename to portlibs/sources/libcustomntfs/source/attrlist.h diff --git a/portlibs/sources/libntfs/bit_ops.h b/portlibs/sources/libcustomntfs/source/bit_ops.h similarity index 100% rename from portlibs/sources/libntfs/bit_ops.h rename to portlibs/sources/libcustomntfs/source/bit_ops.h diff --git a/portlibs/sources/libntfs/bitmap.c b/portlibs/sources/libcustomntfs/source/bitmap.c similarity index 100% rename from portlibs/sources/libntfs/bitmap.c rename to portlibs/sources/libcustomntfs/source/bitmap.c diff --git a/portlibs/sources/libntfs/bitmap.h b/portlibs/sources/libcustomntfs/source/bitmap.h similarity index 100% rename from portlibs/sources/libntfs/bitmap.h rename to portlibs/sources/libcustomntfs/source/bitmap.h diff --git a/portlibs/sources/libntfs/bootsect.c b/portlibs/sources/libcustomntfs/source/bootsect.c similarity index 100% rename from portlibs/sources/libntfs/bootsect.c rename to portlibs/sources/libcustomntfs/source/bootsect.c diff --git a/portlibs/sources/libntfs/bootsect.h b/portlibs/sources/libcustomntfs/source/bootsect.h similarity index 100% rename from portlibs/sources/libntfs/bootsect.h rename to portlibs/sources/libcustomntfs/source/bootsect.h diff --git a/portlibs/sources/libntfs/cache.c b/portlibs/sources/libcustomntfs/source/cache.c similarity index 99% rename from portlibs/sources/libntfs/cache.c rename to portlibs/sources/libcustomntfs/source/cache.c index b1ae2915..faabe628 100644 --- a/portlibs/sources/libntfs/cache.c +++ b/portlibs/sources/libcustomntfs/source/cache.c @@ -376,7 +376,6 @@ int ntfs_invalidate_cache(struct CACHE_HEADER *cache, int flags) { struct CACHED_GENERIC *current; - struct CACHED_GENERIC *previous; struct CACHED_GENERIC *next; struct HASH_ENTRY *link; int count; @@ -412,7 +411,6 @@ int ntfs_invalidate_cache(struct CACHE_HEADER *cache, * Search sequentially in LRU list */ current = cache->most_recent_entry; - previous = (struct CACHED_GENERIC*)NULL; while (current) { if (!compare(current, item)) { next = current->next; @@ -423,7 +421,6 @@ int ntfs_invalidate_cache(struct CACHE_HEADER *cache, current = next; count++; } else { - previous = current; current = current->next; } } diff --git a/portlibs/sources/libntfs/cache.h b/portlibs/sources/libcustomntfs/source/cache.h similarity index 100% rename from portlibs/sources/libntfs/cache.h rename to portlibs/sources/libcustomntfs/source/cache.h diff --git a/portlibs/sources/libntfs/cache2.c b/portlibs/sources/libcustomntfs/source/cache2.c similarity index 100% rename from portlibs/sources/libntfs/cache2.c rename to portlibs/sources/libcustomntfs/source/cache2.c diff --git a/portlibs/sources/libntfs/cache2.h b/portlibs/sources/libcustomntfs/source/cache2.h similarity index 100% rename from portlibs/sources/libntfs/cache2.h rename to portlibs/sources/libcustomntfs/source/cache2.h diff --git a/portlibs/sources/libntfs/collate.c b/portlibs/sources/libcustomntfs/source/collate.c similarity index 100% rename from portlibs/sources/libntfs/collate.c rename to portlibs/sources/libcustomntfs/source/collate.c diff --git a/portlibs/sources/libntfs/collate.h b/portlibs/sources/libcustomntfs/source/collate.h similarity index 100% rename from portlibs/sources/libntfs/collate.h rename to portlibs/sources/libcustomntfs/source/collate.h diff --git a/portlibs/sources/libntfs/compat.c b/portlibs/sources/libcustomntfs/source/compat.c similarity index 100% rename from portlibs/sources/libntfs/compat.c rename to portlibs/sources/libcustomntfs/source/compat.c diff --git a/portlibs/sources/libntfs/compat.h b/portlibs/sources/libcustomntfs/source/compat.h similarity index 100% rename from portlibs/sources/libntfs/compat.h rename to portlibs/sources/libcustomntfs/source/compat.h diff --git a/portlibs/sources/libntfs/compress.c b/portlibs/sources/libcustomntfs/source/compress.c similarity index 88% rename from portlibs/sources/libntfs/compress.c rename to portlibs/sources/libcustomntfs/source/compress.c index 73d493e1..aeb082d5 100644 --- a/portlibs/sources/libntfs/compress.c +++ b/portlibs/sources/libcustomntfs/source/compress.c @@ -28,7 +28,7 @@ * this was put into public domain in 1988 by Haruhiko OKUMURA). * * LZHUF.C English version 1.0 - * Based on Japanese version 29-NOV-1988 + * Based on Japanese version 29-NOV-1988 * LZSS coded by Haruhiko OKUMURA * Adaptive Huffman Coding coded by Haruyasu YOSHIZAKI * Edited and translated to English by Kenji RIKITAKE @@ -62,8 +62,8 @@ #include "logging.h" #include "misc.h" -#undef le16_to_cpup -/* the standard le16_to_cpup() crashes for unaligned data on some processors */ +#undef le16_to_cpup +/* the standard le16_to_cpup() crashes for unaligned data on some processors */ #define le16_to_cpup(p) (*(u8*)(p) + (((u8*)(p))[1] << 8)) /** @@ -81,259 +81,215 @@ typedef enum { NTFS_SB_IS_COMPRESSED = 0x8000, } ntfs_compression_constants; -#define THRESHOLD 3 /* minimal match length for compression */ -#define NIL NTFS_SB_SIZE /* End of tree's node */ - struct COMPRESS_CONTEXT { const unsigned char *inbuf; - unsigned int len; - unsigned int nbt; - int match_position; - unsigned int match_length; - u16 lson[NTFS_SB_SIZE + 1]; - u16 rson[NTFS_SB_SIZE + 257]; - u16 dad[NTFS_SB_SIZE + 1]; + int bufsize; + int size; + int rel; + int mxsz; + s16 head[256]; + s16 lson[NTFS_SB_SIZE]; + s16 rson[NTFS_SB_SIZE]; } ; /* - * Initialize the match tree - */ - -static void ntfs_init_compress_tree(struct COMPRESS_CONTEXT *pctx) -{ - int i; - - for (i = NTFS_SB_SIZE + 1; i <= NTFS_SB_SIZE + 256; i++) - pctx->rson[i] = NIL; /* root */ - for (i = 0; i < NTFS_SB_SIZE; i++) - pctx->dad[i] = NIL; /* node */ -} - -/* - * Insert a new node into match tree for quickly locating - * further similar strings - */ - -static void ntfs_new_node (struct COMPRESS_CONTEXT *pctx, - unsigned int r) -{ - unsigned int pp; - BOOL less; - BOOL done; - const unsigned char *key; - int c; - unsigned long mxi; - unsigned int mxl; - - mxl = (1 << (16 - pctx->nbt)) + 2; - less = FALSE; - done = FALSE; - key = &pctx->inbuf[r]; - pp = NTFS_SB_SIZE + 1 + key[0]; - pctx->rson[r] = pctx->lson[r] = NIL; - pctx->match_length = 0; - do { - if (!less) { - if (pctx->rson[pp] != NIL) - pp = pctx->rson[pp]; - else { - pctx->rson[pp] = r; - pctx->dad[r] = pp; - done = TRUE; - } - } else { - if (pctx->lson[pp] != NIL) - pp = pctx->lson[pp]; - else { - pctx->lson[pp] = r; - pctx->dad[r] = pp; - done = TRUE; - } - } - if (!done) { - register unsigned long i; - register const unsigned char *p1,*p2; - - i = 1; - mxi = NTFS_SB_SIZE - r; - if (mxi < 2) - less = FALSE; - else { - p1 = key; - p2 = &pctx->inbuf[pp]; - /* this loop has a significant impact on performances */ - do { - } while ((p1[i] == p2[i]) && (++i < mxi)); - less = (i < mxi) && (p1[i] < p2[i]); - } - if (i >= THRESHOLD) { - if (i > pctx->match_length) { - pctx->match_position = - r - pp + 2*NTFS_SB_SIZE - 1; - if ((pctx->match_length = i) > mxl) { - i = pctx->rson[pp]; - pctx->rson[r] = i; - pctx->dad[i] = r; - i = pctx->lson[pp]; - pctx->lson[r] = i; - pctx->dad[i] = r; - i = pctx->dad[pp]; - pctx->dad[r] = i; - if (pctx->rson[i] == pp) - pctx->rson[i] = r; - else - pctx->lson[i] = r; - /* remove pp */ - pctx->dad[pp] = NIL; - done = TRUE; - pctx->match_length = mxl; - } - } else - if ((i == pctx->match_length) - && ((c = (r - pp + 2*NTFS_SB_SIZE - 1)) - < pctx->match_position)) - pctx->match_position = c; - } - } - } while (!done); -} - -/* - * Search for the longest previous string matching the - * current one + * Search for the longest sequence matching current position * - * Returns the end of the longest current string which matched - * or zero if there was a bug + * A binary tree is maintained to locate all previously met sequences, + * and this function has to be called for all of them. + * + * This function is heavily used, it has to be optimized carefully + * + * Returns the size of the longest match, + * zero if no match is found. */ -static unsigned int ntfs_nextmatch(struct COMPRESS_CONTEXT *pctx, - unsigned int rr, int dd) +static int ntfs_best_match(struct COMPRESS_CONTEXT *pctx, int i) { - unsigned int bestlen = 0; + s16 *prev; + int node; + register long j; + long maxpos; + long startj; + long bestj; + int bufsize; + int bestnode; + register const unsigned char *p1,*p2; - do { - rr++; - if (pctx->match_length > 0) - pctx->match_length--; - if (!pctx->len) { - ntfs_log_error("compress bug : void run\n"); - goto bug; - } - if (--pctx->len) { - if (rr >= NTFS_SB_SIZE) { - ntfs_log_error("compress bug : buffer overflow\n"); - goto bug; - } - if (((rr + bestlen) < NTFS_SB_SIZE)) { - while ((unsigned int)(1 << pctx->nbt) - <= (rr - 1)) - pctx->nbt++; - ntfs_new_node(pctx,rr); - if (pctx->match_length > bestlen) - bestlen = pctx->match_length; - } else - if (dd > 0) { - rr += dd; - if ((int)pctx->match_length > dd) - pctx->match_length -= dd; - else - pctx->match_length = 0; - if ((int)pctx->len < dd) { - ntfs_log_error("compress bug : run overflows\n"); - goto bug; + p1 = pctx->inbuf; + node = pctx->head[p1[i] & 255]; + if (node >= 0) { + /* search the best match at current position */ + bestnode = node; + bufsize = pctx->bufsize; + /* restrict matches to the longest allowed sequence */ + maxpos = bufsize; + if ((i + pctx->mxsz) < maxpos) + maxpos = i + pctx->mxsz; + startj = i + 1 - maxpos; + bestj = startj; + /* make indexes relative to end of allowed position */ + p1 = &p1[maxpos]; + if (startj < 0) { + do { + /* indexes are negative */ + p2 = &p1[node - i]; + /* no need to compare the first byte */ + j = startj; + /* the second byte cannot lead to useful compression */ + if (p1[j] == p2[j]) { + j++; + if (j < 0) { + do { + } while ((p1[j] == p2[j]) + && (++j < 0)); + } + /* remember the match, if better */ + if (j > bestj) { + bestj = j; + bestnode = node; } - pctx->len -= dd; - dd = 0; } + /* walk in the tree in the right direction */ + if ((j < 0) && (p1[j] < p2[j])) + prev = &pctx->lson[node]; + else + prev = &pctx->rson[node]; + node = *prev; + /* stop if reaching a leaf or maximum length */ + } while ((node >= 0) && (j < 0)); + /* put the node into the tree if we reached a leaf */ + if (node < 0) + *prev = i; } - } while (dd-- > 0); - return (rr); -bug : - return (0); + /* done, return the best match */ + pctx->size = bestj + maxpos - i; + pctx->rel = bestnode - i; + } else { + pctx->head[p1[i] & 255] = i; + pctx->size = 0; + pctx->rel = 0; + } + return (pctx->size); } /* - * Compress an input block + * Compress a 4096-byte block * - * Returns the size of the compressed block (including header) - * or zero if there was an error + * Returns a header of two bytes followed by the compressed data. + * If compression is not effective, the header and an uncompressed + * block is returned. + * + * Note : two bytes may be output before output buffer overflow + * is detected, so a 4100-bytes output buffer must be reserved. + * + * Returns the size of the compressed block, including the + * header (minimal size is 2, maximum size is 4098) + * 0 if an error has been met. */ -static unsigned int ntfs_compress_block(const char *inbuf, - unsigned int size, char *outbuf) +static unsigned int ntfs_compress_block(const char *inbuf, int bufsize, + char *outbuf) { struct COMPRESS_CONTEXT *pctx; - char *ptag; - int dd; - unsigned int rr; - unsigned int last_match_length; - unsigned int q; + int i; /* current position */ + int j; /* end of best match from current position */ + int k; /* end of best match from next position */ + int offs; /* offset to best match */ + int n; + int bp; /* bits to store offset */ + int mxoff; /* max match offset : 1 << bp */ + int mxsz2; unsigned int xout; - unsigned int ntag; + unsigned int q; /* aggregated offset and size */ + int done; + char *ptag; /* location reserved for a tag */ + int tag; /* current value of tag */ + int ntag; /* count of bits still undefined in tag */ pctx = (struct COMPRESS_CONTEXT*)ntfs_malloc(sizeof(struct COMPRESS_CONTEXT)); if (pctx) { + for (n=0; nlson[n] = pctx->rson[n] = -1; + for (n=0; n<256; n++) + pctx->head[n] = -1; pctx->inbuf = (const unsigned char*)inbuf; - ntfs_init_compress_tree(pctx); + pctx->bufsize = bufsize; xout = 2; - ntag = 0; + n = 0; + i = 0; + bp = 4; + mxoff = 1 << bp; + pctx->mxsz = (1 << (16 - bp)) + 2; + tag = 0; + done = -1; + ntag = 8; ptag = &outbuf[xout++]; - *ptag = 0; - rr = 0; - pctx->nbt = 4; - pctx->len = size; - pctx->match_length = 0; - ntfs_new_node(pctx,0); - do { - if (pctx->match_length > pctx->len) - pctx->match_length = pctx->len; - if (pctx->match_length < THRESHOLD) { - pctx->match_length = 1; - if (ntag >= 8) { - ntag = 0; - ptag = &outbuf[xout++]; - *ptag = 0; + while ((i < bufsize) && (xout < (NTFS_SB_SIZE + 2))) { + /* adjust the longest match we can output */ + while (mxoff < i) { + bp++; + mxoff <<= 1; + pctx->mxsz = (pctx->mxsz + 2) >> 1; + } + /* search the best match at current position */ + if (done < i) + do { + ntfs_best_match(pctx,++done); + } while (done < i); + j = i + pctx->size; + if ((j - i) > pctx->mxsz) + j = i + pctx->mxsz; + + if ((j - i) > 2) { + offs = pctx->rel; + /* check whether there is a better run at i+1 */ + ntfs_best_match(pctx,i+1); + done = i+1; + k = i + 1 + pctx->size; + mxsz2 = pctx->mxsz; + if (mxoff <= i) + mxsz2 = (pctx->mxsz + 2) >> 1; + if ((k - i) > mxsz2) + k = i + mxsz2; + if (k > (j + 1)) { + /* issue a single byte */ + outbuf[xout++] = inbuf[i]; + i++; + } else { + q = (~offs << (16 - bp)) + + (j - i - 3); + outbuf[xout++] = q & 255; + outbuf[xout++] = (q >> 8) & 255; + tag |= (1 << (8 - ntag)); + i = j; } - outbuf[xout++] = inbuf[rr]; - ntag++; } else { - while ((unsigned int)(1 << pctx->nbt) - <= (rr - 1)) - pctx->nbt++; - q = (pctx->match_position << (16 - pctx->nbt)) - + pctx->match_length - THRESHOLD; - if (ntag >= 8) { - ntag = 0; - ptag = &outbuf[xout++]; - *ptag = 0; - } - *ptag |= 1 << ntag++; - outbuf[xout++] = q & 255; - outbuf[xout++] = (q >> 8) & 255; + outbuf[xout++] = inbuf[i]; + i++; } - last_match_length = pctx->match_length; - dd = last_match_length; - if (dd-- > 0) { - rr = ntfs_nextmatch(pctx,rr,dd); - if (!rr) - goto bug; + /* store the tag if fully used */ + if (!--ntag) { + *ptag = tag; + ntag = 8; + ptag = &outbuf[xout++]; + tag = 0; } - /* - * stop if input is exhausted or output has exceeded - * the maximum size. Two extra bytes have to be - * reserved in output buffer, as 3 bytes may be - * output in a loop. - */ - } while ((pctx->len > 0) - && (rr < size) && (xout < (NTFS_SB_SIZE + 2))); - /* uncompressed must be full size, so accept if better */ - if (xout < (NTFS_SB_SIZE + 2)) { + } + /* store the last tag, if partially used */ + if (ntag == 8) + xout--; + else + *ptag = tag; + /* uncompressed must be full size, accept if better */ + if ((i >= bufsize) && (xout < (NTFS_SB_SIZE + 2))) { outbuf[0] = (xout - 3) & 255; outbuf[1] = 0xb0 + (((xout - 3) >> 8) & 15); } else { - memcpy(&outbuf[2],inbuf,size); - if (size < NTFS_SB_SIZE) - memset(&outbuf[size+2],0,NTFS_SB_SIZE - size); + memcpy(&outbuf[2],inbuf,bufsize); + if (bufsize < NTFS_SB_SIZE) + memset(&outbuf[bufsize+2], 0, + NTFS_SB_SIZE - bufsize); outbuf[0] = 0xff; outbuf[1] = 0x3f; xout = NTFS_SB_SIZE + 2; @@ -343,9 +299,7 @@ static unsigned int ntfs_compress_block(const char *inbuf, xout = 0; errno = ENOMEM; } - return (xout); /* 0 for an error, > size if cannot compress */ -bug : - return (0); + return (xout); } /** @@ -547,7 +501,7 @@ return_overflow: * code. Might be a bit confusing to debug but there really should never be * errors coming from here. */ -static BOOL ntfs_is_cb_compressed(ntfs_attr *na, runlist_element *rl, +static BOOL ntfs_is_cb_compressed(ntfs_attr *na, runlist_element *rl, VCN cb_start_vcn, int cb_clusters) { /* @@ -667,12 +621,12 @@ s64 ntfs_compressed_attr_pread(ntfs_attr *na, s64 pos, s64 count, void *b) cb_size = na->compression_block_size; cb_size_mask = cb_size - 1UL; cb_clusters = na->compression_block_clusters; - + /* Need a temporary buffer for each loaded compression block. */ cb = (u8*)ntfs_malloc(cb_size); if (!cb) return -1; - + /* Need a temporary buffer for each uncompressed block. */ dest = (u8*)ntfs_malloc(cb_size); if (!dest) { @@ -1512,12 +1466,12 @@ static int ntfs_read_append(ntfs_attr *na, const runlist_element *rl, * or -1 if there were an irrecoverable error (errno set) */ -static int ntfs_flush(ntfs_attr *na, runlist_element *rl, s64 offs, +static s32 ntfs_flush(ntfs_attr *na, runlist_element *rl, s64 offs, const char *outbuf, s32 count, BOOL compress, BOOL appending, VCN *update_from) { - int rounded; - int written; + s32 rounded; + s32 written; int clsz; if (compress) { @@ -1655,7 +1609,7 @@ s64 ntfs_compressed_pwrite(ntfs_attr *na, runlist_element *wrl, s64 wpos, * (we are reopening an existing file to append to it) * Decompress the data and append */ - compsz = compressed_part << vol->cluster_size_bits; + compsz = (s32)compressed_part << vol->cluster_size_bits; outbuf = (char*)ntfs_malloc(na->compression_block_size); if (outbuf) { if (appending) { diff --git a/portlibs/sources/libntfs/compress.h b/portlibs/sources/libcustomntfs/source/compress.h similarity index 100% rename from portlibs/sources/libntfs/compress.h rename to portlibs/sources/libcustomntfs/source/compress.h diff --git a/portlibs/sources/libntfs/config.h b/portlibs/sources/libcustomntfs/source/config.h similarity index 97% rename from portlibs/sources/libntfs/config.h rename to portlibs/sources/libcustomntfs/source/config.h index a0a5da00..f145094c 100644 --- a/portlibs/sources/libntfs/config.h +++ b/portlibs/sources/libcustomntfs/source/config.h @@ -226,6 +226,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_BYTEORDER_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_DISK_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_ENDIAN_H @@ -309,13 +312,13 @@ #define PACKAGE_NAME "ntfs-3g" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "ntfs-3g 2011.4.12" +#define PACKAGE_STRING "ntfs-3g 2012.1.15" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "ntfs-3g" /* Define to the version of this package. */ -#define PACKAGE_VERSION "2011.4.12" +#define PACKAGE_VERSION "2012.1.15" /* POSIX ACL support */ #undef POSIXACLS @@ -345,7 +348,7 @@ #endif /* Version number of package */ -#define VERSION "2011.4.12" +#define VERSION "2012.1.15" /* Define to 1 if this is a Windows OS */ #undef WINDOWS @@ -375,6 +378,9 @@ /* Required define if using POSIX threads */ #undef _REENTRANT +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus diff --git a/portlibs/sources/libntfs/debug.c b/portlibs/sources/libcustomntfs/source/debug.c similarity index 100% rename from portlibs/sources/libntfs/debug.c rename to portlibs/sources/libcustomntfs/source/debug.c diff --git a/portlibs/sources/libntfs/debug.h b/portlibs/sources/libcustomntfs/source/debug.h similarity index 96% rename from portlibs/sources/libntfs/debug.h rename to portlibs/sources/libcustomntfs/source/debug.h index cf39b625..f7f3c6fb 100644 --- a/portlibs/sources/libntfs/debug.h +++ b/portlibs/sources/libcustomntfs/source/debug.h @@ -38,10 +38,10 @@ static __inline__ void ntfs_debug_runlist_dump(const struct _runlist_element *rl #define NTFS_BUG(msg) \ { \ - int ___i; \ + int ___i = 1; \ ntfs_log_critical("Bug in %s(): %s\n", __FUNCTION__, msg); \ ntfs_log_debug("Forcing segmentation fault!"); \ - ___i = ((int*)NULL)[1]; \ + ___i = ((int*)NULL)[___i]; \ } #endif /* defined _NTFS_DEBUG_H */ diff --git a/portlibs/sources/libntfs/device.c b/portlibs/sources/libcustomntfs/source/device.c similarity index 94% rename from portlibs/sources/libntfs/device.c rename to portlibs/sources/libcustomntfs/source/device.c index db840108..274abacb 100644 --- a/portlibs/sources/libntfs/device.c +++ b/portlibs/sources/libcustomntfs/source/device.c @@ -58,6 +58,9 @@ #ifdef HAVE_SYS_MOUNT_H #include #endif +#ifdef HAVE_SYS_DISK_H +#include +#endif #ifdef HAVE_LINUX_FD_H #include #endif @@ -556,6 +559,36 @@ s64 ntfs_device_size_get(struct ntfs_device *dev, int block_size) return (s64)this_floppy.size * 512 / block_size; } } +#endif +#ifdef DIOCGMEDIASIZE + { + /* FreeBSD */ + off_t size; + + if (dev->d_ops->ioctl(dev, DIOCGMEDIASIZE, &size) >= 0) { + ntfs_log_debug("DIOCGMEDIASIZE nr bytes = %llu (0x%llx)\n", + (unsigned long long)size, + (unsigned long long)size); + return (s64)size / block_size; + } + } +#endif +#ifdef DKIOCGETBLOCKCOUNT + { + /* Mac OS X */ + uint64_t blocks; + int sector_size; + + sector_size = ntfs_device_sector_size_get(dev); + if (sector_size >= 0 && dev->d_ops->ioctl(dev, + DKIOCGETBLOCKCOUNT, &blocks) >= 0) + { + ntfs_log_debug("DKIOCGETBLOCKCOUNT nr blocks = %llu (0x%llx)\n", + (unsigned long long) blocks, + (unsigned long long) blocks); + return blocks * sector_size / block_size; + } + } #endif /* * We couldn't figure it out by using a specialized ioctl, @@ -705,6 +738,28 @@ int ntfs_device_sector_size_get(struct ntfs_device *dev) return sect_size; } } +#elif defined(DIOCGSECTORSIZE) + { + /* FreeBSD */ + size_t sect_size = 0; + + if (!dev->d_ops->ioctl(dev, DIOCGSECTORSIZE, §_size)) { + ntfs_log_debug("DIOCGSECTORSIZE sector size = %d bytes\n", + (int) sect_size); + return sect_size; + } + } +#elif defined(DKIOCGETBLOCKSIZE) + { + /* Mac OS X */ + uint32_t sect_size = 0; + + if (!dev->d_ops->ioctl(dev, DKIOCGETBLOCKSIZE, §_size)) { + ntfs_log_debug("DKIOCGETBLOCKSIZE sector size = %d bytes\n", + (int) sect_size); + return sect_size; + } + } #else errno = EOPNOTSUPP; #endif diff --git a/portlibs/sources/libntfs/device.h b/portlibs/sources/libcustomntfs/source/device.h similarity index 100% rename from portlibs/sources/libntfs/device.h rename to portlibs/sources/libcustomntfs/source/device.h diff --git a/portlibs/sources/libntfs/device_io.c b/portlibs/sources/libcustomntfs/source/device_io.c similarity index 100% rename from portlibs/sources/libntfs/device_io.c rename to portlibs/sources/libcustomntfs/source/device_io.c diff --git a/portlibs/sources/libntfs/device_io.h b/portlibs/sources/libcustomntfs/source/device_io.h similarity index 100% rename from portlibs/sources/libntfs/device_io.h rename to portlibs/sources/libcustomntfs/source/device_io.h diff --git a/portlibs/sources/libntfs/dir.c b/portlibs/sources/libcustomntfs/source/dir.c similarity index 99% rename from portlibs/sources/libntfs/dir.c rename to portlibs/sources/libcustomntfs/source/dir.c index 198bc29d..ccae47c3 100644 --- a/portlibs/sources/libntfs/dir.c +++ b/portlibs/sources/libcustomntfs/source/dir.c @@ -257,7 +257,7 @@ u64 ntfs_inode_lookup_by_name(ntfs_inode *dir_ni, u8 *index_end; ntfs_attr *ia_na; int eo, rc; - u32 index_block_size, index_vcn_size; + u32 index_block_size; u8 index_vcn_size_bits; ntfs_log_trace("Entering\n"); @@ -378,11 +378,9 @@ u64 ntfs_inode_lookup_by_name(ntfs_inode *dir_ni, /* Determine the size of a vcn in the directory index. */ if (vol->cluster_size <= index_block_size) { - index_vcn_size = vol->cluster_size; index_vcn_size_bits = vol->cluster_size_bits; } else { - index_vcn_size = vol->sector_size; - index_vcn_size_bits = vol->sector_size_bits; + index_vcn_size_bits = NTFS_BLOCK_SIZE_BITS; } /* Get the starting vcn of the index_block holding the child node. */ @@ -1039,7 +1037,7 @@ int ntfs_readdir(ntfs_inode *dir_ni, s64 *pos, INDEX_ENTRY *ie; INDEX_ALLOCATION *ia = NULL; int rc, ir_pos, bmp_buf_size, bmp_buf_pos, eo; - u32 index_block_size, index_vcn_size; + u32 index_block_size; u8 index_block_size_bits, index_vcn_size_bits; ntfs_log_trace("Entering.\n"); @@ -1131,11 +1129,9 @@ int ntfs_readdir(ntfs_inode *dir_ni, s64 *pos, } index_block_size_bits = ffs(index_block_size) - 1; if (vol->cluster_size <= index_block_size) { - index_vcn_size = vol->cluster_size; index_vcn_size_bits = vol->cluster_size_bits; } else { - index_vcn_size = vol->sector_size; - index_vcn_size_bits = vol->sector_size_bits; + index_vcn_size_bits = NTFS_BLOCK_SIZE_BITS; } /* Are we jumping straight into the index allocation attribute? */ @@ -1517,7 +1513,7 @@ static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, le32 securid, else ir->clusters_per_index_block = ni->vol->indx_record_size >> - ni->vol->sector_size_bits; + NTFS_BLOCK_SIZE_BITS; ir->index.entries_offset = cpu_to_le32(sizeof(INDEX_HEADER)); ir->index.index_length = cpu_to_le32(index_len); ir->index.allocated_size = cpu_to_le32(index_len); @@ -2508,24 +2504,24 @@ int ntfs_set_ntfs_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni, int res = 0; int longlen = 0; int shortlen = 0; - char newname[MAX_DOS_NAME_LENGTH + 1]; + char newname[3*MAX_DOS_NAME_LENGTH + 1]; ntfschar oldname[MAX_DOS_NAME_LENGTH]; int oldlen; - ntfs_volume *vol; - u64 fnum; u64 dnum; BOOL closed = FALSE; ntfschar *shortname = NULL; ntfschar longname[NTFS_MAX_NAME_LEN]; - vol = ni->vol; - fnum = ni->mft_no; - /* convert the string to the NTFS wide chars */ - if (size > MAX_DOS_NAME_LENGTH) - size = MAX_DOS_NAME_LENGTH; + /* copy the string to insert a null char, and truncate */ + if (size > 3*MAX_DOS_NAME_LENGTH) + size = 3*MAX_DOS_NAME_LENGTH; strncpy(newname, value, size); + /* a long name may be truncated badly and be untranslatable */ newname[size] = 0; + /* convert the string to the NTFS wide chars, and truncate */ shortlen = ntfs_mbstoucs(newname, &shortname); + if (shortlen > MAX_DOS_NAME_LENGTH) + shortlen = MAX_DOS_NAME_LENGTH; /* make sure the short name has valid chars */ if ((shortlen < 0) || ntfs_forbidden_chars(shortname,shortlen)) { ntfs_inode_close_in_dir(ni,dir_ni); diff --git a/portlibs/sources/libntfs/dir.h b/portlibs/sources/libcustomntfs/source/dir.h similarity index 100% rename from portlibs/sources/libntfs/dir.h rename to portlibs/sources/libcustomntfs/source/dir.h diff --git a/portlibs/sources/libntfs/efs.c b/portlibs/sources/libcustomntfs/source/efs.c similarity index 99% rename from portlibs/sources/libntfs/efs.c rename to portlibs/sources/libcustomntfs/source/efs.c index 6ccec20a..7957005b 100644 --- a/portlibs/sources/libntfs/efs.c +++ b/portlibs/sources/libcustomntfs/source/efs.c @@ -139,7 +139,6 @@ static int fixup_loop(ntfs_inode *ni) ntfs_attr *na; ATTR_RECORD *a; BOOL restart; - BOOL first; int cnt; int maxcnt; int res = 0; @@ -200,7 +199,6 @@ static int fixup_loop(ntfs_inode *ni) if (na) ntfs_attr_close(na); } - first = FALSE; } while (restart && !res); if (ctx) ntfs_attr_put_search_ctx(ctx); diff --git a/portlibs/sources/libntfs/efs.h b/portlibs/sources/libcustomntfs/source/efs.h similarity index 100% rename from portlibs/sources/libntfs/efs.h rename to portlibs/sources/libcustomntfs/source/efs.h diff --git a/portlibs/sources/libntfs/endians.h b/portlibs/sources/libcustomntfs/source/endians.h similarity index 100% rename from portlibs/sources/libntfs/endians.h rename to portlibs/sources/libcustomntfs/source/endians.h diff --git a/portlibs/sources/libntfs/gekko_io.c b/portlibs/sources/libcustomntfs/source/gekko_io.c similarity index 100% rename from portlibs/sources/libntfs/gekko_io.c rename to portlibs/sources/libcustomntfs/source/gekko_io.c diff --git a/portlibs/sources/libntfs/gekko_io.h b/portlibs/sources/libcustomntfs/source/gekko_io.h similarity index 100% rename from portlibs/sources/libntfs/gekko_io.h rename to portlibs/sources/libcustomntfs/source/gekko_io.h diff --git a/portlibs/sources/libntfs/index.c b/portlibs/sources/libcustomntfs/source/index.c similarity index 97% rename from portlibs/sources/libntfs/index.c rename to portlibs/sources/libcustomntfs/source/index.c index 8080b889..b0c0a4e6 100644 --- a/portlibs/sources/libntfs/index.c +++ b/portlibs/sources/libcustomntfs/source/index.c @@ -83,9 +83,9 @@ static VCN ntfs_ib_pos_to_vcn(ntfs_index_context *icx, s64 pos) static int ntfs_ib_write(ntfs_index_context *icx, INDEX_BLOCK *ib) { s64 ret, vcn = sle64_to_cpu(ib->index_block_vcn); - + ntfs_log_trace("vcn: %lld\n", (long long)vcn); - + ret = ntfs_attr_mst_pwrite(icx->ia_na, ntfs_ib_vcn_to_pos(icx, vcn), 1, icx->block_size, ib); if (ret != 1) { @@ -93,7 +93,7 @@ static int ntfs_ib_write(ntfs_index_context *icx, INDEX_BLOCK *ib) (long long)vcn, (unsigned long long)icx->ni->mft_no); return STATUS_ERROR; } - + return STATUS_OK; } @@ -101,9 +101,9 @@ static int ntfs_icx_ib_write(ntfs_index_context *icx) { if (ntfs_ib_write(icx, icx->ib)) return STATUS_ERROR; - + icx->ib_dirty = FALSE; - + return STATUS_OK; } @@ -122,7 +122,7 @@ ntfs_index_context *ntfs_index_ctx_get(ntfs_inode *ni, ntfs_index_context *icx; ntfs_log_trace("Entering\n"); - + if (!ni) { errno = EINVAL; return NULL; @@ -142,7 +142,7 @@ ntfs_index_context *ntfs_index_ctx_get(ntfs_inode *ni, static void ntfs_index_ctx_free(ntfs_index_context *icx) { ntfs_log_trace("Entering\n"); - + if (!icx->entry) return; @@ -156,7 +156,7 @@ static void ntfs_index_ctx_free(ntfs_index_context *icx) } free(icx->ib); } - + ntfs_attr_close(icx->ia_na); } @@ -181,9 +181,9 @@ void ntfs_index_ctx_put(ntfs_index_context *icx) void ntfs_index_ctx_reinit(ntfs_index_context *icx) { ntfs_log_trace("Entering\n"); - + ntfs_index_ctx_free(icx); - + *icx = (ntfs_index_context) { .ni = icx->ni, .name = icx->name, @@ -225,30 +225,30 @@ static int ntfs_ie_end(INDEX_ENTRY *ie) return ie->ie_flags & INDEX_ENTRY_END || !ie->length; } -/** +/** * Find the last entry in the index block */ static INDEX_ENTRY *ntfs_ie_get_last(INDEX_ENTRY *ie, char *ies_end) { ntfs_log_trace("Entering\n"); - + while ((char *)ie < ies_end && !ntfs_ie_end(ie)) ie = ntfs_ie_get_next(ie); - + return ie; } static INDEX_ENTRY *ntfs_ie_get_by_pos(INDEX_HEADER *ih, int pos) { INDEX_ENTRY *ie; - + ntfs_log_trace("pos: %d\n", pos); - + ie = ntfs_ie_get_first(ih); - + while (pos-- > 0) ie = ntfs_ie_get_next(ie); - + return ie; } @@ -256,16 +256,16 @@ static INDEX_ENTRY *ntfs_ie_prev(INDEX_HEADER *ih, INDEX_ENTRY *ie) { INDEX_ENTRY *ie_prev = NULL; INDEX_ENTRY *tmp; - + ntfs_log_trace("Entering\n"); - + tmp = ntfs_ie_get_first(ih); - + while (tmp != ie) { ie_prev = tmp; tmp = ntfs_ie_get_next(tmp); } - + return ie_prev; } @@ -289,9 +289,9 @@ void ntfs_ie_filename_dump(INDEX_ENTRY *ie) void ntfs_ih_filename_dump(INDEX_HEADER *ih) { INDEX_ENTRY *ie; - + ntfs_log_trace("Entering\n"); - + ie = ntfs_ie_get_first(ih); while (!ntfs_ie_end(ie)) { ntfs_ie_filename_dump(ie); @@ -304,9 +304,9 @@ static int ntfs_ih_numof_entries(INDEX_HEADER *ih) int n; INDEX_ENTRY *ie; u8 *end; - + ntfs_log_trace("Entering\n"); - + end = ntfs_ie_get_end(ih); ie = ntfs_ie_get_first(ih); for (n = 0; !ntfs_ie_end(ie) && (u8 *)ie < end; n++) @@ -327,9 +327,9 @@ static int ntfs_ih_zero_entry(INDEX_HEADER *ih) static void ntfs_ie_delete(INDEX_HEADER *ih, INDEX_ENTRY *ie) { u32 new_size; - + ntfs_log_trace("Entering\n"); - + new_size = le32_to_cpu(ih->index_length) - le16_to_cpu(ie->length); ih->index_length = cpu_to_le32(new_size); memmove(ie, (u8 *)ie + le16_to_cpu(ie->length), @@ -347,9 +347,9 @@ static void ntfs_ie_set_vcn(INDEX_ENTRY *ie, VCN vcn) static void ntfs_ie_insert(INDEX_HEADER *ih, INDEX_ENTRY *ie, INDEX_ENTRY *pos) { int ie_size = le16_to_cpu(ie->length); - + ntfs_log_trace("Entering\n"); - + ih->index_length = cpu_to_le32(le32_to_cpu(ih->index_length) + ie_size); memmove((u8 *)pos + ie_size, pos, le32_to_cpu(ih->index_length) - ((u8 *)pos - (u8 *)ih) - ie_size); @@ -359,13 +359,13 @@ static void ntfs_ie_insert(INDEX_HEADER *ih, INDEX_ENTRY *ie, INDEX_ENTRY *pos) static INDEX_ENTRY *ntfs_ie_dup(INDEX_ENTRY *ie) { INDEX_ENTRY *dup; - + ntfs_log_trace("Entering\n"); - + dup = ntfs_malloc(le16_to_cpu(ie->length)); if (dup) memcpy(dup, ie, le16_to_cpu(ie->length)); - + return dup; } @@ -373,12 +373,12 @@ static INDEX_ENTRY *ntfs_ie_dup_novcn(INDEX_ENTRY *ie) { INDEX_ENTRY *dup; int size = le16_to_cpu(ie->length); - + ntfs_log_trace("Entering\n"); - + if (ie->ie_flags & INDEX_ENTRY_NODE) size -= sizeof(VCN); - + dup = ntfs_malloc(size); if (dup) { memcpy(dup, ie, size); @@ -391,19 +391,19 @@ static INDEX_ENTRY *ntfs_ie_dup_novcn(INDEX_ENTRY *ie) static int ntfs_ia_check(ntfs_index_context *icx, INDEX_BLOCK *ib, VCN vcn) { u32 ib_size = (unsigned)le32_to_cpu(ib->index.allocated_size) + 0x18; - + ntfs_log_trace("Entering\n"); - + if (!ntfs_is_indx_record(ib->magic)) { - + ntfs_log_error("Corrupt index block signature: vcn %lld inode " "%llu\n", (long long)vcn, (unsigned long long)icx->ni->mft_no); return -1; } - + if (sle64_to_cpu(ib->index_block_vcn) != vcn) { - + ntfs_log_error("Corrupt index block: VCN (%lld) is different " "from expected VCN (%lld) in inode %llu\n", (long long)sle64_to_cpu(ib->index_block_vcn), @@ -411,12 +411,12 @@ static int ntfs_ia_check(ntfs_index_context *icx, INDEX_BLOCK *ib, VCN vcn) (unsigned long long)icx->ni->mft_no); return -1; } - + if (ib_size != icx->block_size) { - + ntfs_log_error("Corrupt index block : VCN (%lld) of inode %llu " "has a size (%u) differing from the index " - "specified size (%u)\n", (long long)vcn, + "specified size (%u)\n", (long long)vcn, (unsigned long long)icx->ni->mft_no, ib_size, icx->block_size); return -1; @@ -431,24 +431,24 @@ static INDEX_ROOT *ntfs_ir_lookup(ntfs_inode *ni, ntfschar *name, INDEX_ROOT *ir = NULL; ntfs_log_trace("Entering\n"); - + *ctx = ntfs_attr_get_search_ctx(ni, NULL); if (!*ctx) return NULL; - - if (ntfs_attr_lookup(AT_INDEX_ROOT, name, name_len, CASE_SENSITIVE, + + if (ntfs_attr_lookup(AT_INDEX_ROOT, name, name_len, CASE_SENSITIVE, 0, NULL, 0, *ctx)) { ntfs_log_perror("Failed to lookup $INDEX_ROOT"); goto err_out; } - + a = (*ctx)->attr; if (a->non_resident) { errno = EINVAL; ntfs_log_perror("Non-resident $INDEX_ROOT detected"); goto err_out; } - + ir = (INDEX_ROOT *)((char *)a + le16_to_cpu(a->value_offset)); err_out: if (!ir) { @@ -469,11 +469,11 @@ static INDEX_ROOT *ntfs_ir_lookup2(ntfs_inode *ni, ntfschar *name, u32 len) return ir; } -/** +/** * Find a key in the index block. - * + * * Return values: - * STATUS_OK with errno set to ESUCCESS if we know for sure that the + * STATUS_OK with errno set to ESUCCESS if we know for sure that the * entry exists and @ie_out points to this entry. * STATUS_NOT_FOUND with errno set to ENOENT if we know for sure the * entry doesn't exist and @ie_out is the insertion point. @@ -488,11 +488,11 @@ static int ntfs_ie_lookup(const void *key, const int key_len, INDEX_ENTRY *ie; u8 *index_end; int rc, item = 0; - + ntfs_log_trace("Entering\n"); - + index_end = ntfs_ie_get_end(ih); - + /* * Loop until we exceed valid memory (corruption case) or until we * reach the last entry. @@ -537,14 +537,14 @@ static int ntfs_ie_lookup(const void *key, const int key_len, */ if (rc == -1) break; - + if (!rc) { *ie_out = ie; errno = 0; icx->parent_pos[icx->pindex] = item; return STATUS_OK; } - + item++; } /* @@ -558,7 +558,7 @@ static int ntfs_ie_lookup(const void *key, const int key_len, errno = ENOENT; return STATUS_NOT_FOUND; } - + /* Get the starting vcn of the index_block holding the child node. */ *vcn = ntfs_ie_get_vcn(ie); if (*vcn < 0) { @@ -570,21 +570,21 @@ static int ntfs_ie_lookup(const void *key, const int key_len, ntfs_log_trace("Parent entry number %d\n", item); icx->parent_pos[icx->pindex] = item; - + return STATUS_KEEP_SEARCHING; } static ntfs_attr *ntfs_ia_open(ntfs_index_context *icx, ntfs_inode *ni) { ntfs_attr *na; - + na = ntfs_attr_open(ni, AT_INDEX_ALLOCATION, icx->name, icx->name_len); if (!na) { ntfs_log_perror("Failed to open index allocation of inode " "%llu", (unsigned long long)ni->mft_no); return NULL; } - + return na; } @@ -593,22 +593,22 @@ static int ntfs_ib_read(ntfs_index_context *icx, VCN vcn, INDEX_BLOCK *dst) s64 pos, ret; ntfs_log_trace("vcn: %lld\n", (long long)vcn); - + pos = ntfs_ib_vcn_to_pos(icx, vcn); ret = ntfs_attr_mst_pread(icx->ia_na, pos, 1, icx->block_size, (u8 *)dst); if (ret != 1) { if (ret == -1) ntfs_log_perror("Failed to read index block"); - else + else ntfs_log_error("Failed to read full index block at " "%lld\n", (long long)pos); return -1; } - + if (ntfs_ia_check(icx, dst, vcn)) return -1; - + return 0; } @@ -633,7 +633,7 @@ static int ntfs_icx_parent_dec(ntfs_index_context *icx) } return STATUS_OK; } - + /** * ntfs_index_lookup - find a key in an index and return its index entry * @key: [IN] key for which to search in the index @@ -676,7 +676,7 @@ int ntfs_index_lookup(const void *key, const int key_len, ntfs_index_context *ic int ret, err = 0; ntfs_log_trace("Entering\n"); - + if (!key || key_len <= 0) { errno = EINVAL; ntfs_log_perror("key: %p key_len: %d", key, key_len); @@ -689,7 +689,7 @@ int ntfs_index_lookup(const void *key, const int key_len, ntfs_index_context *ic errno = EIO; return -1; } - + icx->block_size = le32_to_cpu(ir->index_block_size); if (icx->block_size < NTFS_BLOCK_SIZE) { errno = EINVAL; @@ -701,18 +701,18 @@ int ntfs_index_lookup(const void *key, const int key_len, ntfs_index_context *ic if (ni->vol->cluster_size <= icx->block_size) icx->vcn_size_bits = ni->vol->cluster_size_bits; else - icx->vcn_size_bits = ni->vol->sector_size_bits; + icx->vcn_size_bits = NTFS_BLOCK_SIZE_BITS; /* get the appropriate collation function */ icx->collate = ntfs_get_collate_function(ir->collation_rule); if (!icx->collate) { err = errno = EOPNOTSUPP; - ntfs_log_perror("Unknown collation rule 0x%x", + ntfs_log_perror("Unknown collation rule 0x%x", (unsigned)le32_to_cpu(ir->collation_rule)); goto err_out; } - + old_vcn = VCN_INDEX_ROOT_PARENT; - /* + /* * FIXME: check for both ir and ib that the first index entry is * within the index block. */ @@ -721,9 +721,9 @@ int ntfs_index_lookup(const void *key, const int key_len, ntfs_index_context *ic err = errno; goto err_out; } - + icx->ir = ir; - + if (ret != STATUS_KEEP_SEARCHING) { /* STATUS_OK or STATUS_NOT_FOUND */ err = errno; @@ -731,19 +731,19 @@ int ntfs_index_lookup(const void *key, const int key_len, ntfs_index_context *ic icx->parent_vcn[icx->pindex] = old_vcn; goto done; } - + /* Child node present, descend into it. */ - + icx->ia_na = ntfs_ia_open(icx, ni); if (!icx->ia_na) goto err_out; - + ib = ntfs_malloc(icx->block_size); if (!ib) { err = errno; goto err_out; } - + descend_into_child_node: icx->parent_vcn[icx->pindex] = old_vcn; @@ -754,16 +754,16 @@ descend_into_child_node: old_vcn = vcn; ntfs_log_debug("Descend into node with VCN %lld\n", (long long)vcn); - + if (ntfs_ib_read(icx, vcn, ib)) goto err_out; - + ret = ntfs_ie_lookup(key, key_len, icx, &ib->index, &vcn, &ie); if (ret != STATUS_KEEP_SEARCHING) { err = errno; if (ret == STATUS_ERROR) goto err_out; - + /* STATUS_OK or STATUS_NOT_FOUND */ icx->is_in_root = FALSE; icx->ib = ib; @@ -777,7 +777,7 @@ descend_into_child_node: (unsigned long long)ni->mft_no); goto err_out; } - + goto descend_into_child_node; err_out: free(ib); @@ -798,38 +798,38 @@ done: } -static INDEX_BLOCK *ntfs_ib_alloc(VCN ib_vcn, u32 ib_size, +static INDEX_BLOCK *ntfs_ib_alloc(VCN ib_vcn, u32 ib_size, INDEX_HEADER_FLAGS node_type) { INDEX_BLOCK *ib; int ih_size = sizeof(INDEX_HEADER); - + ntfs_log_trace("ib_vcn: %lld ib_size: %u\n", (long long)ib_vcn, ib_size); - + ib = ntfs_calloc(ib_size); if (!ib) return NULL; - + ib->magic = magic_INDX; ib->usa_ofs = cpu_to_le16(sizeof(INDEX_BLOCK)); ib->usa_count = cpu_to_le16(ib_size / NTFS_BLOCK_SIZE + 1); /* Set USN to 1 */ *(u16 *)((char *)ib + le16_to_cpu(ib->usa_ofs)) = cpu_to_le16(1); ib->lsn = cpu_to_le64(0); - + ib->index_block_vcn = cpu_to_sle64(ib_vcn); - + ib->index.entries_offset = cpu_to_le32((ih_size + le16_to_cpu(ib->usa_count) * 2 + 7) & ~7); ib->index.index_length = 0; - ib->index.allocated_size = cpu_to_le32(ib_size - + ib->index.allocated_size = cpu_to_le32(ib_size - (sizeof(INDEX_BLOCK) - ih_size)); ib->index.ih_flags = node_type; - + return ib; -} +} -/** +/** * Find the median by going through all the entries */ static INDEX_ENTRY *ntfs_ie_get_median(INDEX_HEADER *ih) @@ -837,12 +837,12 @@ static INDEX_ENTRY *ntfs_ie_get_median(INDEX_HEADER *ih) INDEX_ENTRY *ie, *ie_start; u8 *ie_end; int i = 0, median; - + ntfs_log_trace("Entering\n"); - + ie = ie_start = ntfs_ie_get_first(ih); ie_end = (u8 *)ntfs_ie_get_end(ih); - + while ((u8 *)ie < ie_end && !ntfs_ie_end(ie)) { ie = ntfs_ie_get_next(ie); i++; @@ -851,12 +851,12 @@ static INDEX_ENTRY *ntfs_ie_get_median(INDEX_HEADER *ih) * NOTE: this could be also the entry at the half of the index block. */ median = i / 2 - 1; - + ntfs_log_trace("Entries: %d median: %d\n", i, median); - + for (i = 0, ie = ie_start; i <= median; i++) ie = ntfs_ie_get_next(ie); - + return ie; } @@ -875,7 +875,7 @@ static int ntfs_ibm_add(ntfs_index_context *icx) u8 bmp[8]; ntfs_log_trace("Entering\n"); - + if (ntfs_attr_exist(icx->ni, AT_BITMAP, icx->name, icx->name_len)) return STATUS_OK; /* @@ -887,7 +887,7 @@ static int ntfs_ibm_add(ntfs_index_context *icx) ntfs_log_perror("Failed to add AT_BITMAP"); return STATUS_ERROR; } - + return STATUS_OK; } @@ -901,7 +901,7 @@ static int ntfs_ibm_modify(ntfs_index_context *icx, VCN vcn, int set) int ret = STATUS_ERROR; ntfs_log_trace("%s vcn: %lld\n", set ? "set" : "clear", (long long)vcn); - + na = ntfs_attr_open(icx->ni, AT_BITMAP, icx->name, icx->name_len); if (!na) { ntfs_log_perror("Failed to open $BITMAP attribute"); @@ -916,17 +916,17 @@ static int ntfs_ibm_modify(ntfs_index_context *icx, VCN vcn, int set) } } } - + if (ntfs_attr_pread(na, bpos, 1, &byte) != 1) { ntfs_log_perror("Failed to read $BITMAP"); goto err_na; } - if (set) + if (set) byte |= bit; else byte &= ~bit; - + if (ntfs_attr_pwrite(na, bpos, 1, &byte) != 1) { ntfs_log_perror("Failed to write $Bitmap"); goto err_na; @@ -956,17 +956,17 @@ static VCN ntfs_ibm_get_free(ntfs_index_context *icx) s64 vcn, byte, size; ntfs_log_trace("Entering\n"); - + bm = ntfs_attr_readall(icx->ni, AT_BITMAP, icx->name, icx->name_len, &size); if (!bm) return (VCN)-1; - + for (byte = 0; byte < size; byte++) { - + if (bm[byte] == 255) continue; - + for (bit = 0; bit < 8; bit++) { if (!(bm[byte] & (1 << bit))) { vcn = ntfs_ibm_pos_to_vcn(icx, byte * 8 + bit); @@ -974,14 +974,14 @@ static VCN ntfs_ibm_get_free(ntfs_index_context *icx) } } } - + vcn = ntfs_ibm_pos_to_vcn(icx, size * 8); -out: +out: ntfs_log_trace("allocated vcn: %lld\n", (long long)vcn); if (ntfs_ibm_set(icx, vcn)) vcn = (VCN)-1; - + free(bm); return vcn; } @@ -992,23 +992,23 @@ static INDEX_BLOCK *ntfs_ir_to_ib(INDEX_ROOT *ir, VCN ib_vcn) INDEX_ENTRY *ie_last; char *ies_start, *ies_end; int i; - + ntfs_log_trace("Entering\n"); - + ib = ntfs_ib_alloc(ib_vcn, le32_to_cpu(ir->index_block_size), LEAF_NODE); if (!ib) return NULL; - + ies_start = (char *)ntfs_ie_get_first(&ir->index); ies_end = (char *)ntfs_ie_get_end(&ir->index); ie_last = ntfs_ie_get_last((INDEX_ENTRY *)ies_start, ies_end); - /* + /* * Copy all entries, including the termination entry * as well, which can never have any data. */ i = (char *)ie_last - ies_start + le16_to_cpu(ie_last->length); memcpy(ntfs_ie_get_first(&ib->index), ies_start, i); - + ib->index.ih_flags = ir->index.ih_flags; ib->index.index_length = cpu_to_le32(i + le32_to_cpu(ib->index.entries_offset)); @@ -1019,7 +1019,7 @@ static void ntfs_ir_nill(INDEX_ROOT *ir) { INDEX_ENTRY *ie_last; char *ies_start, *ies_end; - + ntfs_log_trace("Entering\n"); /* * TODO: This function could be much simpler. @@ -1027,7 +1027,7 @@ static void ntfs_ir_nill(INDEX_ROOT *ir) ies_start = (char *)ntfs_ie_get_first(&ir->index); ies_end = (char *)ntfs_ie_get_end(&ir->index); ie_last = ntfs_ie_get_last((INDEX_ENTRY *)ies_start, ies_end); - /* + /* * Move the index root termination entry forward */ if ((char *)ie_last > ies_start) { @@ -1043,21 +1043,21 @@ static int ntfs_ib_copy_tail(ntfs_index_context *icx, INDEX_BLOCK *src, INDEX_ENTRY *ie_head; /* first entry after the median */ int tail_size, ret; INDEX_BLOCK *dst; - + ntfs_log_trace("Entering\n"); - - dst = ntfs_ib_alloc(new_vcn, icx->block_size, + + dst = ntfs_ib_alloc(new_vcn, icx->block_size, src->index.ih_flags & NODE_MASK); if (!dst) return STATUS_ERROR; - + ie_head = ntfs_ie_get_next(median); - + ies_end = (u8 *)ntfs_ie_get_end(&src->index); tail_size = ies_end - (u8 *)ie_head; memcpy(ntfs_ie_get_first(&dst->index), ie_head, tail_size); - - dst->index.index_length = cpu_to_le32(tail_size + + + dst->index.index_length = cpu_to_le32(tail_size + le32_to_cpu(dst->index.entries_offset)); ret = ntfs_ib_write(icx, dst); @@ -1070,43 +1070,43 @@ static int ntfs_ib_cut_tail(ntfs_index_context *icx, INDEX_BLOCK *ib, { char *ies_start, *ies_end; INDEX_ENTRY *ie_last; - + ntfs_log_trace("Entering\n"); - + ies_start = (char *)ntfs_ie_get_first(&ib->index); ies_end = (char *)ntfs_ie_get_end(&ib->index); - + ie_last = ntfs_ie_get_last((INDEX_ENTRY *)ies_start, ies_end); if (ie_last->ie_flags & INDEX_ENTRY_NODE) ntfs_ie_set_vcn(ie_last, ntfs_ie_get_vcn(ie)); - + memcpy(ie, ie_last, le16_to_cpu(ie_last->length)); - - ib->index.index_length = cpu_to_le32(((char *)ie - ies_start) + + + ib->index.index_length = cpu_to_le32(((char *)ie - ies_start) + le16_to_cpu(ie->length) + le32_to_cpu(ib->index.entries_offset)); - + if (ntfs_ib_write(icx, ib)) return STATUS_ERROR; - + return STATUS_OK; } - + static int ntfs_ia_add(ntfs_index_context *icx) { ntfs_log_trace("Entering\n"); if (ntfs_ibm_add(icx)) return -1; - + if (!ntfs_attr_exist(icx->ni, AT_INDEX_ALLOCATION, icx->name, icx->name_len)) { - + if (ntfs_attr_add(icx->ni, AT_INDEX_ALLOCATION, icx->name, icx->name_len, NULL, 0)) { ntfs_log_perror("Failed to add AT_INDEX_ALLOCATION"); return -1; } } - + icx->ia_na = ntfs_ia_open(icx, icx->ni); if (!icx->ia_na) return -1; @@ -1125,43 +1125,43 @@ static int ntfs_ir_reparent(ntfs_index_context *icx) int ret = STATUS_ERROR; ntfs_log_trace("Entering\n"); - + ir = ntfs_ir_lookup2(icx->ni, icx->name, icx->name_len); if (!ir) goto out; - + if ((ir->index.ih_flags & NODE_MASK) == SMALL_INDEX) if (ntfs_ia_add(icx)) goto out; - + new_ib_vcn = ntfs_ibm_get_free(icx); if (new_ib_vcn == -1) goto out; - + ir = ntfs_ir_lookup2(icx->ni, icx->name, icx->name_len); if (!ir) goto clear_bmp; - + ib = ntfs_ir_to_ib(ir, new_ib_vcn); if (ib == NULL) { ntfs_log_perror("Failed to move index root to index block"); goto clear_bmp; } - + if (ntfs_ib_write(icx, ib)) goto clear_bmp; - + retry : ir = ntfs_ir_lookup(icx->ni, icx->name, icx->name_len, &ctx); if (!ir) goto clear_bmp; - + ntfs_ir_nill(ir); - + ie = ntfs_ie_get_first(&ir->index); ie->ie_flags |= INDEX_ENTRY_NODE; ie->length = cpu_to_le16(sizeof(INDEX_ENTRY_HEADER) + sizeof(VCN)); - + ir->index.ih_flags = LARGE_INDEX; ir->index.index_length = cpu_to_le32(le32_to_cpu(ir->index.entries_offset) + le16_to_cpu(ie->length)); @@ -1197,7 +1197,7 @@ retry : * so in error case we wouldn't lose the IB. */ ntfs_ie_set_vcn(ie, new_ib_vcn); - + ret = STATUS_OK; err_out: free(ib); @@ -1211,56 +1211,56 @@ clear_bmp: /** * ntfs_ir_truncate - Truncate index root attribute - * + * * Returns STATUS_OK, STATUS_RESIDENT_ATTRIBUTE_FILLED_MFT or STATUS_ERROR. */ static int ntfs_ir_truncate(ntfs_index_context *icx, int data_size) -{ +{ ntfs_attr *na; int ret; ntfs_log_trace("Entering\n"); - + na = ntfs_attr_open(icx->ni, AT_INDEX_ROOT, icx->name, icx->name_len); if (!na) { ntfs_log_perror("Failed to open INDEX_ROOT"); return STATUS_ERROR; } /* - * INDEX_ROOT must be resident and its entries can be moved to + * INDEX_ROOT must be resident and its entries can be moved to * INDEX_BLOCK, so ENOSPC isn't a real error. */ ret = ntfs_attr_truncate(na, data_size + offsetof(INDEX_ROOT, index)); if (ret == STATUS_OK) { - + icx->ir = ntfs_ir_lookup2(icx->ni, icx->name, icx->name_len); if (!icx->ir) return STATUS_ERROR; - + icx->ir->index.allocated_size = cpu_to_le32(data_size); - + } else if (ret == STATUS_ERROR) ntfs_log_perror("Failed to truncate INDEX_ROOT"); - + ntfs_attr_close(na); return ret; } - + /** * ntfs_ir_make_space - Make more space for the index root attribute - * + * * On success return STATUS_OK or STATUS_KEEP_SEARCHING. * On error return STATUS_ERROR. */ static int ntfs_ir_make_space(ntfs_index_context *icx, int data_size) -{ +{ int ret; ntfs_log_trace("Entering\n"); ret = ntfs_ir_truncate(icx, data_size); if (ret == STATUS_RESIDENT_ATTRIBUTE_FILLED_MFT) { - + ret = ntfs_ir_reparent(icx); if (ret == STATUS_OK) ret = STATUS_KEEP_SEARCHING; @@ -1277,31 +1277,31 @@ static int ntfs_ir_make_space(ntfs_index_context *icx, int data_size) static int ntfs_ie_add_vcn(INDEX_ENTRY **ie) { INDEX_ENTRY *p, *old = *ie; - + old->length = cpu_to_le16(le16_to_cpu(old->length) + sizeof(VCN)); p = MEM2_realloc(old, le16_to_cpu(old->length)); if (!p) return STATUS_ERROR; - + p->ie_flags |= INDEX_ENTRY_NODE; *ie = p; return STATUS_OK; } -static int ntfs_ih_insert(INDEX_HEADER *ih, INDEX_ENTRY *orig_ie, VCN new_vcn, +static int ntfs_ih_insert(INDEX_HEADER *ih, INDEX_ENTRY *orig_ie, VCN new_vcn, int pos) { INDEX_ENTRY *ie_node, *ie; int ret = STATUS_ERROR; VCN old_vcn; - + ntfs_log_trace("Entering\n"); - + ie = ntfs_ie_dup(orig_ie); if (!ie) return STATUS_ERROR; - + if (!(ie->ie_flags & INDEX_ENTRY_NODE)) if (ntfs_ie_add_vcn(&ie)) goto out; @@ -1309,13 +1309,13 @@ static int ntfs_ih_insert(INDEX_HEADER *ih, INDEX_ENTRY *orig_ie, VCN new_vcn, ie_node = ntfs_ie_get_by_pos(ih, pos); old_vcn = ntfs_ie_get_vcn(ie_node); ntfs_ie_set_vcn(ie_node, new_vcn); - + ntfs_ie_insert(ih, ie, ie_node); ntfs_ie_set_vcn(ie_node, old_vcn); ret = STATUS_OK; -out: +out: free(ie); - + return ret; } @@ -1335,14 +1335,14 @@ static int ntfs_ir_insert_median(ntfs_index_context *icx, INDEX_ENTRY *median, { u32 new_size; int ret; - + ntfs_log_trace("Entering\n"); - + icx->ir = ntfs_ir_lookup2(icx->ni, icx->name, icx->name_len); if (!icx->ir) return STATUS_ERROR; - new_size = le32_to_cpu(icx->ir->index.index_length) + + new_size = le32_to_cpu(icx->ir->index.index_length) + le16_to_cpu(median->length); if (!(median->ie_flags & INDEX_ENTRY_NODE)) new_size += sizeof(VCN); @@ -1350,12 +1350,12 @@ static int ntfs_ir_insert_median(ntfs_index_context *icx, INDEX_ENTRY *median, ret = ntfs_ir_make_space(icx, new_size); if (ret != STATUS_OK) return ret; - + icx->ir = ntfs_ir_lookup2(icx->ni, icx->name, icx->name_len); if (!icx->ir) return STATUS_ERROR; - return ntfs_ih_insert(&icx->ir->index, median, new_vcn, + return ntfs_ih_insert(&icx->ir->index, median, new_vcn, ntfs_icx_parent_pos(icx)); } @@ -1366,20 +1366,20 @@ static int ntfs_ib_split(ntfs_index_context *icx, INDEX_BLOCK *ib); * On error return STATUS_ERROR. */ static int ntfs_ib_insert(ntfs_index_context *icx, INDEX_ENTRY *ie, VCN new_vcn) -{ +{ INDEX_BLOCK *ib; u32 idx_size, allocated_size; int err = STATUS_ERROR; VCN old_vcn; ntfs_log_trace("Entering\n"); - + ib = ntfs_malloc(icx->block_size); if (!ib) return -1; - + old_vcn = ntfs_icx_parent_vcn(icx); - + if (ntfs_ib_read(icx, old_vcn, ib)) goto err_out; @@ -1392,58 +1392,58 @@ static int ntfs_ib_insert(ntfs_index_context *icx, INDEX_ENTRY *ie, VCN new_vcn) err = STATUS_KEEP_SEARCHING; goto err_out; } - + if (ntfs_ih_insert(&ib->index, ie, new_vcn, ntfs_icx_parent_pos(icx))) goto err_out; - + if (ntfs_ib_write(icx, ib)) goto err_out; - + err = STATUS_OK; -err_out: +err_out: free(ib); return err; } /** * ntfs_ib_split - Split an index block - * + * * On success return STATUS_OK or STATUS_KEEP_SEARCHING. * On error return is STATUS_ERROR. */ static int ntfs_ib_split(ntfs_index_context *icx, INDEX_BLOCK *ib) -{ +{ INDEX_ENTRY *median; VCN new_vcn; int ret; ntfs_log_trace("Entering\n"); - + if (ntfs_icx_parent_dec(icx)) return STATUS_ERROR; - + median = ntfs_ie_get_median(&ib->index); new_vcn = ntfs_ibm_get_free(icx); if (new_vcn == -1) return STATUS_ERROR; - + if (ntfs_ib_copy_tail(icx, ib, median, new_vcn)) { ntfs_ibm_clear(icx, new_vcn); return STATUS_ERROR; } - + if (ntfs_icx_parent_vcn(icx) == VCN_INDEX_ROOT_PARENT) ret = ntfs_ir_insert_median(icx, median, new_vcn); else ret = ntfs_ib_insert(icx, median, new_vcn); - + if (ret != STATUS_OK) { ntfs_ibm_clear(icx, new_vcn); return ret; } - + ret = ntfs_ib_cut_tail(icx, ib, median); - + return ret; } @@ -1453,7 +1453,7 @@ int ntfs_ie_add(ntfs_index_context *icx, INDEX_ENTRY *ie) INDEX_HEADER *ih; int allocated_size, new_size; int ret = STATUS_ERROR; - + #ifdef DEBUG /* removed by JPA to make function usable for security indexes char *fn; @@ -1462,9 +1462,9 @@ int ntfs_ie_add(ntfs_index_context *icx, INDEX_ENTRY *ie) ntfs_attr_name_free(&fn); */ #endif - + while (1) { - + if (!ntfs_index_lookup(&ie->key, le16_to_cpu(ie->key_length), icx)) { errno = EEXIST; ntfs_log_perror("Index already have such entry"); @@ -1474,21 +1474,21 @@ int ntfs_ie_add(ntfs_index_context *icx, INDEX_ENTRY *ie) ntfs_log_perror("Failed to find place for new entry"); goto err_out; } - + if (icx->is_in_root) ih = &icx->ir->index; else ih = &icx->ib->index; - + allocated_size = le32_to_cpu(ih->allocated_size); new_size = le32_to_cpu(ih->index_length) + le16_to_cpu(ie->length); - + if (new_size <= allocated_size) break; - + ntfs_log_trace("index block sizes: allocated: %d needed: %d\n", allocated_size, new_size); - + if (icx->is_in_root) { if (ntfs_ir_make_space(icx, new_size) == STATUS_ERROR) goto err_out; @@ -1496,14 +1496,14 @@ int ntfs_ie_add(ntfs_index_context *icx, INDEX_ENTRY *ie) if (ntfs_ib_split(icx, icx->ib) == STATUS_ERROR) goto err_out; } - + ntfs_inode_mark_dirty(icx->actx->ntfs_ino); ntfs_index_ctx_reinit(icx); } - + ntfs_ie_insert(ih, ie, icx->entry); ntfs_index_entry_mark_dirty(icx); - + ret = STATUS_OK; err_out: ntfs_log_trace("%s\n", ret ? "Failed" : "Done"); @@ -1525,17 +1525,17 @@ int ntfs_index_add_filename(ntfs_inode *ni, FILE_NAME_ATTR *fn, MFT_REF mref) int fn_size, ie_size, err, ret = -1; ntfs_log_trace("Entering\n"); - + if (!ni || !fn) { ntfs_log_error("Invalid arguments.\n"); errno = EINVAL; return -1; } - + fn_size = (fn->file_name_length * sizeof(ntfschar)) + sizeof(FILE_NAME_ATTR); ie_size = (sizeof(INDEX_ENTRY_HEADER) + fn_size + 7) & ~7; - + ie = ntfs_calloc(ie_size); if (!ie) return -1; @@ -1544,11 +1544,11 @@ int ntfs_index_add_filename(ntfs_inode *ni, FILE_NAME_ATTR *fn, MFT_REF mref) ie->length = cpu_to_le16(ie_size); ie->key_length = cpu_to_le16(fn_size); memcpy(&ie->key, fn, fn_size); - + icx = ntfs_index_ctx_get(ni, NTFS_INDEX_I30, 4); if (!icx) goto out; - + ret = ntfs_ie_add(icx, ie); err = errno; ntfs_index_ctx_put(icx); @@ -1563,9 +1563,9 @@ static int ntfs_ih_takeout(ntfs_index_context *icx, INDEX_HEADER *ih, { INDEX_ENTRY *ie_roam; int ret = STATUS_ERROR; - + ntfs_log_trace("Entering\n"); - + ie_roam = ntfs_ie_dup_novcn(ie); if (!ie_roam) return STATUS_ERROR; @@ -1577,7 +1577,7 @@ static int ntfs_ih_takeout(ntfs_index_context *icx, INDEX_HEADER *ih, else if (ntfs_ib_write(icx, ib)) goto out; - + ntfs_index_ctx_reinit(icx); ret = ntfs_ie_add(icx, ie_roam); @@ -1593,36 +1593,36 @@ out: static void ntfs_ir_leafify(ntfs_index_context *icx, INDEX_HEADER *ih) { INDEX_ENTRY *ie; - + ntfs_log_trace("Entering\n"); - + ie = ntfs_ie_get_first(ih); ie->ie_flags &= ~INDEX_ENTRY_NODE; ie->length = cpu_to_le16(le16_to_cpu(ie->length) - sizeof(VCN)); - + ih->index_length = cpu_to_le32(le32_to_cpu(ih->index_length) - sizeof(VCN)); ih->ih_flags &= ~LARGE_INDEX; - + /* Not fatal error */ ntfs_ir_truncate(icx, le32_to_cpu(ih->index_length)); } /** - * Used if an empty index block to be deleted has END entry as the parent + * Used if an empty index block to be deleted has END entry as the parent * in the INDEX_ROOT which is not the only one there. */ static int ntfs_ih_reparent_end(ntfs_index_context *icx, INDEX_HEADER *ih, INDEX_BLOCK *ib) { INDEX_ENTRY *ie, *ie_prev; - + ntfs_log_trace("Entering\n"); - + ie = ntfs_ie_get_by_pos(ih, ntfs_icx_parent_pos(icx)); ie_prev = ntfs_ie_prev(ih, ie); - + ntfs_ie_set_vcn(ie, ntfs_ie_get_vcn(ie_prev)); - + return ntfs_ih_takeout(icx, ih, ie_prev, ib); } @@ -1632,48 +1632,48 @@ static int ntfs_index_rm_leaf(ntfs_index_context *icx) INDEX_HEADER *parent_ih; INDEX_ENTRY *ie; int ret = STATUS_ERROR; - + ntfs_log_trace("pindex: %d\n", icx->pindex); - + if (ntfs_icx_parent_dec(icx)) return STATUS_ERROR; if (ntfs_ibm_clear(icx, icx->parent_vcn[icx->pindex + 1])) return STATUS_ERROR; - + if (ntfs_icx_parent_vcn(icx) == VCN_INDEX_ROOT_PARENT) parent_ih = &icx->ir->index; else { ib = ntfs_malloc(icx->block_size); if (!ib) return STATUS_ERROR; - + if (ntfs_ib_read(icx, ntfs_icx_parent_vcn(icx), ib)) goto out; - + parent_ih = &ib->index; } - + ie = ntfs_ie_get_by_pos(parent_ih, ntfs_icx_parent_pos(icx)); if (!ntfs_ie_end(ie)) { ret = ntfs_ih_takeout(icx, parent_ih, ie, ib); goto out; } - + if (ntfs_ih_zero_entry(parent_ih)) { - + if (ntfs_icx_parent_vcn(icx) == VCN_INDEX_ROOT_PARENT) { ntfs_ir_leafify(icx, parent_ih); goto ok; } - + ret = ntfs_index_rm_leaf(icx); goto out; } - + if (ntfs_ih_reparent_end(icx, parent_ih, ib)) goto out; -ok: +ok: ret = STATUS_OK; out: free(ib); @@ -1691,7 +1691,7 @@ static int ntfs_index_rm_node(ntfs_index_context *icx) int delta, ret = STATUS_ERROR; ntfs_log_trace("Entering\n"); - + if (!icx->ia_na) { icx->ia_na = ntfs_ia_open(icx, icx->ni); if (!icx->ia_na) @@ -1701,7 +1701,7 @@ static int ntfs_index_rm_node(ntfs_index_context *icx) ib = ntfs_malloc(icx->block_size); if (!ib) return STATUS_ERROR; - + ie_succ = ntfs_ie_get_next(icx->entry); entry_pos = icx->parent_pos[icx->pindex]++; pindex = icx->pindex; @@ -1709,12 +1709,12 @@ descend: vcn = ntfs_ie_get_vcn(ie_succ); if (ntfs_ib_read(icx, vcn, ib)) goto out; - + ie_succ = ntfs_ie_get_first(&ib->index); if (ntfs_icx_parent_inc(icx)) goto out; - + icx->parent_vcn[icx->pindex] = vcn; icx->parent_pos[icx->pindex] = 0; @@ -1730,7 +1730,7 @@ descend: ie = ntfs_ie_dup(ie_succ); if (!ie) goto out; - + if (ntfs_ie_add_vcn(&ie)) goto out2; @@ -1748,10 +1748,10 @@ descend: ret = ntfs_ir_make_space(icx, new_size); if (ret != STATUS_OK) goto out2; - + ih = &icx->ir->index; entry = ntfs_ie_get_by_pos(ih, entry_pos); - + } else if (new_size > le32_to_cpu(ih->allocated_size)) { icx->pindex = pindex; ret = ntfs_ib_split(icx, icx->ib); @@ -1763,20 +1763,20 @@ descend: ntfs_ie_delete(ih, entry); ntfs_ie_insert(ih, ie, entry); - + if (icx->is_in_root) { if (ntfs_ir_truncate(icx, new_size)) goto out2; } else if (ntfs_icx_ib_write(icx)) goto out2; - + ntfs_ie_delete(&ib->index, ie_succ); - + if (ntfs_ih_zero_entry(&ib->index)) { if (ntfs_index_rm_leaf(icx)) goto out2; - } else + } else if (ntfs_ib_write(icx, ib)) goto out2; @@ -1792,8 +1792,8 @@ out: * ntfs_index_rm - remove entry from the index * @icx: index context describing entry to delete * - * Delete entry described by @icx from the index. Index context is always - * reinitialized after use of this function, so it can be used for index + * Delete entry described by @icx from the index. Index context is always + * reinitialized after use of this function, so it can be used for index * lookup once again. * * Return 0 on success or -1 on error with errno set to the error code. @@ -1805,7 +1805,7 @@ int ntfs_index_rm(ntfs_index_context *icx) int err, ret = STATUS_OK; ntfs_log_trace("Entering\n"); - + if (!icx || (!icx->ib && !icx->ir) || ntfs_ie_end(icx->entry)) { ntfs_log_error("Invalid arguments.\n"); errno = EINVAL; @@ -1815,15 +1815,15 @@ int ntfs_index_rm(ntfs_index_context *icx) ih = &icx->ir->index; else ih = &icx->ib->index; - + if (icx->entry->ie_flags & INDEX_ENTRY_NODE) { - + ret = ntfs_index_rm_node(icx); } else if (icx->is_in_root || !ntfs_ih_one_entry(ih)) { - + ntfs_ie_delete(ih, icx->entry); - + if (icx->is_in_root) { err = ntfs_ir_truncate(icx, le32_to_cpu(ih->index_length)); if (err != STATUS_OK) @@ -1853,7 +1853,7 @@ int ntfs_index_remove(ntfs_inode *dir_ni, ntfs_inode *ni, return -1; while (1) { - + if (ntfs_index_lookup(key, keylen, icx)) goto err_out; @@ -1869,13 +1869,13 @@ int ntfs_index_remove(ntfs_inode *dir_ni, ntfs_inode *ni, goto err_out; else if (ret == STATUS_OK) break; - + ntfs_inode_mark_dirty(icx->actx->ntfs_ino); ntfs_index_ctx_reinit(icx); } ntfs_inode_mark_dirty(icx->actx->ntfs_ino); -out: +out: ntfs_index_ctx_put(icx); return ret; err_out: @@ -1887,7 +1887,7 @@ err_out: /** * ntfs_index_root_get - read the index root of an attribute * @ni: open ntfs inode in which the ntfs attribute resides - * @attr: attribute for which we want its index root + * @attr: attribute for which we want its index root * * This function will read the related index root an ntfs attribute. * @@ -1906,14 +1906,14 @@ INDEX_ROOT *ntfs_index_root_get(ntfs_inode *ni, ATTR_RECORD *attr) if (!ntfs_ir_lookup(ni, name, attr->name_length, &ctx)) return NULL; - + root = ntfs_malloc(sizeof(INDEX_ROOT)); if (!root) goto out; - + *root = *((INDEX_ROOT *)((u8 *)ctx->attr + le16_to_cpu(ctx->attr->value_offset))); -out: +out: ntfs_attr_put_search_ctx(ctx); return root; } @@ -1945,7 +1945,7 @@ static INDEX_ENTRY *ntfs_index_walk_down(INDEX_ENTRY *ie, } else { /* down from non-zero level */ - + ictx->pindex++; } ictx->parent_pos[ictx->pindex] = 0; diff --git a/portlibs/sources/libntfs/index.h b/portlibs/sources/libcustomntfs/source/index.h similarity index 100% rename from portlibs/sources/libntfs/index.h rename to portlibs/sources/libcustomntfs/source/index.h diff --git a/portlibs/sources/libntfs/inode.c b/portlibs/sources/libcustomntfs/source/inode.c similarity index 96% rename from portlibs/sources/libntfs/inode.c rename to portlibs/sources/libcustomntfs/source/inode.c index bdc12a30..a4a01348 100644 --- a/portlibs/sources/libntfs/inode.c +++ b/portlibs/sources/libcustomntfs/source/inode.c @@ -124,7 +124,7 @@ ntfs_inode *ntfs_inode_allocate(ntfs_volume *vol) static void __ntfs_inode_release(ntfs_inode *ni) { if (NInoDirty(ni)) - ntfs_log_error("Releasing dirty inode %lld!\n", + ntfs_log_error("Releasing dirty inode %lld!\n", (long long)ni->mft_no); if (NInoAttrList(ni) && ni->attr_list) free(ni->attr_list); @@ -243,7 +243,7 @@ static ntfs_inode *ntfs_inode_real_open(ntfs_volume *vol, const MFT_REF mref) if (l != ni->attr_list_size) { errno = EIO; ntfs_log_perror("Unexpected attrlist size (%lld <> %u), inode " - "%lld", (long long)l, ni->attr_list_size, + "%lld", (long long)l, ni->attr_list_size, (long long)MREF(mref)); goto put_err_out; } @@ -273,7 +273,7 @@ get_size: set_nino_flag(ni,KnownSize); } ntfs_attr_put_search_ctx(ctx); -out: +out: ntfs_log_leave("\n"); return ni; @@ -313,7 +313,7 @@ err_out: int ntfs_inode_real_close(ntfs_inode *ni) { int ret = -1; - + if (!ni) return 0; @@ -365,7 +365,7 @@ int ntfs_inode_real_close(ntfs_inode *ni) */ if (base_ni->nr_extents) { /* Resize the memory buffer. */ - tmp_nis = MEM2_realloc(tmp_nis, base_ni->nr_extents * + tmp_nis = realloc(tmp_nis, base_ni->nr_extents * sizeof(ntfs_inode *)); /* Ignore errors, they don't really matter. */ if (tmp_nis) @@ -378,8 +378,8 @@ int ntfs_inode_real_close(ntfs_inode *ni) i = -1; break; } - - /* + + /* * We could successfully sync, so only log this error * and try to sync other inode extents too. */ @@ -387,7 +387,7 @@ int ntfs_inode_real_close(ntfs_inode *ni) ntfs_log_error("Extent inode %lld was not found\n", (long long)ni->mft_no); } - + __ntfs_inode_release(ni); ret = 0; err: @@ -437,13 +437,12 @@ static int idata_cache_compare(const struct CACHED_GENERIC *cached, void ntfs_inode_invalidate(ntfs_volume *vol, const MFT_REF mref) { struct CACHED_NIDATA item; - int count; item.inum = MREF(mref); item.ni = (ntfs_inode*)NULL; item.pathname = (const char*)NULL; item.varsize = 0; - count = ntfs_invalidate_cache(vol->nidata_cache, + ntfs_invalidate_cache(vol->nidata_cache, GENERIC(&item),idata_cache_compare,CACHE_FREE); } @@ -574,6 +573,9 @@ int ntfs_inode_close(ntfs_inode *ni) ntfs_inode *ntfs_extent_inode_open(ntfs_inode *base_ni, const MFT_REF mref) { u64 mft_no = MREF_LE(mref); + VCN extent_vcn; + runlist_element *rl; + ntfs_volume *vol; ntfs_inode *ni = NULL; ntfs_inode **extent_nis; int i; @@ -583,10 +585,41 @@ ntfs_inode *ntfs_extent_inode_open(ntfs_inode *base_ni, const MFT_REF mref) ntfs_log_perror("%s", __FUNCTION__); return NULL; } - + ntfs_log_enter("Opening extent inode %lld (base mft record %lld).\n", (unsigned long long)mft_no, (unsigned long long)base_ni->mft_no); + + if (!base_ni->mft_no) { + /* + * When getting extents of MFT, we must be sure + * they are in the MFT part which has already + * been mapped, otherwise we fall into an endless + * recursion. + * Situations have been met where extents locations + * are described in themselves. + * This is a severe error which chkdsk cannot fix. + */ + vol = base_ni->vol; + extent_vcn = mft_no << vol->mft_record_size_bits + >> vol->cluster_size_bits; + rl = vol->mft_na->rl; + if (rl) { + while (rl->length + && ((rl->vcn + rl->length) <= extent_vcn)) + rl++; + } + if (!rl || (rl->lcn < 0)) { + ntfs_log_error("MFT is corrupt, cannot read" + " its unmapped extent record %lld\n", + (long long)mft_no); + ntfs_log_error("Note : chkdsk cannot fix this," + " try ntfsfix\n"); + errno = EIO; + ni = (ntfs_inode*)NULL; + goto out; + } + } /* Is the extent inode already open and attached to the base inode? */ if (base_ni->nr_extents > 0) { @@ -800,7 +833,7 @@ static int ntfs_inode_sync_file_name(ntfs_inode *ni, ntfs_inode *dir_ni) if (dir_ni) index_ni = dir_ni; else - index_ni = ntfs_inode_open(ni->vol, + index_ni = ntfs_inode_open(ni->vol, le64_to_cpu(fn->parent_directory)); if (!index_ni) { if (!err) @@ -963,8 +996,8 @@ static int ntfs_inode_sync_in_dir(ntfs_inode *ni, ntfs_inode *dir_ni) } NInoAttrListSetDirty(ni); goto sync_inode; - } - + } + if (na->data_size == ni->attr_list_size) { if (ntfs_attr_pwrite(na, 0, ni->attr_list_size, ni->attr_list) != ni->attr_list_size) { @@ -986,7 +1019,7 @@ static int ntfs_inode_sync_in_dir(ntfs_inode *ni, ntfs_inode *dir_ni) } ntfs_attr_close(na); } - + sync_inode: /* Write this inode out to the $MFT (and $MFTMirr if applicable). */ if (NInoTestAndClearDirty(ni)) { @@ -1012,8 +1045,8 @@ sync_inode: eni = ni->extent_nis[i]; if (!NInoTestAndClearDirty(eni)) continue; - - if (ntfs_mft_record_write(eni->vol, eni->mft_no, + + if (ntfs_mft_record_write(eni->vol, eni->mft_no, eni->mrec)) { if (!err || errno == EIO) { err = errno; @@ -1033,7 +1066,7 @@ sync_inode: errno = err; ret = -1; } - + ntfs_log_leave("\n"); return ret; } @@ -1102,20 +1135,20 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni) } /* Walk through all attributes. */ while (!ntfs_attr_lookup(AT_UNUSED, NULL, 0, 0, 0, NULL, 0, ctx)) { - + int ale_size; - + if (ctx->attr->type == AT_ATTRIBUTE_LIST) { err = EIO; ntfs_log_perror("Attribute list already present"); goto put_err_out; } - + ale_size = (sizeof(ATTR_LIST_ENTRY) + sizeof(ntfschar) * ctx->attr->name_length + 7) & ~7; al_len += ale_size; - - aln = MEM2_realloc(al, al_len); + + aln = realloc(al, al_len); if (!aln) { err = errno; ntfs_log_perror("Failed to realloc %d bytes", al_len); @@ -1123,9 +1156,9 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni) } ale = (ATTR_LIST_ENTRY *)(aln + ((u8 *)ale - al)); al = aln; - + memset(ale, 0, ale_size); - + /* Add attribute to attribute list. */ ale->type = ctx->attr->type; ale->length = cpu_to_le16((sizeof(ATTR_LIST_ENTRY) + @@ -1192,7 +1225,7 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni) ntfs_attr_close(na); goto remove_attrlist_record;; } - + ntfs_attr_put_search_ctx(ctx); ntfs_attr_close(na); return 0; @@ -1293,12 +1326,12 @@ int ntfs_inode_free_space(ntfs_inode *ni, int size) * find next, because we don't need such. */ while (ctx->ntfs_ino->mft_no != ni->mft_no) { -retry: +retry: if (ntfs_attr_position(AT_UNUSED, ctx)) goto put_err_out; } - if (ntfs_inode_base(ctx->ntfs_ino)->mft_no == FILE_MFT && + if (ntfs_inode_base(ctx->ntfs_ino)->mft_no == FILE_MFT && ctx->attr->type == AT_DATA) goto retry; @@ -1319,10 +1352,10 @@ retry: return 0; } /* - * Reposition to first attribute after $STANDARD_INFORMATION - * and $ATTRIBUTE_LIST instead of simply skipping this attribute - * because in the case when we have got only in-memory attribute - * list then ntfs_attr_lookup will fail when it tries to find + * Reposition to first attribute after $STANDARD_INFORMATION + * and $ATTRIBUTE_LIST instead of simply skipping this attribute + * because in the case when we have got only in-memory attribute + * list then ntfs_attr_lookup will fail when it tries to find * $ATTRIBUTE_LIST. */ ntfs_attr_reinit_search_ctx(ctx); @@ -1364,7 +1397,7 @@ void ntfs_inode_update_times(ntfs_inode *ni, ntfs_time_update_flags mask) ni->last_data_change_time = now; if (mask & NTFS_UPDATE_CTIME) ni->last_mft_change_time = now; - + NInoFileNameSetDirty(ni); NInoSetDirty(ni); } @@ -1377,7 +1410,7 @@ void ntfs_inode_update_times(ntfs_inode *ni, ntfs_time_update_flags mask) * Check if the mft record given by @mft_no and @attr contains the bad sector * list. Please note that mft record numbers describing $Badclus extent inodes * will not match the current $Badclus:$Bad check. - * + * * On success return 1 if the file is $Badclus:$Bad, otherwise return 0. * On error return -1 with errno set to the error code. */ @@ -1391,7 +1424,7 @@ int ntfs_inode_badclus_bad(u64 mft_no, ATTR_RECORD *attr) errno = EINVAL; return -1; } - + if (mft_no != FILE_BadClus) return 0; @@ -1465,7 +1498,7 @@ int ntfs_inode_get_times(ntfs_inode *ni, char *value, size_t size) ret = -ERANGE; } ntfs_attr_put_search_ctx(ctx); - } + } return (ret ? ret : -errno); } diff --git a/portlibs/sources/libntfs/inode.h b/portlibs/sources/libcustomntfs/source/inode.h similarity index 100% rename from portlibs/sources/libntfs/inode.h rename to portlibs/sources/libcustomntfs/source/inode.h diff --git a/portlibs/sources/libntfs/layout.h b/portlibs/sources/libcustomntfs/source/layout.h similarity index 99% rename from portlibs/sources/libntfs/layout.h rename to portlibs/sources/libcustomntfs/source/layout.h index daff97d1..c167135f 100644 --- a/portlibs/sources/libntfs/layout.h +++ b/portlibs/sources/libcustomntfs/source/layout.h @@ -2223,11 +2223,11 @@ typedef struct { /* The below field is NOT present for the quota defaults entry. */ SID sid; /* The SID of the user/object associated with this quota entry. If this field is missing - then the INDEX_ENTRY is padded with zeros - to multiply of 8 which are not counted in + then the INDEX_ENTRY is padded to a multiple + of 8 with zeros which are not counted in the data_length field. If the sid is present then this structure is padded with zeros to - multiply of 8 and the padding is counted in + a multiple of 8 and the padding is counted in the INDEX_ENTRY's data_length. */ } __attribute__((__packed__)) QUOTA_CONTROL_ENTRY; diff --git a/portlibs/sources/libntfs/lcnalloc.c b/portlibs/sources/libcustomntfs/source/lcnalloc.c similarity index 92% rename from portlibs/sources/libntfs/lcnalloc.c rename to portlibs/sources/libcustomntfs/source/lcnalloc.c index a27d43a1..23bbb23d 100644 --- a/portlibs/sources/libntfs/lcnalloc.c +++ b/portlibs/sources/libcustomntfs/source/lcnalloc.c @@ -48,7 +48,7 @@ /* * Plenty possibilities for big optimizations all over in the cluster - * allocation, however at the moment the dominant bottleneck (~ 90%) is + * allocation, however at the moment the dominant bottleneck (~ 90%) is * the update of the mapping pairs which converges to the cubic Faulhaber's * formula as the function of the number of extents (fragments, runs). */ @@ -74,7 +74,7 @@ static void ntfs_cluster_set_zone_pos(LCN start, LCN end, LCN *pos, LCN tc) static void ntfs_cluster_update_zone_pos(ntfs_volume *vol, u8 zone, LCN tc) { ntfs_log_trace("tc = %lld, zone = %d\n", (long long)tc, zone); - + if (zone == ZONE_MFT) ntfs_cluster_set_zone_pos(vol->mft_lcn, vol->mft_zone_end, &vol->mft_zone_pos, tc); @@ -82,7 +82,7 @@ static void ntfs_cluster_update_zone_pos(ntfs_volume *vol, u8 zone, LCN tc) ntfs_cluster_set_zone_pos(vol->mft_zone_end, vol->nr_clusters, &vol->data1_zone_pos, tc); else /* zone == ZONE_DATA2 */ - ntfs_cluster_set_zone_pos(0, vol->mft_zone_start, + ntfs_cluster_set_zone_pos(0, vol->mft_zone_start, &vol->data2_zone_pos, tc); } @@ -112,15 +112,15 @@ static void update_full_status(ntfs_volume *vol, LCN lcn) } } } - + static s64 max_empty_bit_range(unsigned char *buf, int size) { int i, j, run = 0; int max_range = 0; s64 start_pos = -1; - + ntfs_log_trace("Entering\n"); - + i = 0; while (i < size) { switch (*buf) { @@ -144,42 +144,42 @@ static s64 max_empty_bit_range(unsigned char *buf, int size) break; default : for (j = 0; j < 8; j++) { - + int bit = *buf & (1 << j); - + if (bit) { if (run > max_range) { max_range = run; start_pos = (s64)i * 8 + (j - run); } run = 0; - } else + } else run++; } i++; buf++; - + } } - + if (run > max_range) start_pos = (s64)i * 8 - run; - + return start_pos; } -static int bitmap_writeback(ntfs_volume *vol, s64 pos, s64 size, void *b, +static int bitmap_writeback(ntfs_volume *vol, s64 pos, s64 size, void *b, u8 *writeback) { s64 written; - + ntfs_log_trace("Entering\n"); - + if (!*writeback) return 0; - + *writeback = 0; - + written = ntfs_attr_pwrite(vol->lcnbmp_na, pos, size, b); if (written != size) { if (!written) @@ -220,16 +220,16 @@ static int bitmap_writeback(ntfs_volume *vol, s64 pos, s64 size, void *b, * expanded to cover the start of the volume in order to reserve space for the * mft bitmap attribute. * - * The complexity stems from the need of implementing the mft vs data zoned - * approach and from the fact that we have access to the lcn bitmap via up to - * NTFS_LCNALLOC_BSIZE bytes at a time, so we need to cope with crossing over - * boundaries of two buffers. Further, the fact that the allocator allows for - * caller supplied hints as to the location of where allocation should begin - * and the fact that the allocator keeps track of where in the data zones the - * next natural allocation should occur, contribute to the complexity of the - * function. But it should all be worthwhile, because this allocator: + * The complexity stems from the need of implementing the mft vs data zoned + * approach and from the fact that we have access to the lcn bitmap via up to + * NTFS_LCNALLOC_BSIZE bytes at a time, so we need to cope with crossing over + * boundaries of two buffers. Further, the fact that the allocator allows for + * caller supplied hints as to the location of where allocation should begin + * and the fact that the allocator keeps track of where in the data zones the + * next natural allocation should occur, contribute to the complexity of the + * function. But it should all be worthwhile, because this allocator: * 1) implements MFT zone reservation - * 2) causes reduction in fragmentation. + * 2) causes reduction in fragmentation. * The code is not optimized for speed. */ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count, @@ -251,12 +251,12 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count, ntfs_log_enter("Entering with count = 0x%llx, start_lcn = 0x%llx, " "zone = %s_ZONE.\n", (long long)count, (long long) start_lcn, zone == MFT_ZONE ? "MFT" : "DATA"); - + if (!vol || count < 0 || start_lcn < -1 || !vol->lcnbmp_na || (s8)zone < FIRST_ZONE || zone > LAST_ZONE) { errno = EINVAL; - ntfs_log_perror("%s: vcn: %lld, count: %lld, lcn: %lld", - __FUNCTION__, (long long)start_vcn, + ntfs_log_perror("%s: vcn: %lld, count: %lld, lcn: %lld", + __FUNCTION__, (long long)start_vcn, (long long)count, (long long)start_lcn); goto out; } @@ -281,7 +281,7 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count, */ has_guess = 1; zone_start = start_lcn; - + if (zone_start < 0) { if (zone == DATA_ZONE) zone_start = vol->data1_zone_pos; @@ -289,13 +289,13 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count, zone_start = vol->mft_zone_pos; has_guess = 0; } - + used_zone_pos = has_guess ? 0 : 1; - + if (!zone_start || zone_start == vol->mft_zone_start || zone_start == vol->mft_zone_end) pass = 2; - + if (zone_start < vol->mft_zone_start) { zone_end = vol->mft_zone_start; search_zone = ZONE_DATA2; @@ -306,7 +306,7 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count, zone_end = vol->nr_clusters; search_zone = ZONE_DATA1; } - + bmp_pos = zone_start; /* Loop until all clusters are allocated. */ @@ -317,7 +317,7 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count, if (search_zone & vol->full_zones) goto zone_pass_done; last_read_pos = bmp_pos >> 3; - br = ntfs_attr_pread(vol->lcnbmp_na, last_read_pos, + br = ntfs_attr_pread(vol->lcnbmp_na, last_read_pos, NTFS_LCNALLOC_BSIZE, buf); if (br <= 0) { if (!br) @@ -334,7 +334,7 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count, lcn = bmp_pos & 7; bmp_pos &= ~7; writeback = 0; - + while (lcn < buf_size) { byte = buf + (lcn >> 3); bit = 1 << (lcn & 7); @@ -352,7 +352,7 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count, } /* First free bit is at lcn + bmp_pos. */ - + /* Reallocate memory if necessary. */ if ((rlpos + 2) * (int)sizeof(runlist) >= rlsize) { rlsize += 4096; @@ -364,17 +364,17 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count, } rl = trl; } - + /* Allocate the bitmap bit. */ *byte |= bit; writeback = 1; - if (vol->free_clusters <= 0) + if (vol->free_clusters <= 0) ntfs_log_error("Non-positive free clusters " "(%lld)!\n", (long long)vol->free_clusters); - else - vol->free_clusters--; - + else + vol->free_clusters--; + /* * Coalesce with previous run if adjacent LCNs. * Otherwise, append a new run. @@ -382,9 +382,9 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count, if (prev_lcn == lcn + bmp_pos - prev_run_len && rlpos) { ntfs_log_debug("Cluster coalesce: prev_lcn: " "%lld lcn: %lld bmp_pos: %lld " - "prev_run_len: %lld\n", - (long long)prev_lcn, - (long long)lcn, (long long)bmp_pos, + "prev_run_len: %lld\n", + (long long)prev_lcn, + (long long)lcn, (long long)bmp_pos, (long long)prev_run_len); rl[rlpos - 1].length = ++prev_run_len; } else { @@ -393,54 +393,54 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count, prev_run_len; else { rl[rlpos].vcn = start_vcn; - ntfs_log_debug("Start_vcn: %lld\n", + ntfs_log_debug("Start_vcn: %lld\n", (long long)start_vcn); } - + rl[rlpos].lcn = prev_lcn = lcn + bmp_pos; rl[rlpos].length = prev_run_len = 1; rlpos++; } - - ntfs_log_debug("RUN: %-16lld %-16lld %-16lld\n", - (long long)rl[rlpos - 1].vcn, - (long long)rl[rlpos - 1].lcn, + + ntfs_log_debug("RUN: %-16lld %-16lld %-16lld\n", + (long long)rl[rlpos - 1].vcn, + (long long)rl[rlpos - 1].lcn, (long long)rl[rlpos - 1].length); /* Done? */ if (!--clusters) { if (used_zone_pos) - ntfs_cluster_update_zone_pos(vol, + ntfs_cluster_update_zone_pos(vol, search_zone, lcn + bmp_pos + 1 + NTFS_LCNALLOC_SKIP); goto done_ret; } - + lcn++; } - + if (bitmap_writeback(vol, last_read_pos, br, buf, &writeback)) { err = errno; goto err_ret; } - + if (!used_zone_pos) { - + used_zone_pos = 1; - + if (search_zone == ZONE_MFT) zone_start = vol->mft_zone_pos; else if (search_zone == ZONE_DATA1) zone_start = vol->data1_zone_pos; else zone_start = vol->data2_zone_pos; - + if (!zone_start || zone_start == vol->mft_zone_start || zone_start == vol->mft_zone_end) pass = 2; bmp_pos = zone_start; } else bmp_pos += buf_size; - + if (bmp_pos < zone_end) continue; @@ -449,22 +449,22 @@ zone_pass_done: if (pass == 1) { pass = 2; zone_end = zone_start; - + if (search_zone == ZONE_MFT) zone_start = vol->mft_zone_start; else if (search_zone == ZONE_DATA1) zone_start = vol->mft_zone_end; else zone_start = 0; - + /* Sanity check. */ if (zone_end < zone_start) zone_end = zone_start; - + bmp_pos = zone_start; - + continue; - } + } /* pass == 2 */ done_zones_check: done_zones |= search_zone; @@ -473,14 +473,14 @@ done_zones_check: ntfs_log_trace("Switching zone.\n"); pass = 1; if (rlpos) { - LCN tc = rl[rlpos - 1].lcn + + LCN tc = rl[rlpos - 1].lcn + rl[rlpos - 1].length + NTFS_LCNALLOC_SKIP; - + if (used_zone_pos) - ntfs_cluster_update_zone_pos(vol, + ntfs_cluster_update_zone_pos(vol, search_zone, tc); } - + switch (search_zone) { case ZONE_MFT: ntfs_log_trace("Zone switch: mft -> data1\n"); @@ -511,17 +511,17 @@ switch_to_data1_zone: search_zone = ZONE_DATA1; pass = 2; break; } - + bmp_pos = zone_start; - + if (zone_start == zone_end) { ntfs_log_trace("Empty zone, skipped.\n"); goto done_zones_check; } - + continue; } - + ntfs_log_trace("All zones are finished, no space on device.\n"); err = ENOSPC; goto err_ret; @@ -543,7 +543,7 @@ done_err_ret: ntfs_log_perror("Failed to allocate clusters"); rl = NULL; } -out: +out: ntfs_log_leave("\n"); return rl; @@ -585,26 +585,26 @@ int ntfs_cluster_free_from_rl(ntfs_volume *vol, runlist *rl) ntfs_log_trace("Dealloc lcn 0x%llx, len 0x%llx.\n", (long long)rl->lcn, (long long)rl->length); - if (rl->lcn >= 0) { + if (rl->lcn >= 0) { update_full_status(vol,rl->lcn); - if (ntfs_bitmap_clear_run(vol->lcnbmp_na, rl->lcn, + if (ntfs_bitmap_clear_run(vol->lcnbmp_na, rl->lcn, rl->length)) { ntfs_log_perror("Cluster deallocation failed " "(%lld, %lld)", - (long long)rl->lcn, + (long long)rl->lcn, (long long)rl->length); goto out; } - nr_freed += rl->length ; + nr_freed += rl->length ; } } ret = 0; out: - vol->free_clusters += nr_freed; + vol->free_clusters += nr_freed; if (vol->free_clusters > vol->nr_clusters) ntfs_log_error("Too many free clusters (%lld > %lld)!", - (long long)vol->free_clusters, + (long long)vol->free_clusters, (long long)vol->nr_clusters); return ret; } @@ -623,24 +623,24 @@ int ntfs_cluster_free_basic(ntfs_volume *vol, s64 lcn, s64 count) ntfs_log_trace("Dealloc lcn 0x%llx, len 0x%llx.\n", (long long)lcn, (long long)count); - if (lcn >= 0) { + if (lcn >= 0) { update_full_status(vol,lcn); - if (ntfs_bitmap_clear_run(vol->lcnbmp_na, lcn, + if (ntfs_bitmap_clear_run(vol->lcnbmp_na, lcn, count)) { ntfs_log_perror("Cluster deallocation failed " "(%lld, %lld)", - (long long)lcn, + (long long)lcn, (long long)count); goto out; } - nr_freed += count; + nr_freed += count; } ret = 0; out: vol->free_clusters += nr_freed; if (vol->free_clusters > vol->nr_clusters) ntfs_log_error("Too many free clusters (%lld > %lld)!", - (long long)vol->free_clusters, + (long long)vol->free_clusters, (long long)vol->nr_clusters); return ret; } @@ -673,7 +673,7 @@ int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count) errno = EINVAL; return -1; } - + ntfs_log_enter("Entering for inode 0x%llx, attr 0x%x, count 0x%llx, " "vcn 0x%llx.\n", (unsigned long long)na->ni->mft_no, na->type, (long long)count, (long long)start_vcn); @@ -687,7 +687,7 @@ int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count) if (rl->lcn < 0 && rl->lcn != LCN_HOLE) { errno = EIO; - ntfs_log_perror("%s: Unexpected lcn (%lld)", __FUNCTION__, + ntfs_log_perror("%s: Unexpected lcn (%lld)", __FUNCTION__, (long long)rl->lcn); goto leave; } @@ -707,7 +707,7 @@ int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count) to_free)) goto leave; nr_freed = to_free; - } + } /* Go to the next run and adjust the number of clusters left to free. */ ++rl; @@ -724,7 +724,7 @@ int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count) if (rl->lcn < 0 && rl->lcn != LCN_HOLE) { // FIXME: Eeek! We need rollback! (AIA) errno = EIO; - ntfs_log_perror("%s: Invalid lcn (%lli)", + ntfs_log_perror("%s: Invalid lcn (%lli)", __FUNCTION__, (long long)rl->lcn); goto out; } @@ -760,12 +760,12 @@ int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count) ret = nr_freed; out: - vol->free_clusters += nr_freed ; + vol->free_clusters += nr_freed ; if (vol->free_clusters > vol->nr_clusters) ntfs_log_error("Too many free clusters (%lld > %lld)!", - (long long)vol->free_clusters, + (long long)vol->free_clusters, (long long)vol->nr_clusters); -leave: +leave: ntfs_log_leave("\n"); return ret; } diff --git a/portlibs/sources/libntfs/lcnalloc.h b/portlibs/sources/libcustomntfs/source/lcnalloc.h similarity index 100% rename from portlibs/sources/libntfs/lcnalloc.h rename to portlibs/sources/libcustomntfs/source/lcnalloc.h diff --git a/portlibs/sources/libntfs/logfile.c b/portlibs/sources/libcustomntfs/source/logfile.c similarity index 99% rename from portlibs/sources/libntfs/logfile.c rename to portlibs/sources/libcustomntfs/source/logfile.c index 0f8bce96..53d8d68e 100644 --- a/portlibs/sources/libntfs/logfile.c +++ b/portlibs/sources/libcustomntfs/source/logfile.c @@ -468,7 +468,7 @@ BOOL ntfs_check_logfile(ntfs_attr *log_na, RESTART_PAGE_HEADER **rp) u8 *kaddr = NULL; RESTART_PAGE_HEADER *rstr1_ph = NULL; RESTART_PAGE_HEADER *rstr2_ph = NULL; - int log_page_size, log_page_mask, err; + int log_page_size, err; BOOL logfile_is_empty = TRUE; u8 log_page_bits; @@ -481,7 +481,6 @@ BOOL ntfs_check_logfile(ntfs_attr *log_na, RESTART_PAGE_HEADER **rp) if (size > (s64)MaxLogFileSize) size = MaxLogFileSize; log_page_size = DefaultLogPageSize; - log_page_mask = log_page_size - 1; /* * Use generic_ffs() instead of ffs() to enable the compiler to * optimize log_page_size and log_page_bits into constants. @@ -703,7 +702,7 @@ int ntfs_empty_logfile(ntfs_attr *na) char buf[NTFS_BUF_SIZE]; ntfs_log_trace("Entering.\n"); - + if (NVolLogFileEmpty(na->ni->vol)) return 0; @@ -717,7 +716,7 @@ int ntfs_empty_logfile(ntfs_attr *na) pos = 0; while ((count = na->data_size - pos) > 0) { - + if (count > NTFS_BUF_SIZE) count = NTFS_BUF_SIZE; @@ -733,6 +732,6 @@ int ntfs_empty_logfile(ntfs_attr *na) } NVolSetLogFileEmpty(na->ni->vol); - + return 0; } diff --git a/portlibs/sources/libntfs/logfile.h b/portlibs/sources/libcustomntfs/source/logfile.h similarity index 100% rename from portlibs/sources/libntfs/logfile.h rename to portlibs/sources/libcustomntfs/source/logfile.h diff --git a/portlibs/sources/libntfs/logging.c b/portlibs/sources/libcustomntfs/source/logging.c similarity index 100% rename from portlibs/sources/libntfs/logging.c rename to portlibs/sources/libcustomntfs/source/logging.c diff --git a/portlibs/sources/libntfs/logging.h b/portlibs/sources/libcustomntfs/source/logging.h similarity index 100% rename from portlibs/sources/libntfs/logging.h rename to portlibs/sources/libcustomntfs/source/logging.h diff --git a/portlibs/sources/libntfs/mem2.h b/portlibs/sources/libcustomntfs/source/mem2.h similarity index 100% rename from portlibs/sources/libntfs/mem2.h rename to portlibs/sources/libcustomntfs/source/mem2.h diff --git a/portlibs/sources/libntfs/mem_allocate.h b/portlibs/sources/libcustomntfs/source/mem_allocate.h similarity index 100% rename from portlibs/sources/libntfs/mem_allocate.h rename to portlibs/sources/libcustomntfs/source/mem_allocate.h diff --git a/portlibs/sources/libntfs/mft.c b/portlibs/sources/libcustomntfs/source/mft.c similarity index 99% rename from portlibs/sources/libntfs/mft.c rename to portlibs/sources/libcustomntfs/source/mft.c index e93c6646..0640efe9 100644 --- a/portlibs/sources/libntfs/mft.c +++ b/portlibs/sources/libcustomntfs/source/mft.c @@ -216,8 +216,10 @@ int ntfs_mft_record_check(const ntfs_volume *vol, const MFT_REF mref, int ret = -1; if (!ntfs_is_file_record(m->magic)) { - ntfs_log_error("Record %llu has no FILE magic (0x%x)\n", - (unsigned long long)MREF(mref), *(le32 *)m); + if (!NVolNoFixupWarn(vol)) + ntfs_log_error("Record %llu has no FILE magic (0x%x)\n", + (unsigned long long)MREF(mref), + (int)le32_to_cpu(*(le32*)m)); goto err_out; } @@ -1190,7 +1192,7 @@ undo_alloc: static int ntfs_mft_record_init(ntfs_volume *vol, s64 size) { int ret = -1; - ntfs_attr *mft_na, *mftbmp_na; + ntfs_attr *mft_na; s64 old_data_initialized, old_data_size; ntfs_attr_search_ctx *ctx; @@ -1199,7 +1201,6 @@ static int ntfs_mft_record_init(ntfs_volume *vol, s64 size) /* NOTE: Caller must sanity check vol, vol->mft_na and vol->mftbmp_na */ mft_na = vol->mft_na; - mftbmp_na = vol->mftbmp_na; /* * The mft record is outside the initialized data. Extend the mft data @@ -1295,14 +1296,13 @@ undo_data_init: static int ntfs_mft_rec_init(ntfs_volume *vol, s64 size) { int ret = -1; - ntfs_attr *mft_na, *mftbmp_na; + ntfs_attr *mft_na; s64 old_data_initialized, old_data_size; ntfs_attr_search_ctx *ctx; ntfs_log_enter("Entering\n"); mft_na = vol->mft_na; - mftbmp_na = vol->mftbmp_na; if (size > mft_na->allocated_size || size > mft_na->initialized_size) { errno = EIO; diff --git a/portlibs/sources/libntfs/mft.h b/portlibs/sources/libcustomntfs/source/mft.h similarity index 100% rename from portlibs/sources/libntfs/mft.h rename to portlibs/sources/libcustomntfs/source/mft.h diff --git a/portlibs/sources/libntfs/misc.c b/portlibs/sources/libcustomntfs/source/misc.c similarity index 100% rename from portlibs/sources/libntfs/misc.c rename to portlibs/sources/libcustomntfs/source/misc.c diff --git a/portlibs/sources/libntfs/misc.h b/portlibs/sources/libcustomntfs/source/misc.h similarity index 100% rename from portlibs/sources/libntfs/misc.h rename to portlibs/sources/libcustomntfs/source/misc.h diff --git a/portlibs/sources/libntfs/mst.c b/portlibs/sources/libcustomntfs/source/mst.c similarity index 94% rename from portlibs/sources/libntfs/mst.c rename to portlibs/sources/libcustomntfs/source/mst.c index 470942d6..b7937b7a 100644 --- a/portlibs/sources/libntfs/mst.c +++ b/portlibs/sources/libcustomntfs/source/mst.c @@ -47,7 +47,8 @@ * EIO Multi sector transfer error was detected. Magic of the NTFS * record in @b will have been set to "BAAD". */ -int ntfs_mst_post_read_fixup(NTFS_RECORD *b, const u32 size) +int ntfs_mst_post_read_fixup_warn(NTFS_RECORD *b, const u32 size, + BOOL warn) { u16 usa_ofs, usa_count, usn; u16 *usa_pos, *data_pos; @@ -63,9 +64,14 @@ int ntfs_mst_post_read_fixup(NTFS_RECORD *b, const u32 size) (u32)(usa_ofs + (usa_count * 2)) > size || (size >> NTFS_BLOCK_SIZE_BITS) != usa_count) { errno = EINVAL; - ntfs_log_perror("%s: magic: 0x%08x size: %d usa_ofs: %d " - "usa_count: %d", __FUNCTION__, *(le32 *)b, - size, usa_ofs, usa_count); + if (warn) { + ntfs_log_perror("%s: magic: 0x%08lx size: %ld " + " usa_ofs: %d usa_count: %u", + __FUNCTION__, + (long)le32_to_cpu(*(le32 *)b), + (long)size, (int)usa_ofs, + (unsigned int)usa_count); + } return -1; } /* Position of usn in update sequence array. */ @@ -118,6 +124,16 @@ int ntfs_mst_post_read_fixup(NTFS_RECORD *b, const u32 size) return 0; } +/* + * Deprotect multi sector transfer protected data + * with a warning if an error is found. + */ + +int ntfs_mst_post_read_fixup(NTFS_RECORD *b, const u32 size) +{ + return (ntfs_mst_post_read_fixup_warn(b,size,TRUE)); +} + /** * ntfs_mst_pre_write_fixup - apply multi sector transfer protection * @b: pointer to the data to protect diff --git a/portlibs/sources/libntfs/mst.h b/portlibs/sources/libcustomntfs/source/mst.h similarity index 92% rename from portlibs/sources/libntfs/mst.h rename to portlibs/sources/libcustomntfs/source/mst.h index ca813821..d6ca6f27 100644 --- a/portlibs/sources/libntfs/mst.h +++ b/portlibs/sources/libcustomntfs/source/mst.h @@ -25,8 +25,11 @@ #include "types.h" #include "layout.h" +#include "volume.h" extern int ntfs_mst_post_read_fixup(NTFS_RECORD *b, const u32 size); +extern int ntfs_mst_post_read_fixup_warn(NTFS_RECORD *b, const u32 size, + BOOL warn); extern int ntfs_mst_pre_write_fixup(NTFS_RECORD *b, const u32 size); extern void ntfs_mst_post_write_fixup(NTFS_RECORD *b); diff --git a/portlibs/sources/libntfs/ntfs.c b/portlibs/sources/libcustomntfs/source/ntfs.c similarity index 100% rename from portlibs/sources/libntfs/ntfs.c rename to portlibs/sources/libcustomntfs/source/ntfs.c diff --git a/portlibs/sources/libntfs/ntfs.h b/portlibs/sources/libcustomntfs/source/ntfs.h similarity index 100% rename from portlibs/sources/libntfs/ntfs.h rename to portlibs/sources/libcustomntfs/source/ntfs.h diff --git a/portlibs/sources/libntfs/ntfsdir.c b/portlibs/sources/libcustomntfs/source/ntfsdir.c similarity index 100% rename from portlibs/sources/libntfs/ntfsdir.c rename to portlibs/sources/libcustomntfs/source/ntfsdir.c diff --git a/portlibs/sources/libntfs/ntfsdir.h b/portlibs/sources/libcustomntfs/source/ntfsdir.h similarity index 100% rename from portlibs/sources/libntfs/ntfsdir.h rename to portlibs/sources/libcustomntfs/source/ntfsdir.h diff --git a/portlibs/sources/libntfs/ntfsfile.c b/portlibs/sources/libcustomntfs/source/ntfsfile.c similarity index 100% rename from portlibs/sources/libntfs/ntfsfile.c rename to portlibs/sources/libcustomntfs/source/ntfsfile.c diff --git a/portlibs/sources/libntfs/ntfsfile.h b/portlibs/sources/libcustomntfs/source/ntfsfile.h similarity index 100% rename from portlibs/sources/libntfs/ntfsfile.h rename to portlibs/sources/libcustomntfs/source/ntfsfile.h diff --git a/portlibs/sources/libntfs/ntfsfile_frag.c b/portlibs/sources/libcustomntfs/source/ntfsfile_frag.c similarity index 100% rename from portlibs/sources/libntfs/ntfsfile_frag.c rename to portlibs/sources/libcustomntfs/source/ntfsfile_frag.c diff --git a/portlibs/sources/libntfs/ntfsfile_frag.h b/portlibs/sources/libcustomntfs/source/ntfsfile_frag.h similarity index 100% rename from portlibs/sources/libntfs/ntfsfile_frag.h rename to portlibs/sources/libcustomntfs/source/ntfsfile_frag.h diff --git a/portlibs/sources/libntfs/ntfsinternal.c b/portlibs/sources/libcustomntfs/source/ntfsinternal.c similarity index 100% rename from portlibs/sources/libntfs/ntfsinternal.c rename to portlibs/sources/libcustomntfs/source/ntfsinternal.c diff --git a/portlibs/sources/libntfs/ntfsinternal.h b/portlibs/sources/libcustomntfs/source/ntfsinternal.h similarity index 100% rename from portlibs/sources/libntfs/ntfsinternal.h rename to portlibs/sources/libcustomntfs/source/ntfsinternal.h diff --git a/portlibs/sources/libntfs/ntfstime.h b/portlibs/sources/libcustomntfs/source/ntfstime.h similarity index 94% rename from portlibs/sources/libntfs/ntfstime.h rename to portlibs/sources/libcustomntfs/source/ntfstime.h index 426269d7..21c222d9 100644 --- a/portlibs/sources/libntfs/ntfstime.h +++ b/portlibs/sources/libcustomntfs/source/ntfstime.h @@ -36,6 +36,18 @@ #include "types.h" +#ifndef GEKKO +/* + * assume "struct timespec" is not defined if st_mtime is not defined + */ +#if !defined(st_mtime) & !defined(__timespec_defined) +struct timespec { + time_t tv_sec; + long tv_nsec; +} ; +#endif +#endif + /* * There are four times more conversions of internal representation * to ntfs representation than any other conversion, so the most diff --git a/portlibs/sources/libntfs/object_id.c b/portlibs/sources/libcustomntfs/source/object_id.c similarity index 99% rename from portlibs/sources/libntfs/object_id.c rename to portlibs/sources/libcustomntfs/source/object_id.c index 8799ddba..059e8822 100644 --- a/portlibs/sources/libntfs/object_id.c +++ b/portlibs/sources/libcustomntfs/source/object_id.c @@ -287,7 +287,6 @@ static int remove_object_id_index(ntfs_attr *na, ntfs_index_context *xo, if (size >= (s64)sizeof(GUID)) { memcpy(&key.object_id, &old_attr->object_id,sizeof(GUID)); - size = sizeof(GUID); if (!ntfs_index_lookup(&key, sizeof(OBJECT_ID_INDEX_KEY), xo)) { entry = (struct OBJECT_ID_INDEX*)xo->entry; @@ -300,7 +299,6 @@ static int remove_object_id_index(ntfs_attr *na, ntfs_index_context *xo, memcpy(&old_attr->domain_id, &entry->data.domain_id, sizeof(GUID)); - size = sizeof(OBJECT_ID_ATTR); if (ntfs_index_rm(xo)) ret = -1; } diff --git a/portlibs/sources/libntfs/object_id.h b/portlibs/sources/libcustomntfs/source/object_id.h similarity index 100% rename from portlibs/sources/libntfs/object_id.h rename to portlibs/sources/libcustomntfs/source/object_id.h diff --git a/portlibs/sources/libntfs/param.h b/portlibs/sources/libcustomntfs/source/param.h similarity index 86% rename from portlibs/sources/libntfs/param.h rename to portlibs/sources/libcustomntfs/source/param.h index 7420c79f..c3675b72 100644 --- a/portlibs/sources/libntfs/param.h +++ b/portlibs/sources/libcustomntfs/source/param.h @@ -50,6 +50,19 @@ enum { /* maximum cluster size for allowing compression for new files */ #define MAX_COMPRESSION_CLUSTER_SIZE 4096 +/* + * Use of big write buffers + * + * With small volumes, the cluster allocator may fail to allocate + * enough clusters when the volume is nearly full. At most a run + * can be allocated per bitmap chunk. So, there is a danger when the + * number of chunks (capacity/(32768*clsiz)) is less than the number + * of clusters in the biggest write buffer (131072/clsiz). Hence + * a safe minimal capacity is 4GB + */ + +#define SAFE_CAPACITY_FOR_BIG_WRITES 0x100000000LL + /* * Parameters for runlists */ @@ -63,6 +76,11 @@ enum { #define XATTRMAPPINGFILE ".NTFS-3G/XattrMapping" /* default mapping file */ +/* + * Parameters for path canonicalization + */ + +#define MAPPERNAMELTH 256 /* * Permission checking modes for high level and low level diff --git a/portlibs/sources/libcustomntfs/source/realpath.c b/portlibs/sources/libcustomntfs/source/realpath.c new file mode 100644 index 00000000..a93bc698 --- /dev/null +++ b/portlibs/sources/libcustomntfs/source/realpath.c @@ -0,0 +1,103 @@ +/* + * realpath.c - realpath() aware of device mapper + * Originated from the util-linux project. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#ifdef HAVE_LIMITS_H +#include +#endif +#ifdef HAVE_CTYPE_H +#include +#endif + +#include "param.h" +#include "realpath.h" + +/* If there is no realpath() on the system, provide a dummy one. */ +#ifndef HAVE_REALPATH +char *ntfs_realpath(const char *path, char *resolved_path) +{ + strncpy(resolved_path, path, PATH_MAX); + resolved_path[PATH_MAX] = '\0'; + return resolved_path; +} +#endif + + +#ifdef linux + +/* + * Converts private "dm-N" names to "/dev/mapper/" + * + * Since 2.6.29 (patch 784aae735d9b0bba3f8b9faef4c8b30df3bf0128) kernel sysfs + * provides the real DM device names in /sys/block//dm/name + */ +static char * +canonicalize_dm_name(const char *ptname, char *canonical) +{ + FILE *f; + size_t sz; + char path[MAPPERNAMELTH + 24]; + char name[MAPPERNAMELTH + 16]; + char *res = NULL; + + snprintf(path, sizeof(path), "/sys/block/%s/dm/name", ptname); + if (!(f = fopen(path, "r"))) + return NULL; + + /* read "\n" from sysfs */ + if (fgets(name, sizeof(name), f) && (sz = strlen(name)) > 1) { + name[sz - 1] = '\0'; + snprintf(path, sizeof(path), "/dev/mapper/%s", name); + res = strcpy(canonical, path); + } + fclose(f); + return res; +} + +/* + * Canonicalize a device path + * + * Workaround from "basinilya" for fixing device mapper paths. + * + * Background (Phillip Susi, 2011-04-09) + * - ntfs-3g canonicalizes the device name so that if you mount with + * /dev/mapper/foo, the device name listed in mtab is /dev/dm-n, + * so you can not umount /dev/mapper/foo + * - umount won't even recognize and translate /dev/dm-n to the mount + * point, apparently because of the '-' involved. Editing mtab and + * removing the '-' allows you to umount /dev/dmn successfully. + * + * This code restores the devmapper name after canonicalization, + * until a proper fix is implemented. + */ + +char *ntfs_realpath_canonicalize(const char *path, char *canonical) +{ + char *p; + + if (path == NULL) + return NULL; + + if (!ntfs_realpath(path, canonical)) + return NULL; + + p = strrchr(canonical, '/'); + if (p && strncmp(p, "/dm-", 4) == 0 && isdigit(*(p + 4))) { + p = canonicalize_dm_name(p+1, canonical); + if (p) + return p; + } + + return canonical; +} + +#endif diff --git a/portlibs/sources/libcustomntfs/source/realpath.h b/portlibs/sources/libcustomntfs/source/realpath.h new file mode 100644 index 00000000..970d2af8 --- /dev/null +++ b/portlibs/sources/libcustomntfs/source/realpath.h @@ -0,0 +1,24 @@ +/* + * realpath.h - realpath() aware of device mapper + */ + +#ifndef REALPATH_H +#define REALPATH_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_REALPATH +#define ntfs_realpath realpath +#else +extern char *ntfs_realpath(const char *path, char *resolved_path); +#endif + +#ifdef linux +extern char *ntfs_realpath_canonicalize(const char *path, char *resolved_path); +#else +#define ntfs_realpath_canonicalize ntfs_realpath +#endif + +#endif /* REALPATH_H */ diff --git a/portlibs/sources/libntfs/reparse.c b/portlibs/sources/libcustomntfs/source/reparse.c similarity index 100% rename from portlibs/sources/libntfs/reparse.c rename to portlibs/sources/libcustomntfs/source/reparse.c diff --git a/portlibs/sources/libntfs/reparse.h b/portlibs/sources/libcustomntfs/source/reparse.h similarity index 100% rename from portlibs/sources/libntfs/reparse.h rename to portlibs/sources/libcustomntfs/source/reparse.h diff --git a/portlibs/sources/libntfs/runlist.c b/portlibs/sources/libcustomntfs/source/runlist.c similarity index 99% rename from portlibs/sources/libntfs/runlist.c rename to portlibs/sources/libcustomntfs/source/runlist.c index 383a80b2..7e158d44 100644 --- a/portlibs/sources/libntfs/runlist.c +++ b/portlibs/sources/libcustomntfs/source/runlist.c @@ -136,9 +136,10 @@ runlist_element *ntfs_rl_extend(ntfs_attr *na, runlist_element *rl, if (!newrl) { errno = ENOMEM; rl = (runlist_element*)NULL; - } else + } else { na->rl = newrl; rl = &newrl[irl]; + } } else { ntfs_log_error("Cannot extend unmapped runlist"); errno = EIO; @@ -1623,7 +1624,7 @@ errno_set: int ntfs_rl_truncate(runlist **arl, const VCN start_vcn) { runlist *rl; - BOOL is_end = FALSE; + /* BOOL is_end = FALSE; */ if (!arl || !*arl) { errno = EINVAL; @@ -1666,8 +1667,10 @@ int ntfs_rl_truncate(runlist **arl, const VCN start_vcn) */ if (rl->length) { ++rl; +/* if (!rl->length) is_end = TRUE; +*/ rl->vcn = start_vcn; rl->length = 0; } @@ -1675,7 +1678,7 @@ int ntfs_rl_truncate(runlist **arl, const VCN start_vcn) /** * Reallocate memory if necessary. * FIXME: Below code is broken, because runlist allocations must be - * a multiply of 4096. The code caused crashes and corruptions. + * a multiple of 4096. The code caused crashes and corruptions. */ /* if (!is_end) { diff --git a/portlibs/sources/libntfs/runlist.h b/portlibs/sources/libcustomntfs/source/runlist.h similarity index 100% rename from portlibs/sources/libntfs/runlist.h rename to portlibs/sources/libcustomntfs/source/runlist.h diff --git a/portlibs/sources/libntfs/security.c b/portlibs/sources/libcustomntfs/source/security.c similarity index 99% rename from portlibs/sources/libntfs/security.c rename to portlibs/sources/libcustomntfs/source/security.c index c7a87efb..5e70c214 100644 --- a/portlibs/sources/libntfs/security.c +++ b/portlibs/sources/libcustomntfs/source/security.c @@ -127,8 +127,8 @@ struct SDH { /* this is an image of an $SDH index entry */ static ntfschar sii_stream[] = { const_cpu_to_le16('$'), const_cpu_to_le16('S'), - const_cpu_to_le16('I'), - const_cpu_to_le16('I'), + const_cpu_to_le16('I'), + const_cpu_to_le16('I'), const_cpu_to_le16(0) }; static ntfschar sdh_stream[] = { const_cpu_to_le16('$'), const_cpu_to_le16('S'), @@ -684,7 +684,7 @@ static le32 entersecurityattr(ntfs_volume *vol, retries = 0; while (entry) { next = ntfs_index_next(entry,xsii); - if (next) { + if (next) { psii = (struct SII*)next; /* save last key and */ /* available position */ @@ -1024,7 +1024,7 @@ static int update_secur_descr(ntfs_volume *vol, * This is intended to allow graceful upgrades for files which * were created in previous versions, with a security attributes * and no security id. - * + * * It will allocate a security id and replace the individual * security attribute by a reference to the global one * @@ -1064,7 +1064,6 @@ static int upgrade_secur_desc(ntfs_volume *vol, na = ntfs_attr_open(ni, AT_STANDARD_INFORMATION, AT_UNNAMED, 0); if (na) { - res = 0; /* expand standard information attribute to v3.x */ res = ntfs_attr_truncate(na, (s64)sizeof(STANDARD_INFORMATION)); @@ -1373,7 +1372,7 @@ static int leg_compare(const struct CACHED_PERMISSIONS_LEGACY *cached, /* * Resize permission cache table * do not call unless resizing is needed - * + * * If allocation fails, the cache size is not updated * Lack of memory is not considered as an error, the cache is left * consistent and errno is not set. @@ -1469,7 +1468,7 @@ static struct CACHED_PERMISSIONS *enter_cache(struct SECURITY_CONTEXT *scx, if (pxdesc) { pxsize = sizeof(struct POSIX_SECURITY) + (pxdesc->acccnt + pxdesc->defcnt)*sizeof(struct POSIX_ACE); - pxcached = (struct POSIX_SECURITY*)ntfs_malloc(pxsize); + pxcached = (struct POSIX_SECURITY*)malloc(pxsize); if (pxcached) { memcpy(pxcached, pxdesc, pxsize); cacheentry->pxdesc = pxcached; @@ -1500,7 +1499,7 @@ static struct CACHED_PERMISSIONS *enter_cache(struct SECURITY_CONTEXT *scx, /* allocate block, if cache table was allocated */ if (pcache && (index1 <= pcache->head.last)) { cacheblock = (struct CACHED_PERMISSIONS*) - ntfs_malloc(sizeof(struct CACHED_PERMISSIONS) + malloc(sizeof(struct CACHED_PERMISSIONS) << CACHE_PERMISSIONS_BITS); pcache->cachetable[index1] = cacheblock; for (i=0; i<(1 << CACHE_PERMISSIONS_BITS); i++) @@ -1513,7 +1512,7 @@ static struct CACHED_PERMISSIONS *enter_cache(struct SECURITY_CONTEXT *scx, if (pxdesc) { pxsize = sizeof(struct POSIX_SECURITY) + (pxdesc->acccnt + pxdesc->defcnt)*sizeof(struct POSIX_ACE); - pxcached = (struct POSIX_SECURITY*)ntfs_malloc(pxsize); + pxcached = (struct POSIX_SECURITY*)malloc(pxsize); if (pxcached) { memcpy(pxcached, pxdesc, pxsize); cacheentry->pxdesc = pxcached; @@ -2003,7 +2002,7 @@ static int ntfs_get_perm(struct SECURITY_CONTEXT *scx, */ int ntfs_get_posix_acl(struct SECURITY_CONTEXT *scx, ntfs_inode *ni, - const char *name, char *value, size_t size) + const char *name, char *value, size_t size) { const SECURITY_DESCRIPTOR_RELATIVE *phead; struct POSIX_SECURITY *pxdesc; @@ -2013,7 +2012,6 @@ int ntfs_get_posix_acl(struct SECURITY_CONTEXT *scx, ntfs_inode *ni, const SID *gsid; /* group of file/directory */ uid_t uid; gid_t gid; - int perm; BOOL isdir; size_t outsize; @@ -2048,7 +2046,6 @@ int ntfs_get_posix_acl(struct SECURITY_CONTEXT *scx, ntfs_inode *ni, * fetch owner and group for cacheing */ if (pxdesc) { - perm = pxdesc->mode & 07777; /* * Create a security id if there were none * and upgrade option is selected @@ -2062,11 +2059,10 @@ int ntfs_get_posix_acl(struct SECURITY_CONTEXT *scx, ntfs_inode *ni, #if OWNERFROMACL uid = ntfs_find_user(scx->mapping[MAPUSERS],usid); #else - if (!perm && ntfs_same_sid(usid, adminsid)) { + if (!(pxdesc->mode & 07777) + && ntfs_same_sid(usid, adminsid)) { uid = find_tenant(scx, securattr); - if (uid) - perm = 0700; } else uid = ntfs_find_user(scx->mapping[MAPUSERS],usid); #endif @@ -2344,7 +2340,7 @@ int ntfs_get_owner_mode(struct SECURITY_CONTEXT *scx, stbuf->st_uid = ntfs_find_user(scx->mapping[MAPUSERS],usid); #else if (!perm && ntfs_same_sid(usid, adminsid)) { - stbuf->st_uid = + stbuf->st_uid = find_tenant(scx, securattr); if (stbuf->st_uid) @@ -2456,7 +2452,7 @@ static struct POSIX_SECURITY *inherit_posix(struct SECURITY_CONTEXT *scx, /* * Allocate a security_id for a file being created - * + * * Returns zero if not possible (NTFS v3.x required) */ @@ -2678,7 +2674,7 @@ le32 ntfs_alloc_securid(struct SECURITY_CONTEXT *scx, /* * Update ownership and mode of a file, reusing an existing * security descriptor when possible - * + * * Returns zero if successful */ @@ -2893,7 +2889,6 @@ int ntfs_set_posix_acl(struct SECURITY_CONTEXT *scx, ntfs_inode *ni, uid_t uid; uid_t gid; int res; - mode_t mode; BOOL isdir; BOOL deflt; BOOL exist; @@ -2919,7 +2914,6 @@ int ntfs_set_posix_acl(struct SECURITY_CONTEXT *scx, ntfs_inode *ni, gid = cached->gid; oldpxdesc = cached->pxdesc; if (oldpxdesc) { - mode = oldpxdesc->mode; newpxdesc = ntfs_replace_acl(oldpxdesc, (const struct POSIX_ACL*)value,count,deflt); } @@ -2946,7 +2940,6 @@ int ntfs_set_posix_acl(struct SECURITY_CONTEXT *scx, ntfs_inode *ni, || (!exist && (flags & XATTR_REPLACE))) { errno = (exist ? EEXIST : ENODATA); } else { - mode = oldpxdesc->mode; newpxdesc = ntfs_replace_acl(oldpxdesc, (const struct POSIX_ACL*)value,count,deflt); } @@ -3092,7 +3085,7 @@ int ntfs_set_mode(struct SECURITY_CONTEXT *scx, ntfs_inode *ni, mode_t mode) /* must copy before merging */ pxsize = sizeof(struct POSIX_SECURITY) + (oldpxdesc->acccnt + oldpxdesc->defcnt)*sizeof(struct POSIX_ACE); - newpxdesc = (struct POSIX_SECURITY*)ntfs_malloc(pxsize); + newpxdesc = (struct POSIX_SECURITY*)malloc(pxsize); if (newpxdesc) { memcpy(newpxdesc, oldpxdesc, pxsize); if (ntfs_merge_mode_posix(newpxdesc, mode)) @@ -3180,7 +3173,7 @@ int ntfs_sd_add_everyone(ntfs_inode *ni) ACCESS_ALLOWED_ACE *ace; SID *sid; int ret, sd_len; - + /* Create SECURITY_DESCRIPTOR attribute (everyone has full access). */ /* * Calculate security descriptor length. We have 2 sub-authorities in @@ -3188,14 +3181,14 @@ int ntfs_sd_add_everyone(ntfs_inode *ni) * 4 bytes to every SID. */ sd_len = sizeof(SECURITY_DESCRIPTOR_ATTR) + 2 * (sizeof(SID) + 4) + - sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE); + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE); sd = (SECURITY_DESCRIPTOR_RELATIVE*)ntfs_calloc(sd_len); if (!sd) return -1; - + sd->revision = SECURITY_DESCRIPTOR_REVISION; sd->control = SE_DACL_PRESENT | SE_SELF_RELATIVE; - + sid = (SID*)((u8*)sd + sizeof(SECURITY_DESCRIPTOR_ATTR)); sid->revision = SID_REVISION; sid->sub_authority_count = 2; @@ -3203,21 +3196,21 @@ int ntfs_sd_add_everyone(ntfs_inode *ni) sid->sub_authority[1] = const_cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS); sid->identifier_authority.value[5] = 5; sd->owner = cpu_to_le32((u8*)sid - (u8*)sd); - - sid = (SID*)((u8*)sid + sizeof(SID) + 4); + + sid = (SID*)((u8*)sid + sizeof(SID) + 4); sid->revision = SID_REVISION; sid->sub_authority_count = 2; sid->sub_authority[0] = const_cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID); sid->sub_authority[1] = const_cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS); sid->identifier_authority.value[5] = 5; sd->group = cpu_to_le32((u8*)sid - (u8*)sd); - + acl = (ACL*)((u8*)sid + sizeof(SID) + 4); acl->revision = ACL_REVISION; acl->size = const_cpu_to_le16(sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE)); acl->ace_count = const_cpu_to_le16(1); sd->dacl = cpu_to_le32((u8*)acl - (u8*)sd); - + ace = (ACCESS_ALLOWED_ACE*)((u8*)acl + sizeof(ACL)); ace->type = ACCESS_ALLOWED_ACE_TYPE; ace->flags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE; @@ -3232,7 +3225,7 @@ int ntfs_sd_add_everyone(ntfs_inode *ni) sd_len); if (ret) ntfs_log_perror("Failed to add initial SECURITY_DESCRIPTOR"); - + free(sd); return ret; } @@ -3331,7 +3324,7 @@ int ntfs_allowed_access(struct SECURITY_CONTEXT *scx, * * Returns true if access is allowed, including user is root and * no user mapping defined - * + * * Sets errno if there is a problem or if not allowed * * This is used for Posix ACL and checking creation of DOS file names @@ -3479,7 +3472,7 @@ int ntfs_set_owner(struct SECURITY_CONTEXT *scx, ntfs_inode *ni, if (uid && (fileuid != uid)) mode &= 01777; #if POSIXACLS - res = ntfs_set_owner_mode(scx, ni, uid, gid, + res = ntfs_set_owner_mode(scx, ni, uid, gid, mode, pxdesc); #else res = ntfs_set_owner_mode(scx, ni, uid, gid, mode); @@ -3513,16 +3506,16 @@ int ntfs_set_owner(struct SECURITY_CONTEXT *scx, ntfs_inode *ni, int ntfs_set_ownmod(struct SECURITY_CONTEXT *scx, ntfs_inode *ni, uid_t uid, gid_t gid, const mode_t mode) { - const SECURITY_DESCRIPTOR_RELATIVE *phead; const struct CACHED_PERMISSIONS *cached; char *oldattr; - const SID *usid; - const SID *gsid; uid_t fileuid; uid_t filegid; - BOOL isdir; int res; #if POSIXACLS + const SECURITY_DESCRIPTOR_RELATIVE *phead; + const SID *usid; + const SID *gsid; + BOOL isdir; const struct POSIX_SECURITY *oldpxdesc; struct POSIX_SECURITY *newpxdesc = (struct POSIX_SECURITY*)NULL; int pxsize; @@ -3541,7 +3534,7 @@ int ntfs_set_ownmod(struct SECURITY_CONTEXT *scx, ntfs_inode *ni, /* must copy before merging */ pxsize = sizeof(struct POSIX_SECURITY) + (oldpxdesc->acccnt + oldpxdesc->defcnt)*sizeof(struct POSIX_ACE); - newpxdesc = (struct POSIX_SECURITY*)ntfs_malloc(pxsize); + newpxdesc = (struct POSIX_SECURITY*)malloc(pxsize); if (newpxdesc) { memcpy(newpxdesc, oldpxdesc, pxsize); if (ntfs_merge_mode_posix(newpxdesc, mode)) @@ -3555,6 +3548,7 @@ int ntfs_set_ownmod(struct SECURITY_CONTEXT *scx, ntfs_inode *ni, filegid = 0; oldattr = getsecurityattr(scx->vol, ni); if (oldattr) { +#if POSIXACLS isdir = (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) != const_cpu_to_le16(0); phead = (const SECURITY_DESCRIPTOR_RELATIVE*) @@ -3567,7 +3561,6 @@ int ntfs_set_ownmod(struct SECURITY_CONTEXT *scx, ntfs_inode *ni, usid = (const SID*) &oldattr[le32_to_cpu(phead->owner)]; #endif -#if POSIXACLS newpxdesc = ntfs_build_permissions_posix(scx->mapping, oldattr, usid, gsid, isdir); if (!newpxdesc || ntfs_merge_mode_posix(newpxdesc, mode)) @@ -3595,7 +3588,7 @@ int ntfs_set_ownmod(struct SECURITY_CONTEXT *scx, ntfs_inode *ni, if ((int)gid < 0) gid = filegid; #if POSIXACLS - res = ntfs_set_owner_mode(scx, ni, uid, gid, + res = ntfs_set_owner_mode(scx, ni, uid, gid, mode, newpxdesc); #else res = ntfs_set_owner_mode(scx, ni, uid, gid, mode); @@ -3826,9 +3819,9 @@ static int link_single_group(struct MAPPING *usermapping, struct passwd *user, grmem++; if (*grmem) { if (!grcnt) - groups = (gid_t*)ntfs_malloc(sizeof(gid_t)); + groups = (gid_t*)malloc(sizeof(gid_t)); else - groups = (gid_t*)MEM2_realloc(groups, + groups = (gid_t*)realloc(groups, (grcnt+1)*sizeof(gid_t)); if (groups) groups[grcnt++] = gid; @@ -4238,7 +4231,7 @@ void ntfs_close_secure(struct SECURITY_CONTEXT *scx) ntfs_index_ctx_put(vol->secure_xsii); ntfs_index_ctx_put(vol->secure_xsdh); ntfs_inode_close(vol->secure_ni); - + } ntfs_free_mapping(scx->mapping); free_caches(scx); @@ -4784,6 +4777,7 @@ BOOL ntfs_set_file_attributes(struct SECURITY_API *scapi, ni->flags = (ni->flags & ~settable) | (cpu_to_le32(attrib) & settable); NInoSetDirty(ni); + NInoFileNameSetDirty(ni); } if (!ntfs_inode_close(ni)) res = -1; diff --git a/portlibs/sources/libntfs/security.h b/portlibs/sources/libcustomntfs/source/security.h similarity index 100% rename from portlibs/sources/libntfs/security.h rename to portlibs/sources/libcustomntfs/source/security.h diff --git a/portlibs/sources/libntfs/support.h b/portlibs/sources/libcustomntfs/source/support.h similarity index 100% rename from portlibs/sources/libntfs/support.h rename to portlibs/sources/libcustomntfs/source/support.h diff --git a/portlibs/sources/libntfs/types.h b/portlibs/sources/libcustomntfs/source/types.h similarity index 99% rename from portlibs/sources/libntfs/types.h rename to portlibs/sources/libcustomntfs/source/types.h index 77758eaf..fcd13604 100644 --- a/portlibs/sources/libntfs/types.h +++ b/portlibs/sources/libcustomntfs/source/types.h @@ -1,5 +1,5 @@ /* - * types.h - Misc type definitions not related to on-disk structure. + * types.h - Misc type definitions not related to on-disk structure. * Originated from the Linux-NTFS project. * * Copyright (c) 2000-2004 Anton Altaparmakov diff --git a/portlibs/sources/libntfs/unistr.c b/portlibs/sources/libcustomntfs/source/unistr.c similarity index 98% rename from portlibs/sources/libntfs/unistr.c rename to portlibs/sources/libcustomntfs/source/unistr.c index 343e7a34..c033ee12 100644 --- a/portlibs/sources/libntfs/unistr.c +++ b/portlibs/sources/libcustomntfs/source/unistr.c @@ -432,18 +432,18 @@ void ntfs_file_value_upcase(FILE_NAME_ATTR *file_name_attr, so this patch fixes the resulting issues for systems which use UTF-8 and for others, specifying the locale in fstab brings them the encoding which they want. - + If no locale is defined or there was a problem with setting one up and whenever nl_langinfo(CODESET) returns a sting starting with "ANSI", use an internal UCS-2LE <-> UTF-8 codeset converter to fix the bug where NTFS-3G does not show any path names which include international characters!!! (and also fails on creating them) as result. - + Author: Bernhard Kaindl Jean-Pierre Andre made it compliant with RFC3629/RFC2781. */ - -/* + +/* * Return the amount of 8-bit elements in UTF-8 needed (without the terminating * null) to store a given UTF-16LE string. * @@ -462,7 +462,7 @@ static int utf16_to_utf8_size(const ntfschar *ins, const int ins_len, int outs_l if ((c >= 0xdc00) && (c < 0xe000)) { surrog = FALSE; count += 4; - } else + } else goto fail; } else if (c < 0x80) @@ -479,14 +479,14 @@ static int utf16_to_utf8_size(const ntfschar *ins, const int ins_len, int outs_l else if (c >= 0xe000) #endif count += 3; - else + else goto fail; if (count > outs_len) { errno = ENAMETOOLONG; goto out; } } - if (surrog) + if (surrog) goto fail; ret = count; @@ -548,7 +548,7 @@ static int ntfs_utf16_to_utf8(const ntfschar *ins, const int ins_len, *t++ = 0x80 + ((c >> 6) & 15) + ((halfpair & 3) << 4); *t++ = 0x80 + (c & 63); halfpair = 0; - } else + } else goto fail; } else if (c < 0x80) { *t++ = c; @@ -566,12 +566,12 @@ static int ntfs_utf16_to_utf8(const ntfschar *ins, const int ins_len, *t++ = 0xe0 | (c >> 12); *t++ = 0x80 | ((c >> 6) & 0x3f); *t++ = 0x80 | (c & 0x3f); - } else + } else goto fail; } } *t = '\0'; - + #if defined(__APPLE__) || defined(__DARWIN__) #ifdef ENABLE_NFCONV if(nfconvert_utf8 && (t - *outs) > 0) { @@ -600,7 +600,7 @@ static int ntfs_utf16_to_utf8(const ntfschar *ins, const int ins_len, } #endif /* ENABLE_NFCONV */ #endif /* defined(__APPLE__) || defined(__DARWIN__) */ - + ret = t - *outs; out: return ret; @@ -609,8 +609,8 @@ fail: goto out; } -/* - * Return the amount of 16-bit elements in UTF-16LE needed +/* + * Return the amount of 16-bit elements in UTF-16LE needed * (without the terminating null) to store given UTF-8 string. * * Return -1 with errno set if it's longer than PATH_MAX or string is invalid. @@ -625,22 +625,22 @@ static int utf8_to_utf16_size(const char *s) size_t count = 0; while ((byte = *((const unsigned char *)s++))) { - if (++count >= PATH_MAX) + if (++count >= PATH_MAX) goto fail; if (byte >= 0xc0) { if (byte >= 0xF5) { errno = EILSEQ; goto out; } - if (!*s) + if (!*s) break; - if (byte >= 0xC0) + if (byte >= 0xC0) s++; - if (!*s) + if (!*s) break; - if (byte >= 0xE0) + if (byte >= 0xE0) s++; - if (!*s) + if (!*s) break; if (byte >= 0xF0) { s++; @@ -656,11 +656,11 @@ fail: errno = ENAMETOOLONG; goto out; } -/* +/* * This converts one UTF-8 sequence to cpu-endian Unicode value * within range U+0 .. U+10ffff and excluding U+D800 .. U+DFFF * - * Return the number of used utf8 bytes or -1 with errno set + * Return the number of used utf8 bytes or -1 with errno set * if sequence is invalid. */ static int utf8_to_unicode(u32 *wc, const char *s) @@ -726,7 +726,7 @@ fail: * @ins: input multibyte string buffer * @outs: on return contains the (allocated) output utf16 string * @outs_len: length of output buffer in utf16 characters - * + * * Return -1 with errno set. */ static int ntfs_utf8_to_utf16(const char *ins, ntfschar **outs) @@ -787,7 +787,7 @@ static int ntfs_utf8_to_utf16(const char *ins, ntfschar **outs) } t += m; } - + ret = --outpos - *outs; fail: #if defined(__APPLE__) || defined(__DARWIN__) @@ -930,7 +930,7 @@ err_out: * Convert the input multibyte string @ins, from the current locale into the * corresponding little endian, 2-byte Unicode string. * - * The function allocates the string and the caller is responsible for calling + * The function allocates the string and the caller is responsible for calling * free(*@outs); when finished with it. * * On success the function returns the number of Unicode characters written to @@ -961,7 +961,7 @@ int ntfs_mbstoucs(const char *ins, ntfschar **outs) errno = EINVAL; return -1; } - + if (use_utf8) return ntfs_utf8_to_utf16(ins, outs); @@ -1137,8 +1137,8 @@ void ntfs_upcase_table_build(ntfschar *uc, u32 uc_len) * value of "Add" added to it. */ static int uc_run_table[][3] = { /* Start, End, Add */ - {0x0061, 0x007b, -32}, {0x00e0, 0x00f7, -32}, {0x00f8, 0x00ff, -32}, - {0x0256, 0x0258, -205}, {0x028a, 0x028c, -217}, {0x037b, 0x037e, 130}, + {0x0061, 0x007b, -32}, {0x00e0, 0x00f7, -32}, {0x00f8, 0x00ff, -32}, + {0x0256, 0x0258, -205}, {0x028a, 0x028c, -217}, {0x037b, 0x037e, 130}, {0x03ac, 0x03ad, -38}, {0x03ad, 0x03b0, -37}, {0x03b1, 0x03c2, -32}, {0x03c2, 0x03c3, -31}, {0x03c3, 0x03cc, -32}, {0x03cc, 0x03cd, -64}, {0x03cd, 0x03cf, -63}, {0x0430, 0x0450, -32}, {0x0450, 0x0460, -80}, @@ -1262,7 +1262,7 @@ void ntfs_upcase_table_build(ntfschar *uc, u32 uc_len) u32 ntfs_upcase_build_default(ntfschar **upcase) { - u32 upcase_len; + u32 upcase_len = 0; *upcase = (ntfschar*)ntfs_malloc(UPCASE_LEN*2); if (*upcase) { @@ -1310,12 +1310,12 @@ ntfschar *ntfs_locase_table_build(const ntfschar *uc, u32 uc_cnt) * @len: length of output buffer in Unicode characters * * Convert the input @s string into the corresponding little endian, - * 2-byte Unicode string. The length of the converted string is less + * 2-byte Unicode string. The length of the converted string is less * or equal to the maximum length allowed by the NTFS format (255). * * If @s is NULL then return AT_UNNAMED. * - * On success the function returns the Unicode string in an allocated + * On success the function returns the Unicode string in an allocated * buffer and the caller is responsible to free it when it's not needed * anymore. * @@ -1406,16 +1406,18 @@ BOOL ntfs_collapsible_chars(ntfs_volume *vol, { BOOL collapsible; unsigned int ch; + unsigned int cs; int i; collapsible = shortlen == longlen; - if (collapsible) - for (i=0; i= vol->upcase_len) - || ((shortname[i] != longname[i]) - && (shortname[i] != vol->upcase[ch]))) - collapsible = FALSE; + for (i=0; collapsible && (i= vol->upcase_len) + || (cs >= vol->upcase_len) + || (vol->upcase[cs] != vol->upcase[ch]))) + collapsible = FALSE; } return (collapsible); } @@ -1454,7 +1456,7 @@ int ntfs_macosx_normalize_filenames(int normalize) { #else return -1; #endif /* ENABLE_NFCONV */ -} +} int ntfs_macosx_normalize_utf8(const char *utf8_string, char **target, int composed) { @@ -1466,14 +1468,14 @@ int ntfs_macosx_normalize_utf8(const char *utf8_string, char **target, CFIndex requiredBufferLength; char *result = NULL; int resultLength = -1; - + /* Convert the UTF-8 string to a CFString. */ cfSourceString = CFStringCreateWithCString(kCFAllocatorDefault, utf8_string, kCFStringEncodingUTF8); if(cfSourceString == NULL) { ntfs_log_error("CFStringCreateWithCString failed!\n"); return -2; } - + /* Create a mutable string from cfSourceString that we are free to modify. */ cfMutableString = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, cfSourceString); CFRelease(cfSourceString); /* End-of-life. */ @@ -1481,16 +1483,16 @@ int ntfs_macosx_normalize_utf8(const char *utf8_string, char **target, ntfs_log_error("CFStringCreateMutableCopy failed!\n"); return -3; } - + /* Normalize the mutable string to the desired normalization form. */ CFStringNormalize(cfMutableString, (composed != 0 ? kCFStringNormalizationFormC : kCFStringNormalizationFormD)); - + /* Store the resulting string in a '\0'-terminated UTF-8 encoded char* buffer. */ rangeToProcess = CFRangeMake(0, CFStringGetLength(cfMutableString)); if(CFStringGetBytes(cfMutableString, rangeToProcess, kCFStringEncodingUTF8, 0, false, NULL, 0, &requiredBufferLength) > 0) { resultLength = sizeof(char)*(requiredBufferLength + 1); result = ntfs_calloc(resultLength); - + if(result != NULL) { if(CFStringGetBytes(cfMutableString, rangeToProcess, kCFStringEncodingUTF8, 0, false, (UInt8*)result, resultLength-1, &requiredBufferLength) <= 0) { @@ -1505,9 +1507,9 @@ int ntfs_macosx_normalize_utf8(const char *utf8_string, char **target, else ntfs_log_error("Could not perform check for required length of UTF-8 conversion of normalized CFMutableString.\n"); - + CFRelease(cfMutableString); - + if(result != NULL) { *target = result; return resultLength - 1; diff --git a/portlibs/sources/libntfs/unistr.h b/portlibs/sources/libcustomntfs/source/unistr.h similarity index 100% rename from portlibs/sources/libntfs/unistr.h rename to portlibs/sources/libcustomntfs/source/unistr.h diff --git a/portlibs/sources/libntfs/volume.c b/portlibs/sources/libcustomntfs/source/volume.c similarity index 94% rename from portlibs/sources/libntfs/volume.c rename to portlibs/sources/libcustomntfs/source/volume.c index 28e4c907..a18109f1 100644 --- a/portlibs/sources/libntfs/volume.c +++ b/portlibs/sources/libcustomntfs/source/volume.c @@ -54,6 +54,7 @@ #include #endif +#include "param.h" #include "compat.h" #include "volume.h" #include "attrib.h" @@ -67,6 +68,7 @@ #include "dir.h" #include "logging.h" #include "cache.h" +#include "realpath.h" #include "misc.h" const char *ntfs_home = @@ -373,6 +375,12 @@ mft_has_no_attr_list: /* Done with the $Mft mft record. */ ntfs_attr_put_search_ctx(ctx); ctx = NULL; + + /* Update the size fields in the inode. */ + vol->mft_ni->data_size = vol->mft_na->data_size; + vol->mft_ni->allocated_size = vol->mft_na->allocated_size; + set_nino_flag(vol->mft_ni, KnownSize); + /* * The volume is now setup so we can use all read access functions. */ @@ -494,6 +502,12 @@ ntfs_volume *ntfs_volume_startup(struct ntfs_device *dev, unsigned long flags) NVolSetShowSysFiles(vol); NVolSetShowHidFiles(vol); NVolClearHideDotFiles(vol); + /* set default compression */ +#if DEFAULT_COMPRESSION + NVolSetCompression(vol); +#else + NVolClearCompression(vol); +#endif if (flags & MS_RDONLY) NVolSetReadOnly(vol); @@ -1359,18 +1373,6 @@ int ntfs_umount(ntfs_volume *vol, const BOOL force __attribute__((unused))) #ifdef HAVE_MNTENT_H -#ifndef HAVE_REALPATH -/** - * realpath - If there is no realpath on the system - */ -static char *realpath(const char *path, char *resolved_path) -{ - strncpy(resolved_path, path, PATH_MAX); - resolved_path[PATH_MAX] = '\0'; - return resolved_path; -} -#endif - /** * ntfs_mntent_check - desc * @@ -1394,7 +1396,7 @@ static int ntfs_mntent_check(const char *file, unsigned long *mnt_flags) err = errno; goto exit; } - if (!realpath(file, real_file)) { + if (!ntfs_realpath_canonicalize(file, real_file)) { err = errno; goto exit; } @@ -1403,7 +1405,7 @@ static int ntfs_mntent_check(const char *file, unsigned long *mnt_flags) goto exit; } while ((mnt = getmntent(f))) { - if (!realpath(mnt->mnt_fsname, real_fsname)) + if (!ntfs_realpath_canonicalize(mnt->mnt_fsname, real_fsname)) continue; if (!strcmp(real_file, real_fsname)) break; @@ -1730,3 +1732,113 @@ int ntfs_volume_get_free_space(ntfs_volume *vol) } return (ret); } + +/** + * ntfs_volume_rename - change the current label on a volume + * @vol: volume to change the label on + * @label: the new label + * @label_len: the length of @label in ntfschars including the terminating NULL + * character, which is mandatory (the value can not exceed 128) + * + * Change the label on the volume @vol to @label. + */ +int ntfs_volume_rename(ntfs_volume *vol, ntfschar *label, int label_len) +{ + ntfs_attr *na; + char *old_vol_name; + char *new_vol_name = NULL; + int new_vol_name_len; + int err; + + if (NVolReadOnly(vol)) { + ntfs_log_error("Refusing to change label on read-only mounted " + "volume.\n"); + errno = EROFS; + return -1; + } + + label_len *= sizeof(ntfschar); + if (label_len > 0x100) { + ntfs_log_error("New label is too long. Maximum %u characters " + "allowed.\n", + (unsigned)(0x100 / sizeof(ntfschar))); + errno = ERANGE; + return -1; + } + + na = ntfs_attr_open(vol->vol_ni, AT_VOLUME_NAME, AT_UNNAMED, 0); + if (!na) { + if (errno != ENOENT) { + err = errno; + ntfs_log_perror("Lookup of $VOLUME_NAME attribute " + "failed"); + goto err_out; + } + + /* The volume name attribute does not exist. Need to add it. */ + if (ntfs_attr_add(vol->vol_ni, AT_VOLUME_NAME, AT_UNNAMED, 0, + (u8*) label, label_len)) + { + err = errno; + ntfs_log_perror("Encountered error while adding " + "$VOLUME_NAME attribute"); + goto err_out; + } + } + else { + s64 written; + + if (NAttrNonResident(na)) { + err = errno; + ntfs_log_error("Error: Attribute $VOLUME_NAME must be " + "resident.\n"); + goto err_out; + } + + if (na->data_size != label_len) { + if (ntfs_attr_truncate(na, label_len)) { + err = errno; + ntfs_log_perror("Error resizing resident " + "attribute"); + goto err_out; + } + } + + if (label_len) { + written = ntfs_attr_pwrite(na, 0, label_len, label); + if (written == -1) { + err = errno; + ntfs_log_perror("Error when writing " + "$VOLUME_NAME data"); + goto err_out; + } + else if (written != label_len) { + err = EIO; + ntfs_log_error("Partial write when writing " + "$VOLUME_NAME data."); + goto err_out; + + } + } + } + + new_vol_name_len = + ntfs_ucstombs(label, label_len, &new_vol_name, 0); + if (new_vol_name_len == -1) { + err = errno; + ntfs_log_perror("Error while decoding new volume name"); + goto err_out; + } + + old_vol_name = vol->vol_name; + vol->vol_name = new_vol_name; + free(old_vol_name); + + err = 0; +err_out: + if (na) + ntfs_attr_close(na); + if (err) + errno = err; + return err ? -1 : 0; +} diff --git a/portlibs/sources/libntfs/volume.h b/portlibs/sources/libcustomntfs/source/volume.h similarity index 97% rename from portlibs/sources/libntfs/volume.h rename to portlibs/sources/libcustomntfs/source/volume.h index b3f47bf9..9d62d668 100644 --- a/portlibs/sources/libntfs/volume.h +++ b/portlibs/sources/libcustomntfs/source/volume.h @@ -113,6 +113,7 @@ typedef enum { NV_ShowHidFiles, /* 1: Show files marked hidden. */ NV_HideDotFiles, /* 1: Set hidden flag on dot files */ NV_Compression, /* 1: allow compression */ + NV_NoFixupWarn, /* 1: Do not log fixup errors */ } ntfs_volume_state_bits; #define test_nvol_flag(nv, flag) test_bit(NV_##flag, (nv)->state) @@ -147,6 +148,10 @@ typedef enum { #define NVolSetCompression(nv) set_nvol_flag(nv, Compression) #define NVolClearCompression(nv) clear_nvol_flag(nv, Compression) +#define NVolNoFixupWarn(nv) test_nvol_flag(nv, NoFixupWarn) +#define NVolSetNoFixupWarn(nv) set_nvol_flag(nv, NoFixupWarn) +#define NVolClearNoFixupWarn(nv) clear_nvol_flag(nv, NoFixupWarn) + /* * NTFS version 1.1 and 1.2 are used by Windows NT4. * NTFS version 2.x is used by Windows 2000 Beta @@ -297,6 +302,7 @@ extern int ntfs_volume_error(int err); extern void ntfs_mount_error(const char *vol, const char *mntpoint, int err); extern int ntfs_volume_get_free_space(ntfs_volume *vol); +extern int ntfs_volume_rename(ntfs_volume *vol, ntfschar *label, int label_len); extern int ntfs_set_shown_files(ntfs_volume *vol, BOOL show_sys_files, BOOL show_hid_files, BOOL hide_dot_files); diff --git a/portlibs/sources/libntfs/xattrs.c b/portlibs/sources/libcustomntfs/source/xattrs.c similarity index 100% rename from portlibs/sources/libntfs/xattrs.c rename to portlibs/sources/libcustomntfs/source/xattrs.c diff --git a/portlibs/sources/libntfs/xattrs.h b/portlibs/sources/libcustomntfs/source/xattrs.h similarity index 100% rename from portlibs/sources/libntfs/xattrs.h rename to portlibs/sources/libcustomntfs/source/xattrs.h diff --git a/portlibs/sources/libext2fs/source/config.h b/portlibs/sources/libext2fs/source/config.h deleted file mode 100644 index be09663b..00000000 --- a/portlibs/sources/libext2fs/source/config.h +++ /dev/null @@ -1,10 +0,0 @@ - -#define HAVE_UNISTD_H 1 -#define HAVE_SYS_STAT_H 1 -#define HAVE_SYS_TYPES_H 1 -#define HAVE_UTIME_H 1 -#define WORDS_BIGENDIAN 1 -#define HAVE_ERRNO_H 1 -#define EXT2_FLAT_INCLUDES 1 -#define HAVE_STRDUP 1 -#define HAVE_SYS_RESOURCE_H 1 diff --git a/portlibs/sources/libext2fs/source/ext2_err.h b/portlibs/sources/libext2fs/source/ext2_err.h deleted file mode 100644 index 4f127443..00000000 --- a/portlibs/sources/libext2fs/source/ext2_err.h +++ /dev/null @@ -1,152 +0,0 @@ -// -// Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o. -// -// This file may be redistributed under the terms of the GNU Public -// License. -#ifndef EXT2_ERR_H_ -#define EXT2_ERR_H_ - -#define EXT2_ET_OK 0 -#define EXT2_ET_BASE -1 -#define EXT2_ET_MAGIC_EXT2FS_FILSYS -2 -#define EXT2_ET_MAGIC_BADBLOCKS_LIST -3 -#define EXT2_ET_MAGIC_BADBLOCKS_ITERATE -4 -#define EXT2_ET_MAGIC_INODE_SCAN -5 -#define EXT2_ET_MAGIC_IO_CHANNEL -6 -#define EXT2_ET_MAGIC_UNIX_IO_CHANNEL -7 -#define EXT2_ET_MAGIC_IO_MANAGER -8 -#define EXT2_ET_MAGIC_BLOCK_BITMAP -9 -#define EXT2_ET_MAGIC_INODE_BITMAP -10 -#define EXT2_ET_MAGIC_GENERIC_BITMAP -11 -#define EXT2_ET_MAGIC_TEST_IO_CHANNEL -12 -#define EXT2_ET_MAGIC_DBLIST -13 -#define EXT2_ET_MAGIC_ICOUNT -14 -#define EXT2_ET_MAGIC_PQ_IO_CHANNEL -15 -#define EXT2_ET_MAGIC_EXT2_FILE -16 -#define EXT2_ET_MAGIC_E2IMAGE -17 -#define EXT2_ET_MAGIC_INODE_IO_CHANNEL -18 -#define EXT2_ET_MAGIC_EXTENT_HANDLE -19 -#define EXT2_ET_BAD_MAGIC -20 -#define EXT2_ET_REV_TOO_HIGH -21 -#define EXT2_ET_RO_FILSYS -22 -#define EXT2_ET_GDESC_READ -23 -#define EXT2_ET_GDESC_WRITE -24 -#define EXT2_ET_GDESC_BAD_BLOCK_MAP -25 -#define EXT2_ET_GDESC_BAD_INODE_MAP -26 -#define EXT2_ET_GDESC_BAD_INODE_TABLE -27 -#define EXT2_ET_INODE_BITMAP_WRITE -28 -#define EXT2_ET_INODE_BITMAP_READ -29 -#define EXT2_ET_BLOCK_BITMAP_WRITE -30 -#define EXT2_ET_BLOCK_BITMAP_READ -31 -#define EXT2_ET_INODE_TABLE_WRITE -32 -#define EXT2_ET_INODE_TABLE_READ -33 -#define EXT2_ET_NEXT_INODE_READ -34 -#define EXT2_ET_UNEXPECTED_BLOCK_SIZE -35 -#define EXT2_ET_DIR_CORRUPTED -36 -#define EXT2_ET_SHORT_READ -37 -#define EXT2_ET_SHORT_WRITE -38 -#define EXT2_ET_DIR_NO_SPACE -39 -#define EXT2_ET_NO_INODE_BITMAP -40 -#define EXT2_ET_NO_BLOCK_BITMAP -41 -#define EXT2_ET_BAD_INODE_NUM -42 -#define EXT2_ET_BAD_BLOCK_NUM -45 -#define EXT2_ET_EXPAND_DIR_ERR -46 -#define EXT2_ET_TOOSMALL -47 -#define EXT2_ET_BAD_BLOCK_MARK -48 -#define EXT2_ET_BAD_BLOCK_UNMARK -49 -#define EXT2_ET_BAD_BLOCK_TEST -50 -#define EXT2_ET_BAD_INODE_MARK -51 -#define EXT2_ET_BAD_INODE_UNMARK -52 -#define EXT2_ET_BAD_INODE_TEST -53 -#define EXT2_ET_FUDGE_BLOCK_BITMAP_END -54 -#define EXT2_ET_FUDGE_INODE_BITMAP_END -55 -#define EXT2_ET_BAD_IND_BLOCK -56 -#define EXT2_ET_BAD_DIND_BLOCK -57 -#define EXT2_ET_BAD_TIND_BLOCK -58 -#define EXT2_ET_NEQ_BLOCK_BITMAP -59 -#define EXT2_ET_NEQ_INODE_BITMAP -60 -#define EXT2_ET_BAD_DEVICE_NAME -61 -#define EXT2_ET_MISSING_INODE_TABLE -62 -#define EXT2_ET_CORRUPT_SUPERBLOCK -63 -#define EXT2_ET_BAD_GENERIC_MARK -64 -#define EXT2_ET_BAD_GENERIC_UNMARK -65 -#define EXT2_ET_BAD_GENERIC_TEST -66 -#define EXT2_ET_SYMLINK_LOOP -67 -#define EXT2_ET_CALLBACK_NOTHANDLED -68 -#define EXT2_ET_BAD_BLOCK_IN_INODE_TABLE -69 -#define EXT2_ET_UNSUPP_FEATURE -70 -#define EXT2_ET_RO_UNSUPP_FEATURE -71 -#define EXT2_ET_LLSEEK_FAILED -72 -#define EXT2_ET_NO_MEMORY -73 -#define EXT2_ET_INVALID_ARGUMENT -74 -#define EXT2_ET_BLOCK_ALLOC_FAIL -75 -#define EXT2_ET_INODE_ALLOC_FAIL -76 -#define EXT2_ET_NO_DIRECTORY -77 -#define EXT2_ET_TOO_MANY_REFS -78 -#define EXT2_ET_FILE_NOT_FOUND -79 -#define EXT2_ET_FILE_RO -80 -#define EXT2_ET_DB_NOT_FOUND -81 -#define EXT2_ET_DIR_EXISTS -82 -#define EXT2_ET_UNIMPLEMENTED -83 -#define EXT2_ET_CANCEL_REQUESTED -84 -#define EXT2_ET_FILE_TOO_BIG -85 -#define EXT2_ET_JOURNAL_NOT_BLOCK -86 -#define EXT2_ET_NO_JOURNAL_SB -87 -#define EXT2_ET_JOURNAL_TOO_SMALL -88 -#define EXT2_ET_JOURNAL_UNSUPP_VERSION -89 -#define EXT2_ET_LOAD_EXT_JOURNAL -90 -#define EXT2_ET_NO_JOURNAL -91 -#define EXT2_ET_DIRHASH_UNSUPP -92 -#define EXT2_ET_BAD_EA_BLOCK_NUM -93 -#define EXT2_ET_TOO_MANY_INODES -94 -#define EXT2_ET_NOT_IMAGE_FILE -95 -#define EXT2_ET_RES_GDT_BLOCKS -96 -#define EXT2_ET_RESIZE_INODE_CORRUPT -97 -#define EXT2_ET_SET_BMAP_NO_IND -98 -#define EXT2_ET_TDB_SUCCESS -99 -#define EXT2_ET_TDB_ERR_CORRUPT -100 -#define EXT2_ET_TDB_ERR_IO -101 -#define EXT2_ET_TDB_ERR_LOCK -102 -#define EXT2_ET_TDB_ERR_OOM -103 -#define EXT2_ET_TDB_ERR_EXISTS -104 -#define EXT2_ET_TDB_ERR_NOLOCK -105 -#define EXT2_ET_TDB_ERR_EINVAL -106 -#define EXT2_ET_TDB_ERR_NOEXIST -107 -#define EXT2_ET_TDB_ERR_RDONLY -108 -#define EXT2_ET_DBLIST_EMPTY -109 -#define EXT2_ET_RO_BLOCK_ITERATE -110 -#define EXT2_ET_MAGIC_EXTENT_PATH -111 -#define EXT2_ET_MAGIC_RESERVED_10 -112 -#define EXT2_ET_MAGIC_RESERVED_11 -113 -#define EXT2_ET_MAGIC_RESERVED_12 -114 -#define EXT2_ET_MAGIC_RESERVED_13 -115 -#define EXT2_ET_MAGIC_RESERVED_14 -116 -#define EXT2_ET_MAGIC_RESERVED_15 -117 -#define EXT2_ET_MAGIC_RESERVED_16 -118 -#define EXT2_ET_MAGIC_RESERVED_17 -119 -#define EXT2_ET_MAGIC_RESERVED_18 -120 -#define EXT2_ET_MAGIC_RESERVED_19 -121 -#define EXT2_ET_EXTENT_HEADER_BAD -122 -#define EXT2_ET_EXTENT_INDEX_BAD -123 -#define EXT2_ET_EXTENT_LEAF_BAD -124 -#define EXT2_ET_EXTENT_NO_SPACE -125 -#define EXT2_ET_INODE_NOT_EXTENT -126 -#define EXT2_ET_EXTENT_NO_NEXT -127 -#define EXT2_ET_EXTENT_NO_PREV -128 -#define EXT2_ET_EXTENT_NO_UP -129 -#define EXT2_ET_EXTENT_NO_DOWN -130 -#define EXT2_ET_NO_CURRENT_NODE -131 -#define EXT2_ET_OP_NOT_SUPPORTED -132 -#define EXT2_ET_CANT_INSERT_EXTENT -133 -#define EXT2_ET_CANT_SPLIT_EXTENT -134 -#define EXT2_ET_EXTENT_NOT_FOUND -135 -#define EXT2_ET_EXTENT_NOT_SUPPORTED -136 -#define EXT2_ET_EXTENT_INVALID_LENGTH -137 -#define EXT2_ET_IO_CHANNEL_NO_SUPPORT_64 -138 -#define EXT2_NO_MTAB_FILE -139 -#define EXT2_ET_MAGIC_GENERIC_BITMAP64 -140 -#define EXT2_ET_MAGIC_BLOCK_BITMAP64 -141 -#define EXT2_ET_MAGIC_INODE_BITMAP64 -142 -#define EXT2_ET_CANT_USE_LEGACY_BITMAPS -143 - -#endif diff --git a/portlibs/sources/libext2fs/source/ext2_types.h b/portlibs/sources/libext2fs/source/ext2_types.h deleted file mode 100644 index 5f5f7a57..00000000 --- a/portlibs/sources/libext2fs/source/ext2_types.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * If linux/types.h is already been included, assume it has defined - * everything we need. (cross fingers) Other header files may have - * also defined the types that we need. - */ -#ifndef _EXT2_TYPES_H -#define _EXT2_TYPES_H - -typedef unsigned char __u8; -typedef signed char __s8; -typedef unsigned short __u16; -typedef short __s16; -typedef unsigned int __u32; -typedef int __s32; -typedef unsigned long long __u64; -typedef signed long long __s64; - -#endif /* _EXT2_TYPES_H */ diff --git a/portlibs/sources/libext2fs/source/inline.c b/portlibs/sources/libext2fs/source/inline.c deleted file mode 100644 index f9be368b..00000000 --- a/portlibs/sources/libext2fs/source/inline.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * inline.c --- Includes the inlined functions defined in the header - * files as standalone functions, in case the application program - * is compiled with inlining turned off. - * - * Copyright (C) 1993, 1994 Theodore Ts'o. - * - * %Begin-Header% - * This file may be redistributed under the terms of the GNU Library - * General Public License, version 2. - * %End-Header% - */ - - -#include -#include -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#if HAVE_SYS_STAT_H -#include -#endif -#if HAVE_SYS_TYPES_H -#include -#endif - -#include "ext2_fs.h" -#define INCLUDE_INLINE_FUNCS -#include "ext2fs.h" - diff --git a/portlibs/sources/libfat/Makefile b/portlibs/sources/libfat/Makefile deleted file mode 100644 index 261f6d93..00000000 --- a/portlibs/sources/libfat/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -# Quick'n'dirty makefile [BC] v2 - -ifeq ($(strip $(DEVKITPPC)),) -$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") -endif - -include $(DEVKITPPC)/wii_rules - -LIBOGC_INC := $(DEVKITPRO)/libogc/include -LIBOGC_LIB := $(DEVKITPRO)/libogc/lib/wii - -CFLAGS := -O3 $(MACHDEP) -I$(LIBOGC_INC) - -LIB := fat -CFILES := $(wildcard *.c) -OFILES := $(CFILES:.c=.o) -ARC := lib$(LIB).a -HDR := fat.h - -all : $(OFILES) - $(AR) -r $(ARC) $(OFILES) - -clean : - rm -f $(OFILES) $(ARC) - -install : - cp -f $(ARC) ../../lib - cp -f $(HDR) ../../include - cp -f fatfile_frag.h ../../include - -%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ diff --git a/portlibs/sources/libntfs/Makefile b/portlibs/sources/libntfs/Makefile deleted file mode 100644 index 646a97b6..00000000 --- a/portlibs/sources/libntfs/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -# Quick'n'dirty makefile [BC] v2 - -ifeq ($(strip $(DEVKITPPC)),) -$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") -endif - -include $(DEVKITPPC)/wii_rules - -LIBOGC_INC := $(DEVKITPRO)/libogc/include -LIBOGC_LIB := $(DEVKITPRO)/libogc/lib/wii - -CFLAGS := -O3 $(MACHDEP) -I$(LIBOGC_INC) -DHAVE_CONFIG_H - -LIB := ntfs -CFILES := $(wildcard *.c) -OFILES := $(CFILES:.c=.o) -ARC := lib$(LIB).a -HDR := ntfs.h - -all : $(OFILES) - $(AR) -r $(ARC) $(OFILES) - -clean : - rm -f $(OFILES) $(ARC) - -install : - cp -f $(ARC) ../../lib - cp -f $(HDR) ../../include - cp -f ntfsfile_frag.h ../../include - -%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@