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"