ntfs-3g/libntfs/mft.c

1546 lines
50 KiB
C
Raw Normal View History

whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
/*
* mft.c - Mft record handling code. Part of the Linux-NTFS project.
*
* Copyright (c) 2000-2004 Anton Altaparmakov
* Copyright (c) 2005 Yura Pakhuchiy
whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program/include file is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (in the main directory of the Linux-NTFS
* distribution in the file COPYING); if not, write to the Free Software
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#ifdef HAVE_STDLIB_H
whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
#include <stdlib.h>
#endif
#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif
#ifdef HAVE_ERRNO_H
whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
#include <errno.h>
#endif
#ifdef HAVE_STRING_H
whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
#include <string.h>
#endif
#include <time.h>
whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
2003-01-10 00:30:59 +08:00
#include "compat.h"
#include "types.h"
#include "device.h"
whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
#include "debug.h"
#include "bitmap.h"
#include "attrib.h"
#include "inode.h"
#include "volume.h"
#include "layout.h"
#include "lcnalloc.h"
#include "mft.h"
whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
/**
* ntfs_mft_records_read - read records from the mft from disk
whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
* @vol: volume to read from
* @mref: starting mft record number to read
* @count: number of mft records to read
* @b: output data buffer
*
* Read @count mft records starting at @mref from volume @vol into buffer
* @b. Return 0 on success or -1 on error, with errno set to the error
* code.
*
* If any of the records exceed the initialized size of the $MFT/$DATA
* attribute, i.e. they cannot possibly be allocated mft records, assume this
* is a bug and return error code ESPIPE.
*
whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
* The read mft records are mst deprotected and are hence ready to use. The
* caller should check each record with is_baad_record() in case mst
* deprotection failed.
*
* NOTE: @b has to be at least of size @count * vol->mft_record_size.
*/
int ntfs_mft_records_read(const ntfs_volume *vol, const MFT_REF mref,
whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
const s64 count, MFT_RECORD *b)
{
s64 br;
VCN m;
Dprintf("%s(): Entering for inode 0x%llx.\n", __FUNCTION__, MREF(mref));
whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
if (!vol || !vol->mft_na || !b || count < 0) {
errno = EINVAL;
return -1;
}
m = MREF(mref);
/* Refuse to read non-allocated mft records. */
if (m + count > vol->mft_na->initialized_size >>
vol->mft_record_size_bits) {
whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
errno = ESPIPE;
return -1;
}
br = ntfs_attr_mst_pread(vol->mft_na, m << vol->mft_record_size_bits,
count, vol->mft_record_size, b);
if (br != count) {
if (br != -1)
errno = EIO;
if (br >= 0)
Dputs("Error: partition is smaller than it should be!");
else
Dperror("Error reading $Mft record(s)");
return -1;
}
return 0;
}
/**
* ntfs_mft_records_write - write mft records to disk
whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
* @vol: volume to write to
* @mref: starting mft record number to write
* @count: number of mft records to write
* @b: data buffer containing the mft records to write
*
* Write @count mft records starting at @mref from data buffer @b to volume
* @vol. Return 0 on success or -1 on error, with errno set to the error code.
*
* If any of the records exceed the initialized size of the $MFT/$DATA
* attribute, i.e. they cannot possibly be allocated mft records, assume this
* is a bug and return error code ESPIPE.
*
whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
* Before the mft records are written, they are mst protected. After the write,
* they are deprotected again, thus resulting in an increase in the update
* sequence number inside the data buffer @b.
*
* If any mft records are written which are also represented in the mft mirror
* $MFTMirr, we make a copy of the relevant parts of the data buffer @b into a
* temporary buffer before we do the actual write. Then if at least one mft
* record was successfully written, we write the appropriate mft records from
* the copied buffer to the mft mirror, too.
*/
int ntfs_mft_records_write(const ntfs_volume *vol, const MFT_REF mref,
whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
const s64 count, MFT_RECORD *b)
{
s64 bw;
VCN m;
void *bmirr = NULL;
int cnt = 0, res = 0;
Dprintf("%s(): Entering for inode 0x%llx.\n", __FUNCTION__, MREF(mref));
if (!vol || !vol->mft_na || vol->mftmirr_size <= 0 || !b || count < 0) {
whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
errno = EINVAL;
return -1;
}
m = MREF(mref);
/* Refuse to write non-allocated mft records. */
if (m + count > vol->mft_na->initialized_size >>
vol->mft_record_size_bits) {
errno = ESPIPE;
return -1;
}
whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
if (m < vol->mftmirr_size) {
if (!vol->mftmirr_na) {
errno = EINVAL;
return -1;
}
whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
cnt = vol->mftmirr_size - m;
if (cnt > count)
cnt = count;
whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
bmirr = malloc(cnt * vol->mft_record_size);
if (!bmirr)
return -1;
memcpy(bmirr, b, cnt * vol->mft_record_size);
}
bw = ntfs_attr_mst_pwrite(vol->mft_na, m << vol->mft_record_size_bits,
count, vol->mft_record_size, b);
if (bw != count) {
if (bw != -1)
errno = EIO;
if (bw >= 0)
Dputs("Error: partial write while writing $Mft "
"record(s)!\n");
else
Dperror("Error writing $Mft record(s)");
res = errno;
}
if (bmirr && bw > 0) {
if (bw < cnt)
cnt = bw;
bw = ntfs_attr_mst_pwrite(vol->mftmirr_na,
m << vol->mft_record_size_bits, cnt,
vol->mft_record_size, bmirr);
if (bw != cnt) {
if (bw != -1)
errno = EIO;
Dputs("Error: failed to sync $MFTMirr! Run chkdsk.");
res = errno;
}
}
if (bmirr)
free(bmirr);
if (!res)
return res;
errno = res;
return -1;
}
/**
* ntfs_file_record_read - read a FILE record from the mft from disk
whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
* @vol: volume to read from
* @mref: mft reference specifying mft record to read
* @mrec: address of pointer in which to return the mft record
* @attr: address of pointer in which to return the first attribute
*
* Read a FILE record from the mft of @vol from the storage medium. @mref
* specifies the mft record to read, including the sequence number, which can
* be 0 if no sequence number checking is to be performed.
*
* The function allocates a buffer large enough to hold the mft record and
* reads the record into the buffer (mst deprotecting it in the process).
* *@mrec is then set to point to the buffer.
*
* If @attr is not NULL, *@attr is set to point to the first attribute in the
* mft record, i.e. *@attr is a pointer into *@mrec.
*
* Return 0 on success, or -1 on error, with errno set to the error code.
*
* The read mft record is checked for having the magic FILE,
* and for having a matching sequence number (if MSEQNO(*@mref) != 0).
* If either of these fails, -1 is returned and errno is set to EIO. If you get
* this, but you still want to read the mft record (e.g. in order to correct
* it), use ntfs_mft_record_read() directly.
whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
*
* Note: Caller has to free *@mrec when finished.
*
* Note: We do not check if the mft record is flagged in use. The caller can
* check if desired.
*/
int ntfs_file_record_read(const ntfs_volume *vol, const MFT_REF mref,
whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
MFT_RECORD **mrec, ATTR_RECORD **attr)
{
MFT_RECORD *m;
ATTR_RECORD *a;
int err;
if (!vol || !mrec) {
errno = EINVAL;
return -1;
}
m = *mrec;
if (!m) {
m = (MFT_RECORD*)malloc(vol->mft_record_size);
if (!m)
return -1;
}
if (ntfs_mft_record_read(vol, mref, m)) {
whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
err = errno;
goto read_failed;
}
if (!ntfs_is_file_record(m->magic))
whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
goto file_corrupt;
if (MSEQNO(mref) && MSEQNO(mref) != le16_to_cpu(m->sequence_number))
goto file_corrupt;
a = (ATTR_RECORD*)((char*)m + le16_to_cpu(m->attrs_offset));
if (p2n(a) < p2n(m) || (char*)a > (char*)m + vol->mft_record_size)
goto file_corrupt;
*mrec = m;
if (attr)
*attr = a;
return 0;
file_corrupt:
Dputs("ntfs_file_record_read(): file is corrupt.");
whitespace and include guards 2002/07/08 06:23:22-00:00 !antona Don't use string concatenation with __FUNCTION__ as gcc-3.x don't like it. 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/02 23:47:10-00:00 !antona Global replacement of __[su]{8,16,32,64} with [su]{8,16,32,64} and layout.h define it. 2002/06/08 14:12:01-00:00 !antona ntfs_readdir() has arrived. 2002/06/05 20:32:53-00:00 !antona Mft mirror now updated from ntfs_write_mft_record, yey! Fixup ntfstools accordingly. 2002/06/01 00:41:45-00:00 !antona huge update! 2002/04/27 19:49:09-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/24 23:47:42-00:00 !antona Hammer out the API for run list merging. Add calls for low level (using raw run lists and ATTR_RECORDs as parameters) run list merging, mappaing pairs decompression, and vcn to lcn conversion as well as high level (using ntfs_attr as parameter) calls for run list mapping and vcn to lcn conversion. 2002/04/22 10:34:31-00:00 !antona Attribute list support (merging done, part 2, some stuff still incomplete). mkntfs ntfs volume creation. See the changelog... 2002/04/20 23:09:42-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:02-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/16 12:13:53-00:00 !antona New API function mft.[ch]::read_file_record(). Also some cleanups. 2002/04/15 20:04:27-00:00 !antona Fix all compiler warnings that came up with -Wall. Enabled -Wall for ./configure --enable-debug everywhere. Fix a few bugs in mkntfs that came up in the warnings (just error code paths, nothing major). 2002/04/15 19:02:40-00:00 !antona Really fix the library and mkntfs while at it. 2002/04/15 18:54:07-00:00 !antona Update library for the new API. 2002/04/15 18:39:37-00:00 !antona Cleanup some mistakes. 2002/04/15 17:51:26-00:00 !antona read/write_mft_record(s) are here 2002/04/15 00:42:07-00:00 !antona Big rewrite of disk_io.c. Now should have stable API for low level disk access. Move all mft record related stuff from disk_io.c to mft.c. 2002/04/14 14:08:30-00:00 !antona Cleanup library code. Throw away unused stuff. 2002/04/14 13:34:49-00:00 !antona Throw away all unnecessary crap. 2001/12/15 05:13:08-00:00 !antona Remove atomic ops and add compiler version check. 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 14:29:12-00:00 !antona Almost fixed compilaton. Remember to declare a struct type with struct NAME { declaration }; rather than the bogus struct { declaration NAME }; then can use typedef NAME othername; on a forward declaration of NAME (struct NAME;) and all is fine... 2001/04/11 11:49:16-00:00 !antona Header file reorganisation so that it compiles. 2001/04/10 23:37:19-00:00 !antona Ok, ntfsd was a mistake for userspace. It increases complexity no end while not giving us much functionality. Lets get it working and then worry about the kernel. - As it was the idea originally anyway, so this is just a return on the right track. (-8 We keep the timer and signal handler but the only thing we do is to set a bool flag (ntfs_need_sync) and we will just check this in appropriate places and if it is true we call ntfs_sync_volumes() which sets it back to false. This means no more locking at all of any description and no need to worry about the signal handler interrupting things in bad ways and/or at bad times in the main code. 2001/04/09 00:05:37-00:00 !antona More or less finished file handling. (Probably some useful functions are still missing but they will be implemented as need arises.) One thing that is stupid at the moment is we don't limit the amount of cached mft_records so if you were to load loads the machine would eventually run out of memory... Can't happen with files as they are limited to 1000, unless you are short of memory. (Hard limit at the moment, set in ntfs_mount(). Maybe ntfsd should be monitoring memory usage and be throwing out unused cache entries and closed_files? That would mean to have locking everywhere, though.) Still missing: - Convert old code to use new stuff. - Add non-resident attributes somewhere. Either into the mft_entry structure or into the ntfs_file structure, but which? At the moment I tend to mft_entry so they can be synced together with the entries by ntfsd. 2001/04/08 01:58:29-00:00 !antona User space conversion of locking complete. I settled for using simple spinlocks and atomic variables and instead of deadlocking/livelocking when using spin_lock(), use spin_trylock() in a while letting go of the cpu between each call and making a maximum of 100 iterations (or we return EDEADLK error code). This is not the most efficient way, especially as can't have multiple readers but it is the simplest way to go about things. Should now have (almost) all required helper functions for dealing with mft entries implemented. Now need the file handling and then convert the whole project to use the new code and then can finally get back to work on attribute searching... 2001/04/05 20:14:45-00:00 !antona Commit of current state of development including locking a la kernel. This doesn't work on user space (semaphores don't work). Just want to have it committed. Will take out locking / modify it where necessary to use pthreads ASAP. 2001/04/03 23:38:34-00:00 !antona Mark mft entry dirty function complete 2001/03/05 03:04:40-00:00 !antona Corresponding changes to the library. 2001/01/25 22:25:43-00:00 !antona More files added to ntfs lib. Fixed some consistency problems. (Logical change 1.5)
2002-08-23 02:09:47 +08:00
err = EIO;
read_failed:
if (m != *mrec)
free(m);
errno = err;
return -1;
}
/**
* ntfs_mft_record_layout - layout an mft record into a memory buffer
* @vol: volume to which the mft record will belong
* @mref: mft reference specifying the mft record number
* @m: destination buffer of size >= @vol->mft_record_size bytes
*
* Layout an empty, unused mft record with the mft reference @mref into the
* buffer @m. The volume @vol is needed because the mft record structure was
* modified in NTFS 3.1 so we need to know which volume version this mft record
* will be used on.
*
* On success return 0 and on error return -1 with errno set to the error code.
*/
int ntfs_mft_record_layout(const ntfs_volume *vol, const MFT_REF mref,
MFT_RECORD *m)
{
ATTR_RECORD *a;
if (!vol || !m) {
errno = EINVAL;
return -1;
}
/* Aligned to 2-byte boundary. */
if (vol->major_ver < 3 || (vol->major_ver == 3 && !vol->minor_ver))
m->usa_ofs = cpu_to_le16((sizeof(MFT_RECORD_OLD) + 1) & ~1);
else {
/* Abort if mref is > 32 bits. */
if (MREF(mref) & 0x0000ffff00000000ull) {
Dputs("Mft reference exceeds 32 bits!");
errno = ERANGE;
return -1;
}
m->usa_ofs = cpu_to_le16((sizeof(MFT_RECORD) + 1) & ~1);
/*
* Set the NTFS 3.1+ specific fields while we know that the
* volume version is 3.1+.
*/
m->reserved = cpu_to_le16(0);
m->mft_record_number = cpu_to_le32(MREF(mref));
}
m->magic = magic_FILE;
if (vol->mft_record_size >= NTFS_BLOCK_SIZE)
m->usa_count = cpu_to_le16(vol->mft_record_size /
NTFS_BLOCK_SIZE + 1);
else {
m->usa_count = cpu_to_le16(1);
Dprintf("Sector size is bigger than MFT record size. "
"Setting usa_count to 1. If Windows\nchkdsk "
"reports this as corruption, please email "
"linux-ntfs-dev@lists.sf.net\nstating that "
"you saw this message and that the file "
"system created was corrupt.\nThank you.\n");
}
/* Set the update sequence number to 1. */
*(u16*)((u8*)m + le16_to_cpu(m->usa_ofs)) = cpu_to_le16(1);
m->lsn = cpu_to_le64(0ull);
m->sequence_number = cpu_to_le16(1);
m->link_count = cpu_to_le16(0);
/* Aligned to 8-byte boundary. */
m->attrs_offset = cpu_to_le16((le16_to_cpu(m->usa_ofs) +
(le16_to_cpu(m->usa_count) << 1) + 7) & ~7);
m->flags = cpu_to_le16(0);
/*
* Using attrs_offset plus eight bytes (for the termination attribute),
* aligned to 8-byte boundary.
*/
m->bytes_in_use = cpu_to_le32((le16_to_cpu(m->attrs_offset) + 8 + 7) &
~7);
m->bytes_allocated = cpu_to_le32(vol->mft_record_size);
m->base_mft_record = cpu_to_le64((MFT_REF)0);
m->next_attr_instance = cpu_to_le16(0);
a = (ATTR_RECORD*)((u8*)m + le16_to_cpu(m->attrs_offset));
a->type = AT_END;
a->length = cpu_to_le32(0);
/* Finally, clear the unused part of the mft record. */
memset((u8*)a + 8, 0, vol->mft_record_size - ((u8*)a + 8 - (u8*)m));
return 0;
}
/**
* ntfs_mft_record_format - format an mft record on an ntfs volume
* @vol: volume on which to format the mft record
* @mref: mft reference specifying mft record to format
*
* Format the mft record with the mft reference @mref in $MFT/$DATA, i.e. lay
* out an empty, unused mft record in memory and write it to the volume @vol.
*
* On success return 0 and on error return -1 with errno set to the error code.
*/
int ntfs_mft_record_format(const ntfs_volume *vol, const MFT_REF mref)
{
MFT_RECORD *m;
int err;
if (!vol || !vol->mft_na) {
errno = EINVAL;
return -1;
}
m = malloc(vol->mft_record_size);
if (!m)
return -1;
if (ntfs_mft_record_layout(vol, mref, m)) {
err = errno;
free(m);
errno = err;
return -1;
}
if (ntfs_mft_record_write(vol, mref, m)) {
err = errno;
free(m);
errno = err;
return -1;
}
free(m);
return 0;
}
#ifdef DEBUG
static const char *es = " Leaving inconsistent metadata. Run chkdsk.";
#endif
static inline unsigned int ntfs_ffz(unsigned int word)
{
return ffs(~word) - 1;
}
#ifndef PAGE_SIZE
#define PAGE_SIZE 4096
#endif
/**
* ntfs_mft_bitmap_find_free_rec - find a free mft record in the mft bitmap
* @vol: volume on which to search for a free mft record
* @base_ni: open base inode if allocating an extent mft record or NULL
*
* Search for a free mft record in the mft bitmap attribute on the ntfs volume
* @vol.
*
* If @base_ni is NULL start the search at the default allocator position.
*
* If @base_ni is not NULL start the search at the mft record after the base
* mft record @base_ni.
*
* Return the free mft record on success and -1 on error with errno set to the
* error code. An error code of ENOSPC means that there are no free mft
2005-07-07 06:47:01 +08:00
* records in the currently initialized mft bitmap.
*/
static int ntfs_mft_bitmap_find_free_rec(ntfs_volume *vol, ntfs_inode *base_ni)
{
s64 pass_end, ll, data_pos, pass_start, ofs, bit;
ntfs_attr *mftbmp_na;
u8 *buf, *byte;
unsigned int size;
u8 pass, b;
mftbmp_na = vol->mftbmp_na;
/*
* Set the end of the pass making sure we do not overflow the mft
* bitmap.
*/
size = PAGE_SIZE;
pass_end = vol->mft_na->allocated_size >> vol->mft_record_size_bits;
ll = mftbmp_na->initialized_size << 3;
if (pass_end > ll)
pass_end = ll;
pass = 1;
if (!base_ni)
data_pos = vol->mft_data_pos;
else
data_pos = base_ni->mft_no + 1;
if (data_pos < 24)
data_pos = 24;
if (data_pos >= pass_end) {
data_pos = 24;
pass = 2;
/* This happens on a freshly formatted volume. */
if (data_pos >= pass_end) {
errno = ENOSPC;
return -1;
}
}
pass_start = data_pos;
buf = (u8*)malloc(PAGE_SIZE);
if (!buf)
return -1;
ntfs_debug("Starting bitmap search: pass %u, pass_start 0x%llx, "
"pass_end 0x%llx, data_pos 0x%llx.", pass,
(long long)pass_start, (long long)pass_end,
(long long)data_pos);
#ifdef DEBUG
byte = NULL;
b = 0;
#endif
/* Loop until a free mft record is found. */
for (; pass <= 2; size = PAGE_SIZE) {
/* Cap size to pass_end. */
ofs = data_pos >> 3;
ll = ((pass_end + 7) >> 3) - ofs;
if (size > ll)
size = ll;
ll = ntfs_attr_pread(mftbmp_na, ofs, size, buf);
if (ll < 0) {
ntfs_error(vol->sb, "Failed to read mft bitmap "
"attribute, aborting.");
free(buf);
return -1;
}
ntfs_debug("Read 0x%llx bytes.", (long long)ll);
/* If we read at least one byte, search @buf for a zero bit. */
if (ll) {
size = ll << 3;
bit = data_pos & 7;
data_pos &= ~7ull;
ntfs_debug("Before inner for loop: size 0x%x, "
"data_pos 0x%llx, bit 0x%llx, "
"*byte 0x%hhx, b %u.", size,
(long long)data_pos, (long long)bit,
byte ? *byte : -1, b);
for (; bit < size && data_pos + bit < pass_end;
bit &= ~7ull, bit += 8) {
byte = buf + (bit >> 3);
if (*byte == 0xff)
continue;
/* Note: ffz() result must be zero based. */
b = ntfs_ffz((unsigned long)*byte);
if (b < 8 && b >= (bit & 7)) {
free(buf);
return data_pos + (bit & ~7ull) + b;
}
}
ntfs_debug("After inner for loop: size 0x%x, "
"data_pos 0x%llx, bit 0x%llx, "
"*byte 0x%hhx, b %u.", size,
(long long)data_pos, (long long)bit,
byte ? *byte : -1, b);
data_pos += size;
/*
* If the end of the pass has not been reached yet,
* continue searching the mft bitmap for a zero bit.
*/
if (data_pos < pass_end)
continue;
}
/* Do the next pass. */
pass++;
if (pass == 2) {
/*
* Starting the second pass, in which we scan the first
* part of the zone which we omitted earlier.
*/
pass_end = pass_start;
data_pos = pass_start = 24;
ntfs_debug("pass %i, pass_start 0x%llx, pass_end "
"0x%llx.", pass, (long long)pass_start,
(long long)pass_end);
if (data_pos >= pass_end)
break;
}
}
/* No free mft records in currently initialized mft bitmap. */
free(buf);
errno = ENOSPC;
return -1;
}
/**
* ntfs_mft_bitmap_extend_allocation - extend mft bitmap attribute by a cluster
* @vol: volume on which to extend the mft bitmap attribute
*
* Extend the mft bitmap attribute on the ntfs volume @vol by one cluster.
*
* Note: Only changes allocated_size, i.e. does not touch initialized_size or
* data_size.
*
* Return 0 on success and -1 on error with errno set to the error code.
*/
static int ntfs_mft_bitmap_extend_allocation(ntfs_volume *vol)
{
LCN lcn;
s64 ll = 0; /* silence compiler warning */
ntfs_attr *mftbmp_na, *lcnbmp_na;
runlist_element *rl, *rl2 = NULL; /* silence compiler warning */
ntfs_attr_search_ctx *ctx;
MFT_RECORD *m = NULL; /* silence compiler warning */
ATTR_RECORD *a = NULL; /* silence compiler warning */
int ret, mp_size;
u32 old_alen = 0; /* silence compiler warning */
u8 b, tb;
struct {
u8 added_cluster:1;
u8 added_run:1;
u8 mp_rebuilt:1;
} status = { 0, 0, 0 };
mftbmp_na = vol->mftbmp_na;
lcnbmp_na = vol->lcnbmp_na;
/*
* Determine the last lcn of the mft bitmap. The allocated size of the
* mft bitmap cannot be zero so we are ok to do this.
*/
rl = ntfs_attr_find_vcn(mftbmp_na, (mftbmp_na->allocated_size - 1) >>
vol->cluster_size_bits);
if (!rl || !rl->length || rl->lcn < 0) {
ntfs_error(vol->sb, "Failed to determine last allocated "
"cluster of mft bitmap attribute.");
if (rl)
errno = EIO;
return -1;
}
lcn = rl->lcn + rl->length;
/*
* Attempt to get the cluster following the last allocated cluster by
* hand as it may be in the MFT zone so the allocator would not give it
* to us.
*/
ret = (int)ntfs_attr_pread(lcnbmp_na, lcn >> 3, 1, &b);
if (ret < 0) {
ntfs_error(vol->sb, "Failed to read from lcn bitmap.");
return -1;
}
ntfs_debug("Read %i byte%s.", ret, ret == 1 ? "" : "s");
tb = 1 << (lcn & 7ull);
if (ret == 1 && b != 0xff && !(b & tb)) {
/* Next cluster is free, allocate it. */
b |= tb;
ret = (int)ntfs_attr_pwrite(lcnbmp_na, lcn >> 3, 1, &b);
if (ret < 1) {
ntfs_error(vol->sb, "Failed to write to lcn "
"bitmap.");
if (!ret)
errno = EIO;
return -1;
}
/* Update the mft bitmap runlist. */
rl->length++;
rl[1].vcn++;
status.added_cluster = 1;
ntfs_debug("Appending one cluster to mft bitmap.");
} else {
/* Allocate a cluster from the DATA_ZONE. */
rl2 = ntfs_cluster_alloc(vol, rl[1].vcn, 1, lcn, DATA_ZONE);
if (!rl2) {
ntfs_error(vol->sb, "Failed to allocate a cluster for "
"the mft bitmap.");
return -1;
}
rl = ntfs_runlists_merge(mftbmp_na->rl, rl2);
if (!rl) {
ret = errno;
ntfs_error(vol->sb, "Failed to merge runlists for mft "
"bitmap.");
if (ntfs_cluster_free_from_rl(vol, rl2))
2005-07-07 06:47:01 +08:00
ntfs_error(vol->sb, "Failed to deallocate "
"cluster.%s", es);
free(rl2);
errno = ret;
return -1;
}
mftbmp_na->rl = rl;
status.added_run = 1;
ntfs_debug("Adding one run to mft bitmap.");
/* Find the last run in the new runlist. */
for (; rl[1].length; rl++)
;
}
/*
* Update the attribute record as well. Note: @rl is the last
* (non-terminator) runlist element of mft bitmap.
*/
ctx = ntfs_attr_get_search_ctx(mftbmp_na->ni, NULL);
if (!ctx) {
ntfs_error(vol->sb, "Failed to get search context.");
goto undo_alloc;
}
if (ntfs_attr_lookup(mftbmp_na->type, mftbmp_na->name,
mftbmp_na->name_len, 0, rl[1].vcn, NULL, 0, ctx)) {
ntfs_error(vol->sb, "Failed to find last attribute extent of "
"mft bitmap attribute.");
goto undo_alloc;
}
m = ctx->mrec;
a = ctx->attr;
ll = sle64_to_cpu(a->lowest_vcn);
rl2 = ntfs_attr_find_vcn(mftbmp_na, ll);
if (!rl2 || !rl2->length) {
ntfs_error(vol->sb, "Failed to determine previous last "
"allocated cluster of mft bitmap attribute.");
if (rl2)
errno = EIO;
goto undo_alloc;
}
/* Get the size for the new mapping pairs array for this extent. */
mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll);
if (mp_size <= 0) {
ntfs_error(vol->sb, "Get size for mapping pairs failed for "
"mft bitmap attribute extent.");
goto undo_alloc;
}
/* Expand the attribute record if necessary. */
old_alen = le32_to_cpu(a->length);
if (ntfs_attr_record_resize(m, a, mp_size +
le16_to_cpu(a->mapping_pairs_offset))) {
if (errno != ENOSPC) {
ntfs_error(vol->sb, "Failed to resize attribute "
"record for mft bitmap attribute.");
goto undo_alloc;
}
// TODO: Deal with this by moving this extent to a new mft
// record or by starting a new extent in a new mft record.
ntfs_error(vol->sb, "Not enough space in this mft record to "
2005-07-07 06:47:01 +08:00
"accommodate extended mft bitmap attribute "
"extent. Cannot handle this yet.");
errno = EOPNOTSUPP;
goto undo_alloc;
}
status.mp_rebuilt = 1;
/* Generate the mapping pairs array directly into the attr record. */
if (ntfs_mapping_pairs_build(vol, (u8*)a +
le16_to_cpu(a->mapping_pairs_offset), mp_size, rl2, ll,
NULL)) {
ntfs_error(vol->sb, "Failed to build mapping pairs array for "
"mft bitmap attribute.");
errno = EIO;
goto undo_alloc;
}
/* Update the highest_vcn. */
a->highest_vcn = cpu_to_sle64(rl[1].vcn - 1);
/*
* We now have extended the mft bitmap allocated_size by one cluster.
* Reflect this in the ntfs_attr structure and the attribute record.
*/
if (a->lowest_vcn) {
/*
* We are not in the first attribute extent, switch to it, but
* first ensure the changes will make it to disk later.
*/
ntfs_inode_mark_dirty(ctx->ntfs_ino);
ntfs_attr_reinit_search_ctx(ctx);
if (ntfs_attr_lookup(mftbmp_na->type, mftbmp_na->name,
mftbmp_na->name_len, 0, 0, NULL, 0, ctx)) {
ntfs_error(vol->sb, "Failed to find first attribute "
"extent of mft bitmap attribute.");
goto restore_undo_alloc;
}
a = ctx->attr;
}
mftbmp_na->allocated_size += vol->cluster_size;
a->allocated_size = cpu_to_sle64(mftbmp_na->allocated_size);
/* Ensure the changes make it to disk. */
ntfs_inode_mark_dirty(ctx->ntfs_ino);
ntfs_attr_put_search_ctx(ctx);
return 0;
restore_undo_alloc:
ret = errno;
ntfs_attr_reinit_search_ctx(ctx);
if (ntfs_attr_lookup(mftbmp_na->type, mftbmp_na->name,
mftbmp_na->name_len, 0, rl[1].vcn, NULL, 0, ctx)) {
ntfs_error(vol->sb, "Failed to find last attribute extent of "
"mft bitmap attribute.%s", es);
ntfs_attr_put_search_ctx(ctx);
mftbmp_na->allocated_size += vol->cluster_size;
/*
* The only thing that is now wrong is ->allocated_size of the
* base attribute extent which chkdsk should be able to fix.
*/
errno = ret;
return -1;
}
m = ctx->mrec;
a = ctx->attr;
a->highest_vcn = cpu_to_sle64(rl[1].vcn - 2);
errno = ret;
undo_alloc:
ret = errno;
if (status.added_cluster) {
/* Truncate the last run in the runlist by one cluster. */
rl->length--;
rl[1].vcn--;
} else if (status.added_run) {
lcn = rl->lcn;
/* Remove the last run from the runlist. */
rl->lcn = rl[1].lcn;
rl->length = 0;
}
/* Deallocate the cluster. */
if (ntfs_bitmap_clear_bit(lcnbmp_na, lcn))
ntfs_error(vol->sb, "Failed to free cluster.%s", es);
if (status.mp_rebuilt) {
if (ntfs_mapping_pairs_build(vol, (u8*)a +
le16_to_cpu(a->mapping_pairs_offset),
old_alen - le16_to_cpu(a->mapping_pairs_offset),
rl2, ll, NULL))
ntfs_error(vol->sb, "Failed to restore mapping "
"pairs array.%s", es);
if (ntfs_attr_record_resize(m, a, old_alen))
ntfs_error(vol->sb, "Failed to restore attribute "
"record.%s",
es);
ntfs_inode_mark_dirty(ctx->ntfs_ino);
}
if (ctx)
ntfs_attr_put_search_ctx(ctx);
errno = ret;
return -1;
}
/**
* ntfs_mft_bitmap_extend_initialized - extend mft bitmap initialized data
* @vol: volume on which to extend the mft bitmap attribute
*
* Extend the initialized portion of the mft bitmap attribute on the ntfs
* volume @vol by 8 bytes.
*
* Note: Only changes initialized_size and data_size, i.e. requires that
* allocated_size is big enough to fit the new initialized_size.
*
* Return 0 on success and -1 on error with errno set to the error code.
*/
static int ntfs_mft_bitmap_extend_initialized(ntfs_volume *vol)
{
s64 old_data_size, old_initialized_size, ll;
ntfs_attr *mftbmp_na;
ntfs_attr_search_ctx *ctx;
ATTR_RECORD *a;
int err;
mftbmp_na = vol->mftbmp_na;
ctx = ntfs_attr_get_search_ctx(mftbmp_na->ni, NULL);
if (!ctx) {
ntfs_error(vol->sb, "Failed to get search context.");
return -1;
}
if (ntfs_attr_lookup(mftbmp_na->type, mftbmp_na->name,
mftbmp_na->name_len, 0, 0, NULL, 0, ctx)) {
ntfs_error(vol->sb, "Failed to find first attribute extent of "
"mft bitmap attribute.");
err = errno;
goto put_err_out;
}
a = ctx->attr;
old_data_size = mftbmp_na->data_size;
old_initialized_size = mftbmp_na->initialized_size;
mftbmp_na->initialized_size += 8;
a->initialized_size = cpu_to_sle64(mftbmp_na->initialized_size);
if (mftbmp_na->initialized_size > mftbmp_na->data_size) {
mftbmp_na->data_size = mftbmp_na->initialized_size;
a->data_size = cpu_to_sle64(mftbmp_na->data_size);
}
/* Ensure the changes make it to disk. */
ntfs_inode_mark_dirty(ctx->ntfs_ino);
ntfs_attr_put_search_ctx(ctx);
/* Initialize the mft bitmap attribute value with zeroes. */
ll = 0;
ll = ntfs_attr_pwrite(mftbmp_na, old_initialized_size, 8, &ll);
if (ll == 8) {
ntfs_debug("Wrote eight initialized bytes to mft bitmap.");
return 0;
}
ntfs_error(vol->sb, "Failed to write to mft bitmap.");
err = errno;
if (ll >= 0)
err = EIO;
/* Try to recover from the error. */
ctx = ntfs_attr_get_search_ctx(mftbmp_na->ni, NULL);
if (!ctx) {
ntfs_error(vol->sb, "Failed to get search context.%s", es);
goto err_out;
}
if (ntfs_attr_lookup(mftbmp_na->type, mftbmp_na->name,
mftbmp_na->name_len, 0, 0, NULL, 0, ctx)) {
ntfs_error(vol->sb, "Failed to find first attribute extent of "
"mft bitmap attribute.%s", es);
put_err_out:
ntfs_attr_put_search_ctx(ctx);
goto err_out;
}
a = ctx->attr;
mftbmp_na->initialized_size = old_initialized_size;
a->initialized_size = cpu_to_sle64(old_initialized_size);
if (mftbmp_na->data_size != old_data_size) {
mftbmp_na->data_size = old_data_size;
a->data_size = cpu_to_sle64(old_data_size);
}
ntfs_inode_mark_dirty(ctx->ntfs_ino);
ntfs_attr_put_search_ctx(ctx);
ntfs_debug("Restored status of mftbmp: allocated_size 0x%llx, "
"data_size 0x%llx, initialized_size 0x%llx.",
(long long)mftbmp_na->allocated_size,
(long long)mftbmp_na->data_size,
(long long)mftbmp_na->initialized_size);
err_out:
errno = err;
return -1;
}
/**
* ntfs_mft_data_extend_allocation - extend mft data attribute
* @vol: volume on which to extend the mft data attribute
*
* Extend the mft data attribute on the ntfs volume @vol by 16 mft records
* worth of clusters or if not enough space for this by one mft record worth
* of clusters.
*
* Note: Only changes allocated_size, i.e. does not touch initialized_size or
* data_size.
*
* Return 0 on success and -1 on error with errno set to the error code.
*/
static int ntfs_mft_data_extend_allocation(ntfs_volume *vol)
{
LCN lcn;
VCN old_last_vcn;
s64 min_nr, nr, ll = 0; /* silence compiler warning */
ntfs_attr *mft_na;
runlist_element *rl, *rl2;
ntfs_attr_search_ctx *ctx;
MFT_RECORD *m = NULL; /* silence compiler warning */
ATTR_RECORD *a = NULL; /* silence compiler warning */
int err, mp_size;
u32 old_alen = 0; /* silence compiler warning */
BOOL mp_rebuilt = FALSE;
ntfs_debug("Extending mft data allocation.");
mft_na = vol->mft_na;
/*
* Determine the preferred allocation location, i.e. the last lcn of
* the mft data attribute. The allocated size of the mft data
* attribute cannot be zero so we are ok to do this.
*/
rl = ntfs_attr_find_vcn(mft_na,
(mft_na->allocated_size - 1) >> vol->cluster_size_bits);
if (!rl || !rl->length || rl->lcn < 0) {
ntfs_error(vol->sb, "Failed to determine last allocated "
"cluster of mft data attribute.");
if (rl)
errno = EIO;
return -1;
}
lcn = rl->lcn + rl->length;
ntfs_debug("Last lcn of mft data attribute is 0x%llx.", (long long)lcn);
/* Minimum allocation is one mft record worth of clusters. */
min_nr = vol->mft_record_size >> vol->cluster_size_bits;
if (!min_nr)
min_nr = 1;
/* Want to allocate 16 mft records worth of clusters. */
nr = vol->mft_record_size << 4 >> vol->cluster_size_bits;
if (!nr)
nr = min_nr;
ntfs_debug("Trying mft data allocation with default cluster count "
"%lli.", (long long)nr);
old_last_vcn = rl[1].vcn;
do {
rl2 = ntfs_cluster_alloc(vol, old_last_vcn, nr, lcn, MFT_ZONE);
if (rl2)
break;
if (errno != ENOSPC || nr == min_nr) {
ntfs_error(vol->sb, "Failed to allocate the minimal "
"number of clusters (%lli) for the "
"mft data attribute.", (long long)nr);
return -1;
}
/*
* There is not enough space to do the allocation, but there
* might be enough space to do a minimal allocation so try that
* before failing.
*/
nr = min_nr;
ntfs_debug("Retrying mft data allocation with minimal cluster "
"count %lli.", (long long)nr);
} while (1);
rl = ntfs_runlists_merge(mft_na->rl, rl2);
if (!rl) {
err = errno;
ntfs_error(vol->sb, "Failed to merge runlists for mft data "
"attribute.");
if (ntfs_cluster_free_from_rl(vol, rl2))
2005-07-07 06:47:01 +08:00
ntfs_error(vol->sb, "Failed to deallocate clusters "
"from the mft data attribute.%s", es);
free(rl2);
errno = err;
return -1;
}
mft_na->rl = rl;
ntfs_debug("Allocated %lli clusters.", nr);
/* Find the last run in the new runlist. */
for (; rl[1].length; rl++)
;
/* Update the attribute record as well. */
ctx = ntfs_attr_get_search_ctx(mft_na->ni, NULL);
if (!ctx) {
ntfs_error(vol->sb, "Failed to get search context.");
goto undo_alloc;
}
if (ntfs_attr_lookup(mft_na->type, mft_na->name, mft_na->name_len, 0,
rl[1].vcn, NULL, 0, ctx)) {
ntfs_error(vol->sb, "Failed to find last attribute extent of "
"mft data attribute.");
goto undo_alloc;
}
m = ctx->mrec;
a = ctx->attr;
ll = sle64_to_cpu(a->lowest_vcn);
rl2 = ntfs_attr_find_vcn(mft_na, ll);
if (!rl2 || !rl2->length) {
ntfs_error(vol->sb, "Failed to determine previous last "
"allocated cluster of mft data attribute.");
if (rl2)
errno = EIO;
goto undo_alloc;
}
/* Get the size for the new mapping pairs array for this extent. */
mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll);
if (mp_size <= 0) {
ntfs_error(vol->sb, "Get size for mapping pairs failed for "
"mft data attribute extent.");
goto undo_alloc;
}
/* Expand the attribute record if necessary. */
old_alen = le32_to_cpu(a->length);
if (ntfs_attr_record_resize(m, a,
mp_size + le16_to_cpu(a->mapping_pairs_offset))) {
if (errno != ENOSPC) {
ntfs_error(vol->sb, "Failed to resize attribute "
"record for mft data attribute.");
goto undo_alloc;
}
// TODO: Deal with this by moving this extent to a new mft
// record or by starting a new extent in a new mft record.
// Note: Use the special reserved mft records and ensure that
// this extent is not required to find the mft record in
// question.
ntfs_error(vol->sb, "Not enough space in this mft record to "
2005-07-07 06:47:01 +08:00
"accommodate extended mft data attribute "
"extent. Cannot handle this yet.");
errno = EOPNOTSUPP;
goto undo_alloc;
}
mp_rebuilt = TRUE;
/*
* Generate the mapping pairs array directly into the attribute record.
*/
if (ntfs_mapping_pairs_build(vol,
(u8*)a + le16_to_cpu(a->mapping_pairs_offset), mp_size,
rl2, ll, NULL)) {
ntfs_error(vol->sb, "Failed to build mapping pairs array of "
"mft data attribute.");
errno = EIO;
goto undo_alloc;
}
/* Update the highest_vcn. */
a->highest_vcn = cpu_to_sle64(rl[1].vcn - 1);
/*
* We now have extended the mft data allocated_size by nr clusters.
* Reflect this in the ntfs_attr structure and the attribute record.
* @rl is the last (non-terminator) runlist element of mft data
* attribute.
*/
if (a->lowest_vcn) {
/*
* We are not in the first attribute extent, switch to it, but
* first ensure the changes will make it to disk later.
*/
ntfs_inode_mark_dirty(ctx->ntfs_ino);
ntfs_attr_reinit_search_ctx(ctx);
if (ntfs_attr_lookup(mft_na->type, mft_na->name,
mft_na->name_len, 0, 0, NULL, 0, ctx)) {
ntfs_error(vol->sb, "Failed to find first attribute "
"extent of mft data attribute.");
goto restore_undo_alloc;
}
a = ctx->attr;
}
mft_na->allocated_size += nr << vol->cluster_size_bits;
a->allocated_size = cpu_to_sle64(mft_na->allocated_size);
/* Ensure the changes make it to disk. */
ntfs_inode_mark_dirty(ctx->ntfs_ino);
ntfs_attr_put_search_ctx(ctx);
return 0;
restore_undo_alloc:
err = errno;
ntfs_attr_reinit_search_ctx(ctx);
if (ntfs_attr_lookup(mft_na->type, mft_na->name, mft_na->name_len, 0,
rl[1].vcn, NULL, 0, ctx)) {
ntfs_error(vol->sb, "Failed to find last attribute extent of "
"mft data attribute.%s", es);
ntfs_attr_put_search_ctx(ctx);
mft_na->allocated_size += nr << vol->cluster_size_bits;
/*
* The only thing that is now wrong is ->allocated_size of the
* base attribute extent which chkdsk should be able to fix.
*/
errno = err;
return -1;
}
m = ctx->mrec;
a = ctx->attr;
a->highest_vcn = cpu_to_sle64(old_last_vcn - 1);
errno = err;
undo_alloc:
err = errno;
if (ntfs_cluster_free(vol, mft_na, old_last_vcn, -1) < 0)
ntfs_error(vol->sb, "Failed to free clusters from mft data "
"attribute.%s", es);
if (ntfs_rl_truncate(&mft_na->rl, old_last_vcn))
ntfs_error(vol->sb, "Failed to truncate mft data attribute "
"runlist.%s", es);
if (mp_rebuilt) {
if (ntfs_mapping_pairs_build(vol, (u8*)a +
le16_to_cpu(a->mapping_pairs_offset),
old_alen - le16_to_cpu(a->mapping_pairs_offset),
rl2, ll, NULL))
ntfs_error(vol->sb, "Failed to restore mapping pairs "
"array.%s", es);
if (ntfs_attr_record_resize(m, a, old_alen))
ntfs_error(vol->sb, "Failed to restore attribute "
"record.%s", es);
ntfs_inode_mark_dirty(ctx->ntfs_ino);
}
if (ctx)
ntfs_attr_put_search_ctx(ctx);
errno = err;
return -1;
}
/**
* ntfs_mft_record_alloc - allocate an mft record on an ntfs volume
* @vol: volume on which to allocate the mft record
* @base_ni: open base inode if allocating an extent mft record or NULL
*
* Allocate an mft record in $MFT/$DATA of an open ntfs volume @vol.
*
* If @base_ni is NULL make the mft record a base mft record and allocate it at
* the default allocator position.
*
* If @base_ni is not NULL make the allocated mft record an extent record,
* allocate it starting at the mft record after the base mft record and attach
* the allocated and opened ntfs inode to the base inode @base_ni.
*
* On success return the now opened ntfs (extent) inode of the mft record.
*
* On error return NULL with errno set to the error code.
*
* To find a free mft record, we scan the mft bitmap for a zero bit. To
* optimize this we start scanning at the place specified by @base_ni or if
* @base_ni is NULL we start where we last stopped and we perform wrap around
* when we reach the end. Note, we do not try to allocate mft records below
* number 24 because numbers 0 to 15 are the defined system files anyway and 16
* to 24 are special in that they are used for storing extension mft records
* for the $DATA attribute of $MFT. This is required to avoid the possibility
* of creating a run list with a circular dependence which once written to disk
* can never be read in again. Windows will only use records 16 to 24 for
* normal files if the volume is completely out of space. We never use them
* which means that when the volume is really out of space we cannot create any
* more files while Windows can still create up to 8 small files. We can start
* doing this at some later time, it does not matter much for now.
*
* When scanning the mft bitmap, we only search up to the last allocated mft
* record. If there are no free records left in the range 24 to number of
* allocated mft records, then we extend the $MFT/$DATA attribute in order to
* create free mft records. We extend the allocated size of $MFT/$DATA by 16
* records at a time or one cluster, if cluster size is above 16kiB. If there
* is not sufficient space to do this, we try to extend by a single mft record
* or one cluster, if cluster size is above the mft record size, but we only do
* this if there is enough free space, which we know from the values returned
* by the failed cluster allocation function when we tried to do the first
* allocation.
*
* No matter how many mft records we allocate, we initialize only the first
* allocated mft record, incrementing mft data size and initialized size
* accordingly, open an ntfs_inode for it and return it to the caller, unless
* there are less than 24 mft records, in which case we allocate and initialize
* mft records until we reach record 24 which we consider as the first free mft
* record for use by normal files.
*
* If during any stage we overflow the initialized data in the mft bitmap, we
* extend the initialized size (and data size) by 8 bytes, allocating another
* cluster if required. The bitmap data size has to be at least equal to the
* number of mft records in the mft, but it can be bigger, in which case the
2005-07-07 06:47:01 +08:00
* superfluous bits are padded with zeroes.
*
* Thus, when we return successfully (return value non-zero), we will have:
* - initialized / extended the mft bitmap if necessary,
* - initialized / extended the mft data if necessary,
* - set the bit corresponding to the mft record being allocated in the
* mft bitmap,
* - open an ntfs_inode for the allocated mft record, and we will
* - return the ntfs_inode.
*
* On error (return value zero), nothing will have changed. If we had changed
2005-07-07 06:47:01 +08:00
* anything before the error occurred, we will have reverted back to the
* starting state before returning to the caller. Thus, except for bugs, we
* should always leave the volume in a consistent state when returning from
* this function.
*
* Note, this function cannot make use of most of the normal functions, like
* for example for attribute resizing, etc, because when the run list overflows
* the base mft record and an attribute list is used, it is very important that
* the extension mft records used to store the $DATA attribute of $MFT can be
* reached without having to read the information contained inside them, as
* this would make it impossible to find them in the first place after the
* volume is dismounted. $MFT/$BITMAP probably does not need to follow this
* rule because the bitmap is not essential for finding the mft records, but on
* the other hand, handling the bitmap in this special way would make life
* easier because otherwise there might be circular invocations of functions
* when reading the bitmap but if we are careful, we should be able to avoid
* all problems.
*/
ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, ntfs_inode *base_ni)
{
s64 ll, bit, old_data_initialized, old_data_size;
ntfs_attr *mft_na, *mftbmp_na;
ntfs_attr_search_ctx *ctx;
MFT_RECORD *m;
ATTR_RECORD *a;
ntfs_inode *ni;
int err;
u16 seq_no, usn;
if (base_ni)
ntfs_debug("Entering (allocating an extent mft record for "
"base mft record 0x%llx).",
(long long)base_ni->mft_no);
else
ntfs_debug("Entering (allocating a base mft record).");
if (!vol || !vol->mft_na || !vol->mftbmp_na) {
errno = EINVAL;
return NULL;
}
mft_na = vol->mft_na;
mftbmp_na = vol->mftbmp_na;
bit = ntfs_mft_bitmap_find_free_rec(vol, base_ni);
if (bit >= 0) {
ntfs_debug("Found free record (#1), bit 0x%llx.",
(long long)bit);
goto found_free_rec;
}
if (errno != ENOSPC)
return NULL;
/*
* No free mft records left. If the mft bitmap already covers more
* than the currently used mft records, the next records are all free,
* so we can simply allocate the first unused mft record.
* Note: We also have to make sure that the mft bitmap at least covers
* the first 24 mft records as they are special and whilst they may not
* be in use, we do not allocate from them.
*/
ll = mft_na->initialized_size >> vol->mft_record_size_bits;
if (mftbmp_na->initialized_size << 3 > ll &&
mftbmp_na->initialized_size > 3) {
bit = ll;
if (bit < 24)
bit = 24;
ntfs_debug("Found free record (#2), bit 0x%llx.",
(long long)bit);
goto found_free_rec;
}
/*
* The mft bitmap needs to be expanded until it covers the first unused
* mft record that we can allocate.
* Note: The smallest mft record we allocate is mft record 24.
*/
ntfs_debug("Status of mftbmp before extension: allocated_size 0x%llx, "
"data_size 0x%llx, initialized_size 0x%llx.",
(long long)mftbmp_na->allocated_size,
(long long)mftbmp_na->data_size,
(long long)mftbmp_na->initialized_size);
if (mftbmp_na->initialized_size + 8 > mftbmp_na->allocated_size) {
/* Need to extend bitmap by one more cluster. */
ntfs_debug("mftbmp: initialized_size + 8 > allocated_size.");
if (ntfs_mft_bitmap_extend_allocation(vol))
goto err_out;
ntfs_debug("Status of mftbmp after allocation extension: "
"allocated_size 0x%llx, data_size 0x%llx, "
"initialized_size 0x%llx.",
(long long)mftbmp_na->allocated_size,
(long long)mftbmp_na->data_size,
(long long)mftbmp_na->initialized_size);
}
/*
* We now have sufficient allocated space, extend the initialized_size
* as well as the data_size if necessary and fill the new space with
* zeroes.
*/
bit = mftbmp_na->initialized_size << 3;
if (ntfs_mft_bitmap_extend_initialized(vol))
goto err_out;
2005-07-07 06:47:01 +08:00
ntfs_debug("Status of mftbmp after initialized extension: "
"allocated_size 0x%llx, data_size 0x%llx, "
"initialized_size 0x%llx.",
(long long)mftbmp_na->allocated_size,
(long long)mftbmp_na->data_size,
(long long)mftbmp_na->initialized_size);
ntfs_debug("Found free record (#3), bit 0x%llx.", (long long)bit);
found_free_rec:
/* @bit is the found free mft record, allocate it in the mft bitmap. */
ntfs_debug("At found_free_rec.");
if (ntfs_bitmap_set_bit(mftbmp_na, bit)) {
ntfs_error(vol->sb, "Failed to allocate bit in mft bitmap.");
goto err_out;
}
ntfs_debug("Set bit 0x%llx in mft bitmap.", (long long)bit);
/* The mft bitmap is now uptodate. Deal with mft data attribute now. */
ll = (bit + 1) << vol->mft_record_size_bits;
if (ll <= mft_na->initialized_size) {
ntfs_debug("Allocated mft record already initialized.");
goto mft_rec_already_initialized;
}
ntfs_debug("Initializing allocated mft record.");
/*
* The mft record is outside the initialized data. Extend the mft data
* attribute until it covers the allocated record. The loop is only
* actually traversed more than once when a freshly formatted volume is
* first written to so it optimizes away nicely in the common case.
*/
ntfs_debug("Status of mft data before extension: "
"allocated_size 0x%llx, data_size 0x%llx, "
"initialized_size 0x%llx.",
(long long)mft_na->allocated_size,
(long long)mft_na->data_size,
(long long)mft_na->initialized_size);
while (ll > mft_na->allocated_size) {
if (ntfs_mft_data_extend_allocation(vol))
goto undo_mftbmp_alloc;
ntfs_debug("Status of mft data after allocation extension: "
"allocated_size 0x%llx, data_size 0x%llx, "
"initialized_size 0x%llx.",
(long long)mft_na->allocated_size,
(long long)mft_na->data_size,
(long long)mft_na->initialized_size);
}
old_data_initialized = mft_na->initialized_size;
old_data_size = mft_na->data_size;
/*
* Extend mft data initialized size (and data size of course) to reach
2005-07-07 06:47:01 +08:00
* the allocated mft record, formatting the mft records along the way.
* Note: We only modify the ntfs_attr structure as that is all that is
* needed by ntfs_mft_record_format(). We will update the attribute
* record itself in one fell swoop later on.
*/
while (ll > mft_na->initialized_size) {
s64 ll2 = mft_na->initialized_size >> vol->mft_record_size_bits;
mft_na->initialized_size += vol->mft_record_size;
if (mft_na->initialized_size > mft_na->data_size)
mft_na->data_size = mft_na->initialized_size;
ntfs_debug("Initializing mft record 0x%llx.", (long long)ll2);
err = ntfs_mft_record_format(vol, ll2);
if (err) {
ntfs_error(vol->sb, "Failed to format mft record.");
goto undo_data_init;
}
}
/* Update the mft data attribute record to reflect the new sizes. */
ctx = ntfs_attr_get_search_ctx(mft_na->ni, NULL);
if (!ctx) {
ntfs_error(vol->sb, "Failed to get search context.");
goto undo_data_init;
}
if (ntfs_attr_lookup(mft_na->type, mft_na->name, mft_na->name_len, 0,
0, NULL, 0, ctx)) {
ntfs_error(vol->sb, "Failed to find first attribute extent of "
"mft data attribute.");
ntfs_attr_put_search_ctx(ctx);
goto undo_data_init;
}
a = ctx->attr;
a->initialized_size = cpu_to_sle64(mft_na->initialized_size);
a->data_size = cpu_to_sle64(mft_na->data_size);
/* Ensure the changes make it to disk. */
ntfs_inode_mark_dirty(ctx->ntfs_ino);
ntfs_attr_put_search_ctx(ctx);
ntfs_debug("Status of mft data after mft record initialization: "
"allocated_size 0x%llx, data_size 0x%llx, "
"initialized_size 0x%llx.",
(long long)mft_na->allocated_size,
(long long)mft_na->data_size,
(long long)mft_na->initialized_size);
/* Sanity checks. */
if (mft_na->data_size > mft_na->allocated_size ||
mft_na->initialized_size > mft_na->data_size)
NTFS_BUG("mft_na sanity checks failed");
// BUG_ON(mft_na->initialized_size > mft_na->data_size);
// BUG_ON(mft_na->data_size > mft_na->allocated_size);
mft_rec_already_initialized:
/*
* We now have allocated and initialized the mft record. Need to read
* it from disk and re-format it, preserving the sequence number if it
* is not zero as well as the update sequence number if it is not zero
* or -1 (0xffff).
*/
m = (MFT_RECORD*)malloc(vol->mft_record_size);
if (!m) {
ntfs_error(vol->sb, "Failed to allocate buffer for mft "
"record.");
goto undo_mftbmp_alloc;
}
if (ntfs_mft_record_read(vol, bit, m)) {
err = errno;
ntfs_error(vol->sb, "Failed to read mft record.");
free(m);
errno = err;
goto undo_mftbmp_alloc;
}
/* Sanity check that the mft record is really not in use. */
if (ntfs_is_file_record(m->magic) && (m->flags & MFT_RECORD_IN_USE)) {
ntfs_error(vol->sb, "Mft record 0x%llx was marked unused in "
"mft bitmap but is marked used itself. "
"Corrupt filesystem or library bug! "
"Run chkdsk immediately!", (long long)bit);
free(m);
errno = EIO;
goto undo_mftbmp_alloc;
}
seq_no = m->sequence_number;
usn = *(u16*)((u8*)m + le16_to_cpu(m->usa_ofs));
if (ntfs_mft_record_layout(vol, bit, m)) {
err = errno;
ntfs_error(vol->sb, "Failed to re-format mft record.");
free(m);
errno = err;
goto undo_mftbmp_alloc;
}
if (le16_to_cpu(seq_no))
m->sequence_number = seq_no;
seq_no = le16_to_cpu(usn);
if (seq_no && seq_no != 0xffff)
*(u16*)((u8*)m + le16_to_cpu(m->usa_ofs)) = usn;
/* Set the mft record itself in use. */
m->flags |= MFT_RECORD_IN_USE;
/* Now need to open an ntfs inode for the mft record. */
ni = ntfs_inode_allocate(vol);
if (!ni) {
err = errno;
ntfs_error(vol->sb, "Failed to allocate buffer for inode.");
free(m);
errno = err;
goto undo_mftbmp_alloc;
}
ni->mft_no = bit;
ni->mrec = m;
/*
* If we are allocating an extent mft record, make the opened inode an
* extent inode and attach it to the base inode. Also, set the base
* mft record reference in the extent inode.
*/
if (base_ni) {
ni->nr_extents = -1;
ni->base_ni = base_ni;
m->base_mft_record = MK_LE_MREF(base_ni->mft_no,
le16_to_cpu(base_ni->mrec->sequence_number));
/*
* Attach the extent inode to the base inode, reallocating
* memory if needed.
*/
if (!(base_ni->nr_extents & 3)) {
ntfs_inode **extent_nis;
int i;
i = (base_ni->nr_extents + 4) * sizeof(ntfs_inode *);
extent_nis = (ntfs_inode**)malloc(i);
if (!extent_nis) {
err = errno;
ntfs_error(vol->sb, "Failed to allocate "
"buffer for extent inodes "
"array.");
free(m);
free(ni);
errno = err;
goto undo_mftbmp_alloc;
}
if (base_ni->extent_nis) {
memcpy(extent_nis, base_ni->extent_nis,
i - 4 * sizeof(ntfs_inode *));
free(base_ni->extent_nis);
}
base_ni->extent_nis = extent_nis;
}
base_ni->extent_nis[base_ni->nr_extents++] = ni;
}
/* Make sure the allocated inode is written out to disk later. */
ntfs_inode_mark_dirty(ni);
/* Initialize time, allocated and data size in ntfs_inode struct. */
ni->data_size = ni->allocated_size = -1;
ni->creation_time = ni->last_data_change_time =
ni->last_mft_change_time =
ni->last_access_time = time(NULL);
/* Update the default mft allocation position if it was used. */
if (!base_ni)
vol->mft_data_pos = bit + 1;
/* Return the opened, allocated inode of the allocated mft record. */
ntfs_debug("Returning opened, allocated %sinode 0x%llx.",
base_ni ? "extent " : "", (long long)bit);
return ni;
undo_data_init:
mft_na->initialized_size = old_data_initialized;
mft_na->data_size = old_data_size;
undo_mftbmp_alloc:
err = errno;
if (ntfs_bitmap_clear_bit(mftbmp_na, bit))
ntfs_error(vol->sb, "Failed to clear bit in mft bitmap.%s", es);
errno = err;
err_out:
if (!errno)
errno = EIO;
return NULL;
}
/**
* ntfs_mft_record_free - free an mft record on an ntfs volume
* @vol: volume on which to free the mft record
* @ni: open ntfs inode of the mft record to free
*
* Free the mft record of the open inode @ni on the mounted ntfs volume @vol.
* Note that this function calls ntfs_inode_close() internally and hence you
* cannot use the pointer @ni any more after this function returns success.
*
* On success return 0 and on error return -1 with errno set to the error code.
*/
int ntfs_mft_record_free(ntfs_volume *vol, ntfs_inode *ni)
{
u64 mft_no;
int err;
u16 seq_no, old_seq_no;
Dprintf("%s(): Entering for inode 0x%llx.\n",
__FUNCTION__, (long long) ni->mft_no);
if (!vol || !vol->mftbmp_na || !ni) {
errno = EINVAL;
return -1;
}
/* Cache the mft reference for later. */
mft_no = ni->mft_no;
/* Mark the mft record as not in use. */
ni->mrec->flags &= ~MFT_RECORD_IN_USE;
/* Increment the sequence number, skipping zero, if it is not zero. */
old_seq_no = ni->mrec->sequence_number;
seq_no = le16_to_cpu(old_seq_no);
if (seq_no == 0xffff)
seq_no = 1;
else if (seq_no)
seq_no++;
ni->mrec->sequence_number = cpu_to_le16(seq_no);
/* Set the inode dirty and write it out. */
ntfs_inode_mark_dirty(ni);
if (ntfs_inode_sync(ni)) {
err = errno;
goto sync_rollback;
}
/* Clear the bit in the $MFT/$BITMAP corresponding to this record. */
if (ntfs_bitmap_clear_bit(vol->mftbmp_na, mft_no)) {
err = errno;
// FIXME: If ntfs_bitmap_clear_run() guarantees rollback on
// error, this could be changed to goto sync_rollback;
goto bitmap_rollback;
}
/* Throw away the now freed inode. */
if (!ntfs_inode_close(ni))
return 0;
err = errno;
/* Rollback what we did... */
bitmap_rollback:
if (ntfs_bitmap_set_bit(vol->mftbmp_na, mft_no))
Dputs("Eeek! Rollback failed in ntfs_mft_record_free(). "
"Leaving inconsistent metadata!");
sync_rollback:
ni->mrec->flags |= MFT_RECORD_IN_USE;
ni->mrec->sequence_number = old_seq_no;
ntfs_inode_mark_dirty(ni);
errno = err;
return -1;
}