diff --git a/.vs/ext2fs.vcxproj b/.vs/ext2fs.vcxproj
index 67148a4d..8a51025c 100644
--- a/.vs/ext2fs.vcxproj
+++ b/.vs/ext2fs.vcxproj
@@ -61,6 +61,7 @@
+
@@ -79,6 +80,7 @@
+
@@ -89,6 +91,7 @@
+
@@ -99,6 +102,7 @@
+
diff --git a/.vs/ext2fs.vcxproj.filters b/.vs/ext2fs.vcxproj.filters
index e7004006..72367e3b 100644
--- a/.vs/ext2fs.vcxproj.filters
+++ b/.vs/ext2fs.vcxproj.filters
@@ -147,6 +147,12 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
@@ -200,5 +206,11 @@
Header Files
+
+ Header Files
+
+
+ Header Files
+
\ No newline at end of file
diff --git a/src/Makefile.am b/src/Makefile.am
index 8cbdf4fd..f7610a42 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -12,7 +12,7 @@ AM_V_WINDRES = $(AM_V_WINDRES_$(V))
rufus_SOURCES = badblocks.c checksum.c dev.c dos.c dos_locale.c drive.c format.c icon.c iso.c localization.c \
net.c parser.c pki.c process.c rufus.c smart.c stdfn.c stdio.c stdlg.c syslinux.c ui.c vhd.c
-rufus_CFLAGS = -I./ms-sys/inc -I./syslinux/libfat -I./syslinux/libinstaller -I./syslinux/win -I./libcdio $(AM_CFLAGS) -Wno-shadow
+rufus_CFLAGS = -I./ms-sys/inc -I./syslinux/libfat -I./syslinux/libinstaller -I./syslinux/win -I./libcdio $(AM_CFLAGS) -DEXT2_FLAT_INCLUDES=0 -Wno-shadow
rufus_LDFLAGS = $(AM_LDFLAGS) -mwindows
rufus_LDADD = rufus_rc.o bled/libbled.a ext2fs/libext2fs.a ms-sys/libmssys.a syslinux/libfat/libfat.a syslinux/libinstaller/libinstaller.a syslinux/win/libwin.a \
libcdio/iso9660/libiso9660.a libcdio/udf/libudf.a libcdio/driver/libdriver.a -lsetupapi -lole32 -lgdi32 -lshlwapi -lcrypt32 -lwintrust -lcomdlg32 -lcomctl32 -luuid -lpsapi
diff --git a/src/Makefile.in b/src/Makefile.in
index d0764301..ef014d36 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -275,7 +275,7 @@ AM_V_WINDRES = $(AM_V_WINDRES_$(V))
rufus_SOURCES = badblocks.c checksum.c dev.c dos.c dos_locale.c drive.c format.c icon.c iso.c localization.c \
net.c parser.c pki.c process.c rufus.c smart.c stdfn.c stdio.c stdlg.c syslinux.c ui.c vhd.c
-rufus_CFLAGS = -I./ms-sys/inc -I./syslinux/libfat -I./syslinux/libinstaller -I./syslinux/win -I./libcdio $(AM_CFLAGS) -Wno-shadow
+rufus_CFLAGS = -I./ms-sys/inc -I./syslinux/libfat -I./syslinux/libinstaller -I./syslinux/win -I./libcdio $(AM_CFLAGS) -DEXT2_FLAT_INCLUDES=0 -Wno-shadow
rufus_LDFLAGS = $(AM_LDFLAGS) -mwindows
rufus_LDADD = rufus_rc.o bled/libbled.a ext2fs/libext2fs.a ms-sys/libmssys.a syslinux/libfat/libfat.a syslinux/libinstaller/libinstaller.a syslinux/win/libwin.a \
libcdio/iso9660/libiso9660.a libcdio/udf/libudf.a libcdio/driver/libdriver.a -lsetupapi -lole32 -lgdi32 -lshlwapi -lcrypt32 -lwintrust -lcomdlg32 -lcomctl32 -luuid -lpsapi
diff --git a/src/ext2fs/LICENSE.txt b/src/ext2fs/LICENSE.txt
new file mode 100644
index 00000000..de775243
--- /dev/null
+++ b/src/ext2fs/LICENSE.txt
@@ -0,0 +1,481 @@
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 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.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it. You can use it for
+your libraries, 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 library, or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library. If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, 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 companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software. To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+ Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs. This
+license, the GNU Library General Public License, applies to certain
+designated libraries. This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+ The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it. Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program. However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+ Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries. We
+concluded that weaker conditions might promote sharing better.
+
+ However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves. This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them. (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.) The hope is that this
+will lead to faster development of free libraries.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+ Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License"). Each licensee is
+addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, 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 library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete 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 distribute a copy of this License along with the
+Library.
+
+ 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 Library or any portion
+of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+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 Library, 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 Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you 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.
+
+ If distribution of 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 satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ c) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ d) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. 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.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library 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.
+
+ 9. 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 Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+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.
+
+ 11. 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 Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library 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 Library.
+
+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.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library 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.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Library 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 Library
+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 Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+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
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "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
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. 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 LIBRARY 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
+LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. 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 library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; 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.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ , 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/src/ext2fs/Makefile.am b/src/ext2fs/Makefile.am
index 1f4bb618..a46f1a3e 100644
--- a/src/ext2fs/Makefile.am
+++ b/src/ext2fs/Makefile.am
@@ -1,9 +1,10 @@
noinst_LIBRARIES = libext2fs.a
-libext2fs_a_SOURCES = alloc.c alloc_sb.c alloc_stats.c alloc_tables.c badblocks.c bb_inode.c bitmaps.c \
- bitops.c blkmap64_ba.c blkmap64_rb.c blknum.c block.c bmap.c closefs.c crc16.c crc32c.c csum.c \
- dirblock.c dir_iterate.c extent.c ext_attr.c extent.c fileio.c freefs.c gen_bitmap.c gen_bitmap64.c \
- get_num_dirs.c i_block.c ind_block.c initialize.c inline.c inline_data.c inode.c io_manager.c link.c \
- lookup.c missing.c mkdir.c mmp.c newdir.c nt_io.c punch.c rbtree.c read_bb.c rw_bitmaps.c symlink.c valid_blk.c
+libext2fs_a_SOURCES = alloc.c alloc_sb.c alloc_stats.c alloc_tables.c badblocks.c bb_inode.c \
+ bitmaps.c bitops.c blkmap64_ba.c blkmap64_rb.c blknum.c block.c bmap.c closefs.c crc16.c \
+ crc32c.c csum.c dirblock.c dir_iterate.c extent.c ext_attr.c extent.c fileio.c freefs.c \
+ gen_bitmap.c gen_bitmap64.c get_num_dirs.c hashmap.c i_block.c ind_block.c initialize.c inline.c \
+ inline_data.c inode.c io_manager.c link.c lookup.c missing.c mkdir.c mmp.c newdir.c nt_io.c \
+ punch.c rbtree.c read_bb.c rw_bitmaps.c sha512.c symlink.c valid_blk.c
-libext2fs_a_CFLAGS = $(AM_CFLAGS) -DEXT2_FLAT_INCLUDES -DHAVE_CONFIG_H -I. -I.. -Wno-undef -Wno-strict-aliasing -Wno-shadow
+libext2fs_a_CFLAGS = $(AM_CFLAGS) -DEXT2_FLAT_INCLUDES=0 -DHAVE_CONFIG_H -I. -I.. -Wno-undef -Wno-strict-aliasing -Wno-shadow
diff --git a/src/ext2fs/Makefile.in b/src/ext2fs/Makefile.in
index 688ef4b9..bb507c5b 100644
--- a/src/ext2fs/Makefile.in
+++ b/src/ext2fs/Makefile.in
@@ -111,7 +111,8 @@ am_libext2fs_a_OBJECTS = libext2fs_a-alloc.$(OBJEXT) \
libext2fs_a-gen_bitmap.$(OBJEXT) \
libext2fs_a-gen_bitmap64.$(OBJEXT) \
libext2fs_a-get_num_dirs.$(OBJEXT) \
- libext2fs_a-i_block.$(OBJEXT) libext2fs_a-ind_block.$(OBJEXT) \
+ libext2fs_a-hashmap.$(OBJEXT) libext2fs_a-i_block.$(OBJEXT) \
+ libext2fs_a-ind_block.$(OBJEXT) \
libext2fs_a-initialize.$(OBJEXT) libext2fs_a-inline.$(OBJEXT) \
libext2fs_a-inline_data.$(OBJEXT) libext2fs_a-inode.$(OBJEXT) \
libext2fs_a-io_manager.$(OBJEXT) libext2fs_a-link.$(OBJEXT) \
@@ -120,7 +121,8 @@ am_libext2fs_a_OBJECTS = libext2fs_a-alloc.$(OBJEXT) \
libext2fs_a-newdir.$(OBJEXT) libext2fs_a-nt_io.$(OBJEXT) \
libext2fs_a-punch.$(OBJEXT) libext2fs_a-rbtree.$(OBJEXT) \
libext2fs_a-read_bb.$(OBJEXT) libext2fs_a-rw_bitmaps.$(OBJEXT) \
- libext2fs_a-symlink.$(OBJEXT) libext2fs_a-valid_blk.$(OBJEXT)
+ libext2fs_a-sha512.$(OBJEXT) libext2fs_a-symlink.$(OBJEXT) \
+ libext2fs_a-valid_blk.$(OBJEXT)
libext2fs_a_OBJECTS = $(am_libext2fs_a_OBJECTS)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
@@ -268,13 +270,14 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
noinst_LIBRARIES = libext2fs.a
-libext2fs_a_SOURCES = alloc.c alloc_sb.c alloc_stats.c alloc_tables.c badblocks.c bb_inode.c bitmaps.c \
- bitops.c blkmap64_ba.c blkmap64_rb.c blknum.c block.c bmap.c closefs.c crc16.c crc32c.c csum.c \
- dirblock.c dir_iterate.c extent.c ext_attr.c extent.c fileio.c freefs.c gen_bitmap.c gen_bitmap64.c \
- get_num_dirs.c i_block.c ind_block.c initialize.c inline.c inline_data.c inode.c io_manager.c link.c \
- lookup.c missing.c mkdir.c mmp.c newdir.c nt_io.c punch.c rbtree.c read_bb.c rw_bitmaps.c symlink.c valid_blk.c
+libext2fs_a_SOURCES = alloc.c alloc_sb.c alloc_stats.c alloc_tables.c badblocks.c bb_inode.c \
+ bitmaps.c bitops.c blkmap64_ba.c blkmap64_rb.c blknum.c block.c bmap.c closefs.c crc16.c \
+ crc32c.c csum.c dirblock.c dir_iterate.c extent.c ext_attr.c extent.c fileio.c freefs.c \
+ gen_bitmap.c gen_bitmap64.c get_num_dirs.c hashmap.c i_block.c ind_block.c initialize.c inline.c \
+ inline_data.c inode.c io_manager.c link.c lookup.c missing.c mkdir.c mmp.c newdir.c nt_io.c \
+ punch.c rbtree.c read_bb.c rw_bitmaps.c sha512.c symlink.c valid_blk.c
-libext2fs_a_CFLAGS = $(AM_CFLAGS) -DEXT2_FLAT_INCLUDES -DHAVE_CONFIG_H -I. -I.. -Wno-undef -Wno-strict-aliasing -Wno-shadow
+libext2fs_a_CFLAGS = $(AM_CFLAGS) -DEXT2_FLAT_INCLUDES=0 -DHAVE_CONFIG_H -I. -I.. -Wno-undef -Wno-strict-aliasing -Wno-shadow
all: all-am
.SUFFIXES:
@@ -486,6 +489,12 @@ libext2fs_a-get_num_dirs.o: get_num_dirs.c
libext2fs_a-get_num_dirs.obj: get_num_dirs.c
$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libext2fs_a_CFLAGS) $(CFLAGS) -c -o libext2fs_a-get_num_dirs.obj `if test -f 'get_num_dirs.c'; then $(CYGPATH_W) 'get_num_dirs.c'; else $(CYGPATH_W) '$(srcdir)/get_num_dirs.c'; fi`
+libext2fs_a-hashmap.o: hashmap.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libext2fs_a_CFLAGS) $(CFLAGS) -c -o libext2fs_a-hashmap.o `test -f 'hashmap.c' || echo '$(srcdir)/'`hashmap.c
+
+libext2fs_a-hashmap.obj: hashmap.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libext2fs_a_CFLAGS) $(CFLAGS) -c -o libext2fs_a-hashmap.obj `if test -f 'hashmap.c'; then $(CYGPATH_W) 'hashmap.c'; else $(CYGPATH_W) '$(srcdir)/hashmap.c'; fi`
+
libext2fs_a-i_block.o: i_block.c
$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libext2fs_a_CFLAGS) $(CFLAGS) -c -o libext2fs_a-i_block.o `test -f 'i_block.c' || echo '$(srcdir)/'`i_block.c
@@ -594,6 +603,12 @@ libext2fs_a-rw_bitmaps.o: rw_bitmaps.c
libext2fs_a-rw_bitmaps.obj: rw_bitmaps.c
$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libext2fs_a_CFLAGS) $(CFLAGS) -c -o libext2fs_a-rw_bitmaps.obj `if test -f 'rw_bitmaps.c'; then $(CYGPATH_W) 'rw_bitmaps.c'; else $(CYGPATH_W) '$(srcdir)/rw_bitmaps.c'; fi`
+libext2fs_a-sha512.o: sha512.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libext2fs_a_CFLAGS) $(CFLAGS) -c -o libext2fs_a-sha512.o `test -f 'sha512.c' || echo '$(srcdir)/'`sha512.c
+
+libext2fs_a-sha512.obj: sha512.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libext2fs_a_CFLAGS) $(CFLAGS) -c -o libext2fs_a-sha512.obj `if test -f 'sha512.c'; then $(CYGPATH_W) 'sha512.c'; else $(CYGPATH_W) '$(srcdir)/sha512.c'; fi`
+
libext2fs_a-symlink.o: symlink.c
$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libext2fs_a_CFLAGS) $(CFLAGS) -c -o libext2fs_a-symlink.o `test -f 'symlink.c' || echo '$(srcdir)/'`symlink.c
diff --git a/src/ext2fs/bitmaps.c b/src/ext2fs/bitmaps.c
index 84021917..e25db2c6 100644
--- a/src/ext2fs/bitmaps.c
+++ b/src/ext2fs/bitmaps.c
@@ -125,6 +125,7 @@ errcode_t ext2fs_allocate_subcluster_bitmap(ext2_filsys fs,
{
__u64 start, end, real_end;
ext2fs_generic_bitmap bmap;
+ ext2fs_generic_bitmap_64 bmap64;
errcode_t retval;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
@@ -147,14 +148,15 @@ errcode_t ext2fs_allocate_subcluster_bitmap(ext2_filsys fs,
end, real_end, descr, &bmap);
if (retval)
return retval;
- bmap->cluster_bits = 0;
+ bmap64 = (ext2fs_generic_bitmap_64) bmap;
+ bmap64->cluster_bits = 0;
*ret = bmap;
return 0;
}
int ext2fs_get_bitmap_granularity(ext2fs_block_bitmap bitmap)
{
- ext2fs_generic_bitmap bmap = bitmap;
+ ext2fs_generic_bitmap_64 bmap = (ext2fs_generic_bitmap_64) bitmap;
if (!EXT2FS_IS_64_BITMAP(bmap))
return 0;
diff --git a/src/ext2fs/blkmap64_ba.c b/src/ext2fs/blkmap64_ba.c
index 3707a61e..85cb38d2 100644
--- a/src/ext2fs/blkmap64_ba.c
+++ b/src/ext2fs/blkmap64_ba.c
@@ -40,7 +40,7 @@ struct ext2fs_ba_private_struct {
typedef struct ext2fs_ba_private_struct *ext2fs_ba_private;
-static errcode_t ba_alloc_private_data (ext2fs_generic_bitmap bitmap)
+static errcode_t ba_alloc_private_data (ext2fs_generic_bitmap_64 bitmap)
{
ext2fs_ba_private bp;
errcode_t retval;
@@ -69,7 +69,7 @@ static errcode_t ba_alloc_private_data (ext2fs_generic_bitmap bitmap)
}
static errcode_t ba_new_bmap(ext2_filsys fs EXT2FS_ATTR((unused)),
- ext2fs_generic_bitmap bitmap)
+ ext2fs_generic_bitmap_64 bitmap)
{
ext2fs_ba_private bp;
errcode_t retval;
@@ -86,7 +86,7 @@ static errcode_t ba_new_bmap(ext2_filsys fs EXT2FS_ATTR((unused)),
return 0;
}
-static void ba_free_bmap(ext2fs_generic_bitmap bitmap)
+static void ba_free_bmap(ext2fs_generic_bitmap_64 bitmap)
{
ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
@@ -101,8 +101,8 @@ static void ba_free_bmap(ext2fs_generic_bitmap bitmap)
bp = 0;
}
-static errcode_t ba_copy_bmap(ext2fs_generic_bitmap src,
- ext2fs_generic_bitmap dest)
+static errcode_t ba_copy_bmap(ext2fs_generic_bitmap_64 src,
+ ext2fs_generic_bitmap_64 dest)
{
ext2fs_ba_private src_bp = (ext2fs_ba_private) src->private;
ext2fs_ba_private dest_bp;
@@ -121,7 +121,7 @@ static errcode_t ba_copy_bmap(ext2fs_generic_bitmap src,
return 0;
}
-static errcode_t ba_resize_bmap(ext2fs_generic_bitmap bmap,
+static errcode_t ba_resize_bmap(ext2fs_generic_bitmap_64 bmap,
__u64 new_end, __u64 new_real_end)
{
ext2fs_ba_private bp = (ext2fs_ba_private) bmap->private;
@@ -162,7 +162,7 @@ static errcode_t ba_resize_bmap(ext2fs_generic_bitmap bmap,
}
-static int ba_mark_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
+static int ba_mark_bmap(ext2fs_generic_bitmap_64 bitmap, __u64 arg)
{
ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
blk64_t bitno = (blk64_t) arg;
@@ -170,7 +170,7 @@ static int ba_mark_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
return ext2fs_set_bit64(bitno - bitmap->start, bp->bitarray);
}
-static int ba_unmark_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
+static int ba_unmark_bmap(ext2fs_generic_bitmap_64 bitmap, __u64 arg)
{
ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
blk64_t bitno = (blk64_t) arg;
@@ -178,7 +178,7 @@ static int ba_unmark_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
return ext2fs_clear_bit64(bitno - bitmap->start, bp->bitarray);
}
-static int ba_test_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
+static int ba_test_bmap(ext2fs_generic_bitmap_64 bitmap, __u64 arg)
{
ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
blk64_t bitno = (blk64_t) arg;
@@ -186,7 +186,7 @@ static int ba_test_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
return ext2fs_test_bit64(bitno - bitmap->start, bp->bitarray);
}
-static void ba_mark_bmap_extent(ext2fs_generic_bitmap bitmap, __u64 arg,
+static void ba_mark_bmap_extent(ext2fs_generic_bitmap_64 bitmap, __u64 arg,
unsigned int num)
{
ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
@@ -197,7 +197,7 @@ static void ba_mark_bmap_extent(ext2fs_generic_bitmap bitmap, __u64 arg,
ext2fs_fast_set_bit64(bitno + i - bitmap->start, bp->bitarray);
}
-static void ba_unmark_bmap_extent(ext2fs_generic_bitmap bitmap, __u64 arg,
+static void ba_unmark_bmap_extent(ext2fs_generic_bitmap_64 bitmap, __u64 arg,
unsigned int num)
{
ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
@@ -208,7 +208,7 @@ static void ba_unmark_bmap_extent(ext2fs_generic_bitmap bitmap, __u64 arg,
ext2fs_fast_clear_bit64(bitno + i - bitmap->start, bp->bitarray);
}
-static int ba_test_clear_bmap_extent(ext2fs_generic_bitmap bitmap,
+static int ba_test_clear_bmap_extent(ext2fs_generic_bitmap_64 bitmap,
__u64 start, unsigned int len)
{
ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
@@ -282,7 +282,7 @@ static int ba_test_clear_bmap_extent(ext2fs_generic_bitmap bitmap,
}
-static errcode_t ba_set_bmap_range(ext2fs_generic_bitmap bitmap,
+static errcode_t ba_set_bmap_range(ext2fs_generic_bitmap_64 bitmap,
__u64 start, size_t num, void *in)
{
ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
@@ -292,7 +292,7 @@ static errcode_t ba_set_bmap_range(ext2fs_generic_bitmap bitmap,
return 0;
}
-static errcode_t ba_get_bmap_range(ext2fs_generic_bitmap bitmap,
+static errcode_t ba_get_bmap_range(ext2fs_generic_bitmap_64 bitmap,
__u64 start, size_t num, void *out)
{
ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
@@ -302,7 +302,7 @@ static errcode_t ba_get_bmap_range(ext2fs_generic_bitmap bitmap,
return 0;
}
-static void ba_clear_bmap(ext2fs_generic_bitmap bitmap)
+static void ba_clear_bmap(ext2fs_generic_bitmap_64 bitmap)
{
ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
@@ -311,20 +311,20 @@ static void ba_clear_bmap(ext2fs_generic_bitmap bitmap)
}
#ifdef ENABLE_BMAP_STATS
-static void ba_print_stats(ext2fs_generic_bitmap bitmap)
+static void ba_print_stats(ext2fs_generic_bitmap_64 bitmap)
{
fprintf(stderr, "%16llu Bytes used by bitarray\n",
((bitmap->real_end - bitmap->start) >> 3) + 1 +
sizeof(struct ext2fs_ba_private_struct));
}
#else
-static void ba_print_stats(ext2fs_generic_bitmap bitmap EXT2FS_ATTR((unused)))
+static void ba_print_stats(ext2fs_generic_bitmap_64 bitmap EXT2FS_ATTR((unused)))
{
}
#endif
/* Find the first zero bit between start and end, inclusive. */
-static errcode_t ba_find_first_zero(ext2fs_generic_bitmap bitmap,
+static errcode_t ba_find_first_zero(ext2fs_generic_bitmap_64 bitmap,
__u64 start, __u64 end, __u64 *out)
{
ext2fs_ba_private bp = (ext2fs_ba_private)bitmap->private;
@@ -398,7 +398,7 @@ static errcode_t ba_find_first_zero(ext2fs_generic_bitmap bitmap,
}
/* Find the first one bit between start and end, inclusive. */
-static errcode_t ba_find_first_set(ext2fs_generic_bitmap bitmap,
+static errcode_t ba_find_first_set(ext2fs_generic_bitmap_64 bitmap,
__u64 start, __u64 end, __u64 *out)
{
ext2fs_ba_private bp = (ext2fs_ba_private)bitmap->private;
diff --git a/src/ext2fs/blkmap64_rb.c b/src/ext2fs/blkmap64_rb.c
index 55704774..1fd55274 100644
--- a/src/ext2fs/blkmap64_rb.c
+++ b/src/ext2fs/blkmap64_rb.c
@@ -74,15 +74,15 @@ static void print_tree(struct rb_root *root)
struct rb_node *node = NULL;
struct bmap_rb_extent *ext;
- printf("\t\t\t=================================\n");
+ fprintf(stderr, "\t\t\t=================================\n");
node = ext2fs_rb_first(root);
for (node = ext2fs_rb_first(root); node != NULL;
node = ext2fs_rb_next(node)) {
ext = node_to_extent(node);
- printf("\t\t\t--> (%llu -> %llu)\n",
+ fprintf(stderr, "\t\t\t--> (%llu -> %llu)\n",
ext->start, ext->start + ext->count);
}
- printf("\t\t\t=================================\n");
+ fprintf(stderr, "\t\t\t=================================\n");
}
static void check_tree(struct rb_root *root, const char *msg)
@@ -94,35 +94,41 @@ static void check_tree(struct rb_root *root, const char *msg)
node = ext2fs_rb_next(node)) {
ext = node_to_extent(node);
if (ext->count == 0) {
- printf("Tree Error: count is zero\n");
- printf("extent: %llu -> %llu (%llu)\n", ext->start,
- ext->start + ext->count, ext->count);
+ fprintf(stderr, "Tree Error: count is zero\n");
+ fprintf(stderr, "extent: %llu -> %llu (%llu)\n",
+ ext->start, ext->start + ext->count,
+ ext->count);
goto err_out;
}
if (ext->start + ext->count < ext->start) {
- printf("Tree Error: start or count is crazy\n");
- printf("extent: %llu -> %llu (%llu)\n", ext->start,
- ext->start + ext->count, ext->count);
+ fprintf(stderr,
+ "Tree Error: start or count is crazy\n");
+ fprintf(stderr, "extent: %llu -> %llu (%llu)\n",
+ ext->start, ext->start + ext->count,
+ ext->count);
goto err_out;
}
if (old) {
if (old->start > ext->start) {
- printf("Tree Error: start is crazy\n");
- printf("extent: %llu -> %llu (%llu)\n",
+ fprintf(stderr, "Tree Error: start is crazy\n");
+ fprintf(stderr, "extent: %llu -> %llu (%llu)\n",
old->start, old->start + old->count,
old->count);
- printf("extent next: %llu -> %llu (%llu)\n",
+ fprintf(stderr,
+ "extent next: %llu -> %llu (%llu)\n",
ext->start, ext->start + ext->count,
ext->count);
goto err_out;
}
if ((old->start + old->count) >= ext->start) {
- printf("Tree Error: extent is crazy\n");
- printf("extent: %llu -> %llu (%llu)\n",
+ fprintf(stderr,
+ "Tree Error: extent is crazy\n");
+ fprintf(stderr, "extent: %llu -> %llu (%llu)\n",
old->start, old->start + old->count,
old->count);
- printf("extent next: %llu -> %llu (%llu)\n",
+ fprintf(stderr,
+ "extent next: %llu -> %llu (%llu)\n",
ext->start, ext->start + ext->count,
ext->count);
goto err_out;
@@ -133,7 +139,7 @@ static void check_tree(struct rb_root *root, const char *msg)
return;
err_out:
- printf("%s\n", msg);
+ fprintf(stderr, "%s\n", msg);
print_tree(root);
exit(1);
}
@@ -171,7 +177,7 @@ static void rb_free_extent(struct ext2fs_rb_private *bp,
ext2fs_free_mem(&ext);
}
-static errcode_t rb_alloc_private_data (ext2fs_generic_bitmap bitmap)
+static errcode_t rb_alloc_private_data (ext2fs_generic_bitmap_64 bitmap)
{
struct ext2fs_rb_private *bp;
errcode_t retval;
@@ -195,7 +201,7 @@ static errcode_t rb_alloc_private_data (ext2fs_generic_bitmap bitmap)
}
static errcode_t rb_new_bmap(ext2_filsys fs EXT2FS_ATTR((unused)),
- ext2fs_generic_bitmap bitmap)
+ ext2fs_generic_bitmap_64 bitmap)
{
errcode_t retval;
@@ -219,7 +225,7 @@ static void rb_free_tree(struct rb_root *root)
}
}
-static void rb_free_bmap(ext2fs_generic_bitmap bitmap)
+static void rb_free_bmap(ext2fs_generic_bitmap_64 bitmap)
{
struct ext2fs_rb_private *bp;
@@ -230,8 +236,8 @@ static void rb_free_bmap(ext2fs_generic_bitmap bitmap)
bp = 0;
}
-static errcode_t rb_copy_bmap(ext2fs_generic_bitmap src,
- ext2fs_generic_bitmap dest)
+static errcode_t rb_copy_bmap(ext2fs_generic_bitmap_64 src,
+ ext2fs_generic_bitmap_64 dest)
{
struct ext2fs_rb_private *src_bp, *dest_bp;
struct bmap_rb_extent *src_ext, *dest_ext;
@@ -296,7 +302,7 @@ static void rb_truncate(__u64 new_max, struct rb_root *root)
}
}
-static errcode_t rb_resize_bmap(ext2fs_generic_bitmap bmap,
+static errcode_t rb_resize_bmap(ext2fs_generic_bitmap_64 bmap,
__u64 new_end, __u64 new_real_end)
{
struct ext2fs_rb_private *bp;
@@ -391,6 +397,9 @@ static int rb_insert_extent(__u64 start, __u64 count,
struct bmap_rb_extent *ext;
int retval = 0;
+ if (count == 0)
+ return 0;
+
bp->rcursor_next = NULL;
ext = bp->wcursor;
if (ext) {
@@ -566,7 +575,7 @@ static int rb_remove_extent(__u64 start, __u64 count,
return retval;
}
-static int rb_mark_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
+static int rb_mark_bmap(ext2fs_generic_bitmap_64 bitmap, __u64 arg)
{
struct ext2fs_rb_private *bp;
int retval;
@@ -579,7 +588,7 @@ static int rb_mark_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
return retval;
}
-static int rb_unmark_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
+static int rb_unmark_bmap(ext2fs_generic_bitmap_64 bitmap, __u64 arg)
{
struct ext2fs_rb_private *bp;
int retval;
@@ -594,7 +603,7 @@ static int rb_unmark_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
}
inline
-static int rb_test_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
+static int rb_test_bmap(ext2fs_generic_bitmap_64 bitmap, __u64 arg)
{
struct ext2fs_rb_private *bp;
@@ -604,7 +613,7 @@ static int rb_test_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
return rb_test_bit(bp, arg);
}
-static void rb_mark_bmap_extent(ext2fs_generic_bitmap bitmap, __u64 arg,
+static void rb_mark_bmap_extent(ext2fs_generic_bitmap_64 bitmap, __u64 arg,
unsigned int num)
{
struct ext2fs_rb_private *bp;
@@ -616,7 +625,7 @@ static void rb_mark_bmap_extent(ext2fs_generic_bitmap bitmap, __u64 arg,
check_tree(&bp->root, __func__);
}
-static void rb_unmark_bmap_extent(ext2fs_generic_bitmap bitmap, __u64 arg,
+static void rb_unmark_bmap_extent(ext2fs_generic_bitmap_64 bitmap, __u64 arg,
unsigned int num)
{
struct ext2fs_rb_private *bp;
@@ -628,7 +637,7 @@ static void rb_unmark_bmap_extent(ext2fs_generic_bitmap bitmap, __u64 arg,
check_tree(&bp->root, __func__);
}
-static int rb_test_clear_bmap_extent(ext2fs_generic_bitmap bitmap,
+static int rb_test_clear_bmap_extent(ext2fs_generic_bitmap_64 bitmap,
__u64 start, unsigned int len)
{
struct rb_node *parent = NULL, **n;
@@ -684,7 +693,7 @@ static int rb_test_clear_bmap_extent(ext2fs_generic_bitmap bitmap,
return retval;
}
-static errcode_t rb_set_bmap_range(ext2fs_generic_bitmap bitmap,
+static errcode_t rb_set_bmap_range(ext2fs_generic_bitmap_64 bitmap,
__u64 start, size_t num, void *in)
{
struct ext2fs_rb_private *bp;
@@ -730,7 +739,7 @@ static errcode_t rb_set_bmap_range(ext2fs_generic_bitmap bitmap,
return 0;
}
-static errcode_t rb_get_bmap_range(ext2fs_generic_bitmap bitmap,
+static errcode_t rb_get_bmap_range(ext2fs_generic_bitmap_64 bitmap,
__u64 start, size_t num, void *out)
{
@@ -795,7 +804,7 @@ static errcode_t rb_get_bmap_range(ext2fs_generic_bitmap bitmap,
return 0;
}
-static void rb_clear_bmap(ext2fs_generic_bitmap bitmap)
+static void rb_clear_bmap(ext2fs_generic_bitmap_64 bitmap)
{
struct ext2fs_rb_private *bp;
@@ -808,7 +817,7 @@ static void rb_clear_bmap(ext2fs_generic_bitmap bitmap)
check_tree(&bp->root, __func__);
}
-static errcode_t rb_find_first_zero(ext2fs_generic_bitmap bitmap,
+static errcode_t rb_find_first_zero(ext2fs_generic_bitmap_64 bitmap,
__u64 start, __u64 end, __u64 *out)
{
struct rb_node *parent = NULL, **n;
@@ -844,7 +853,7 @@ static errcode_t rb_find_first_zero(ext2fs_generic_bitmap bitmap,
return 0;
}
-static errcode_t rb_find_first_set(ext2fs_generic_bitmap bitmap,
+static errcode_t rb_find_first_set(ext2fs_generic_bitmap_64 bitmap,
__u64 start, __u64 end, __u64 *out)
{
struct rb_node *parent = NULL, **n;
@@ -893,7 +902,7 @@ static errcode_t rb_find_first_set(ext2fs_generic_bitmap bitmap,
}
#ifdef ENABLE_BMAP_STATS
-static void rb_print_stats(ext2fs_generic_bitmap bitmap)
+static void rb_print_stats(ext2fs_generic_bitmap_64 bitmap)
{
struct ext2fs_rb_private *bp;
struct rb_node *node = NULL;
@@ -954,7 +963,7 @@ static void rb_print_stats(ext2fs_generic_bitmap bitmap)
eff);
}
#else
-static void rb_print_stats(ext2fs_generic_bitmap bitmap EXT2FS_ATTR((unused)))
+static void rb_print_stats(ext2fs_generic_bitmap_64 bitmap EXT2FS_ATTR((unused)))
{
}
#endif
diff --git a/src/ext2fs/blknum.c b/src/ext2fs/blknum.c
index aa0e9118..9ee5c66e 100644
--- a/src/ext2fs/blknum.c
+++ b/src/ext2fs/blknum.c
@@ -208,7 +208,7 @@ __u32 ext2fs_block_bitmap_checksum(ext2_filsys fs, dgrp_t group)
gdp = ext4fs_group_desc(fs, fs->group_desc, group);
csum = gdp->bg_block_bitmap_csum_lo;
- if (fs->super->s_desc_size >= EXT4_BG_BLOCK_BITMAP_CSUM_HI_LOCATION)
+ if (EXT2_DESC_SIZE(fs->super) >= EXT4_BG_BLOCK_BITMAP_CSUM_HI_LOCATION)
csum |= ((__u32)gdp->bg_block_bitmap_csum_hi << 16);
return csum;
}
@@ -249,7 +249,7 @@ __u32 ext2fs_inode_bitmap_checksum(ext2_filsys fs, dgrp_t group)
gdp = ext4fs_group_desc(fs, fs->group_desc, group);
csum = gdp->bg_inode_bitmap_csum_lo;
- if (fs->super->s_desc_size >= EXT4_BG_INODE_BITMAP_CSUM_HI_END)
+ if (EXT2_DESC_SIZE(fs->super) >= EXT4_BG_INODE_BITMAP_CSUM_HI_END)
csum |= ((__u32)gdp->bg_inode_bitmap_csum_hi << 16);
return csum;
}
diff --git a/src/ext2fs/bmap.c b/src/ext2fs/bmap.c
index 1ed98aa4..65c45c51 100644
--- a/src/ext2fs/bmap.c
+++ b/src/ext2fs/bmap.c
@@ -225,8 +225,10 @@ static errcode_t extent_bmap(ext2_filsys fs, ext2_ino_t ino,
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)
+ if (retval == EXT2_ET_EXTENT_NOT_FOUND) {
+ extent.e_lblk = block;
goto got_block;
+ }
return retval;
}
retval = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT, &extent);
diff --git a/src/ext2fs/bmap64.h b/src/ext2fs/bmap64.h
index d8c7a3c3..de334548 100644
--- a/src/ext2fs/bmap64.h
+++ b/src/ext2fs/bmap64.h
@@ -37,7 +37,7 @@ struct ext2_bmap_statistics {
};
-struct ext2fs_struct_generic_bitmap {
+struct ext2fs_struct_generic_bitmap_64 {
errcode_t magic;
ext2_filsys fs;
struct ext2_bitmap_ops *bitmap_ops;
@@ -53,6 +53,8 @@ struct ext2fs_struct_generic_bitmap {
#endif
};
+typedef struct ext2fs_struct_generic_bitmap_64 *ext2fs_generic_bitmap_64;
+
#define EXT2FS_IS_32_BITMAP(bmap) \
(((bmap)->magic == EXT2_ET_MAGIC_GENERIC_BITMAP) || \
((bmap)->magic == EXT2_ET_MAGIC_BLOCK_BITMAP) || \
@@ -66,37 +68,37 @@ struct ext2fs_struct_generic_bitmap {
struct ext2_bitmap_ops {
int type;
/* Generic bmap operators */
- errcode_t (*new_bmap)(ext2_filsys fs, ext2fs_generic_bitmap bmap);
- void (*free_bmap)(ext2fs_generic_bitmap bitmap);
- errcode_t (*copy_bmap)(ext2fs_generic_bitmap src,
- ext2fs_generic_bitmap dest);
- errcode_t (*resize_bmap)(ext2fs_generic_bitmap bitmap,
+ errcode_t (*new_bmap)(ext2_filsys fs, ext2fs_generic_bitmap_64 bmap);
+ void (*free_bmap)(ext2fs_generic_bitmap_64 bitmap);
+ errcode_t (*copy_bmap)(ext2fs_generic_bitmap_64 src,
+ ext2fs_generic_bitmap_64 dest);
+ errcode_t (*resize_bmap)(ext2fs_generic_bitmap_64 bitmap,
__u64 new_end,
__u64 new_real_end);
/* bit set/test operators */
- int (*mark_bmap)(ext2fs_generic_bitmap bitmap, __u64 arg);
- int (*unmark_bmap)(ext2fs_generic_bitmap bitmap, __u64 arg);
- int (*test_bmap)(ext2fs_generic_bitmap bitmap, __u64 arg);
- void (*mark_bmap_extent)(ext2fs_generic_bitmap bitmap, __u64 arg,
+ int (*mark_bmap)(ext2fs_generic_bitmap_64 bitmap, __u64 arg);
+ int (*unmark_bmap)(ext2fs_generic_bitmap_64 bitmap, __u64 arg);
+ int (*test_bmap)(ext2fs_generic_bitmap_64 bitmap, __u64 arg);
+ void (*mark_bmap_extent)(ext2fs_generic_bitmap_64 bitmap, __u64 arg,
unsigned int num);
- void (*unmark_bmap_extent)(ext2fs_generic_bitmap bitmap, __u64 arg,
+ void (*unmark_bmap_extent)(ext2fs_generic_bitmap_64 bitmap, __u64 arg,
unsigned int num);
- int (*test_clear_bmap_extent)(ext2fs_generic_bitmap bitmap,
+ int (*test_clear_bmap_extent)(ext2fs_generic_bitmap_64 bitmap,
__u64 arg, unsigned int num);
- errcode_t (*set_bmap_range)(ext2fs_generic_bitmap bitmap,
+ errcode_t (*set_bmap_range)(ext2fs_generic_bitmap_64 bitmap,
__u64 start, size_t num, void *in);
- errcode_t (*get_bmap_range)(ext2fs_generic_bitmap bitmap,
+ errcode_t (*get_bmap_range)(ext2fs_generic_bitmap_64 bitmap,
__u64 start, size_t num, void *out);
- void (*clear_bmap)(ext2fs_generic_bitmap bitmap);
- void (*print_stats)(ext2fs_generic_bitmap);
+ void (*clear_bmap)(ext2fs_generic_bitmap_64 bitmap);
+ void (*print_stats)(ext2fs_generic_bitmap_64);
/* Find the first zero bit between start and end, inclusive.
* May be NULL, in which case a generic function is used. */
- errcode_t (*find_first_zero)(ext2fs_generic_bitmap bitmap,
+ errcode_t (*find_first_zero)(ext2fs_generic_bitmap_64 bitmap,
__u64 start, __u64 end, __u64 *out);
/* Find the first set bit between start and end, inclusive.
* May be NULL, in which case a generic function is used. */
- errcode_t (*find_first_set)(ext2fs_generic_bitmap bitmap,
+ errcode_t (*find_first_set)(ext2fs_generic_bitmap_64 bitmap,
__u64 start, __u64 end, __u64 *out);
};
diff --git a/src/ext2fs/config.h b/src/ext2fs/config.h
index 7a0eaef5..25c484a7 100644
--- a/src/ext2fs/config.h
+++ b/src/ext2fs/config.h
@@ -190,23 +190,17 @@
#define INTDIV0_RAISES_SIGFPE 1
/* The size of `int', as computed by sizeof. */
-#define SIZEOF_INT sizeof(int)
+#define SIZEOF_INT 4
/* The size of `long', as computed by sizeof. */
-#define SIZEOF_LONG sizeof(long)
+#define SIZEOF_LONG 4
/* The size of `long long', as computed by sizeof. */
-#define SIZEOF_LONG_LONG sizeof(long long)
-
-/* The size of `off_t', as computed by sizeof. */
-#define SIZEOF_OFF_T 4
+#define SIZEOF_LONG_LONG 8
/* The size of `short', as computed by sizeof. */
#define SIZEOF_SHORT 2
-/* The size of `time_t', as computed by sizeof. */
-#define SIZEOF_TIME_T 4
-
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
@@ -216,43 +210,15 @@
/* Define if the POSIX multithreading library can be used. */
#define USE_POSIX_THREADS 1
-/* Enable extensions on AIX 3, Interix. */
-#ifndef _ALL_SOURCE
-# define _ALL_SOURCE 1
-#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
-/* Enable threading extensions on Solaris. */
-#ifndef _POSIX_PTHREAD_SEMANTICS
-# define _POSIX_PTHREAD_SEMANTICS 1
-#endif
-/* Enable extensions on HP NonStop. */
-#ifndef _TANDEM_SOURCE
-# define _TANDEM_SOURCE 1
-#endif
-/* Enable general extensions on Solaris. */
-#ifndef __EXTENSIONS__
-# define __EXTENSIONS__ 1
-#endif
-
-/* Define to 1 to build uuidd */
-#define USE_UUIDD 1
/* Define if the native Windows multithreading API can be used. */
/* #undef USE_WINDOWS_THREADS */
#define USE_WINDOWS_THREADS 1
-/* version for gettext */
-//#define VERSION "0.14.1"
-
-/* Define to 2 if the system does not provide POSIX.1 features except with
- this defined. */
-/* #undef _POSIX_1_SOURCE */
-
-/* Define to 1 if you need to in order for `stat' and other things to work. */
-/* #undef _POSIX_SOURCE */
/* Please see the Gnulib manual for how to use these macros.
@@ -370,24 +336,6 @@
#define __attribute__(x)
#endif
-
-/* 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 as the type of the result of subtracting two pointers, if the system
- doesn't define it. */
-/* #undef ptrdiff_t */
-
-/* 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 */
-
#define __libc_lock_t gl_lock_t
#define __libc_lock_define gl_lock_define
#define __libc_lock_define_initialized gl_lock_define_initialized
diff --git a/src/ext2fs/csum.c b/src/ext2fs/csum.c
index d755b9a7..98236137 100644
--- a/src/ext2fs/csum.c
+++ b/src/ext2fs/csum.c
@@ -10,6 +10,11 @@
* %End-Header%
*/
+#include "config.h"
+#if HAVE_SYS_TYPES_H
+#include
+#endif
+
#include "ext2_fs.h"
#include "ext2fs.h"
#include "crc16.h"
@@ -558,7 +563,7 @@ int ext2fs_inode_bitmap_csum_verify(ext2_filsys fs, dgrp_t group,
provided = gdp->bg_inode_bitmap_csum_lo;
calculated = ext2fs_crc32c_le(fs->csum_seed, (unsigned char *)bitmap,
size);
- if (fs->super->s_desc_size >= EXT4_BG_INODE_BITMAP_CSUM_HI_END)
+ if (EXT2_DESC_SIZE(fs->super) >= EXT4_BG_INODE_BITMAP_CSUM_HI_END)
provided |= (__u32)gdp->bg_inode_bitmap_csum_hi << 16;
else
calculated &= 0xFFFF;
@@ -578,7 +583,7 @@ errcode_t ext2fs_inode_bitmap_csum_set(ext2_filsys fs, dgrp_t group,
crc = ext2fs_crc32c_le(fs->csum_seed, (unsigned char *)bitmap, size);
gdp->bg_inode_bitmap_csum_lo = crc & 0xFFFF;
- if (fs->super->s_desc_size >= EXT4_BG_INODE_BITMAP_CSUM_HI_END)
+ if (EXT2_DESC_SIZE(fs->super) >= EXT4_BG_INODE_BITMAP_CSUM_HI_END)
gdp->bg_inode_bitmap_csum_hi = crc >> 16;
return 0;
@@ -596,7 +601,7 @@ int ext2fs_block_bitmap_csum_verify(ext2_filsys fs, dgrp_t group,
provided = gdp->bg_block_bitmap_csum_lo;
calculated = ext2fs_crc32c_le(fs->csum_seed, (unsigned char *)bitmap,
size);
- if (fs->super->s_desc_size >= EXT4_BG_BLOCK_BITMAP_CSUM_HI_LOCATION)
+ if (EXT2_DESC_SIZE(fs->super) >= EXT4_BG_BLOCK_BITMAP_CSUM_HI_LOCATION)
provided |= (__u32)gdp->bg_block_bitmap_csum_hi << 16;
else
calculated &= 0xFFFF;
@@ -616,7 +621,7 @@ errcode_t ext2fs_block_bitmap_csum_set(ext2_filsys fs, dgrp_t group,
crc = ext2fs_crc32c_le(fs->csum_seed, (unsigned char *)bitmap, size);
gdp->bg_block_bitmap_csum_lo = crc & 0xFFFF;
- if (fs->super->s_desc_size >= EXT4_BG_BLOCK_BITMAP_CSUM_HI_LOCATION)
+ if (EXT2_DESC_SIZE(fs->super) >= EXT4_BG_BLOCK_BITMAP_CSUM_HI_LOCATION)
gdp->bg_block_bitmap_csum_hi = crc >> 16;
return 0;
diff --git a/src/ext2fs/ext2_fs.h b/src/ext2fs/ext2_fs.h
index 73bab51c..6aa497f8 100644
--- a/src/ext2fs/ext2_fs.h
+++ b/src/ext2fs/ext2_fs.h
@@ -16,10 +16,31 @@
#ifndef _LINUX_EXT2_FS_H
#define _LINUX_EXT2_FS_H
-#include "ext2_types.h" /* Changed from linux/types.h */
+#include /* Changed from linux/types.h */
-#ifdef _MSC_VER
-#define __attribute__(x)
+#if defined(__GNUC__) || defined(__clang__)
+# ifdef __MINGW32__
+ /* gcc 4.7 miscompiles packed structures in MS-bitfield mode */
+# define EXT2FS_PACKME
+# define EXT2FS_PACKED __attribute__((packed,gcc_struct))
+# else
+# define EXT2FS_PACKME
+# define EXT2FS_PACKED __attribute__((packed))
+# endif
+#elif defined(_MSC_VER)
+# define EXT2FS_PACKME __pragma(pack(push, 1))
+# define EXT2FS_PACKED __pragma(pack(pop))
+#else
+# error "EXT2FS_PACKED is not defined for this compiler"
+#endif
+
+#ifndef __GNUC_PREREQ
+#if defined(__GNUC__) && defined(__GNUC_MINOR__)
+#define __GNUC_PREREQ(maj, min) \
+ ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+#else
+#define __GNUC_PREREQ(maj, min) 0
+#endif
#endif
/*
@@ -325,6 +346,7 @@ struct ext2_dx_tail {
#define EXT2_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/
#define EXT4_HUGE_FILE_FL 0x00040000 /* Set to each huge file */
#define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
+#define EXT4_VERITY_FL 0x00100000 /* Verity protected inode */
#define EXT4_EA_INODE_FL 0x00200000 /* Inode used for large EA */
/* EXT4_EOFBLOCKS_FL 0x00400000 was here */
#define FS_NOCOW_FL 0x00800000 /* Do not cow file */
@@ -333,10 +355,11 @@ struct ext2_dx_tail {
#define EXT4_SNAPFILE_SHRUNK_FL 0x08000000 /* Snapshot shrink has completed */
#define EXT4_INLINE_DATA_FL 0x10000000 /* Inode has inline data */
#define EXT4_PROJINHERIT_FL 0x20000000 /* Create with parents projid */
+#define EXT4_CASEFOLD_FL 0x40000000 /* Casefolded file */
#define EXT2_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
-#define EXT2_FL_USER_VISIBLE 0x204BDFFF /* User visible flags */
-#define EXT2_FL_USER_MODIFIABLE 0x204B80FF /* User modifiable flags */
+#define EXT2_FL_USER_VISIBLE 0x604BDFFF /* User visible flags */
+#define EXT2_FL_USER_MODIFIABLE 0x604B80FF /* User modifiable flags */
/*
* ioctl commands
@@ -382,17 +405,17 @@ struct ext4_new_group_input {
* Structure of an inode on the disk
*/
struct ext2_inode {
- __u16 i_mode; /* File mode */
+/*00*/ __u16 i_mode; /* File mode */
__u16 i_uid; /* Low 16 bits of Owner Uid */
__u32 i_size; /* Size in bytes */
__u32 i_atime; /* Access time */
__u32 i_ctime; /* Inode change time */
- __u32 i_mtime; /* Modification time */
+/*10*/ __u32 i_mtime; /* Modification time */
__u32 i_dtime; /* Deletion Time */
__u16 i_gid; /* Low 16 bits of Group Id */
__u16 i_links_count; /* Links count */
__u32 i_blocks; /* Blocks count */
- __u32 i_flags; /* File flags */
+/*20*/ __u32 i_flags; /* File flags */
union {
struct {
__u32 l_i_version; /* was l_i_reserved1 */
@@ -401,11 +424,11 @@ struct ext2_inode {
__u32 h_i_translator;
} hurd1;
} osd1; /* OS dependent 1 */
- __u32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
- __u32 i_generation; /* File version (for NFS) */
+/*28*/ __u32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
+/*64*/ __u32 i_generation; /* File version (for NFS) */
__u32 i_file_acl; /* File ACL */
__u32 i_size_high;
- __u32 i_faddr; /* Fragment address */
+/*70*/ __u32 i_faddr; /* Fragment address */
union {
struct {
__u16 l_i_blocks_hi;
@@ -430,17 +453,17 @@ struct ext2_inode {
* Permanent part of an large inode on the disk
*/
struct ext2_inode_large {
- __u16 i_mode; /* File mode */
+/*00*/ __u16 i_mode; /* File mode */
__u16 i_uid; /* Low 16 bits of Owner Uid */
__u32 i_size; /* Size in bytes */
__u32 i_atime; /* Access time */
__u32 i_ctime; /* Inode Change time */
- __u32 i_mtime; /* Modification time */
+/*10*/ __u32 i_mtime; /* Modification time */
__u32 i_dtime; /* Deletion Time */
__u16 i_gid; /* Low 16 bits of Group Id */
__u16 i_links_count; /* Links count */
__u32 i_blocks; /* Blocks count */
- __u32 i_flags; /* File flags */
+/*20*/ __u32 i_flags; /* File flags */
union {
struct {
__u32 l_i_version; /* was l_i_reserved1 */
@@ -449,11 +472,11 @@ struct ext2_inode_large {
__u32 h_i_translator;
} hurd1;
} osd1; /* OS dependent 1 */
- __u32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
- __u32 i_generation; /* File version (for NFS) */
+/*28*/ __u32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
+/*64*/ __u32 i_generation; /* File version (for NFS) */
__u32 i_file_acl; /* File ACL */
__u32 i_size_high;
- __u32 i_faddr; /* Fragment address */
+/*70*/ __u32 i_faddr; /* Fragment address */
union {
struct {
__u16 l_i_blocks_hi;
@@ -472,15 +495,15 @@ struct ext2_inode_large {
__u32 h_i_author;
} hurd2;
} osd2; /* OS dependent 2 */
- __u16 i_extra_isize;
+/*80*/ __u16 i_extra_isize;
__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) */
- __u32 i_crtime; /* File creation time */
+/*90*/ __u32 i_crtime; /* File creation time */
__u32 i_crtime_extra; /* extra File creation time (nsec << 2 | epoch)*/
__u32 i_version_hi; /* high 32 bits for 64-bit version */
- __u32 i_projid; /* Project ID */
+/*9c*/ __u32 i_projid; /* Project ID */
};
#define EXT4_INODE_CSUM_HI_EXTRA_END \
@@ -612,48 +635,48 @@ struct ext2_inode *EXT2_INODE(struct ext2_inode_large *large_inode)
* Policy provided via an ioctl on the topmost directory. This
* structure is also in the kernel.
*/
-struct ext4_encryption_policy {
+EXT2FS_PACKME struct ext4_encryption_policy {
char version;
char contents_encryption_mode;
char filenames_encryption_mode;
char flags;
char master_key_descriptor[EXT4_KEY_DESCRIPTOR_SIZE];
-} __attribute__((__packed__));
+} EXT2FS_PACKED;
-struct ext4_encryption_key {
+EXT2FS_PACKME struct ext4_encryption_key {
__u32 mode;
char raw[EXT4_MAX_KEY_SIZE];
__u32 size;
-} __attribute__((__packed__));
+} EXT2FS_PACKED;
/*
* Structure of the super block
*/
struct ext2_super_block {
- __u32 s_inodes_count; /* Inodes count */
+/*000*/ __u32 s_inodes_count; /* Inodes count */
__u32 s_blocks_count; /* Blocks count */
__u32 s_r_blocks_count; /* Reserved blocks count */
__u32 s_free_blocks_count; /* Free blocks count */
- __u32 s_free_inodes_count; /* Free inodes count */
+/*010*/ __u32 s_free_inodes_count; /* Free inodes count */
__u32 s_first_data_block; /* First Data Block */
__u32 s_log_block_size; /* Block size */
__u32 s_log_cluster_size; /* Allocation cluster size */
- __u32 s_blocks_per_group; /* # Blocks per group */
+/*020*/ __u32 s_blocks_per_group; /* # Blocks per group */
__u32 s_clusters_per_group; /* # Fragments per group */
__u32 s_inodes_per_group; /* # Inodes per group */
__u32 s_mtime; /* Mount time */
- __u32 s_wtime; /* Write time */
+/*030*/ __u32 s_wtime; /* Write time */
__u16 s_mnt_count; /* Mount count */
__s16 s_max_mnt_count; /* Maximal mount count */
__u16 s_magic; /* Magic signature */
__u16 s_state; /* File system state */
__u16 s_errors; /* Behaviour when detecting errors */
__u16 s_minor_rev_level; /* minor revision level */
- __u32 s_lastcheck; /* time of last check */
+/*040*/ __u32 s_lastcheck; /* time of last check */
__u32 s_checkinterval; /* max. time between checks */
__u32 s_creator_os; /* OS */
__u32 s_rev_level; /* Revision level */
- __u16 s_def_resuid; /* Default uid for reserved blocks */
+/*050*/ __u16 s_def_resuid; /* Default uid for reserved blocks */
__u16 s_def_resgid; /* Default gid for reserved blocks */
/*
* These fields are for EXT2_DYNAMIC_REV superblocks only.
@@ -669,15 +692,15 @@ struct ext2_super_block {
* things it doesn't understand...
*/
__u32 s_first_ino; /* First non-reserved inode */
- __u16 s_inode_size; /* size of inode structure */
+ __u16 s_inode_size; /* size of inode structure */
__u16 s_block_group_nr; /* block group # of this superblock */
__u32 s_feature_compat; /* compatible feature set */
- __u32 s_feature_incompat; /* incompatible feature set */
+/*060*/ __u32 s_feature_incompat; /* incompatible feature set */
__u32 s_feature_ro_compat; /* readonly-compatible feature set */
- __u8 s_uuid[16]; /* 128-bit uuid for volume */
- char s_volume_name[EXT2_LABEL_LEN]; /* volume name */
- char s_last_mounted[64]; /* directory where last mounted */
- __u32 s_algorithm_usage_bitmap; /* For compression */
+/*068*/ __u8 s_uuid[16]; /* 128-bit uuid for volume */
+/*078*/ char s_volume_name[EXT2_LABEL_LEN]; /* volume name */
+/*088*/ char s_last_mounted[64]; /* directory where last mounted */
+/*0c8*/ __u32 s_algorithm_usage_bitmap; /* For compression */
/*
* Performance hints. Directory preallocation should only
* happen if the EXT2_FEATURE_COMPAT_DIR_PREALLOC flag is on.
@@ -688,63 +711,71 @@ struct ext2_super_block {
/*
* Journaling support valid if EXT2_FEATURE_COMPAT_HAS_JOURNAL set.
*/
- __u8 s_journal_uuid[16]; /* uuid of journal superblock */
- __u32 s_journal_inum; /* inode number of journal file */
+/*0d0*/ __u8 s_journal_uuid[16]; /* uuid of journal superblock */
+/*0e0*/ __u32 s_journal_inum; /* inode number of journal file */
__u32 s_journal_dev; /* device number of journal file */
__u32 s_last_orphan; /* start of list of inodes to delete */
- __u32 s_hash_seed[4]; /* HTREE hash seed */
- __u8 s_def_hash_version; /* Default hash version to use */
- __u8 s_jnl_backup_type; /* Default type of journal backup */
+/*0ec*/ __u32 s_hash_seed[4]; /* HTREE hash seed */
+/*0fc*/ __u8 s_def_hash_version; /* Default hash version to use */
+ __u8 s_jnl_backup_type; /* Default type of journal backup */
__u16 s_desc_size; /* Group desc. size: INCOMPAT_64BIT */
- __u32 s_default_mount_opts;
+/*100*/ __u32 s_default_mount_opts; /* default EXT2_MOUNT_* flags used */
__u32 s_first_meta_bg; /* First metablock group */
__u32 s_mkfs_time; /* When the filesystem was created */
- __u32 s_jnl_blocks[17]; /* Backup of the journal inode */
- __u32 s_blocks_count_hi; /* Blocks count high 32bits */
+/*10c*/ __u32 s_jnl_blocks[17]; /* Backup of the journal inode */
+/*150*/ __u32 s_blocks_count_hi; /* Blocks count high 32bits */
__u32 s_r_blocks_count_hi; /* Reserved blocks count high 32 bits*/
- __u32 s_free_blocks_hi; /* Free blocks count */
+ __u32 s_free_blocks_hi; /* Free blocks count */
__u16 s_min_extra_isize; /* All inodes have at least # bytes */
- __u16 s_want_extra_isize; /* New inodes should reserve # bytes */
- __u32 s_flags; /* Miscellaneous flags */
- __u16 s_raid_stride; /* RAID stride */
+ __u16 s_want_extra_isize; /* New inodes should reserve # bytes */
+/*160*/ __u32 s_flags; /* Miscellaneous flags */
+ __u16 s_raid_stride; /* RAID stride in blocks */
__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)*/
+ __u64 s_mmp_block; /* Block for multi-mount protection */
+/*170*/ __u32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/
__u8 s_log_groups_per_flex; /* FLEX_BG group size */
__u8 s_checksum_type; /* metadata checksum algorithm */
__u8 s_encryption_level; /* versioning level for encryption */
__u8 s_reserved_pad; /* Padding to next 32bits */
__u64 s_kbytes_written; /* nr of lifetime kilobytes written */
- __u32 s_snapshot_inum; /* Inode number of active snapshot */
+/*180*/ __u32 s_snapshot_inum; /* Inode number of active snapshot */
__u32 s_snapshot_id; /* sequential ID of active snapshot */
- __u64 s_snapshot_r_blocks_count; /* reserved blocks for active
- snapshot's future use */
- __u32 s_snapshot_list; /* inode number of the head of the on-disk snapshot list */
+ __u64 s_snapshot_r_blocks_count; /* active snapshot reserved blocks */
+/*190*/ __u32 s_snapshot_list; /* inode number of disk snapshot list */
#define EXT4_S_ERR_START ext4_offsetof(struct ext2_super_block, s_error_count)
__u32 s_error_count; /* number of fs errors */
__u32 s_first_error_time; /* first time an error happened */
__u32 s_first_error_ino; /* inode involved in first error */
- __u64 s_first_error_block; /* block involved of first error */
+/*1a0*/ __u64 s_first_error_block; /* block involved in first error */
__u8 s_first_error_func[32]; /* function where the error happened */
- __u32 s_first_error_line; /* line number where error happened */
+/*1c8*/ __u32 s_first_error_line; /* line number where error happened */
__u32 s_last_error_time; /* most recent time of an error */
- __u32 s_last_error_ino; /* inode involved in last error */
+/*1d0*/ __u32 s_last_error_ino; /* inode involved in last error */
__u32 s_last_error_line; /* line number where error happened */
__u64 s_last_error_block; /* block involved of last error */
- __u8 s_last_error_func[32]; /* function where the error happened */
+/*1e0*/ __u8 s_last_error_func[32]; /* function where the error happened */
#define EXT4_S_ERR_END ext4_offsetof(struct ext2_super_block, s_mount_opts)
- __u8 s_mount_opts[64];
- __u32 s_usr_quota_inum; /* inode number of user quota file */
+/*200*/ __u8 s_mount_opts[64];
+/*240*/ __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_backup_bgs[2]; /* If sparse_super2 enabled */
- __u8 s_encrypt_algos[4]; /* Encryption algorithms in use */
- __u8 s_encrypt_pw_salt[16]; /* Salt used for string2key algorithm */
- __le32 s_lpf_ino; /* Location of the lost+found inode */
- __le32 s_prj_quota_inum; /* inode for tracking project quota */
- __le32 s_checksum_seed; /* crc32c(orig_uuid) if csum_seed set */
- __le32 s_reserved[98]; /* Padding to the end of the block */
- __u32 s_checksum; /* crc32c(superblock) */
+/*24c*/ __u32 s_backup_bgs[2]; /* If sparse_super2 enabled */
+/*254*/ __u8 s_encrypt_algos[4]; /* Encryption algorithms in use */
+/*258*/ __u8 s_encrypt_pw_salt[16]; /* Salt used for string2key algorithm */
+/*268*/ __le32 s_lpf_ino; /* Location of the lost+found inode */
+ __le32 s_prj_quota_inum; /* inode for tracking project quota */
+/*270*/ __le32 s_checksum_seed; /* crc32c(orig_uuid) if csum_seed set */
+/*274*/ __u8 s_wtime_hi;
+ __u8 s_mtime_hi;
+ __u8 s_mkfs_time_hi;
+ __u8 s_lastcheck_hi;
+ __u8 s_first_error_time_hi;
+ __u8 s_last_error_time_hi;
+ __u8 s_pad[2];
+/*27c*/ __le16 s_encoding; /* Filename charset encoding */
+ __le16 s_encoding_flags; /* Filename charset encoding flags */
+ __le32 s_reserved[95]; /* Padding to the end of the block */
+/*3fc*/ __u32 s_checksum; /* crc32c(superblock) */
};
#define EXT4_S_ERR_LEN (EXT4_S_ERR_END - EXT4_S_ERR_START)
@@ -816,7 +847,8 @@ struct ext2_super_block {
#define EXT4_FEATURE_RO_COMPAT_REPLICA 0x0800
#define EXT4_FEATURE_RO_COMPAT_READONLY 0x1000
#define EXT4_FEATURE_RO_COMPAT_PROJECT 0x2000 /* Project quota */
-
+#define EXT4_FEATURE_RO_COMPAT_SHARED_BLOCKS 0x4000
+#define EXT4_FEATURE_RO_COMPAT_VERITY 0x8000
#define EXT2_FEATURE_INCOMPAT_COMPRESSION 0x0001
#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002
@@ -833,6 +865,7 @@ struct ext2_super_block {
#define EXT4_FEATURE_INCOMPAT_LARGEDIR 0x4000 /* >2GB or 3-lvl htree */
#define EXT4_FEATURE_INCOMPAT_INLINE_DATA 0x8000 /* data in inode */
#define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000
+#define EXT4_FEATURE_INCOMPAT_FNAME_ENCODING 0x20000
#define EXT4_FEATURE_COMPAT_FUNCS(name, ver, flagname) \
static inline int ext2fs_has_feature_##name(struct ext2_super_block *sb) \
@@ -908,6 +941,8 @@ EXT4_FEATURE_RO_COMPAT_FUNCS(metadata_csum, 4, METADATA_CSUM)
EXT4_FEATURE_RO_COMPAT_FUNCS(replica, 4, REPLICA)
EXT4_FEATURE_RO_COMPAT_FUNCS(readonly, 4, READONLY)
EXT4_FEATURE_RO_COMPAT_FUNCS(project, 4, PROJECT)
+EXT4_FEATURE_RO_COMPAT_FUNCS(shared_blocks, 4, SHARED_BLOCKS)
+EXT4_FEATURE_RO_COMPAT_FUNCS(verity, 4, VERITY)
EXT4_FEATURE_INCOMPAT_FUNCS(compression, 2, COMPRESSION)
EXT4_FEATURE_INCOMPAT_FUNCS(filetype, 2, FILETYPE)
@@ -924,6 +959,7 @@ EXT4_FEATURE_INCOMPAT_FUNCS(csum_seed, 4, CSUM_SEED)
EXT4_FEATURE_INCOMPAT_FUNCS(largedir, 4, LARGEDIR)
EXT4_FEATURE_INCOMPAT_FUNCS(inline_data, 4, INLINE_DATA)
EXT4_FEATURE_INCOMPAT_FUNCS(encrypt, 4, ENCRYPT)
+EXT4_FEATURE_INCOMPAT_FUNCS(fname_encoding, 4, FNAME_ENCODING)
#define EXT2_FEATURE_COMPAT_SUPP 0
#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \
@@ -933,7 +969,8 @@ EXT4_FEATURE_INCOMPAT_FUNCS(encrypt, 4, ENCRYPT)
#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
EXT4_FEATURE_RO_COMPAT_DIR_NLINK| \
- EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
+ EXT2_FEATURE_RO_COMPAT_BTREE_DIR| \
+ EXT4_FEATURE_RO_COMPAT_VERITY)
/*
* Default values for user and/or group using reserved blocks
@@ -1107,4 +1144,11 @@ struct mmp_struct {
*/
#define EXT4_INLINE_DATA_DOTDOT_SIZE (4)
+#define EXT4_ENC_ASCII 0
+#define EXT4_ENC_UTF8_11_0 1
+
+#define EXT4_ENC_STRICT_MODE_FL (1 << 0) /* Reject invalid sequences */
+#define EXT4_UTF8_NORMALIZATION_TYPE_NFKD (1 << 1)
+#define EXT4_UTF8_CASEFOLD_TYPE_NFKDCF (1 << 4)
+
#endif /* _LINUX_EXT2_FS_H */
diff --git a/src/ext2fs/ext2_io.h b/src/ext2fs/ext2_io.h
index c286ad1c..5540900a 100644
--- a/src/ext2fs/ext2_io.h
+++ b/src/ext2fs/ext2_io.h
@@ -12,7 +12,7 @@
#ifndef _EXT2FS_EXT2_IO_H
#define _EXT2FS_EXT2_IO_H
-#include "ext2_types.h"
+#include
/*
* ext2_loff_t is defined here since unix_io.c needs it.
diff --git a/src/ext2fs/ext2_types.h b/src/ext2fs/ext2_types.h
index 8e26ec44..d1e9d29a 100644
--- a/src/ext2fs/ext2_types.h
+++ b/src/ext2fs/ext2_types.h
@@ -7,151 +7,46 @@
!defined(_EXT2_TYPES_H))
#define _EXT2_TYPES_H
+#include
#ifndef HAVE___U8
#define HAVE___U8
-#ifdef __U8_TYPEDEF
-typedef __U8_TYPEDEF __u8;
-#else
-typedef unsigned char __u8;
-#endif
+typedef uint8_t __u8;
#endif /* HAVE___U8 */
#ifndef HAVE___S8
#define HAVE___S8
-#ifdef __S8_TYPEDEF
-typedef __S8_TYPEDEF __s8;
-#else
-typedef signed char __s8;
-#endif
+typedef int8_t __s8;
#endif /* HAVE___S8 */
#ifndef HAVE___U16
#define HAVE___U16
-#ifdef __U16_TYPEDEF
-typedef __U16_TYPEDEF __u16;
-#else
-#if (4 == 2)
-typedef unsigned int __u16;
-#else
-#if (2 == 2)
-typedef unsigned short __u16;
-#else
-#undef HAVE___U16
- ?==error: undefined 16 bit type
-#endif /* SIZEOF_SHORT == 2 */
-#endif /* SIZEOF_INT == 2 */
-#endif /* __U16_TYPEDEF */
+typedef uint16_t __u16;
#endif /* HAVE___U16 */
#ifndef HAVE___S16
#define HAVE___S16
-#ifdef __S16_TYPEDEF
-typedef __S16_TYPEDEF __s16;
-#else
-#if (4 == 2)
-typedef int __s16;
-#else
-#if (2 == 2)
-typedef short __s16;
-#else
-#undef HAVE___S16
- ?==error: undefined 16 bit type
-#endif /* SIZEOF_SHORT == 2 */
-#endif /* SIZEOF_INT == 2 */
-#endif /* __S16_TYPEDEF */
+typedef int16_t __s16;
#endif /* HAVE___S16 */
#ifndef HAVE___U32
#define HAVE___U32
-#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
-#undef HAVE___U32
- ?== error: undefined 32 bit type
-#endif /* SIZEOF_SHORT == 4 */
-#endif /* SIZEOF_LONG == 4 */
-#endif /* SIZEOF_INT == 4 */
-#endif /* __U32_TYPEDEF */
+typedef uint32_t __u32;
#endif /* HAVE___U32 */
#ifndef HAVE___S32
#define HAVE___S32
-#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
-#undef HAVE___S32
- ?== error: undefined 32 bit type
-#endif /* SIZEOF_SHORT == 4 */
-#endif /* SIZEOF_LONG == 4 */
-#endif /* SIZEOF_INT == 4 */
-#endif /* __S32_TYPEDEF */
+typedef int32_t __s32;
#endif /* HAVE___S32 */
#ifndef HAVE___U64
#define HAVE___U64
-#ifdef __U64_TYPEDEF
-typedef __U64_TYPEDEF __u64;
-#else
-#if (4 == 8)
-typedef unsigned int __u64;
-#else
-#if (8 == 8)
-typedef unsigned long long __u64;
-#else
-#if (4 == 8)
-typedef unsigned long __u64;
-#else
-#undef HAVE___U64
- ?== error: undefined 64 bit type
-#endif /* SIZEOF_LONG_LONG == 8 */
-#endif /* SIZEOF_LONG == 8 */
-#endif /* SIZEOF_INT == 8 */
-#endif /* __U64_TYPEDEF */
+typedef uint64_t __u64;
#endif /* HAVE___U64 */
#ifndef HAVE___S64
#define HAVE___S64
-#ifdef __S64_TYPEDEF
-typedef __S64_TYPEDEF __s64;
-#else
-#if (4 == 8)
-typedef int __s64;
-#else
-#if (8 == 8)
-#if defined(__GNUC__)
-typedef __signed__ long long __s64;
-#else
-typedef signed long long __s64;
-#endif /* __GNUC__ */
-#else
-#if (4 == 8)
-typedef long __s64;
-#else
-#undef HAVE___S64
- ?== error: undefined 64 bit type
-#endif /* SIZEOF_LONG_LONG == 8 */
-#endif /* SIZEOF_LONG == 8 */
-#endif /* SIZEOF_INT == 8 */
-#endif /* __S64_TYPEDEF */
+typedef int64_t __s64;
#endif /* HAVE___S64 */
#undef __S8_TYPEDEF
@@ -165,8 +60,6 @@ typedef long __s64;
#endif /* _*_TYPES_H */
-#include
-
/* endian checking stuff */
#ifndef EXT2_ENDIAN_H_
#define EXT2_ENDIAN_H_
diff --git a/src/ext2fs/ext2fs.h b/src/ext2fs/ext2fs.h
index 6f36259a..045e6a2b 100644
--- a/src/ext2fs/ext2fs.h
+++ b/src/ext2fs/ext2fs.h
@@ -95,6 +95,8 @@ typedef __u32 __bitwise ext2_dirhash_t;
#include
#endif
+#include "hashmap.h"
+
#define EXT2_QSORT_TYPE int
typedef struct struct_ext2_filsys *ext2_filsys;
@@ -103,9 +105,14 @@ typedef struct struct_ext2_filsys *ext2_filsys;
#define EXT2FS_UNMARK_ERROR 1
#define EXT2FS_TEST_ERROR 2
-typedef struct ext2fs_struct_generic_bitmap *ext2fs_generic_bitmap;
-typedef struct ext2fs_struct_generic_bitmap *ext2fs_inode_bitmap;
-typedef struct ext2fs_struct_generic_bitmap *ext2fs_block_bitmap;
+struct ext2fs_struct_generic_bitmap_base {
+ errcode_t magic;
+ ext2_filsys fs;
+};
+
+typedef struct ext2fs_struct_generic_bitmap_base *ext2fs_generic_bitmap;
+typedef struct ext2fs_struct_generic_bitmap_base *ext2fs_inode_bitmap;
+typedef struct ext2fs_struct_generic_bitmap_base *ext2fs_block_bitmap;
#define EXT2_FIRST_INODE(s) EXT2_FIRST_INO(s)
@@ -189,6 +196,8 @@ typedef struct ext2_file *ext2_file_t;
#define EXT2_FLAG_DIRECT_IO 0x80000
#define EXT2_FLAG_SKIP_MMP 0x100000
#define EXT2_FLAG_IGNORE_CSUM_ERRORS 0x200000
+#define EXT2_FLAG_SHARE_DUP 0x400000
+#define EXT2_FLAG_IGNORE_SB_ERRORS 0x800000
/*
* Special flag in the ext2 inode i_flag field that means that this is
@@ -289,10 +298,15 @@ struct struct_ext2_filsys {
blk64_t len, blk64_t *pblk, blk64_t *plen);
void (*block_alloc_stats_range)(ext2_filsys fs, blk64_t blk, blk_t num,
int inuse);
+
+ /* hashmap for SHA of data blocks */
+ struct ext2fs_hashmap* block_sha_map;
+
+ const struct nls_table *encoding;
};
-#ifdef EXT2_FLAT_INCLUDES
-#include "bitops.h"
+#if EXT2_FLAT_INCLUDES
+#include "e2_bitops.h"
#else
#include
#endif
@@ -557,6 +571,16 @@ typedef struct ext2_icount *ext2_icount_t;
*/
#define BMAP_RET_UNINIT 0x0001
+/*
+ * Flags for ext2fs_read_inode2
+ */
+#define READ_INODE_NOCSUM 0x0001
+
+/*
+ * Flags for ext2fs_write_inode2
+ */
+#define WRITE_INODE_NOCSUM 0x0001
+
/*
* Flags for imager.c functions
*/
@@ -598,6 +622,7 @@ typedef struct ext2_icount *ext2_icount_t;
EXT4_FEATURE_INCOMPAT_64BIT|\
EXT4_FEATURE_INCOMPAT_INLINE_DATA|\
EXT4_FEATURE_INCOMPAT_ENCRYPT|\
+ EXT4_FEATURE_INCOMPAT_FNAME_ENCODING|\
EXT4_FEATURE_INCOMPAT_CSUM_SEED|\
EXT4_FEATURE_INCOMPAT_LARGEDIR)
@@ -611,7 +636,9 @@ typedef struct ext2_icount *ext2_icount_t;
EXT4_FEATURE_RO_COMPAT_QUOTA|\
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM|\
EXT4_FEATURE_RO_COMPAT_READONLY |\
- EXT4_FEATURE_RO_COMPAT_PROJECT)
+ EXT4_FEATURE_RO_COMPAT_PROJECT |\
+ EXT4_FEATURE_RO_COMPAT_SHARED_BLOCKS |\
+ EXT4_FEATURE_RO_COMPAT_VERITY)
/*
* These features are only allowed if EXT2_FLAG_SOFTSUPP_FEATURES is passed
@@ -1153,6 +1180,12 @@ extern errcode_t ext2fs_dirhash(int version, const char *name, int len,
ext2_dirhash_t *ret_hash,
ext2_dirhash_t *ret_minor_hash);
+extern errcode_t ext2fs_dirhash2(int version, const char *name, int len,
+ const struct nls_table *charset,
+ int hash_flags,
+ const __u32 *seed,
+ ext2_dirhash_t *ret_hash,
+ ext2_dirhash_t *ret_minor_hash);
/* dir_iterate.c */
extern errcode_t ext2fs_get_rec_len(ext2_filsys fs,
@@ -1275,7 +1308,9 @@ extern errcode_t ext2fs_extent_goto(ext2_extent_handle_t handle,
extern errcode_t ext2fs_extent_goto2(ext2_extent_handle_t handle,
int leaf_level, blk64_t blk);
extern errcode_t ext2fs_extent_fix_parents(ext2_extent_handle_t handle);
-size_t ext2fs_max_extent_depth(ext2_extent_handle_t handle);
+extern size_t ext2fs_max_extent_depth(ext2_extent_handle_t handle);
+extern errcode_t ext2fs_fix_extents_checksums(ext2_filsys fs, ext2_ino_t ino,
+ struct ext2_inode *inode);
/* fallocate.c */
#define EXT2_FALLOCATE_ZERO_BLOCKS (0x1)
@@ -1400,7 +1435,7 @@ extern errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ext2_ino_t *ret_num_dirs);
/* getsize.c */
extern errcode_t ext2fs_get_device_size(const char *file, int blocksize,
- blk64_t *retblocks);
+ blk_t *retblocks);
extern errcode_t ext2fs_get_device_size2(const char *file, int blocksize,
blk64_t *retblocks);
@@ -1499,13 +1534,19 @@ extern int ext2fs_inode_scan_flags(ext2_inode_scan scan, int set_flags,
extern errcode_t ext2fs_read_inode_full(ext2_filsys fs, ext2_ino_t ino,
struct ext2_inode * inode,
int bufsize);
-extern errcode_t ext2fs_read_inode (ext2_filsys fs, ext2_ino_t ino,
+extern errcode_t ext2fs_read_inode(ext2_filsys fs, ext2_ino_t ino,
struct ext2_inode * inode);
+extern errcode_t ext2fs_read_inode2(ext2_filsys fs, ext2_ino_t ino,
+ struct ext2_inode * inode,
+ int bufsize, int flags);
extern errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino,
struct ext2_inode * inode,
int bufsize);
extern errcode_t ext2fs_write_inode(ext2_filsys fs, ext2_ino_t ino,
struct ext2_inode * inode);
+extern errcode_t ext2fs_write_inode2(ext2_filsys fs, ext2_ino_t ino,
+ struct ext2_inode * inode,
+ int bufsize, int flags);
extern errcode_t ext2fs_write_new_inode(ext2_filsys fs, ext2_ino_t ino,
struct ext2_inode * inode);
extern errcode_t ext2fs_get_blocks(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks);
@@ -1724,6 +1765,7 @@ extern blk_t ext2fs_group_first_block(ext2_filsys fs, dgrp_t group);
extern blk_t ext2fs_group_last_block(ext2_filsys fs, dgrp_t group);
extern blk_t ext2fs_inode_data_blocks(ext2_filsys fs,
struct ext2_inode *inode);
+extern int ext2fs_htree_intnode_maxrecs(ext2_filsys fs, int blocks);
extern unsigned int ext2fs_div_ceil(unsigned int a, unsigned int b);
extern __u64 ext2fs_div64_ceil(__u64 a, __u64 b);
extern int ext2fs_dirent_name_len(const struct ext2_dir_entry *entry);
@@ -1959,18 +2001,6 @@ _INLINE_ blk_t ext2fs_inode_data_blocks(ext2_filsys fs,
return (blk_t) ext2fs_inode_data_blocks2(fs, inode);
}
-/* htree levels for ext4 */
-#define EXT4_HTREE_LEVEL_COMPAT 2
-#define EXT4_HTREE_LEVEL 3
-
-static inline unsigned int ext2_dir_htree_level(ext2_filsys fs)
-{
- if (ext2fs_has_feature_largedir(fs->super))
- return EXT4_HTREE_LEVEL;
-
- return EXT4_HTREE_LEVEL_COMPAT;
-}
-
_INLINE_ int ext2fs_htree_intnode_maxrecs(ext2_filsys fs, int blocks)
{
return blocks * ((fs->blocksize - 8) / sizeof(struct ext2_dx_entry));
@@ -2029,6 +2059,18 @@ ext2fs_const_inode(const struct ext2_inode_large * large_inode)
#undef _INLINE_
#endif
+/* htree levels for ext4 */
+#define EXT4_HTREE_LEVEL_COMPAT 2
+#define EXT4_HTREE_LEVEL 3
+
+static inline unsigned int ext2_dir_htree_level(ext2_filsys fs)
+{
+ if (ext2fs_has_feature_largedir(fs->super))
+ return EXT4_HTREE_LEVEL;
+
+ return EXT4_HTREE_LEVEL_COMPAT;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/src/ext2fs/ext4_acl.h b/src/ext2fs/ext4_acl.h
index 69ff79d5..8d4d9745 100644
--- a/src/ext2fs/ext4_acl.h
+++ b/src/ext2fs/ext4_acl.h
@@ -50,6 +50,13 @@ typedef struct {
typedef struct {
__le32 a_version;
+#if __GNUC_PREREQ (4, 8)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpedantic"
+#endif
posix_acl_xattr_entry a_entries[0];
+#if __GNUC_PREREQ (4, 8)
+#pragma GCC diagnostic pop
+#endif
} posix_acl_xattr_header;
diff --git a/src/ext2fs/ext_attr.c b/src/ext2fs/ext_attr.c
index 536e387e..78a823a9 100644
--- a/src/ext2fs/ext_attr.c
+++ b/src/ext2fs/ext_attr.c
@@ -357,13 +357,13 @@ static const char *find_ea_prefix(int index)
return NULL;
}
-static int find_ea_index(const char *fullname, char **name, int *index)
+static int find_ea_index(const char *fullname, const char **name, int *index)
{
struct ea_name_index *e;
for (e = ea_names; e->name; e++) {
if (strncmp(fullname, e->name, strlen(e->name)) == 0) {
- *name = (char *)fullname + strlen(e->name);
+ *name = fullname + strlen(e->name);
*index = e->index;
return 1;
}
@@ -525,8 +525,10 @@ posix_acl_xattr_count(size_t size)
static errcode_t convert_posix_acl_to_disk_buffer(const void *value, size_t size,
void *out_buf, size_t *size_out)
{
- posix_acl_xattr_header *header = (posix_acl_xattr_header*) value;
- posix_acl_xattr_entry *entry = (posix_acl_xattr_entry *)(header+1), *end;
+ const posix_acl_xattr_header *header =
+ (const posix_acl_xattr_header*) value;
+ const posix_acl_xattr_entry *end, *entry =
+ (const posix_acl_xattr_entry *)(header+1);
ext4_acl_header *ext_acl;
size_t s;
char *e;
@@ -574,12 +576,12 @@ static errcode_t convert_posix_acl_to_disk_buffer(const void *value, size_t size
return 0;
}
-static errcode_t convert_disk_buffer_to_posix_acl(const char *value, size_t size,
+static errcode_t convert_disk_buffer_to_posix_acl(const void *value, size_t size,
void **out_buf, size_t *size_out)
{
posix_acl_xattr_header *header;
posix_acl_xattr_entry *entry;
- ext4_acl_header *ext_acl = (ext4_acl_header *) value;
+ const ext4_acl_header *ext_acl = (const ext4_acl_header *) value;
errcode_t err;
const char *cp;
char *out;
@@ -597,7 +599,7 @@ static errcode_t convert_disk_buffer_to_posix_acl(const char *value, size_t size
header->a_version = ext2fs_cpu_to_le32(POSIX_ACL_XATTR_VERSION);
entry = (posix_acl_xattr_entry *) (out + sizeof(posix_acl_xattr_header));
- cp = value + sizeof(ext4_acl_header);
+ cp = (const char *) value + sizeof(ext4_acl_header);
size -= sizeof(ext4_acl_header);
while (size > 0) {
@@ -635,13 +637,13 @@ static errcode_t convert_disk_buffer_to_posix_acl(const char *value, size_t size
static errcode_t
write_xattrs_to_buffer(ext2_filsys fs, struct ext2_xattr *attrs, int count,
- char *entries_start, unsigned int storage_size,
+ void *entries_start, unsigned int storage_size,
unsigned int value_offset_correction, int write_hash)
{
struct ext2_xattr *x;
- struct ext2_ext_attr_entry *e = (struct ext2_ext_attr_entry *) entries_start;
- char *end = entries_start + storage_size;
- char *shortname;
+ struct ext2_ext_attr_entry *e = entries_start;
+ char *end = (char *) entries_start + storage_size;
+ const char *shortname;
unsigned int value_size;
int idx, ret;
errcode_t err;
@@ -652,7 +654,6 @@ write_xattrs_to_buffer(ext2_filsys fs, struct ext2_xattr *attrs, int count,
shortname = x->name;
ret = find_ea_index(x->name, &shortname, &idx);
- /* Calculate value size */
value_size = ((x->value_len + EXT2_EXT_ATTR_PAD - 1) /
EXT2_EXT_ATTR_PAD) * EXT2_EXT_ATTR_PAD;
@@ -669,8 +670,8 @@ write_xattrs_to_buffer(ext2_filsys fs, struct ext2_xattr *attrs, int count,
e->e_value_offs = 0;
} else {
end -= value_size;
- e->e_value_offs = end - entries_start +
- value_offset_correction;
+ e->e_value_offs = end - (char *) entries_start +
+ value_offset_correction;
memcpy(end, x->value, e->e_value_size);
}
@@ -692,7 +693,7 @@ write_xattrs_to_buffer(ext2_filsys fs, struct ext2_xattr *attrs, int count,
errcode_t ext2fs_xattrs_write(struct ext2_xattr_handle *handle)
{
ext2_filsys fs = handle->fs;
- const int inode_size = EXT2_INODE_SIZE(fs->super);
+ const unsigned int inode_size = EXT2_INODE_SIZE(fs->super);
struct ext2_inode_large *inode;
char *start, *block_buf = NULL;
struct ext2_ext_attr_header *header;
@@ -1359,7 +1360,7 @@ static int xattr_find_position(struct ext2_xattr *attrs, int count,
{
struct ext2_xattr *x;
int i;
- char *shortname, *x_shortname;
+ const char *shortname, *x_shortname;
int name_idx, x_name_idx;
int shortname_len, x_shortname_len;
@@ -1395,7 +1396,7 @@ static errcode_t xattr_array_update(struct ext2_xattr_handle *h,
int add_to_ibody;
int needed;
int name_len, name_idx;
- char *shortname;
+ const char *shortname;
int new_idx;
int ret;
@@ -1501,7 +1502,7 @@ static int space_used(struct ext2_xattr *attrs, int count)
{
int total = 0;
struct ext2_xattr *x;
- char *shortname;
+ const char *shortname;
int i, len, name_idx;
for (i = 0, x = attrs; i < count; i++, x++) {
@@ -1594,7 +1595,8 @@ errcode_t ext2fs_xattr_set(struct ext2_xattr_handle *h,
ret = EXT2_ET_FILESYSTEM_CORRUPTED;
goto out;
}
- ret = xattr_array_update(h, name, value, value_len, ibody_free,
+ ret = xattr_array_update(h, name, new_value, value_len,
+ ibody_free,
0 /* block_free */, old_idx,
0 /* in_inode */);
if (ret)
@@ -1613,12 +1615,12 @@ errcode_t ext2fs_xattr_set(struct ext2_xattr_handle *h,
value_len > EXT4_XATTR_MIN_LARGE_EA_SIZE(fs->blocksize))
in_inode = 1;
- ret = xattr_array_update(h, name, value, value_len, ibody_free,
+ ret = xattr_array_update(h, name, new_value, value_len, ibody_free,
block_free, old_idx, in_inode);
if (ret == EXT2_ET_EA_NO_SPACE && !in_inode &&
ext2fs_has_feature_ea_inode(fs->super))
- ret = xattr_array_update(h, name, value, value_len, ibody_free,
- block_free, old_idx, 1 /* in_inode */);
+ ret = xattr_array_update(h, name, new_value, value_len,
+ ibody_free, block_free, old_idx, 1 /* in_inode */);
if (ret)
goto out;
diff --git a/src/ext2fs/extent.c b/src/ext2fs/extent.c
index a9cdae79..ac3dbfec 100644
--- a/src/ext2fs/extent.c
+++ b/src/ext2fs/extent.c
@@ -1737,6 +1737,54 @@ size_t ext2fs_max_extent_depth(ext2_extent_handle_t handle)
return last_result;
}
+errcode_t ext2fs_fix_extents_checksums(ext2_filsys fs, ext2_ino_t ino,
+ struct ext2_inode *inode)
+{
+ ext2_extent_handle_t handle;
+ struct ext2fs_extent extent;
+ errcode_t errcode;
+ int save_flags = fs->flags;
+
+ if (!ext2fs_has_feature_metadata_csum(fs->super) ||
+ (inode && !(inode->i_flags & EXT4_EXTENTS_FL)))
+ return 0;
+
+ errcode = ext2fs_extent_open2(fs, ino, inode, &handle);
+ if (errcode) {
+ if (errcode == EXT2_ET_INODE_NOT_EXTENT)
+ errcode = 0;
+ return errcode;
+ }
+
+ fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
+ errcode = ext2fs_extent_get(handle, EXT2_EXTENT_ROOT, &extent);
+ if (errcode)
+ goto out;
+
+ do {
+ /* Skip to the end of a block of leaf nodes */
+ if (extent.e_flags & EXT2_EXTENT_FLAGS_LEAF) {
+ errcode = ext2fs_extent_get(handle,
+ EXT2_EXTENT_LAST_SIB,
+ &extent);
+ if (errcode)
+ break;
+ }
+
+ errcode = ext2fs_extent_get(handle, EXT2_EXTENT_NEXT, &extent);
+ if (errcode == EXT2_ET_EXTENT_CSUM_INVALID)
+ errcode = update_path(handle);
+ } while (errcode == 0);
+
+out:
+ /* Ok if we run off the end */
+ if (errcode == EXT2_ET_EXTENT_NO_NEXT)
+ errcode = 0;
+ ext2fs_extent_free(handle);
+ fs->flags = save_flags;
+ return errcode;
+}
+
#ifdef DEBUG
/*
* Override debugfs's prompt
diff --git a/src/ext2fs/fileio.c b/src/ext2fs/fileio.c
index 810a7fd8..a0b5d971 100644
--- a/src/ext2fs/fileio.c
+++ b/src/ext2fs/fileio.c
@@ -32,6 +32,12 @@ struct ext2_file {
char *buf;
};
+struct block_entry {
+ blk64_t physblock;
+ unsigned char sha[EXT2FS_SHA512_LENGTH];
+};
+typedef struct block_entry *block_entry_t;
+
#define BMAP_BUFFER (file->buf + fs->blocksize)
errcode_t ext2fs_file_open2(ext2_filsys fs, ext2_ino_t ino,
@@ -389,6 +395,8 @@ errcode_t ext2fs_file_write(ext2_file_t file, const void *buf,
errcode_t retval = 0;
unsigned int start, c, count = 0;
const char *ptr = (const char *) buf;
+ block_entry_t new_block = NULL, old_block = NULL;
+ int bmap_flags = 0;
EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
fs = file->fs;
@@ -424,22 +432,59 @@ errcode_t ext2fs_file_write(ext2_file_t file, const void *buf,
if (retval)
goto fail;
+ file->flags |= EXT2_FILE_BUF_DIRTY;
+ memcpy(file->buf+start, ptr, c);
+
/*
* OK, the physical block hasn't been allocated yet.
* Allocate it.
*/
if (!file->physblock) {
+ bmap_flags = (file->ino ? BMAP_ALLOC : 0);
+ if (fs->flags & EXT2_FLAG_SHARE_DUP) {
+ new_block = calloc(1, sizeof(*new_block));
+ if (!new_block) {
+ retval = EXT2_ET_NO_MEMORY;
+ goto fail;
+ }
+ ext2fs_sha512((const unsigned char*)file->buf,
+ fs->blocksize, new_block->sha);
+ old_block = ext2fs_hashmap_lookup(
+ fs->block_sha_map,
+ new_block->sha,
+ sizeof(new_block->sha));
+ }
+
+ if (old_block) {
+ file->physblock = old_block->physblock;
+ bmap_flags |= BMAP_SET;
+ free(new_block);
+ new_block = NULL;
+ }
+
retval = ext2fs_bmap2(fs, file->ino, &file->inode,
BMAP_BUFFER,
- file->ino ? BMAP_ALLOC : 0,
+ bmap_flags,
file->blockno, 0,
&file->physblock);
- if (retval)
+ if (retval) {
+ free(new_block);
+ new_block = NULL;
goto fail;
+ }
+
+ if (new_block) {
+ new_block->physblock = file->physblock;
+ ext2fs_hashmap_add(fs->block_sha_map, new_block,
+ new_block->sha, sizeof(new_block->sha));
+ }
+
+ if (bmap_flags & BMAP_SET) {
+ ext2fs_iblk_add_blocks(fs, &file->inode, 1);
+ ext2fs_write_inode(fs, file->ino, &file->inode);
+ }
}
- file->flags |= EXT2_FILE_BUF_DIRTY;
- memcpy(file->buf+start, ptr, c);
file->pos += c;
ptr += c;
count += c;
diff --git a/src/ext2fs/freefs.c b/src/ext2fs/freefs.c
index ea9742ef..68b8e9a4 100644
--- a/src/ext2fs/freefs.c
+++ b/src/ext2fs/freefs.c
@@ -17,6 +17,7 @@
#include "ext2_fs.h"
#include "ext2fsP.h"
+#include "hashmap.h"
void ext2fs_free(ext2_filsys fs)
{
@@ -59,6 +60,9 @@ void ext2fs_free(ext2_filsys fs)
if (fs->mmp_cmp)
ext2fs_free_mem(&fs->mmp_cmp);
+ if (fs->block_sha_map)
+ ext2fs_hashmap_free(fs->block_sha_map);
+
fs->magic = 0;
ext2fs_zero_blocks2(NULL, 0, 0, NULL, NULL);
diff --git a/src/ext2fs/gen_bitmap.c b/src/ext2fs/gen_bitmap.c
index d0061b82..c94c21b6 100644
--- a/src/ext2fs/gen_bitmap.c
+++ b/src/ext2fs/gen_bitmap.c
@@ -28,7 +28,7 @@
#include "ext2_fs.h"
#include "ext2fsP.h"
-struct ext2fs_struct_generic_bitmap {
+struct ext2fs_struct_generic_bitmap_32 {
errcode_t magic;
ext2_filsys fs;
__u32 start, end;
@@ -39,6 +39,8 @@ struct ext2fs_struct_generic_bitmap {
__u32 reserved[7];
};
+typedef struct ext2fs_struct_generic_bitmap_32 *ext2fs_generic_bitmap_32;
+
#define EXT2FS_IS_32_BITMAP(bmap) \
(((bmap)->magic == EXT2_ET_MAGIC_GENERIC_BITMAP) || \
((bmap)->magic == EXT2_ET_MAGIC_BLOCK_BITMAP) || \
@@ -53,9 +55,11 @@ struct ext2fs_struct_generic_bitmap {
* Used by previously inlined function, so we have to export this and
* not change the function signature
*/
-void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
+void ext2fs_warn_bitmap2(ext2fs_generic_bitmap gen_bitmap,
int code, unsigned long arg)
{
+ ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
+
#ifndef OMIT_COM_ERR
if (bitmap->description)
com_err(0, bitmap->base_error_code+code,
@@ -79,11 +83,11 @@ errcode_t ext2fs_make_generic_bitmap(errcode_t magic, ext2_filsys fs,
const char *descr, char *init_map,
ext2fs_generic_bitmap *ret)
{
- ext2fs_generic_bitmap bitmap;
+ ext2fs_generic_bitmap_32 bitmap;
errcode_t retval;
size_t size;
- retval = ext2fs_get_mem(sizeof(struct ext2fs_struct_generic_bitmap),
+ retval = ext2fs_get_mem(sizeof(struct ext2fs_struct_generic_bitmap_32),
&bitmap);
if (retval)
return retval;
@@ -127,7 +131,7 @@ errcode_t ext2fs_make_generic_bitmap(errcode_t magic, ext2_filsys fs,
memcpy(bitmap->bitmap, init_map, size);
else
memset(bitmap->bitmap, 0, size);
- *ret = bitmap;
+ *ret = (ext2fs_generic_bitmap) bitmap;
return 0;
}
@@ -141,9 +145,11 @@ errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
start, end, real_end, descr, 0, ret);
}
-errcode_t ext2fs_copy_generic_bitmap(ext2fs_generic_bitmap src,
+errcode_t ext2fs_copy_generic_bitmap(ext2fs_generic_bitmap gen_src,
ext2fs_generic_bitmap *dest)
{
+ ext2fs_generic_bitmap_32 src = (ext2fs_generic_bitmap_32) gen_src;
+
return (ext2fs_make_generic_bitmap(src->magic, src->fs,
src->start, src->end,
src->real_end,
@@ -151,9 +157,11 @@ errcode_t ext2fs_copy_generic_bitmap(ext2fs_generic_bitmap src,
dest));
}
-void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap)
+void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap gen_bitmap)
{
- if (check_magic(bitmap))
+ ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
+
+ if (check_magic(gen_bitmap))
return;
bitmap->magic = 0;
@@ -171,6 +179,8 @@ void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap)
int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
blk_t bitno)
{
+ ext2fs_generic_bitmap_32 bitmap32 = (ext2fs_generic_bitmap_32) bitmap;
+
if (!EXT2FS_IS_32_BITMAP(bitmap)) {
if (EXT2FS_IS_64_BITMAP(bitmap)) {
ext2fs_warn_bitmap32(bitmap, __func__);
@@ -183,16 +193,18 @@ int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
return 0;
}
- if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+ if ((bitno < bitmap32->start) || (bitno > bitmap32->end)) {
ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, bitno);
return 0;
}
- return ext2fs_test_bit(bitno - bitmap->start, bitmap->bitmap);
+ return ext2fs_test_bit(bitno - bitmap32->start, bitmap32->bitmap);
}
int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
__u32 bitno)
{
+ ext2fs_generic_bitmap_32 bitmap32 = (ext2fs_generic_bitmap_32) bitmap;
+
if (!EXT2FS_IS_32_BITMAP(bitmap)) {
if (EXT2FS_IS_64_BITMAP(bitmap)) {
ext2fs_warn_bitmap32(bitmap, __func__);
@@ -205,16 +217,18 @@ int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
return 0;
}
- if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+ if ((bitno < bitmap32->start) || (bitno > bitmap32->end)) {
ext2fs_warn_bitmap2(bitmap, EXT2FS_MARK_ERROR, bitno);
return 0;
}
- return ext2fs_set_bit(bitno - bitmap->start, bitmap->bitmap);
+ return ext2fs_set_bit(bitno - bitmap32->start, bitmap32->bitmap);
}
int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
blk_t bitno)
{
+ ext2fs_generic_bitmap_32 bitmap32 = (ext2fs_generic_bitmap_32) bitmap;
+
if (!EXT2FS_IS_32_BITMAP(bitmap)) {
if (EXT2FS_IS_64_BITMAP(bitmap)) {
ext2fs_warn_bitmap32(bitmap, __func__);
@@ -227,15 +241,17 @@ int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
return 0;
}
- if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+ if ((bitno < bitmap32->start) || (bitno > bitmap32->end)) {
ext2fs_warn_bitmap2(bitmap, EXT2FS_UNMARK_ERROR, bitno);
return 0;
}
- return ext2fs_clear_bit(bitno - bitmap->start, bitmap->bitmap);
+ return ext2fs_clear_bit(bitno - bitmap32->start, bitmap32->bitmap);
}
__u32 ext2fs_get_generic_bitmap_start(ext2fs_generic_bitmap bitmap)
{
+ ext2fs_generic_bitmap_32 bitmap32 = (ext2fs_generic_bitmap_32) bitmap;
+
if (!EXT2FS_IS_32_BITMAP(bitmap)) {
if (EXT2FS_IS_64_BITMAP(bitmap)) {
ext2fs_warn_bitmap32(bitmap, __func__);
@@ -248,11 +264,13 @@ __u32 ext2fs_get_generic_bitmap_start(ext2fs_generic_bitmap bitmap)
return 0;
}
- return bitmap->start;
+ return bitmap32->start;
}
__u32 ext2fs_get_generic_bitmap_end(ext2fs_generic_bitmap bitmap)
{
+ ext2fs_generic_bitmap_32 bitmap32 = (ext2fs_generic_bitmap_32) bitmap;
+
if (!EXT2FS_IS_32_BITMAP(bitmap)) {
if (EXT2FS_IS_64_BITMAP(bitmap)) {
ext2fs_warn_bitmap32(bitmap, __func__);
@@ -264,11 +282,13 @@ __u32 ext2fs_get_generic_bitmap_end(ext2fs_generic_bitmap bitmap)
#endif
return 0;
}
- return bitmap->end;
+ return bitmap32->end;
}
void ext2fs_clear_generic_bitmap(ext2fs_generic_bitmap bitmap)
{
+ ext2fs_generic_bitmap_32 bitmap32 = (ext2fs_generic_bitmap_32) bitmap;
+
if (!EXT2FS_IS_32_BITMAP(bitmap)) {
if (EXT2FS_IS_64_BITMAP(bitmap)) {
ext2fs_warn_bitmap32(bitmap, __func__);
@@ -282,14 +302,16 @@ void ext2fs_clear_generic_bitmap(ext2fs_generic_bitmap bitmap)
return;
}
- memset(bitmap->bitmap, 0,
- (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1));
+ memset(bitmap32->bitmap, 0,
+ (size_t) (((bitmap32->real_end - bitmap32->start) / 8) + 1));
}
-errcode_t ext2fs_fudge_generic_bitmap_end(ext2fs_inode_bitmap bitmap,
+errcode_t ext2fs_fudge_generic_bitmap_end(ext2fs_inode_bitmap gen_bitmap,
errcode_t magic, errcode_t neq,
ext2_ino_t end, ext2_ino_t *oend)
{
+ ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
+
EXT2_CHECK_MAGIC(bitmap, magic);
if (end > bitmap->real_end)
@@ -302,8 +324,9 @@ errcode_t ext2fs_fudge_generic_bitmap_end(ext2fs_inode_bitmap bitmap,
errcode_t ext2fs_resize_generic_bitmap(errcode_t magic,
__u32 new_end, __u32 new_real_end,
- ext2fs_generic_bitmap bmap)
+ ext2fs_generic_bitmap gen_bmap)
{
+ ext2fs_generic_bitmap_32 bmap = (ext2fs_generic_bitmap_32) gen_bmap;
errcode_t retval;
size_t size, new_size;
__u32 bitno;
@@ -344,9 +367,11 @@ errcode_t ext2fs_resize_generic_bitmap(errcode_t magic,
}
errcode_t ext2fs_compare_generic_bitmap(errcode_t magic, errcode_t neq,
- ext2fs_generic_bitmap bm1,
- ext2fs_generic_bitmap bm2)
+ ext2fs_generic_bitmap gen_bm1,
+ ext2fs_generic_bitmap gen_bm2)
{
+ ext2fs_generic_bitmap_32 bm1 = (ext2fs_generic_bitmap_32) gen_bm1;
+ ext2fs_generic_bitmap_32 bm2 = (ext2fs_generic_bitmap_32) gen_bm2;
blk_t i;
if (!bm1 || bm1->magic != magic)
@@ -361,15 +386,16 @@ errcode_t ext2fs_compare_generic_bitmap(errcode_t magic, errcode_t neq,
return neq;
for (i = bm1->end - ((bm1->end - bm1->start) % 8); i <= bm1->end; i++)
- if (ext2fs_fast_test_block_bitmap(bm1, i) !=
- ext2fs_fast_test_block_bitmap(bm2, i))
+ if (ext2fs_fast_test_block_bitmap(gen_bm1, i) !=
+ ext2fs_fast_test_block_bitmap(gen_bm2, i))
return neq;
return 0;
}
-void ext2fs_set_generic_bitmap_padding(ext2fs_generic_bitmap map)
+void ext2fs_set_generic_bitmap_padding(ext2fs_generic_bitmap gen_map)
{
+ ext2fs_generic_bitmap_32 map = (ext2fs_generic_bitmap_32) gen_map;
__u32 i, j;
/* Protect loop from wrap-around if map->real_end is maxed */
@@ -379,11 +405,13 @@ void ext2fs_set_generic_bitmap_padding(ext2fs_generic_bitmap map)
ext2fs_set_bit(j, map->bitmap);
}
-errcode_t ext2fs_get_generic_bitmap_range(ext2fs_generic_bitmap bmap,
+errcode_t ext2fs_get_generic_bitmap_range(ext2fs_generic_bitmap gen_bmap,
errcode_t magic,
__u32 start, __u32 num,
void *out)
{
+ ext2fs_generic_bitmap_32 bmap = (ext2fs_generic_bitmap_32) gen_bmap;
+
if (!bmap || (bmap->magic != magic))
return magic;
@@ -394,11 +422,13 @@ errcode_t ext2fs_get_generic_bitmap_range(ext2fs_generic_bitmap bmap,
return 0;
}
-errcode_t ext2fs_set_generic_bitmap_range(ext2fs_generic_bitmap bmap,
+errcode_t ext2fs_set_generic_bitmap_range(ext2fs_generic_bitmap gen_bmap,
errcode_t magic,
__u32 start, __u32 num,
void *in)
{
+ ext2fs_generic_bitmap_32 bmap = (ext2fs_generic_bitmap_32) gen_bmap;
+
if (!bmap || (bmap->magic != magic))
return magic;
@@ -432,10 +462,11 @@ int ext2fs_mem_is_zero(const char *mem, size_t len)
/*
* Return true if all of the bits in a specified range are clear
*/
-static int ext2fs_test_clear_generic_bitmap_range(ext2fs_generic_bitmap bitmap,
+static int ext2fs_test_clear_generic_bitmap_range(ext2fs_generic_bitmap gen_bitmap,
unsigned int start,
unsigned int len)
{
+ ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
size_t start_byte, len_byte = len >> 3;
unsigned int start_bit, len_bit = len % 8;
int first_bit = 0;
@@ -504,14 +535,15 @@ static int ext2fs_test_clear_generic_bitmap_range(ext2fs_generic_bitmap bitmap,
return ext2fs_mem_is_zero(ADDR + start_byte, len_byte);
}
-errcode_t ext2fs_find_first_zero_generic_bitmap(ext2fs_generic_bitmap bitmap,
+errcode_t ext2fs_find_first_zero_generic_bitmap(ext2fs_generic_bitmap gen_bitmap,
__u32 start, __u32 end,
__u32 *out)
{
+ ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
blk_t b;
if (start < bitmap->start || end > bitmap->end || start > end) {
- ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, start);
+ ext2fs_warn_bitmap2(gen_bitmap, EXT2FS_TEST_ERROR, start);
return EINVAL;
}
@@ -527,14 +559,15 @@ errcode_t ext2fs_find_first_zero_generic_bitmap(ext2fs_generic_bitmap bitmap,
return ENOENT;
}
-errcode_t ext2fs_find_first_set_generic_bitmap(ext2fs_generic_bitmap bitmap,
+errcode_t ext2fs_find_first_set_generic_bitmap(ext2fs_generic_bitmap gen_bitmap,
__u32 start, __u32 end,
__u32 *out)
{
+ ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
blk_t b;
if (start < bitmap->start || end > bitmap->end || start > end) {
- ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, start);
+ ext2fs_warn_bitmap2(gen_bitmap, EXT2FS_TEST_ERROR, start);
return EINVAL;
}
@@ -550,11 +583,14 @@ errcode_t ext2fs_find_first_set_generic_bitmap(ext2fs_generic_bitmap bitmap,
return ENOENT;
}
-int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
+int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap gen_bitmap,
blk_t block, int num)
{
+ ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
+
EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_BLOCK_BITMAP);
- if ((block < bitmap->start) || (block+num-1 > bitmap->real_end)) {
+ if ((block < bitmap->start) || (block > bitmap->real_end) ||
+ (block+num-1 > bitmap->real_end)) {
ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
block, bitmap->description);
return 0;
@@ -563,11 +599,14 @@ int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
bitmap, block, num);
}
-int ext2fs_test_inode_bitmap_range(ext2fs_inode_bitmap bitmap,
+int ext2fs_test_inode_bitmap_range(ext2fs_inode_bitmap gen_bitmap,
ext2_ino_t inode, int num)
{
+ ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
+
EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_INODE_BITMAP);
- if ((inode < bitmap->start) || (inode+num-1 > bitmap->real_end)) {
+ if ((inode < bitmap->start) || (inode > bitmap->real_end) ||
+ (inode+num-1 > bitmap->real_end)) {
ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST,
inode, bitmap->description);
return 0;
@@ -576,12 +615,14 @@ int ext2fs_test_inode_bitmap_range(ext2fs_inode_bitmap bitmap,
bitmap, inode, num);
}
-void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap gen_bitmap,
blk_t block, int num)
{
+ ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
int i;
- if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+ if ((block < bitmap->start) || (block > bitmap->end) ||
+ (block+num-1 > bitmap->end)) {
ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
bitmap->description);
return;
@@ -590,12 +631,14 @@ void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
ext2fs_fast_set_bit(block + i - bitmap->start, bitmap->bitmap);
}
-void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
- blk_t block, int num)
+void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap gen_bitmap,
+ blk_t block, int num)
{
+ ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
int i;
- if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+ if ((block < bitmap->start) || (block > bitmap->end) ||
+ (block+num-1 > bitmap->end)) {
ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
bitmap->description);
return;
diff --git a/src/ext2fs/gen_bitmap64.c b/src/ext2fs/gen_bitmap64.c
index 3fc73498..6e4d8b71 100644
--- a/src/ext2fs/gen_bitmap64.c
+++ b/src/ext2fs/gen_bitmap64.c
@@ -68,7 +68,7 @@
* e2fsck can request an encoding which is optimized for that.
*/
-static void warn_bitmap(ext2fs_generic_bitmap bitmap,
+static void warn_bitmap(ext2fs_generic_bitmap_64 bitmap,
int code, __u64 arg)
{
#ifndef OMIT_COM_ERR
@@ -93,7 +93,7 @@ errcode_t ext2fs_alloc_generic_bmap(ext2_filsys fs, errcode_t magic,
const char *descr,
ext2fs_generic_bitmap *ret)
{
- ext2fs_generic_bitmap bitmap;
+ ext2fs_generic_bitmap_64 bitmap;
struct ext2_bitmap_ops *ops;
ext2_ino_t num_dirs;
errcode_t retval;
@@ -119,7 +119,7 @@ errcode_t ext2fs_alloc_generic_bmap(ext2_filsys fs, errcode_t magic,
return EINVAL;
}
- retval = ext2fs_get_memzero(sizeof(struct ext2fs_struct_generic_bitmap),
+ retval = ext2fs_get_memzero(sizeof(struct ext2fs_struct_generic_bitmap_64),
&bitmap);
if (retval)
return retval;
@@ -170,12 +170,12 @@ errcode_t ext2fs_alloc_generic_bmap(ext2_filsys fs, errcode_t magic,
return retval;
}
- *ret = bitmap;
+ *ret = (ext2fs_generic_bitmap) bitmap;
return 0;
}
#ifdef ENABLE_BMAP_STATS
-static void ext2fs_print_bmap_statistics(ext2fs_generic_bitmap bitmap)
+static void ext2fs_print_bmap_statistics(ext2fs_generic_bitmap_64 bitmap)
{
struct ext2_bmap_statistics *stats = &bitmap->stats;
#ifdef ENABLE_BMAP_STATS_OPS
@@ -241,13 +241,15 @@ static void ext2fs_print_bmap_statistics(ext2fs_generic_bitmap bitmap)
}
#endif
-void ext2fs_free_generic_bmap(ext2fs_generic_bitmap bmap)
+void ext2fs_free_generic_bmap(ext2fs_generic_bitmap gen_bmap)
{
+ ext2fs_generic_bitmap_64 bmap = (ext2fs_generic_bitmap_64) gen_bmap;
+
if (!bmap)
return;
if (EXT2FS_IS_32_BITMAP(bmap)) {
- ext2fs_free_generic_bitmap(bmap);
+ ext2fs_free_generic_bitmap(gen_bmap);
return;
}
@@ -271,24 +273,25 @@ void ext2fs_free_generic_bmap(ext2fs_generic_bitmap bmap)
ext2fs_free_mem(&bmap);
}
-errcode_t ext2fs_copy_generic_bmap(ext2fs_generic_bitmap src,
+errcode_t ext2fs_copy_generic_bmap(ext2fs_generic_bitmap gen_src,
ext2fs_generic_bitmap *dest)
{
+ ext2fs_generic_bitmap_64 src = (ext2fs_generic_bitmap_64) gen_src;
char *descr, *new_descr;
- ext2fs_generic_bitmap new_bmap;
+ ext2fs_generic_bitmap_64 new_bmap;
errcode_t retval;
if (!src)
return EINVAL;
if (EXT2FS_IS_32_BITMAP(src))
- return ext2fs_copy_generic_bitmap(src, dest);
+ return ext2fs_copy_generic_bitmap(gen_src, dest);
if (!EXT2FS_IS_64_BITMAP(src))
return EINVAL;
/* Allocate a new bitmap struct */
- retval = ext2fs_get_memzero(sizeof(struct ext2fs_struct_generic_bitmap),
+ retval = ext2fs_get_memzero(sizeof(struct ext2fs_struct_generic_bitmap_64),
&new_bmap);
if (retval)
return retval;
@@ -336,21 +339,23 @@ errcode_t ext2fs_copy_generic_bmap(ext2fs_generic_bitmap src,
return retval;
}
- *dest = new_bmap;
+ *dest = (ext2fs_generic_bitmap) new_bmap;
return 0;
}
-errcode_t ext2fs_resize_generic_bmap(ext2fs_generic_bitmap bmap,
+errcode_t ext2fs_resize_generic_bmap(ext2fs_generic_bitmap gen_bmap,
__u64 new_end,
__u64 new_real_end)
{
+ ext2fs_generic_bitmap_64 bmap = (ext2fs_generic_bitmap_64) gen_bmap;
+
if (!bmap)
return EINVAL;
if (EXT2FS_IS_32_BITMAP(bmap))
- return ext2fs_resize_generic_bitmap(bmap->magic, new_end,
- new_real_end, bmap);
+ return ext2fs_resize_generic_bitmap(gen_bmap->magic, new_end,
+ new_real_end, gen_bmap);
if (!EXT2FS_IS_64_BITMAP(bmap))
return EINVAL;
@@ -360,10 +365,12 @@ errcode_t ext2fs_resize_generic_bmap(ext2fs_generic_bitmap bmap,
return bmap->bitmap_ops->resize_bmap(bmap, new_end, new_real_end);
}
-errcode_t ext2fs_fudge_generic_bmap_end(ext2fs_generic_bitmap bitmap,
+errcode_t ext2fs_fudge_generic_bmap_end(ext2fs_generic_bitmap gen_bitmap,
errcode_t neq,
__u64 end, __u64 *oend)
{
+ ext2fs_generic_bitmap_64 bitmap = (ext2fs_generic_bitmap_64) gen_bitmap;
+
if (!bitmap)
return EINVAL;
@@ -371,7 +378,8 @@ errcode_t ext2fs_fudge_generic_bmap_end(ext2fs_generic_bitmap bitmap,
ext2_ino_t tmp_oend;
int retval;
- retval = ext2fs_fudge_generic_bitmap_end(bitmap, bitmap->magic,
+ retval = ext2fs_fudge_generic_bitmap_end(gen_bitmap,
+ bitmap->magic,
neq, end, &tmp_oend);
if (oend)
*oend = tmp_oend;
@@ -389,13 +397,15 @@ errcode_t ext2fs_fudge_generic_bmap_end(ext2fs_generic_bitmap bitmap,
return 0;
}
-__u64 ext2fs_get_generic_bmap_start(ext2fs_generic_bitmap bitmap)
+__u64 ext2fs_get_generic_bmap_start(ext2fs_generic_bitmap gen_bitmap)
{
+ ext2fs_generic_bitmap_64 bitmap = (ext2fs_generic_bitmap_64) gen_bitmap;
+
if (!bitmap)
return EINVAL;
if (EXT2FS_IS_32_BITMAP(bitmap))
- return ext2fs_get_generic_bitmap_start(bitmap);
+ return ext2fs_get_generic_bitmap_start(gen_bitmap);
if (!EXT2FS_IS_64_BITMAP(bitmap))
return EINVAL;
@@ -403,13 +413,15 @@ __u64 ext2fs_get_generic_bmap_start(ext2fs_generic_bitmap bitmap)
return bitmap->start;
}
-__u64 ext2fs_get_generic_bmap_end(ext2fs_generic_bitmap bitmap)
+__u64 ext2fs_get_generic_bmap_end(ext2fs_generic_bitmap gen_bitmap)
{
+ ext2fs_generic_bitmap_64 bitmap = (ext2fs_generic_bitmap_64) gen_bitmap;
+
if (!bitmap)
return EINVAL;
if (EXT2FS_IS_32_BITMAP(bitmap))
- return ext2fs_get_generic_bitmap_end(bitmap);
+ return ext2fs_get_generic_bitmap_end(gen_bitmap);
if (!EXT2FS_IS_64_BITMAP(bitmap))
return EINVAL;
@@ -417,27 +429,31 @@ __u64 ext2fs_get_generic_bmap_end(ext2fs_generic_bitmap bitmap)
return bitmap->end;
}
-void ext2fs_clear_generic_bmap(ext2fs_generic_bitmap bitmap)
+void ext2fs_clear_generic_bmap(ext2fs_generic_bitmap gen_bitmap)
{
+ ext2fs_generic_bitmap_64 bitmap = (ext2fs_generic_bitmap_64) gen_bitmap;
+
if (EXT2FS_IS_32_BITMAP(bitmap))
- ext2fs_clear_generic_bitmap(bitmap);
+ ext2fs_clear_generic_bitmap(gen_bitmap);
else
- bitmap->bitmap_ops->clear_bmap (bitmap);
+ bitmap->bitmap_ops->clear_bmap(bitmap);
}
-int ext2fs_mark_generic_bmap(ext2fs_generic_bitmap bitmap,
+int ext2fs_mark_generic_bmap(ext2fs_generic_bitmap gen_bitmap,
__u64 arg)
{
+ ext2fs_generic_bitmap_64 bitmap = (ext2fs_generic_bitmap_64) gen_bitmap;
+
if (!bitmap)
return 0;
if (EXT2FS_IS_32_BITMAP(bitmap)) {
if (arg & ~0xffffffffULL) {
- ext2fs_warn_bitmap2(bitmap,
+ ext2fs_warn_bitmap2(gen_bitmap,
EXT2FS_MARK_ERROR, 0xffffffff);
return 0;
}
- return ext2fs_mark_generic_bitmap(bitmap, arg);
+ return ext2fs_mark_generic_bitmap(gen_bitmap, arg);
}
if (!EXT2FS_IS_64_BITMAP(bitmap))
@@ -462,19 +478,21 @@ int ext2fs_mark_generic_bmap(ext2fs_generic_bitmap bitmap,
return bitmap->bitmap_ops->mark_bmap(bitmap, arg);
}
-int ext2fs_unmark_generic_bmap(ext2fs_generic_bitmap bitmap,
+int ext2fs_unmark_generic_bmap(ext2fs_generic_bitmap gen_bitmap,
__u64 arg)
{
+ ext2fs_generic_bitmap_64 bitmap = (ext2fs_generic_bitmap_64) gen_bitmap;
+
if (!bitmap)
return 0;
if (EXT2FS_IS_32_BITMAP(bitmap)) {
if (arg & ~0xffffffffULL) {
- ext2fs_warn_bitmap2(bitmap, EXT2FS_UNMARK_ERROR,
+ ext2fs_warn_bitmap2(gen_bitmap, EXT2FS_UNMARK_ERROR,
0xffffffff);
return 0;
}
- return ext2fs_unmark_generic_bitmap(bitmap, arg);
+ return ext2fs_unmark_generic_bitmap(gen_bitmap, arg);
}
if (!EXT2FS_IS_64_BITMAP(bitmap))
@@ -492,19 +510,20 @@ int ext2fs_unmark_generic_bmap(ext2fs_generic_bitmap bitmap,
return bitmap->bitmap_ops->unmark_bmap(bitmap, arg);
}
-int ext2fs_test_generic_bmap(ext2fs_generic_bitmap bitmap,
+int ext2fs_test_generic_bmap(ext2fs_generic_bitmap gen_bitmap,
__u64 arg)
{
+ ext2fs_generic_bitmap_64 bitmap = (ext2fs_generic_bitmap_64) gen_bitmap;
if (!bitmap)
return 0;
if (EXT2FS_IS_32_BITMAP(bitmap)) {
if (arg & ~0xffffffffULL) {
- ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR,
+ ext2fs_warn_bitmap2(gen_bitmap, EXT2FS_TEST_ERROR,
0xffffffff);
return 0;
}
- return ext2fs_test_generic_bitmap(bitmap, arg);
+ return ext2fs_test_generic_bitmap(gen_bitmap, arg);
}
if (!EXT2FS_IS_64_BITMAP(bitmap))
@@ -529,20 +548,22 @@ int ext2fs_test_generic_bmap(ext2fs_generic_bitmap bitmap,
return bitmap->bitmap_ops->test_bmap(bitmap, arg);
}
-errcode_t ext2fs_set_generic_bmap_range(ext2fs_generic_bitmap bmap,
+errcode_t ext2fs_set_generic_bmap_range(ext2fs_generic_bitmap gen_bmap,
__u64 start, unsigned int num,
void *in)
{
+ ext2fs_generic_bitmap_64 bmap = (ext2fs_generic_bitmap_64) gen_bmap;
+
if (!bmap)
return EINVAL;
if (EXT2FS_IS_32_BITMAP(bmap)) {
if ((start+num-1) & ~0xffffffffULL) {
- ext2fs_warn_bitmap2(bmap, EXT2FS_UNMARK_ERROR,
+ ext2fs_warn_bitmap2(gen_bmap, EXT2FS_UNMARK_ERROR,
0xffffffff);
return EINVAL;
}
- return ext2fs_set_generic_bitmap_range(bmap, bmap->magic,
+ return ext2fs_set_generic_bitmap_range(gen_bmap, bmap->magic,
start, num, in);
}
@@ -554,20 +575,22 @@ errcode_t ext2fs_set_generic_bmap_range(ext2fs_generic_bitmap bmap,
return bmap->bitmap_ops->set_bmap_range(bmap, start, num, in);
}
-errcode_t ext2fs_get_generic_bmap_range(ext2fs_generic_bitmap bmap,
+errcode_t ext2fs_get_generic_bmap_range(ext2fs_generic_bitmap gen_bmap,
__u64 start, unsigned int num,
void *out)
{
+ ext2fs_generic_bitmap_64 bmap = (ext2fs_generic_bitmap_64) gen_bmap;
+
if (!bmap)
return EINVAL;
if (EXT2FS_IS_32_BITMAP(bmap)) {
if ((start+num-1) & ~0xffffffffULL) {
- ext2fs_warn_bitmap2(bmap,
+ ext2fs_warn_bitmap2(gen_bmap,
EXT2FS_UNMARK_ERROR, 0xffffffff);
return EINVAL;
}
- return ext2fs_get_generic_bitmap_range(bmap, bmap->magic,
+ return ext2fs_get_generic_bitmap_range(gen_bmap, bmap->magic,
start, num, out);
}
@@ -580,9 +603,11 @@ errcode_t ext2fs_get_generic_bmap_range(ext2fs_generic_bitmap bmap,
}
errcode_t ext2fs_compare_generic_bmap(errcode_t neq,
- ext2fs_generic_bitmap bm1,
- ext2fs_generic_bitmap bm2)
+ ext2fs_generic_bitmap gen_bm1,
+ ext2fs_generic_bitmap gen_bm2)
{
+ ext2fs_generic_bitmap_64 bm1 = (ext2fs_generic_bitmap_64) gen_bm1;
+ ext2fs_generic_bitmap_64 bm2 = (ext2fs_generic_bitmap_64) gen_bm2;
blk64_t i;
if (!bm1 || !bm2)
@@ -592,7 +617,8 @@ errcode_t ext2fs_compare_generic_bmap(errcode_t neq,
/* Now we know both bitmaps have the same magic */
if (EXT2FS_IS_32_BITMAP(bm1))
- return ext2fs_compare_generic_bitmap(bm1->magic, neq, bm1, bm2);
+ return ext2fs_compare_generic_bitmap(bm1->magic, neq,
+ gen_bm1, gen_bm2);
if (!EXT2FS_IS_64_BITMAP(bm1))
return EINVAL;
@@ -602,19 +628,20 @@ errcode_t ext2fs_compare_generic_bmap(errcode_t neq,
return neq;
for (i = bm1->end - ((bm1->end - bm1->start) % 8); i <= bm1->end; i++)
- if (ext2fs_test_generic_bmap(bm1, i) !=
- ext2fs_test_generic_bmap(bm2, i))
+ if (ext2fs_test_generic_bmap(gen_bm1, i) !=
+ ext2fs_test_generic_bmap(gen_bm2, i))
return neq;
return 0;
}
-void ext2fs_set_generic_bmap_padding(ext2fs_generic_bitmap bmap)
+void ext2fs_set_generic_bmap_padding(ext2fs_generic_bitmap gen_bmap)
{
+ ext2fs_generic_bitmap_64 bmap = (ext2fs_generic_bitmap_64) gen_bmap;
__u64 start, num;
if (EXT2FS_IS_32_BITMAP(bmap)) {
- ext2fs_set_generic_bitmap_padding(bmap);
+ ext2fs_set_generic_bitmap_padding(gen_bmap);
return;
}
@@ -624,9 +651,10 @@ void ext2fs_set_generic_bmap_padding(ext2fs_generic_bitmap bmap)
/* XXX ought to warn on error */
}
-int ext2fs_test_block_bitmap_range2(ext2fs_block_bitmap bmap,
+int ext2fs_test_block_bitmap_range2(ext2fs_block_bitmap gen_bmap,
blk64_t block, unsigned int num)
{
+ ext2fs_generic_bitmap_64 bmap = (ext2fs_generic_bitmap_64) gen_bmap;
__u64 end = block + num;
if (!bmap)
@@ -637,7 +665,8 @@ int ext2fs_test_block_bitmap_range2(ext2fs_block_bitmap bmap,
bmap, block);
if (EXT2FS_IS_32_BITMAP(bmap)) {
- if ((block+num-1) & ~0xffffffffULL) {
+ if ((block & ~0xffffffffULL) ||
+ ((block+num-1) & ~0xffffffffULL)) {
ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap,
EXT2FS_UNMARK_ERROR, 0xffffffff);
return EINVAL;
@@ -657,7 +686,8 @@ int ext2fs_test_block_bitmap_range2(ext2fs_block_bitmap bmap,
end >>= bmap->cluster_bits;
num = end - block;
- if ((block < bmap->start) || (block+num-1 > bmap->end)) {
+ if ((block < bmap->start) || (block > bmap->end) ||
+ (block+num-1 > bmap->end)) {
ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST, block,
bmap->description);
return EINVAL;
@@ -666,16 +696,18 @@ int ext2fs_test_block_bitmap_range2(ext2fs_block_bitmap bmap,
return bmap->bitmap_ops->test_clear_bmap_extent(bmap, block, num);
}
-void ext2fs_mark_block_bitmap_range2(ext2fs_block_bitmap bmap,
+void ext2fs_mark_block_bitmap_range2(ext2fs_block_bitmap gen_bmap,
blk64_t block, unsigned int num)
{
+ ext2fs_generic_bitmap_64 bmap = (ext2fs_generic_bitmap_64) gen_bmap;
__u64 end = block + num;
if (!bmap)
return;
if (EXT2FS_IS_32_BITMAP(bmap)) {
- if ((block+num-1) & ~0xffffffffULL) {
+ if ((block & ~0xffffffffULL) ||
+ ((block+num-1) & ~0xffffffffULL)) {
ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap,
EXT2FS_UNMARK_ERROR, 0xffffffff);
return;
@@ -695,7 +727,8 @@ void ext2fs_mark_block_bitmap_range2(ext2fs_block_bitmap bmap,
end >>= bmap->cluster_bits;
num = end - block;
- if ((block < bmap->start) || (block+num-1 > bmap->end)) {
+ if ((block < bmap->start) || (block > bmap->end) ||
+ (block+num-1 > bmap->end)) {
ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
bmap->description);
return;
@@ -704,16 +737,18 @@ void ext2fs_mark_block_bitmap_range2(ext2fs_block_bitmap bmap,
bmap->bitmap_ops->mark_bmap_extent(bmap, block, num);
}
-void ext2fs_unmark_block_bitmap_range2(ext2fs_block_bitmap bmap,
+void ext2fs_unmark_block_bitmap_range2(ext2fs_block_bitmap gen_bmap,
blk64_t block, unsigned int num)
{
+ ext2fs_generic_bitmap_64 bmap = (ext2fs_generic_bitmap_64) gen_bmap;
__u64 end = block + num;
if (!bmap)
return;
if (EXT2FS_IS_32_BITMAP(bmap)) {
- if ((block+num-1) & ~0xffffffffULL) {
+ if ((block & ~0xffffffffULL) ||
+ ((block+num-1) & ~0xffffffffULL)) {
ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap,
EXT2FS_UNMARK_ERROR, 0xffffffff);
return;
@@ -733,7 +768,8 @@ void ext2fs_unmark_block_bitmap_range2(ext2fs_block_bitmap bmap,
end >>= bmap->cluster_bits;
num = end - block;
- if ((block < bmap->start) || (block+num-1 > bmap->end)) {
+ if ((block < bmap->start) || (block > bmap->end) ||
+ (block+num-1 > bmap->end)) {
ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
bmap->description);
return;
@@ -742,8 +778,10 @@ void ext2fs_unmark_block_bitmap_range2(ext2fs_block_bitmap bmap,
bmap->bitmap_ops->unmark_bmap_extent(bmap, block, num);
}
-void ext2fs_warn_bitmap32(ext2fs_generic_bitmap bitmap, const char *func)
+void ext2fs_warn_bitmap32(ext2fs_generic_bitmap gen_bitmap, const char *func)
{
+ ext2fs_generic_bitmap_64 bitmap = (ext2fs_generic_bitmap_64) gen_bitmap;
+
#ifndef OMIT_COM_ERR
if (bitmap && bitmap->description)
com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
@@ -758,21 +796,22 @@ void ext2fs_warn_bitmap32(ext2fs_generic_bitmap bitmap, const char *func)
errcode_t ext2fs_convert_subcluster_bitmap(ext2_filsys fs,
ext2fs_block_bitmap *bitmap)
{
- ext2fs_block_bitmap cmap, bmap;
+ ext2fs_generic_bitmap_64 bmap, cmap;
+ ext2fs_block_bitmap gen_bmap = *bitmap, gen_cmap;
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))
+ bmap = (ext2fs_generic_bitmap_64) gen_bmap;
+ if (fs->cluster_ratio_bits == ext2fs_get_bitmap_granularity(gen_bmap))
return 0; /* Nothing to do */
retval = ext2fs_allocate_block_bitmap(fs, "converted cluster bitmap",
- &cmap);
+ &gen_cmap);
if (retval)
return retval;
+ cmap = (ext2fs_generic_bitmap_64) gen_cmap;
i = bmap->start;
b_end = bmap->end;
bmap->end = bmap->real_end;
@@ -781,8 +820,8 @@ errcode_t ext2fs_convert_subcluster_bitmap(ext2_filsys fs,
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);
+ if (ext2fs_test_block_bitmap2(gen_bmap, i)) {
+ ext2fs_mark_block_bitmap2(gen_cmap, i);
i += ratio - n;
n = 0;
continue;
@@ -793,14 +832,15 @@ errcode_t ext2fs_convert_subcluster_bitmap(ext2_filsys fs,
}
bmap->end = b_end;
cmap->end = c_end;
- ext2fs_free_block_bitmap(bmap);
- *bitmap = cmap;
+ ext2fs_free_block_bitmap(gen_bmap);
+ *bitmap = (ext2fs_block_bitmap) cmap;
return 0;
}
errcode_t ext2fs_find_first_zero_generic_bmap(ext2fs_generic_bitmap bitmap,
__u64 start, __u64 end, __u64 *out)
{
+ ext2fs_generic_bitmap_64 bmap64 = (ext2fs_generic_bitmap_64) bitmap;
__u64 cstart, cend, cout;
errcode_t retval;
@@ -826,27 +866,27 @@ errcode_t ext2fs_find_first_zero_generic_bmap(ext2fs_generic_bitmap bitmap,
if (!EXT2FS_IS_64_BITMAP(bitmap))
return EINVAL;
- cstart = start >> bitmap->cluster_bits;
- cend = end >> bitmap->cluster_bits;
+ cstart = start >> bmap64->cluster_bits;
+ cend = end >> bmap64->cluster_bits;
- if (cstart < bitmap->start || cend > bitmap->end || start > end) {
- warn_bitmap(bitmap, EXT2FS_TEST_ERROR, start);
+ if (cstart < bmap64->start || cend > bmap64->end || start > end) {
+ warn_bitmap(bmap64, EXT2FS_TEST_ERROR, start);
return EINVAL;
}
- if (bitmap->bitmap_ops->find_first_zero) {
- retval = bitmap->bitmap_ops->find_first_zero(bitmap, cstart,
+ if (bmap64->bitmap_ops->find_first_zero) {
+ retval = bmap64->bitmap_ops->find_first_zero(bmap64, cstart,
cend, &cout);
if (retval)
return retval;
found:
- cout <<= bitmap->cluster_bits;
+ cout <<= bmap64->cluster_bits;
*out = (cout >= start) ? cout : start;
return 0;
}
for (cout = cstart; cout <= cend; cout++)
- if (!bitmap->bitmap_ops->test_bmap(bitmap, cout))
+ if (!bmap64->bitmap_ops->test_bmap(bmap64, cout))
goto found;
return ENOENT;
@@ -855,6 +895,7 @@ errcode_t ext2fs_find_first_zero_generic_bmap(ext2fs_generic_bitmap bitmap,
errcode_t ext2fs_find_first_set_generic_bmap(ext2fs_generic_bitmap bitmap,
__u64 start, __u64 end, __u64 *out)
{
+ ext2fs_generic_bitmap_64 bmap64 = (ext2fs_generic_bitmap_64) bitmap;
__u64 cstart, cend, cout;
errcode_t retval;
@@ -880,27 +921,27 @@ errcode_t ext2fs_find_first_set_generic_bmap(ext2fs_generic_bitmap bitmap,
if (!EXT2FS_IS_64_BITMAP(bitmap))
return EINVAL;
- cstart = start >> bitmap->cluster_bits;
- cend = end >> bitmap->cluster_bits;
+ cstart = start >> bmap64->cluster_bits;
+ cend = end >> bmap64->cluster_bits;
- if (cstart < bitmap->start || cend > bitmap->end || start > end) {
- warn_bitmap(bitmap, EXT2FS_TEST_ERROR, start);
+ if (cstart < bmap64->start || cend > bmap64->end || start > end) {
+ warn_bitmap(bmap64, EXT2FS_TEST_ERROR, start);
return EINVAL;
}
- if (bitmap->bitmap_ops->find_first_set) {
- retval = bitmap->bitmap_ops->find_first_set(bitmap, cstart,
+ if (bmap64->bitmap_ops->find_first_set) {
+ retval = bmap64->bitmap_ops->find_first_set(bmap64, cstart,
cend, &cout);
if (retval)
return retval;
found:
- cout <<= bitmap->cluster_bits;
+ cout <<= bmap64->cluster_bits;
*out = (cout >= start) ? cout : start;
return 0;
}
for (cout = cstart; cout <= cend; cout++)
- if (bitmap->bitmap_ops->test_bmap(bitmap, cout))
+ if (bmap64->bitmap_ops->test_bmap(bmap64, cout))
goto found;
return ENOENT;
diff --git a/src/ext2fs/hashmap.c b/src/ext2fs/hashmap.c
new file mode 100644
index 00000000..3d8ee814
--- /dev/null
+++ b/src/ext2fs/hashmap.c
@@ -0,0 +1,85 @@
+#include "hashmap.h"
+#include
+
+uint32_t ext2fs_djb2_hash(const void *str, size_t size)
+{
+ int c;
+ const char *s = str;
+ uint32_t hash = 5381;
+
+ while (size-- > 0) {
+ c = *s++;
+ hash = ((hash << 5) + hash) + c;
+ }
+ return hash;
+}
+
+struct ext2fs_hashmap *ext2fs_hashmap_create(
+ uint32_t(*hash_fct)(const void*, size_t),
+ void(*free_fct)(void*), size_t size)
+{
+ struct ext2fs_hashmap *h = calloc(sizeof(struct ext2fs_hashmap) +
+ sizeof(struct ext2fs_hashmap_entry) * size, 1);
+ h->size = size;
+ h->free = free_fct;
+ h->hash = hash_fct;
+ h->first = h->last = NULL;
+ return h;
+}
+
+void ext2fs_hashmap_add(struct ext2fs_hashmap *h, void *data, const void *key,
+ size_t key_len)
+{
+ uint32_t hash = h->hash(key, key_len) % h->size;
+ struct ext2fs_hashmap_entry *e = malloc(sizeof(*e));
+
+ e->data = data;
+ e->key = key;
+ e->key_len = key_len;
+ e->next = h->entries[hash];
+ h->entries[hash] = e;
+
+ e->list_prev = NULL;
+ e->list_next = h->first;
+ if (h->first)
+ h->first->list_prev = e;
+ h->first = e;
+ if (!h->last)
+ h->last = e;
+}
+
+void *ext2fs_hashmap_lookup(struct ext2fs_hashmap *h, const void *key,
+ size_t key_len)
+{
+ struct ext2fs_hashmap_entry *iter;
+ uint32_t hash = h->hash(key, key_len) % h->size;
+
+ for (iter = h->entries[hash]; iter; iter = iter->next)
+ if (iter->key_len == key_len && !memcmp(iter->key, key, key_len))
+ return iter->data;
+ return NULL;
+}
+
+void *ext2fs_hashmap_iter_in_order(struct ext2fs_hashmap *h,
+ struct ext2fs_hashmap_entry **it)
+{
+ *it = *it ? (*it)->list_next : h->first;
+ return *it ? (*it)->data : NULL;
+}
+
+void ext2fs_hashmap_free(struct ext2fs_hashmap *h)
+{
+ size_t i;
+
+ for (i = 0; i < h->size; ++i) {
+ struct ext2fs_hashmap_entry *it = h->entries[i];
+ while (it) {
+ struct ext2fs_hashmap_entry *tmp = it->next;
+ if (h->free)
+ h->free(it->data);
+ free(it);
+ it = tmp;
+ }
+ }
+ free(h);
+}
diff --git a/src/ext2fs/hashmap.h b/src/ext2fs/hashmap.h
new file mode 100644
index 00000000..656d3d90
--- /dev/null
+++ b/src/ext2fs/hashmap.h
@@ -0,0 +1,54 @@
+#ifndef HASHMAP_H
+# define HASHMAP_H
+
+# include
+# include
+
+#ifndef __GNUC_PREREQ
+#if defined(__GNUC__) && defined(__GNUC_MINOR__)
+#define __GNUC_PREREQ(maj, min) \
+ ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+#else
+#define __GNUC_PREREQ(maj, min) 0
+#endif
+#endif
+
+struct ext2fs_hashmap {
+ uint32_t size;
+ uint32_t(*hash)(const void *key, size_t len);
+ void(*free)(void*);
+ struct ext2fs_hashmap_entry *first;
+ struct ext2fs_hashmap_entry *last;
+ struct ext2fs_hashmap_entry {
+ void *data;
+ const void *key;
+ size_t key_len;
+ struct ext2fs_hashmap_entry *next;
+ struct ext2fs_hashmap_entry *list_next;
+ struct ext2fs_hashmap_entry *list_prev;
+#if __GNUC_PREREQ (4, 8)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpedantic"
+#endif
+ } *entries[0];
+#if __GNUC_PREREQ (4, 8)
+#pragma GCC diagnostic pop
+#endif
+};
+
+struct ext2fs_hashmap *ext2fs_hashmap_create(
+ uint32_t(*hash_fct)(const void*, size_t),
+ void(*free_fct)(void*), size_t size);
+void ext2fs_hashmap_add(struct ext2fs_hashmap *h, void *data, const void *key,
+ size_t key_len);
+void *ext2fs_hashmap_lookup(struct ext2fs_hashmap *h, const void *key,
+ size_t key_len);
+void *ext2fs_hashmap_iter_in_order(struct ext2fs_hashmap *h,
+ struct ext2fs_hashmap_entry **it);
+void ext2fs_hashmap_del(struct ext2fs_hashmap *h,
+ struct ext2fs_hashmap_entry *e);
+void ext2fs_hashmap_free(struct ext2fs_hashmap *h);
+
+uint32_t ext2fs_djb2_hash(const void *str, size_t size);
+
+#endif /* !HASHMAP_H */
diff --git a/src/ext2fs/initialize.c b/src/ext2fs/initialize.c
index a69becdc..30b1ae03 100644
--- a/src/ext2fs/initialize.c
+++ b/src/ext2fs/initialize.c
@@ -109,15 +109,8 @@ errcode_t ext2fs_initialize(const char *name, int flags,
double reserved_ratio;
char *time_env;
- if (!name || !param || !ext2fs_blocks_count(param)) {
- com_err("ext2fs_initialize", EXT2_ET_INVALID_ARGUMENT, "invalid argument");
+ if (!param || !ext2fs_blocks_count(param))
return EXT2_ET_INVALID_ARGUMENT;
- }
-
- if (!name || !param || !ext2fs_blocks_count(param)) {
- com_err("ext2fs_initialize", EXT2_ET_INVALID_ARGUMENT, "invalid argument");
- return EXT2_ET_INVALID_ARGUMENT;
- }
retval = ext2fs_get_mem(sizeof(struct struct_ext2_filsys), &fs);
if (retval)
@@ -193,6 +186,10 @@ errcode_t ext2fs_initialize(const char *name, int flags,
set_field(s_flags, 0);
assign_field(s_backup_bgs[0]);
assign_field(s_backup_bgs[1]);
+
+ assign_field(s_encoding);
+ assign_field(s_encoding_flags);
+
if (super->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP) {
retval = EXT2_ET_UNSUPP_FEATURE;
goto cleanup;
@@ -302,7 +299,7 @@ retry:
i = fs->blocksize >= 4096 ? 1 : 4096 / fs->blocksize;
if (ext2fs_has_feature_64bit(super) &&
- (ext2fs_blocks_count(super) / i) > (1ULL << 32))
+ (ext2fs_blocks_count(super) / i) >= (1ULL << 32))
set_field(s_inodes_count, ~0U);
else
set_field(s_inodes_count, ext2fs_blocks_count(super) / i);
@@ -389,6 +386,13 @@ ipg_retry:
retval = EXT2_ET_RES_GDT_BLOCKS;
goto cleanup;
}
+ /* Enable meta_bg if we'd lose more than 3/4 of a BG to GDT blocks. */
+ if (super->s_reserved_gdt_blocks + fs->desc_blocks >
+ super->s_blocks_per_group * 3 / 4) {
+ ext2fs_set_feature_meta_bg(fs->super);
+ ext2fs_clear_feature_resize_inode(fs->super);
+ set_field(s_reserved_gdt_blocks, 0);
+ }
/*
* Calculate the maximum number of bookkeeping blocks per
@@ -399,11 +403,6 @@ ipg_retry:
overhead = (int) (3 + fs->inode_blocks_per_group +
super->s_reserved_gdt_blocks);
- /* Enable meta_bg if we'd lose more than 3/4 of a BG to GDT blocks. */
- if (super->s_reserved_gdt_blocks + fs->desc_blocks >
- super->s_blocks_per_group * 3 / 4)
- ext2fs_set_feature_meta_bg(fs->super);
-
if (ext2fs_has_feature_meta_bg(fs->super))
overhead++;
else
diff --git a/src/ext2fs/inode.c b/src/ext2fs/inode.c
index 015cfe4b..75df418d 100644
--- a/src/ext2fs/inode.c
+++ b/src/ext2fs/inode.c
@@ -179,6 +179,14 @@ errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
EXT2_INODE_SCAN_DEFAULT_BUFFER_BLOCKS;
scan->current_block = ext2fs_inode_table_loc(scan->fs,
scan->current_group);
+ if (scan->current_block &&
+ ((scan->current_block < fs->super->s_first_data_block) ||
+ (scan->current_block + fs->inode_blocks_per_group - 1 >=
+ ext2fs_blocks_count(fs->super)))) {
+ ext2fs_free_mem(&scan);
+ return EXT2_ET_GDESC_BAD_INODE_TABLE;
+ }
+
scan->inodes_left = EXT2_INODES_PER_GROUP(scan->fs->super);
scan->blocks_left = scan->fs->inode_blocks_per_group;
if (ext2fs_has_group_desc_csum(fs)) {
@@ -288,7 +296,11 @@ static errcode_t get_next_blockgroup(ext2_inode_scan scan)
(fs->blocksize / scan->inode_size - 1)) *
scan->inode_size / fs->blocksize;
}
-
+ if (scan->current_block &&
+ ((scan->current_block < fs->super->s_first_data_block) ||
+ (scan->current_block + fs->inode_blocks_per_group - 1 >=
+ ext2fs_blocks_count(fs->super))))
+ return EXT2_ET_GDESC_BAD_INODE_TABLE;
return 0;
}
@@ -728,11 +740,13 @@ errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ext2_ino_t *ino,
/*
* Functions to read and write a single inode.
*/
-errcode_t ext2fs_read_inode_full(ext2_filsys fs, ext2_ino_t ino,
- struct ext2_inode * inode, int bufsize)
+errcode_t ext2fs_read_inode2(ext2_filsys fs, ext2_ino_t ino,
+ struct ext2_inode * inode, int bufsize,
+ int flags)
{
blk64_t block_nr;
- unsigned long group, block, offset;
+ dgrp_t group;
+ unsigned long block, offset;
char *ptr;
errcode_t retval;
unsigned i;
@@ -782,10 +796,14 @@ errcode_t ext2fs_read_inode_full(ext2_filsys fs, ext2_ino_t ino,
offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
EXT2_INODE_SIZE(fs->super);
block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);
- if (!ext2fs_inode_table_loc(fs, (unsigned) group))
+ block_nr = ext2fs_inode_table_loc(fs, group);
+ if (!block_nr)
return EXT2_ET_MISSING_INODE_TABLE;
- block_nr = ext2fs_inode_table_loc(fs, group) +
- block;
+ if ((block_nr < fs->super->s_first_data_block) ||
+ (block_nr + fs->inode_blocks_per_group - 1 >=
+ ext2fs_blocks_count(fs->super)))
+ return EXT2_ET_GDESC_BAD_INODE_TABLE;
+ block_nr += block;
io = fs->io;
}
offset &= (EXT2_BLOCK_SIZE(fs->super) - 1);
@@ -833,24 +851,33 @@ errcode_t ext2fs_read_inode_full(ext2_filsys fs, ext2_ino_t ino,
}
memcpy(inode, iptr, (bufsize > length) ? length : bufsize);
- if (!(fs->flags & EXT2_FLAG_IGNORE_CSUM_ERRORS) && fail_csum)
+ if (!(fs->flags & EXT2_FLAG_IGNORE_CSUM_ERRORS) &&
+ !(flags & READ_INODE_NOCSUM) && fail_csum)
return EXT2_ET_INODE_CSUM_INVALID;
return 0;
}
+errcode_t ext2fs_read_inode_full(ext2_filsys fs, ext2_ino_t ino,
+ struct ext2_inode * inode, int bufsize)
+{
+ return ext2fs_read_inode2(fs, ino, inode, bufsize, 0);
+}
+
errcode_t ext2fs_read_inode(ext2_filsys fs, ext2_ino_t ino,
struct ext2_inode * inode)
{
- return ext2fs_read_inode_full(fs, ino, inode,
- sizeof(struct ext2_inode));
+ return ext2fs_read_inode2(fs, ino, inode,
+ sizeof(struct ext2_inode), 0);
}
-errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino,
- struct ext2_inode * inode, int bufsize)
+errcode_t ext2fs_write_inode2(ext2_filsys fs, ext2_ino_t ino,
+ struct ext2_inode * inode, int bufsize,
+ int flags)
{
blk64_t block_nr;
- unsigned long group, block, offset;
+ dgrp_t group;
+ unsigned long block, offset;
errcode_t retval = 0;
struct ext2_inode_large *w_inode;
char *ptr;
@@ -876,13 +903,9 @@ errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino,
return retval;
if (bufsize < length) {
- int old_flags = fs->flags;
- fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
- retval = ext2fs_read_inode_full(fs, ino,
- (struct ext2_inode *)w_inode,
- length);
- fs->flags = (old_flags & EXT2_FLAG_IGNORE_CSUM_ERRORS) |
- (fs->flags & ~EXT2_FLAG_IGNORE_CSUM_ERRORS);
+ retval = ext2fs_read_inode2(fs, ino,
+ (struct ext2_inode *)w_inode,
+ length, READ_INODE_NOCSUM);
if (retval)
goto errout;
}
@@ -912,19 +935,28 @@ errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino,
ext2fs_swap_inode_full(fs, w_inode, w_inode, 1, length);
#endif
- retval = ext2fs_inode_csum_set(fs, ino, w_inode);
- if (retval)
- goto errout;
+ if ((flags & WRITE_INODE_NOCSUM) == 0) {
+ retval = ext2fs_inode_csum_set(fs, ino, w_inode);
+ if (retval)
+ goto errout;
+ }
group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super);
offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
EXT2_INODE_SIZE(fs->super);
block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);
- if (!ext2fs_inode_table_loc(fs, (unsigned) group)) {
+ block_nr = ext2fs_inode_table_loc(fs, (unsigned) group);
+ if (!block_nr) {
retval = EXT2_ET_MISSING_INODE_TABLE;
goto errout;
}
- block_nr = ext2fs_inode_table_loc(fs, (unsigned) group) + block;
+ if ((block_nr < fs->super->s_first_data_block) ||
+ (block_nr + fs->inode_blocks_per_group - 1 >=
+ ext2fs_blocks_count(fs->super))) {
+ retval = EXT2_ET_GDESC_BAD_INODE_TABLE;
+ goto errout;
+ }
+ block_nr += block;
offset &= (EXT2_BLOCK_SIZE(fs->super) - 1);
@@ -964,11 +996,17 @@ errout:
return retval;
}
+errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino,
+ struct ext2_inode * inode, int bufsize)
+{
+ return ext2fs_write_inode2(fs, ino, inode, bufsize, 0);
+}
+
errcode_t ext2fs_write_inode(ext2_filsys fs, ext2_ino_t ino,
struct ext2_inode *inode)
{
- return ext2fs_write_inode_full(fs, ino, inode,
- sizeof(struct ext2_inode));
+ return ext2fs_write_inode2(fs, ino, inode,
+ sizeof(struct ext2_inode), 0);
}
/*
diff --git a/src/ext2fs/mmp.c b/src/ext2fs/mmp.c
index 5c01df71..7f87ab48 100644
--- a/src/ext2fs/mmp.c
+++ b/src/ext2fs/mmp.c
@@ -36,7 +36,7 @@
#define O_DIRECT 0
#endif
-#ifndef _MSC_VER
+#if __GNUC_PREREQ (4, 6)
#pragma GCC diagnostic push
#ifndef CONFIG_MMP
#pragma GCC diagnostic ignored "-Wunused-parameter"
@@ -198,7 +198,7 @@ static errcode_t ext2fs_mmp_reset(ext2_filsys fs)
mmp_s->mmp_magic = EXT4_MMP_MAGIC;
mmp_s->mmp_seq = EXT4_MMP_SEQ_CLEAN;
mmp_s->mmp_time = 0;
-#if _BSD_SOURCE || _XOPEN_SOURCE >= 500
+#ifdef HAVE_GETHOSTNAME
gethostname(mmp_s->mmp_nodename, sizeof(mmp_s->mmp_nodename));
#else
mmp_s->mmp_nodename[0] = '\0';
@@ -273,6 +273,10 @@ out:
#endif
}
+#ifndef min
+#define min(x, y) ((x) < (y) ? (x) : (y))
+#endif
+
/*
* Make sure that the fs is not mounted or being fsck'ed while opening the fs.
*/
@@ -320,7 +324,7 @@ errcode_t ext2fs_mmp_start(ext2_filsys fs)
if (mmp_s->mmp_check_interval > mmp_check_interval)
mmp_check_interval = mmp_s->mmp_check_interval;
- sleep(2 * mmp_check_interval + 1);
+ sleep(min(mmp_check_interval * 2 + 1, mmp_check_interval + 60));
retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, fs->mmp_buf);
if (retval)
@@ -336,7 +340,7 @@ clean_seq:
goto mmp_error;
mmp_s->mmp_seq = seq = ext2fs_mmp_new_seq();
-#if _BSD_SOURCE || _XOPEN_SOURCE >= 500
+#ifdef HAVE_GETHOSTNAME
gethostname(mmp_s->mmp_nodename, sizeof(mmp_s->mmp_nodename));
#else
strcpy(mmp_s->mmp_nodename, "unknown host");
@@ -348,7 +352,7 @@ clean_seq:
if (retval)
goto mmp_error;
- sleep(2 * mmp_check_interval + 1);
+ sleep(min(2 * mmp_check_interval + 1, mmp_check_interval + 60));
retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, fs->mmp_buf);
if (retval)
@@ -465,6 +469,6 @@ mmp_error:
return EXT2_ET_OP_NOT_SUPPORTED;
#endif
}
-#ifndef _MSC_VER
+#if __GNUC_PREREQ (4, 6)
#pragma GCC diagnostic pop
#endif
diff --git a/src/ext2fs/nt_io.c b/src/ext2fs/nt_io.c
index a6477c0e..01d46396 100644
--- a/src/ext2fs/nt_io.c
+++ b/src/ext2fs/nt_io.c
@@ -23,6 +23,7 @@
#include
#include
+#include
#include "config.h"
#include "ext2fs.h"
@@ -41,9 +42,6 @@ PF_TYPE_DECL(NTAPI, NTSTATUS, NtDeviceIoControlFile, (HANDLE, HANDLE, PIO_APC_RO
PF_TYPE_DECL(NTAPI, NTSTATUS, NtFsControlFile, (HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID, PIO_STATUS_BLOCK, ULONG, PVOID, ULONG, PVOID, ULONG));
PF_TYPE_DECL(NTAPI, NTSTATUS, NtDelayExecution, (BOOLEAN, PLARGE_INTEGER));
-// TODO: Sort out ASSERT and __attribute__(align)
-#define ASSERT(x)
-
#define ARGUMENT_PRESENT(ArgumentPointer) ((CHAR *)((ULONG_PTR)(ArgumentPointer)) != (CHAR *)(NULL))
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
@@ -52,8 +50,8 @@ PF_TYPE_DECL(NTAPI, NTSTATUS, NtDelayExecution, (BOOLEAN, PLARGE_INTEGER));
#define BooleanFlagOn(Flags, SingleFlag) ((BOOLEAN)((((Flags) & (SingleFlag)) != 0)))
-#define EXT2_CHECK_MAGIC(struct, code) if ((struct)->magic != (code)) return (code)
-#define EXT2_ET_MAGIC_NT_IO_CHANNEL 0x10ed
+#define EXT2_CHECK_MAGIC(struct, code) if ((struct)->magic != (code)) return (code)
+#define EXT2_ET_MAGIC_NT_IO_CHANNEL 0x10ed
// Private data block
typedef struct _NT_PRIVATE_DATA {
@@ -148,7 +146,7 @@ static ERROR_ENTRY ErrorTable[] = {
{ ERROR_NOT_ENOUGH_QUOTA, ENOMEM }
};
-static unsigned _MapDosError (IN ULONG WinError)
+static unsigned _MapDosError(IN ULONG WinError)
{
int i;
@@ -167,7 +165,6 @@ static unsigned _MapDosError (IN ULONG WinError)
return EINVAL;
}
-
// Map NT status to dos error.
static __inline unsigned _MapNtStatus(IN NTSTATUS Status)
{
@@ -180,7 +177,6 @@ static __inline unsigned _MapNtStatus(IN NTSTATUS Status)
//
static NTSTATUS _OpenNtName(IN PCSTR Name, IN BOOLEAN Readonly, OUT PHANDLE Handle, OUT PBOOLEAN OpenedReadonly OPTIONAL)
{
-// ANSI_STRING AnsiString;
UNICODE_STRING UnicodeString;
WCHAR Buffer[512];
NTSTATUS Status = EFAULT;
@@ -189,8 +185,8 @@ static NTSTATUS _OpenNtName(IN PCSTR Name, IN BOOLEAN Readonly, OUT PHANDLE Hand
PF_INIT(NtDelayExecution, Ntdll);
PF_INIT_OR_OUT(NtOpenFile, Ntdll);
- utf8_to_wchar_no_alloc(Name, Buffer, ARRAYSIZE(Buffer));
// Make Unicode name from input string
+ utf8_to_wchar_no_alloc(Name, Buffer, ARRAYSIZE(Buffer));
UnicodeString.Buffer = Buffer;
UnicodeString.Length = (USHORT) wcslen(Buffer) * 2;
UnicodeString.MaximumLength = sizeof(Buffer); // in bytes!!!
@@ -210,10 +206,7 @@ static NTSTATUS _OpenNtName(IN PCSTR Name, IN BOOLEAN Readonly, OUT PHANDLE Hand
// Maybe was just mounted? wait 0.5 sec and retry.
LARGE_INTEGER Interval;
Interval.QuadPart = -5000000; // 0.5 sec. from now
- if (pfNtDelayExecution != NULL)
- pfNtDelayExecution(FALSE, &Interval);
- else
- Sleep(500);
+ pfNtDelayExecution(FALSE, &Interval);
Status = pfNtOpenFile(Handle, SYNCHRONIZE | FILE_READ_DATA | (Readonly ? 0 : FILE_WRITE_DATA),
&ObjectAttributes, &IoStatusBlock, FILE_SHARE_WRITE | FILE_SHARE_READ,
@@ -388,7 +381,6 @@ static PCSTR _NormalizeDeviceName(IN PCSTR Device, IN PSTR NormalizedDeviceNameB
return NormalizedDeviceNameBuffer;
}
-
static VOID _GetDeviceSize(IN HANDLE h, OUT unsigned __int64 *FsSize)
{
PARTITION_INFORMATION_EX pi;
@@ -473,8 +465,8 @@ static BOOLEAN _BlockIo(IN HANDLE Handle, IN LARGE_INTEGER Offset, IN ULONG Byte
PF_INIT_OR_OUT(NtWriteFile, NtDll);
// Should be aligned
- ASSERT(0 == (Bytes % 512));
- ASSERT(0 == (Offset.LowPart % 512));
+ assert((Bytes % 512) == 0);
+ assert((Offset.LowPart % 512) == 0);
// Perform io
if(Read) {
@@ -496,8 +488,6 @@ out:
return FALSE;
}
-
-
static BOOLEAN _RawWrite(IN HANDLE Handle, IN LARGE_INTEGER Offset, IN ULONG Bytes, OUT const CHAR* Buffer, OUT unsigned* Errno)
{
return _BlockIo(Handle, Offset, Bytes, (PCHAR)Buffer, FALSE, Errno);
@@ -515,18 +505,14 @@ static BOOLEAN _SetPartType(IN HANDLE Handle, IN UCHAR Type)
if (pfNtDeviceIoControlFile == NULL)
return FALSE;
return NT_SUCCESS(pfNtDeviceIoControlFile(Handle, NULL, NULL, NULL, &IoStatusBlock,
- IOCTL_DISK_SET_PARTITION_INFO, &Type,
- sizeof(Type), NULL, 0));
+ IOCTL_DISK_SET_PARTITION_INFO, &Type, sizeof(Type), NULL, 0));
}
-
//
// Interface functions.
// Is_mounted is set to 1 if the device is mounted, 0 otherwise
//
-
-errcode_t
-ext2fs_check_if_mounted(const char *file, int *mount_flags)
+errcode_t ext2fs_check_if_mounted(const char *file, int *mount_flags)
{
HANDLE h;
BOOLEAN Readonly;
@@ -542,12 +528,10 @@ ext2fs_check_if_mounted(const char *file, int *mount_flags)
return 0;
}
-
-
// Returns the number of blocks in a partition
// Note: Do *NOT* be tempted to cache the device size according to the NT path as
// different removable devices (e.g. UFD) may be remounted under the same path.
-errcode_t ext2fs_get_device_size(const char *file, int blocksize, blk64_t *retblocks)
+errcode_t ext2fs_get_device_size2(const char *file, int blocksize, blk64_t *retblocks)
{
__int64 fs_size = 0;
HANDLE h;
@@ -569,7 +553,6 @@ errcode_t ext2fs_get_device_size(const char *file, int blocksize, blk64_t *retbl
//
// Table elements
//
-
static errcode_t nt_open(const char *name, int flags, io_channel *channel)
{
io_channel io = NULL;
@@ -698,7 +681,7 @@ static errcode_t nt_set_blksize(io_channel channel, int blksize)
free(nt_data->buffer);
nt_data->buffer_block_number = 0xffffffff;
nt_data->buffer_size = channel->block_size;
- ASSERT(0 == (nt_data->BufferSize % 512));
+ assert((nt_data->buffer_size % 512) == 0);
nt_data->buffer = malloc(nt_data->buffer_size);
if (nt_data->buffer == NULL)
@@ -741,7 +724,7 @@ static errcode_t nt_read_blk(io_channel channel, unsigned long block, int count,
} else {
read_size = size;
read_buffer = buf;
- ASSERT((read_size % channel->block_size) == 0);
+ assert((read_size % channel->block_size) == 0);
}
if (!_RawRead(nt_data->handle, offset, read_size, read_buffer, &errcode)) {
@@ -752,7 +735,7 @@ static errcode_t nt_read_blk(io_channel channel, unsigned long block, int count,
}
if (read_buffer != buf) {
- ASSERT(size <= read_size);
+ assert(size <= read_size);
memcpy(buf, read_buffer, size);
}
@@ -785,7 +768,7 @@ static errcode_t nt_write_blk(io_channel channel, unsigned long block, int count
}
- ASSERT(0 == (write_size % 512));
+ assert((write_size % 512) == 0);
offset.QuadPart = block * channel->block_size;
if (!_RawWrite(nt_data->handle, offset, write_size, buf, &errcode)) {
diff --git a/src/ext2fs/rbtree.h b/src/ext2fs/rbtree.h
index ada31bba..6bd049a4 100644
--- a/src/ext2fs/rbtree.h
+++ b/src/ext2fs/rbtree.h
@@ -97,8 +97,17 @@ static inline struct page * rb_insert_page_cache(struct inode * inode,
#include
#include
-// TODO: MSVC __attribute__(x)
-#define __attribute__(x)
+#include "config.h"
+
+#if defined(__GNUC__) || defined(__clang__)
+#define EXT2FS_ALIGN_START(m)
+#define EXT2FS_ALIGN_END(m) __attribute__ ((__aligned__(m)))
+#elif defined(_MSC_VER)
+#define EXT2FS_ALIGN_START(m) __declspec(align(m))
+#define EXT2FS_ALIGN_END(m)
+#else
+#error
+#endif
#undef offsetof
#ifdef __compiler_offsetof
@@ -111,14 +120,14 @@ static inline struct page * rb_insert_page_cache(struct inode * inode,
const __typeof__( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
-struct rb_node
+EXT2FS_ALIGN_START(SIZEOF_LONG) struct rb_node
{
uintptr_t rb_parent_color;
#define RB_RED 0
#define RB_BLACK 1
struct rb_node *rb_right;
struct rb_node *rb_left;
-} __attribute__((aligned(sizeof(long))));
+} EXT2FS_ALIGN_END(SIZEOF_LONG);
/* The alignment might seem pointless, but allegedly CRIS needs it */
struct rb_root
diff --git a/src/ext2fs/sha512.c b/src/ext2fs/sha512.c
new file mode 100644
index 00000000..fe2dd52e
--- /dev/null
+++ b/src/ext2fs/sha512.c
@@ -0,0 +1,302 @@
+/*
+ * sha512.c --- The sha512 algorithm
+ *
+ * Copyright (C) 2004 Sam Hocevar
+ * (copied from libtomcrypt and then relicensed under GPLv2)
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+
+#include "config.h"
+#if HAVE_SYS_TYPES_H
+#include
+#endif
+#include "ext2fs.h"
+
+/* the K array */
+#define CONST64(n) n
+static const __u64 K[80] = {
+ CONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd),
+ CONST64(0xb5c0fbcfec4d3b2f), CONST64(0xe9b5dba58189dbbc),
+ CONST64(0x3956c25bf348b538), CONST64(0x59f111f1b605d019),
+ CONST64(0x923f82a4af194f9b), CONST64(0xab1c5ed5da6d8118),
+ CONST64(0xd807aa98a3030242), CONST64(0x12835b0145706fbe),
+ CONST64(0x243185be4ee4b28c), CONST64(0x550c7dc3d5ffb4e2),
+ CONST64(0x72be5d74f27b896f), CONST64(0x80deb1fe3b1696b1),
+ CONST64(0x9bdc06a725c71235), CONST64(0xc19bf174cf692694),
+ CONST64(0xe49b69c19ef14ad2), CONST64(0xefbe4786384f25e3),
+ CONST64(0x0fc19dc68b8cd5b5), CONST64(0x240ca1cc77ac9c65),
+ CONST64(0x2de92c6f592b0275), CONST64(0x4a7484aa6ea6e483),
+ CONST64(0x5cb0a9dcbd41fbd4), CONST64(0x76f988da831153b5),
+ CONST64(0x983e5152ee66dfab), CONST64(0xa831c66d2db43210),
+ CONST64(0xb00327c898fb213f), CONST64(0xbf597fc7beef0ee4),
+ CONST64(0xc6e00bf33da88fc2), CONST64(0xd5a79147930aa725),
+ CONST64(0x06ca6351e003826f), CONST64(0x142929670a0e6e70),
+ CONST64(0x27b70a8546d22ffc), CONST64(0x2e1b21385c26c926),
+ CONST64(0x4d2c6dfc5ac42aed), CONST64(0x53380d139d95b3df),
+ CONST64(0x650a73548baf63de), CONST64(0x766a0abb3c77b2a8),
+ CONST64(0x81c2c92e47edaee6), CONST64(0x92722c851482353b),
+ CONST64(0xa2bfe8a14cf10364), CONST64(0xa81a664bbc423001),
+ CONST64(0xc24b8b70d0f89791), CONST64(0xc76c51a30654be30),
+ CONST64(0xd192e819d6ef5218), CONST64(0xd69906245565a910),
+ CONST64(0xf40e35855771202a), CONST64(0x106aa07032bbd1b8),
+ CONST64(0x19a4c116b8d2d0c8), CONST64(0x1e376c085141ab53),
+ CONST64(0x2748774cdf8eeb99), CONST64(0x34b0bcb5e19b48a8),
+ CONST64(0x391c0cb3c5c95a63), CONST64(0x4ed8aa4ae3418acb),
+ CONST64(0x5b9cca4f7763e373), CONST64(0x682e6ff3d6b2b8a3),
+ CONST64(0x748f82ee5defb2fc), CONST64(0x78a5636f43172f60),
+ CONST64(0x84c87814a1f0ab72), CONST64(0x8cc702081a6439ec),
+ CONST64(0x90befffa23631e28), CONST64(0xa4506cebde82bde9),
+ CONST64(0xbef9a3f7b2c67915), CONST64(0xc67178f2e372532b),
+ CONST64(0xca273eceea26619c), CONST64(0xd186b8c721c0c207),
+ CONST64(0xeada7dd6cde0eb1e), CONST64(0xf57d4f7fee6ed178),
+ CONST64(0x06f067aa72176fba), CONST64(0x0a637dc5a2c898a6),
+ CONST64(0x113f9804bef90dae), CONST64(0x1b710b35131c471b),
+ CONST64(0x28db77f523047d84), CONST64(0x32caab7b40c72493),
+ CONST64(0x3c9ebe0a15c9bebc), CONST64(0x431d67c49c100d4c),
+ CONST64(0x4cc5d4becb3e42b6), CONST64(0x597f299cfc657e2a),
+ CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817)
+};
+#define Ch(x,y,z) (z ^ (x & (y ^ z)))
+#define Maj(x,y,z) (((x | y) & z) | (x & y))
+#define S(x, n) ROR64c(x, n)
+#define R(x, n) (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((__u64)n))
+#define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39))
+#define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41))
+#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7))
+#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6))
+#define RND(a,b,c,d,e,f,g,h,i)\
+ t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i];\
+ t1 = Sigma0(a) + Maj(a, b, c);\
+ d += t0;\
+ h = t0 + t1;
+#define STORE64H(x, y) \
+ do { \
+ (y)[0] = (unsigned char)(((x)>>56)&255);\
+ (y)[1] = (unsigned char)(((x)>>48)&255);\
+ (y)[2] = (unsigned char)(((x)>>40)&255);\
+ (y)[3] = (unsigned char)(((x)>>32)&255);\
+ (y)[4] = (unsigned char)(((x)>>24)&255);\
+ (y)[5] = (unsigned char)(((x)>>16)&255);\
+ (y)[6] = (unsigned char)(((x)>>8)&255);\
+ (y)[7] = (unsigned char)((x)&255); } while(0)
+
+#define LOAD64H(x, y)\
+ do {x = \
+ (((__u64)((y)[0] & 255)) << 56) |\
+ (((__u64)((y)[1] & 255)) << 48) |\
+ (((__u64)((y)[2] & 255)) << 40) |\
+ (((__u64)((y)[3] & 255)) << 32) |\
+ (((__u64)((y)[4] & 255)) << 24) |\
+ (((__u64)((y)[5] & 255)) << 16) |\
+ (((__u64)((y)[6] & 255)) << 8) |\
+ (((__u64)((y)[7] & 255)));\
+ } while(0)
+
+#define ROR64c(x, y) \
+ ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((__u64)(y)&CONST64(63))) | \
+ ((x)<<((__u64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF))
+
+struct sha512_state {
+ __u64 length, state[8];
+ unsigned long curlen;
+ unsigned char buf[128];
+};
+
+/* This is a highly simplified version from libtomcrypt */
+struct hash_state {
+ struct sha512_state sha512;
+};
+
+static void sha512_compress(struct hash_state * md, const unsigned char *buf)
+{
+ __u64 S[8], W[80], t0, t1;
+ int i;
+
+ /* copy state into S */
+ for (i = 0; i < 8; i++) {
+ S[i] = md->sha512.state[i];
+ }
+
+ /* copy the state into 1024-bits into W[0..15] */
+ for (i = 0; i < 16; i++) {
+ LOAD64H(W[i], buf + (8*i));
+ }
+
+ /* fill W[16..79] */
+ for (i = 16; i < 80; i++) {
+ W[i] = Gamma1(W[i - 2]) + W[i - 7] +
+ Gamma0(W[i - 15]) + W[i - 16];
+ }
+
+ for (i = 0; i < 80; i += 8) {
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0);
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1);
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2);
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3);
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4);
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5);
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6);
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7);
+ }
+
+ /* feedback */
+ for (i = 0; i < 8; i++) {
+ md->sha512.state[i] = md->sha512.state[i] + S[i];
+ }
+}
+
+static void sha512_init(struct hash_state * md)
+{
+ md->sha512.curlen = 0;
+ md->sha512.length = 0;
+ md->sha512.state[0] = CONST64(0x6a09e667f3bcc908);
+ md->sha512.state[1] = CONST64(0xbb67ae8584caa73b);
+ md->sha512.state[2] = CONST64(0x3c6ef372fe94f82b);
+ md->sha512.state[3] = CONST64(0xa54ff53a5f1d36f1);
+ md->sha512.state[4] = CONST64(0x510e527fade682d1);
+ md->sha512.state[5] = CONST64(0x9b05688c2b3e6c1f);
+ md->sha512.state[6] = CONST64(0x1f83d9abfb41bd6b);
+ md->sha512.state[7] = CONST64(0x5be0cd19137e2179);
+}
+
+static void sha512_done(struct hash_state * md, unsigned char *out)
+{
+ int i;
+
+ /* increase the length of the message */
+ md->sha512.length += md->sha512.curlen * CONST64(8);
+
+ /* append the '1' bit */
+ md->sha512.buf[md->sha512.curlen++] = (unsigned char)0x80;
+
+ /* if the length is currently above 112 bytes we append zeros then
+ * compress. Then we can fall back to padding zeros and length encoding
+ * like normal. */
+ if (md->sha512.curlen > 112) {
+ while (md->sha512.curlen < 128) {
+ md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
+ }
+ sha512_compress(md, md->sha512.buf);
+ md->sha512.curlen = 0;
+ }
+
+ /* pad upto 120 bytes of zeroes note: that from 112 to 120 is the 64 MSB
+ * of the length. We assume that you won't hash > 2^64 bits of data. */
+ while (md->sha512.curlen < 120) {
+ md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
+ }
+
+ /* store length */
+ STORE64H(md->sha512.length, md->sha512.buf + 120);
+ sha512_compress(md, md->sha512.buf);
+
+ /* copy output */
+ for (i = 0; i < 8; i++) {
+ STORE64H(md->sha512.state[i], out+(8 * i));
+ }
+}
+
+#define MIN(x, y) ( ((x)<(y))?(x):(y) )
+#define SHA512_BLOCKSIZE 128
+static void sha512_process(struct hash_state * md,
+ const unsigned char *in,
+ unsigned long inlen)
+{
+ unsigned long n;
+
+ while (inlen > 0) {
+ if (md->sha512.curlen == 0 && inlen >= SHA512_BLOCKSIZE) {
+ sha512_compress(md, in);
+ md->sha512.length += SHA512_BLOCKSIZE * 8;
+ in += SHA512_BLOCKSIZE;
+ inlen -= SHA512_BLOCKSIZE;
+ } else {
+ n = MIN(inlen, (SHA512_BLOCKSIZE - md->sha512.curlen));
+ memcpy(md->sha512.buf + md->sha512.curlen,
+ in, (size_t)n);
+ md->sha512.curlen += n;
+ in += n;
+ inlen -= n;
+ if (md->sha512.curlen == SHA512_BLOCKSIZE) {
+ sha512_compress(md, md->sha512.buf);
+ md->sha512.length += SHA512_BLOCKSIZE * 8;
+ md->sha512.curlen = 0;
+ }
+ }
+ }
+}
+
+void ext2fs_sha512(const unsigned char *in, unsigned long in_size,
+ unsigned char out[EXT2FS_SHA512_LENGTH])
+{
+ struct hash_state md;
+
+ sha512_init(&md);
+ sha512_process(&md, in, in_size);
+ sha512_done(&md, out);
+}
+
+#ifdef UNITTEST
+static const struct {
+ char *msg;
+ unsigned char hash[64];
+} tests[] = {
+ { "",
+ { 0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd,
+ 0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07,
+ 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc,
+ 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce,
+ 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0,
+ 0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f,
+ 0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81,
+ 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e }
+ },
+ { "abc",
+ { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
+ 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
+ 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
+ 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
+ 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
+ 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
+ 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
+ 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f }
+ },
+ { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+ { 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
+ 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
+ 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
+ 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
+ 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
+ 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
+ 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
+ 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 }
+ },
+};
+
+int main(int argc, char **argv)
+{
+ int i;
+ int errors = 0;
+ unsigned char tmp[64];
+
+ for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
+ unsigned char *msg = (unsigned char *) tests[i].msg;
+ int len = strlen(tests[i].msg);
+
+ ext2fs_sha512(msg, len, tmp);
+ printf("SHA512 test message %d: ", i);
+ if (memcmp(tmp, tests[i].hash, 64) != 0) {
+ printf("FAILED\n");
+ errors++;
+ } else
+ printf("OK\n");
+ }
+ return errors;
+}
+
+#endif /* UNITTEST */
diff --git a/src/format.c b/src/format.c
index fd79be9d..edf51da1 100644
--- a/src/format.c
+++ b/src/format.c
@@ -690,7 +690,7 @@ BOOL FormatExt2Fs(void)
CloseHandle(h);
// TODO: We could probably remove that call and get our size from a different means
- r = ext2fs_get_device_size(path, EXT2_BLOCK_SIZE(&features), &size);
+ r = ext2fs_get_device_size2(path, EXT2_BLOCK_SIZE(&features), &size);
uprintf("ext2fs_get_device_size: %d", r);
// TODO: ERROR HANDLING
// Set the number of blocks and reserved blocks
diff --git a/src/rufus.rc b/src/rufus.rc
index 858910c3..e373ba9d 100644
--- a/src/rufus.rc
+++ b/src/rufus.rc
@@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 232, 326
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_ACCEPTFILES
-CAPTION "Rufus 3.6.1518"
+CAPTION "Rufus 3.6.1519"
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
BEGIN
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
@@ -394,8 +394,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 3,6,1518,0
- PRODUCTVERSION 3,6,1518,0
+ FILEVERSION 3,6,1519,0
+ PRODUCTVERSION 3,6,1519,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -413,13 +413,13 @@ BEGIN
VALUE "Comments", "https://akeo.ie"
VALUE "CompanyName", "Akeo Consulting"
VALUE "FileDescription", "Rufus"
- VALUE "FileVersion", "3.6.1518"
+ VALUE "FileVersion", "3.6.1519"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2019 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "https://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus-3.6.exe"
VALUE "ProductName", "Rufus"
- VALUE "ProductVersion", "3.6.1518"
+ VALUE "ProductVersion", "3.6.1519"
END
END
BLOCK "VarFileInfo"