From be6376f85e9594c94736ac1c6f0cd9c72cd0ad98 Mon Sep 17 00:00:00 2001 From: "cantab.net!aia21" Date: Sun, 29 Dec 2002 21:37:21 +0000 Subject: [PATCH] New API provided by mft.[hc]: ntfs_mft_record_alloc(), -- WIP ntfs_mft_record_free(). (Logical change 1.74) --- include/mft.h | 5 +++ libntfs/mft.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 93 insertions(+), 1 deletion(-) diff --git a/include/mft.h b/include/mft.h index 96ec291b..ff423fe7 100644 --- a/include/mft.h +++ b/include/mft.h @@ -23,6 +23,7 @@ #define _NTFS_MFT_H #include "volume.h" +#include "inode.h" #include "layout.h" extern int ntfs_mft_records_read(const ntfs_volume *vol, const MFT_REF mref, @@ -100,5 +101,9 @@ static __inline__ u32 ntfs_mft_record_get_data_size(const MFT_RECORD *m) return le32_to_cpu(m->bytes_in_use); } +extern ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, u64 start); + +extern int ntfs_mft_record_free(ntfs_volume *vol, ntfs_inode *ni); + #endif /* defined _NTFS_MFT_H */ diff --git a/libntfs/mft.c b/libntfs/mft.c index 695647c8..80ae3adc 100644 --- a/libntfs/mft.c +++ b/libntfs/mft.c @@ -23,11 +23,15 @@ #include #include -#include "mft.h" +#include "types.h" #include "disk_io.h" #include "debug.h" #include "bitmap.h" #include "attrib.h" +#include "inode.h" +#include "volume.h" +#include "layout.h" +#include "mft.h" /** * ntfs_mft_records_read - read records from the mft from disk @@ -231,3 +235,86 @@ read_failed: return -1; } +/** + * ntfs_mft_record_alloc - allocate an mft record on an ntfs volume + * @vol: mounted ntfs volume on which to allocate the mft record + * @start: starting mft record at which to allocate (or -1 if none) + * + * Allocate an mft record in $MFT/$DATA starting to search for a free record + * at mft record number @start or at the current allocator position if + * @start_mref is -1, on the mounted ntfs volume @vol. + * + * On success return the now opened ntfs inode of the mft record. + * + * On error return NULL with errno set to the error code. + */ +ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, u64 start) +{ + if (!vol || !vol->mftbmp_na) { + errno = EINVAL; + return NULL; + } + + errno = ENOTSUP; + return NULL; +} + +/** + * ntfs_mft_record_free - free an mft record on an ntfs volume + * @vol: mounted ntfs 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; + u16 seq_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. */ + seq_no = le16_to_cpu(ni->mrec->sequence_number); + 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 close it so it is written out. */ + ntfs_inode_mark_dirty(ni); + if (ntfs_inode_close(ni)) { + int eo = errno; + // FIXME: Eeek! We need rollback! (AIA) + fprintf(stderr, "%s(): Eeek! Failed to close the inode." + "Leaving inconsistent metadata!\n", + __FUNCTION__); + errno = eo; + return -1; + } + + /* Clear the bit in the $MFT/$BITMAP corresponding to this record. */ + if (ntfs_bitmap_clear_run(vol->mftbmp_na, mft_no, 1)) { + // FIXME: Eeek! We need rollback! (AIA) + fprintf(stderr, "%s(): Eeek! Failed to clear the allocation " + "in the mft bitmap. Leaving deleted mft record " + "marked as in use in the mft bitmap and " + "pretending we succeeded. Error: %s\n", + __FUNCTION__, strerror(errno)); + } + return 0; +} +