Merge set_ntfs_volume_flags() and code from ntfsfix as a new library

function: ntfs_set_volume_flags(). Note, ntfs_set_volume_flags() is
moving to volume.[ch]

2002/07/12 12:38:54-00:00 !szaka
Rewrote $LogFile reset using new inode API and moved it from ntfsfix to
libntfs as ntfs_reset_logfile(). ntfsresize also resets log file.

2002/07/12 07:10:44-00:00 !szaka
NTFS_V* version macros and ntfs_is_version_supported() added.
Modified ntfsfix and ntfsresize to use them.

2002/07/11 16:20:34-00:00 !flatcap
whitespace and include guards

2002/07/08 23:27:17-00:00 !flatcap
added AT_NONAME so we can search for a (un)named attribute or just
iterate through all attributes

2002/07/07 19:44:57-00:00 !antona
Change ntfs_read_file_record() not to abort if the inode is not in use. Adapt callers which care to check this themselves.

2002/07/03 21:56:01-00:00 !antona
Updates

2002/07/02 23:47:11-00:00 !antona
Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it.

2002/06/05 20:32:53-00:00 !antona
Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly.

2002/06/02 23:02:20-00:00 !antona
More fixes and updates.

2002/04/29 01:53:55-00:00 !antona
Loads of stuff. Improvements, start on attr pread and attr mst_pread. Write to follow. ntfslabel cleanup and extensions. libntfs cleanups, fixes, etc.

2002/04/27 19:49:10-00:00 !antona
Update library, new APIs ntfs_attr_find_vcn(), misc fixes and cleanups, make all the utilities compile, fix bugs I noticed in ntfslabel and it now works properly.

2002/04/21 01:26:39-00:00 !antona
Cleanup/streamline include file dependencies.

2002/04/20 23:09:43-00:00 !antona
Port attribute lookup functions with attribute list support from ntfs tng driver. Port/reimplement extent mft record handling code as well. Rename out all dollar signs from type names and constants. Adapt all callers to new API. Note mkntfs is currently broken due to some needed work.

2002/04/20 01:53:03-00:00 !antona
Rename mft code adding ntfs_ prefix. Change all return values to zero on success. Thanks to mattjf for pointing out the inconsistencies.

2002/04/19 21:09:55-00:00 !antona
Finished provisional inode.c::ntfs_{open,close}_inode() functions. Also, started defining API provided by attrib.[ch], so far only done search context related stuff.

2002/04/16 15:34:32-00:00 !antona
Fix the library...

2002/04/15 19:17:24-00:00 !antona
Fix ntfsfix as well. This completes all changes and everything should be just as functional as before.

2002/04/14 14:15:47-00:00 !antona
Cleanups and updates.

2002/03/12 22:11:02-00:00 !antona
Final tidyups.

2002/03/12 22:00:44-00:00 !antona
Fix a few small mistakes

2002/03/12 21:48:27-00:00 !antona
Change version numbers of mkntfs and ntfsfix to match linux-ntfs release and add options to mkntfs to disable content indexing on the volume and to enable compression on the volume.

2002/01/26 02:22:05-00:00 !antona
Fix two bugs (we called is_baad_record instead of is_baad_recordp...). Thanks to
 David Martinez Moreno for reporting the compile time warnings on ia64 which led me to find the bugs.

2001/12/06 01:14:52-00:00 !antona
Added mount flags to ntfs_mount and adapted utilities to new mount syntax.

2001/11/09 18:24:32-00:00 !antona
Updates to docs, layout.h and ntfsfix to support Windows XP NTFS

2001/08/02 01:44:57-00:00 !antona
Add ntfsfix man page and spell fixes. Update to 1.2.1 version and update all text files to go with it and the rpm spec file.

2001/06/01 02:07:26-00:00 !antona
It has been a long time since last commit. At moment have done a lot of work
on mkntfs but also at the moment ntfsfix and ntfsdump_logfile and libntfs are
broken. Basically only mkntfs works and that is not complete either.

2001/04/11 15:47:36-00:00 !antona
Fix

2001/04/11 15:29:39-00:00 !flatcap
minor build fixes

2001/04/08 03:02:55-00:00 !antona
Added cvs Id header.

2001/04/02 23:02:41-00:00 !antona
Fixed a braino the compiler didn't catch...

2001/04/02 02:38:39-00:00 !antona
I think version reporting is now fixed.

2001/04/02 02:20:53-00:00 !antona
Fixed up the automatic version numbering (I hope).

2001/04/02 02:13:57-00:00 !antona
Make the ntfsfix version be equal to the Revision in CVS.

2001/04/02 02:04:37-00:00 !antona
Everything compiles again! Yey! (Don't know about working though, haven't tried
it... So be careful...)
The definitely final find_{first_}attr() functions are in place. Currently
still no support for attribute lists.
The two new _RE files contain the C-fied and more or less (more less than more
actually) cleaned up functions from the ntfs driver. Once they are cleaned
up (find_attr() is already completed but I left it in the _RE files for future
reference/educational value) and modified to suit my ideas of how they should
work, which are not quite the same as the driver way, they will make it into
attrib.[ch].
If anyone gives the new code a try, I would be interested in whether it worked
or not... (-;

2001/03/02 15:06:37-00:00 !antona
Full commit of my current dircetory. New files not yet added.

2001/02/03 04:21:49-00:00 !antona
Finished first public release. This is the final commit to make sure
everything is in cvs.

2001/02/02 00:16:18-00:00 !antona
Changed make process to using autoconf/automake/libtool.
Added necessary files for this and for the gnu standard.
Inititial checkin. Probably still stuff missing. Will know soon...

2001/01/30 12:55:21-00:00 !antona
Fixed the compilation issues.

2001/01/27 14:22:02-00:00 !antona
Added a logfile dumper as a new utility.
Almost finished the first ntfsfix release. (Still missingin CVS are attrib.c
for ntfslib and the makefiles to build everything.)
Fixes for nested packed structure/union typedefs as gcc doesn't automatically
nest the __attribute__ ((__packed__)), even though according to the gcc info
page it does. (Thanks to Yuri Per <yuri@acronis.com> for pointing this out.)

2001/01/24 21:02:37-00:00 !antona
Added ntfsfix program.

(Logical change 1.5)
edge.strict_endians
!szaka 2002-08-22 18:09:47 +00:00
parent 2ba0affba6
commit e80befbfb5
1 changed files with 317 additions and 0 deletions

View File

@ -0,0 +1,317 @@
/*
* $Id$
*
* NtfsFix - Part of the Linux-NTFS project.
*
* Copyright (c) 2000-2002 Anton Altaparmakov.
*
* This utility will attempt to fix a partition that has been damaged by the
* current Linux-NTFS driver. It should be run after dismounting a NTFS
* partition that has been mounted read-write under Linux and before rebooting
* into Windows NT/2000. NtfsFix can be run even after Windows has had mounted
* the partition, but it might be too late and irreversible damage to the data
* might have been done already.
*
* Anton Altaparmakov <aia21@cantab.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (in the main directory of the Linux-NTFS source
* in the file COPYING); if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* WARNING: This program might not work on architectures which do not allow
* unaligned access. For those, the program would need to start using
* get/put_unaligned macros (#include <asm/unaligned.h>), but not doing it yet,
* since NTFS really mostly applies to ia32 only, which does allow unaligned
* accesses. We might not actually have a problem though, since the structs are
* defined as being packed so that might be enough for gcc to insert the
* correct code.
*
* If anyone using a non-little endian and/or an aligned access only CPU tries
* this program please let me know whether it works or not!
*
* Anton Altaparmakov <aia21@cantab.net>
*/
#include "config.h"
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include "types.h"
#include "attrib.h"
#include "mft.h"
#include "disk_io.h"
#include "logfile.h"
int main(int argc, char **argv)
{
s64 l, br;
const char *EXEC_NAME = "NtfsFix";
const char *OK = "OK";
const char *FAILED = "FAILED";
unsigned char *m = NULL, *m2 = NULL;
ntfs_volume *vol;
unsigned long mnt_flags;
int i;
u16 flags;
BOOL done, force = FALSE;
printf("\n");
if (argc != 2 || !argv[1]) {
printf("%s v%s - Attempt to fix an NTFS partition that "
"has been damaged by the\nLinux NTFS driver. Note that "
"you should run it every time after you have used\nthe "
"Linux NTFS driver to write to an NTFS partition to "
"prevent massive data\ncorruption from happening when "
"Windows mounts the partition.\nIMPORTANT: Run this "
"only *after* unmounting the partition in Linux but "
"*before*\nrebooting into Windows NT/2000/XP or you "
"*will* suffer! - You have been warned!\n\n"
/* Generic copyright / disclaimer. */
"Copyright (c) 2000-2002 Anton Altaparmakov.\n\n"
"%s is free software, released under the GNU "
"General Public License and you\nare welcome to "
"redistribute it under certain conditions.\n"
"%s comes with ABSOLUTELY NO WARRANTY; for details "
"read the file GNU\nGeneral Public License to be found "
"in the file COPYING in the main Linux-NTFS\n"
"distribution directory.\n\n"
/* Generic part ends here. */
"Syntax: ntfsfix partition_or_file_name\n"
" e.g. ntfsfix /dev/hda6\n\n", EXEC_NAME,
VERSION, EXEC_NAME, EXEC_NAME);
fprintf(stderr, "Error: incorrect syntax\n");
exit(1);
}
if (!ntfs_check_if_mounted(argv[1], &mnt_flags)) {
if ((mnt_flags & NTFS_MF_MOUNTED) &&
!(mnt_flags & NTFS_MF_READONLY) && !force) {
fprintf(stderr, "Refusing to operate on read-write "
"mounted device %s.\n", argv[1]);
exit(1);
}
} else
fprintf(stderr, "Failed to determine whether %s is mounted: "
"%s\n", argv[1], strerror(errno));
/* Attempt a full mount first. */
printf("Mounting volume... ");
vol = ntfs_mount(argv[1], 0);
if (vol) {
puts(OK);
printf("\nProcessing of $MFT and $MFTMirr completed "
"successfully.\n\n");
goto mount_ok;
}
puts(FAILED);
puts("Attempting to correct errors.");
vol = ntfs_startup_volume(argv[1], 0);
if (!vol) {
puts(FAILED);
perror("Failed to startup volume");
fprintf(stderr, "Volume is corrupt. You should run chkdsk.");
goto error_exit;
}
puts("Processing $MFT and $MFTMirr.");
/* Load data from $MFT and $MFTMirr and compare the contents. */
m = (u8*)malloc(vol->mftmirr_size << vol->mft_record_size_bits);
m2 = (u8*)malloc(vol->mftmirr_size << vol->mft_record_size_bits);
if (!m || !m2) {
perror("Failed to allocate memory");
goto error_exit;
}
printf("Reading $MFT... ");
l = ntfs_attr_mst_pread(vol->mft_na, 0, vol->mftmirr_size,
vol->mft_record_size, m);
if (l != vol->mftmirr_size) {
puts(FAILED);
if (l != -1)
errno = EIO;
perror("Failed to read $MFT");
goto error_exit;
}
puts(OK);
printf("Reading $MFTMirr... ");
l = ntfs_attr_mst_pread(vol->mftmirr_na, 0, vol->mftmirr_size,
vol->mft_record_size, m2);
if (l != vol->mftmirr_size) {
puts(FAILED);
if (l != -1)
errno = EIO;
perror("Failed to read $MFTMirr");
goto error_exit;
}
puts(OK);
/*
* FIXME: Need to actually check the $MFTMirr for being real. Otherwise
* we might corrupt the partition if someone is experimenting with
* software RAID and the $MFTMirr is not actually in the position we
* expect it to be... )-:
* FIXME: We should emit a warning it $MFTMirr is damaged and ask
* user whether to recreate it from $MFT or whether to abort. - The
* warning needs to include the danger of software RAID arrays.
* Maybe we should go as far as to detect whether we are running on a
* MD disk and if yes then bomb out right at the start of the program?
*/
printf("Comparing $MFTMirr to $MFT... ");
done = FALSE;
for (i = 0; i < vol->mftmirr_size; ++i) {
const char *ESTR[12] = { "$MFT", "$MFTMirr", "$LogFile",
"$Volume", "$AttrDef", "root directory", "$Bitmap",
"$Boot", "$BadClus", "$Secure", "$UpCase", "$Extend" };
const char *s;
if (i < 12)
s = ESTR[i];
else if (i < 16)
s = "system file";
else
s = "mft record";
if (is_baad_recordp(m + i * vol->mft_record_size)) {
puts("FAILED");
fprintf(stderr, "$MFT error: Incomplete multi sector "
"transfer detected in %s.\nCannot "
"handle this yet. )-:\n", s);
goto error_exit;
}
if (!is_mft_recordp(m + i * vol->mft_record_size)) {
puts("FAILED");
fprintf(stderr, "$MFT error: Invalid mft record for "
"%s.\nCannot handle this yet. )-:\n",
s);
goto error_exit;
}
if (is_baad_recordp(m2 + i * vol->mft_record_size)) {
puts("FAILED");
fprintf(stderr, "$MFTMirr error: Incomplete multi "
"sector transfer detected in %s.\n", s);
goto error_exit;
}
if (!is_mft_recordp(m2 + i * vol->mft_record_size)) {
puts("FAILED");
fprintf(stderr, "$MFTMirr error: Invalid mft record "
"for %s.\n", s);
goto error_exit;
}
if (memcmp((u8*)m + i * vol->mft_record_size, (u8*)m2 +
i * vol->mft_record_size,
ntfs_get_mft_record_data_size((MFT_RECORD*)(
(u8*)m + i * vol->mft_record_size)))) {
if (!done) {
done = TRUE;
puts(FAILED);
printf("Correcting differences in "
"$MFTMirr... ");
}
br = ntfs_write_mft_record(vol, i, (MFT_RECORD*)(m +
i * vol->mft_record_size));
if (br) {
puts(FAILED);
perror("Error correcting $MFTMirr");
goto error_exit;
}
}
}
puts(OK);
free(m);
free(m2);
m = m2 = NULL;
printf("Processing of $MFT and $MFTMirr completed successfully.\n\n");
if (ntfs_umount(vol, 0))
ntfs_umount(vol, 1);
vol = ntfs_mount(argv[1], 0);
if (!vol) {
perror("Remount failed");
goto error_exit;
}
mount_ok:
m = NULL;
/* Check NTFS version is ok for us (in $Volume) */
printf("NTFS volume version is %i.%i.\n\n", vol->major_ver,
vol->minor_ver);
if (ntfs_is_version_supported(vol)) {
fprintf(stderr, "Error: Unknown NTFS version.\n");
goto error_exit;
}
printf("Setting required flags on partition... ");
/*
* Set chkdsk flag, i.e. mark the partition dirty so chkdsk will run
* and fix it for us.
*/
flags = vol->flags | VOLUME_IS_DIRTY;
/* If NTFS volume version >= 2.0 then set mounted on NT4 flag. */
if (vol->major_ver >= 2)
flags |= VOLUME_MOUNTED_ON_NT4;
if (ntfs_set_volume_flags(vol, flags)) {
puts(FAILED);
fprintf(stderr, "Error setting volume flags.\n");
goto error_exit;
}
puts(OK);
printf("\n");
printf("Going to empty the journal ($LogFile)... ");
if (ntfs_reset_logfile(vol)) {
puts(FAILED);
perror("Failed to reset $LogFile");
goto error_exit;
}
puts(OK);
printf("\n");
if (vol->major_ver >= 3) {
/* FIXME: If on NTFS 3.0+, check for presence of the usn journal and
disable it (if present) as Win2k might be unhappy otherwise and Bad
Things(TM) could happen depending on what applications are actually
using it for. */
}
/* FIXME: Should we be marking the quota out of date, too? */
/* That's all for now! */
printf("NTFS partition %s was processed successfully.\n",
vol->dev_name);
/* Set return code to 0. */
i = 0;
final_exit:
if (m)
free(m);
if (m2)
free(m2);
if (vol && ntfs_umount(vol, 0))
ntfs_umount(vol, 1);
return i;
error_exit:
i = 1;
goto final_exit;
}