patch-2.4.7 linux/fs/ntfs/super.c
Next file: linux/fs/ntfs/super.h
Previous file: linux/fs/ntfs/struct.h
Back to the patch index
Back to the overall index
- Lines: 343
- Date:
Mon Jul 16 15:14:10 2001
- Orig file:
v2.4.6/linux/fs/ntfs/super.c
- Orig date:
Wed Apr 18 11:49:13 2001
diff -u --recursive --new-file v2.4.6/linux/fs/ntfs/super.c linux/fs/ntfs/super.c
@@ -1,9 +1,10 @@
-/* super.c
+/*
+ * super.c
*
- * Copyright (C) 1995-1997, 1999 Martin von Löwis
- * Copyright (C) 1996-1997 Régis Duchesne
- * Copyright (C) 1999 Steve Dodd
- * Copyright (C) 2000-2001 Anton Altparmakov (AIA)
+ * Copyright (C) 1995-1997, 1999 Martin von Löwis
+ * Copyright (C) 1996-1997 Régis Duchesne
+ * Copyright (C) 1999 Steve Dodd
+ * Copyright (C) 2000-2001 Anton Altparmakov (AIA)
*/
#include "ntfstypes.h"
@@ -40,17 +41,17 @@
start = NTFS_GETU16(record + 4);
count = NTFS_GETU16(record + 6);
count--;
- if(size && vol->blocksize * count != size)
+ if(size && vol->sector_size * count != size)
return 0;
fixup = NTFS_GETU16(record + start);
start += 2;
- offset = vol->blocksize - 2;
+ offset = vol->sector_size - 2;
while (count--){
if (NTFS_GETU16(record + offset) != fixup)
return 0;
NTFS_PUTU16(record + offset, NTFS_GETU16(record + start));
start += 2;
- offset += vol->blocksize;
+ offset += vol->sector_size;
}
return 1;
}
@@ -61,6 +62,8 @@
*/
int ntfs_init_volume(ntfs_volume *vol, char *boot)
{
+ int sectors_per_cluster_bits;
+
/* Historical default values, in case we don't load $AttrDef. */
vol->at_standard_information = 0x10;
vol->at_attribute_list = 0x20;
@@ -75,53 +78,71 @@
vol->at_bitmap = 0xB0;
vol->at_symlink = 0xC0;
/* Sector size */
- vol->blocksize = NTFS_GETU16(boot + 0xB);
- vol->clusterfactorbits = ffs(NTFS_GETU8(boot + 0xD)) - 1;
+ vol->sector_size = NTFS_GETU16(boot + 0xB);
+ ntfs_debug(DEBUG_FILE3, "ntfs_init_volume: vol->sector_size = 0x%x\n",
+ vol->sector_size);
+ ntfs_debug(DEBUG_FILE3, "ntfs_init_volume: sectors_per_cluster = "
+ "0x%x\n", NTFS_GETU8(boot + 0xD));
+ sectors_per_cluster_bits = ffs(NTFS_GETU8(boot + 0xD)) - 1;
+ ntfs_debug(DEBUG_FILE3, "ntfs_init_volume: sectors_per_cluster_bits "
+ "= 0x%x\n", sectors_per_cluster_bits);
vol->mft_clusters_per_record = NTFS_GETS8(boot + 0x40);
+ ntfs_debug(DEBUG_FILE3, "ntfs_init_volume: vol->mft_clusters_per_record"
+ " = 0x%x\n", vol->mft_clusters_per_record);
vol->index_clusters_per_record = NTFS_GETS8(boot + 0x44);
- /* Just some consistency checks. */
- if (NTFS_GETU32(boot + 0x40) > 256)
- ntfs_error("Unexpected data #1 in boot block\n");
- if (NTFS_GETU32(boot+ 0x44) > 256)
- ntfs_error("Unexpected data #2 in boot block\n");
- vol->clustersize = vol->blocksize << vol->clusterfactorbits;
+ ntfs_debug(DEBUG_FILE3, "ntfs_init_volume: "
+ "vol->index_clusters_per_record = 0x%x\n",
+ vol->index_clusters_per_record);
+ vol->cluster_size = vol->sector_size << sectors_per_cluster_bits;
+ vol->cluster_size_bits = ffs(vol->cluster_size) - 1;
+ ntfs_debug(DEBUG_FILE3, "ntfs_init_volume: vol->cluster_size = 0x%x\n",
+ vol->cluster_size);
+ ntfs_debug(DEBUG_FILE3, "ntfs_init_volume: vol->cluster_size_bits = "
+ "0x%x\n", vol->cluster_size_bits);
if (vol->mft_clusters_per_record > 0)
- vol->mft_recordsize =
- vol->clustersize * vol->mft_clusters_per_record;
- else {
- /* If mft_recordsize < clustersize then mft_clusters_per_record
- = -log2(mft_recordsize) bytes. Mft_recordsize normaly equals
- 1024 bytes, which is encoded as 0xF6. */
- if (vol->mft_clusters_per_record < -31 ||
- -9 < vol->mft_clusters_per_record) {
- ntfs_error("Unexpected mft clusters per record value "
- "in boot block.\n");
- return -1;
- }
- vol->mft_recordsize = 1 << (-vol->mft_clusters_per_record);
- }
+ vol->mft_record_size = vol->cluster_size <<
+ (ffs(vol->mft_clusters_per_record) - 1);
+ else
+ /*
+ * When mft_record_size < cluster_size, mft_clusters_per_record
+ * = -log2(mft_record_size) bytes. mft_record_size normaly is
+ * 1024 bytes, which is encoded as 0xF6 (-10 in decimal).
+ */
+ vol->mft_record_size = 1 << -vol->mft_clusters_per_record;
+ vol->mft_record_size_bits = ffs(vol->mft_record_size) - 1;
+ ntfs_debug(DEBUG_FILE3, "ntfs_init_volume: vol->mft_record_size = 0x%x"
+ "\n", vol->mft_record_size);
+ ntfs_debug(DEBUG_FILE3, "ntfs_init_volume: vol->mft_record_size_bits = "
+ "0x%x\n", vol->mft_record_size_bits);
if (vol->index_clusters_per_record > 0)
- vol->index_recordsize =
- vol->clustersize * vol->index_clusters_per_record;
- else {
- /* If index_recordsize < clustersize then
- index_clusters_per_record = -log2(index_recordsize) bytes.
- Index_recordsize normaly equals 1024 bytes, which is
- encoded as 0xF6. */
- if (vol->index_clusters_per_record < -31 ||
- -9 < vol->index_clusters_per_record) {
- ntfs_error("Unexpected index clusters per record "
- "value in boot block.\n");
- return -1;
- }
- vol->index_recordsize = 1 << (-vol->index_clusters_per_record);
- }
- if (NTFS_GETU64(boot + 0x30) >= (1ULL << 32)) {
- ntfs_error("Would require 64-bit inodes to mount partition.");
+ vol->index_record_size = vol->cluster_size <<
+ (ffs(vol->index_clusters_per_record) - 1);
+ else
+ /*
+ * When index_record_size < cluster_size,
+ * index_clusters_per_record = -log2(index_record_size) bytes.
+ * index_record_size normaly equals 4096 bytes, which is
+ * encoded as 0xF4 (-12 in decimal).
+ */
+ vol->index_record_size = 1 << -vol->index_clusters_per_record;
+ vol->index_record_size_bits = ffs(vol->index_record_size) - 1;
+ ntfs_debug(DEBUG_FILE3, "ntfs_init_volume: vol->index_record_size = "
+ "0x%x\n", vol->index_record_size);
+ ntfs_debug(DEBUG_FILE3, "ntfs_init_volume: vol->index_record_size_bits "
+ "= 0x%x\n", vol->index_record_size_bits);
+ /*
+ * Check mft and mftmirr locations for 64-bit-ness. NOTE: This is a
+ * crude check only as many other things could be out of bounds later
+ * on, but it will catch at least some of the cases, since the mftmirr
+ * is located in the middle of the volume so if the volume is very
+ * large the mftmirr probably will be out of 32-bit bounds.
+ */
+ vol->mft_lcn = NTFS_GETS64(boot + 0x30);
+ if (vol->mft_lcn >= (__s64)1 << 31 ||
+ NTFS_GETS64(boot + 0x38) >= (__s64)1 << 31) {
+ ntfs_error("Cannot handle 64-bit clusters yet.\n");
return -1;
}
- /* FIXME: long long value */
- vol->mft_cluster = NTFS_GETU64(boot + 0x30);
/* This will be initialized later. */
vol->upcase = 0;
vol->upcase_length = 0;
@@ -151,6 +172,11 @@
ntfs_volume *vol = attrdef->vol;
ntfs_u16* name = (ntfs_u16*)def;
+ if (!type) {
+ ntfs_debug(DEBUG_OTHER, "process_atrdef: finished processing "
+ "and returning 1\n");
+ return 1;
+ }
if (ntfs_ua_strncmp(name, "$STANDARD_INFORMATION", 64) == 0) {
vol->at_standard_information = type;
check_type = 0x10;
@@ -190,9 +216,12 @@
check_type = 0xC0;
}
if (check_type && check_type != type) {
- ntfs_error("Unexpected type %x for %x\n", type, check_type);
+ ntfs_error("process_attrdef: unexpected type 0x%x for 0x%x\n",
+ type, check_type);
return -EINVAL;
}
+ ntfs_debug(DEBUG_OTHER, "process_attrdef: found %s attribute of type "
+ "0x%x\n", check_type ? "known" : "unknown", type);
return 0;
}
@@ -200,9 +229,12 @@
{
ntfs_u8 *buf;
ntfs_io io;
- int offset, error,i;
+ __s64 offset;
+ unsigned i;
+ int error;
ntfs_attribute *data;
+ ntfs_debug(DEBUG_BSD, "Entered ntfs_init_attrdef()\n");
buf = ntfs_malloc(4050); /* 90*45 */
if (!buf)
return -ENOMEM;
@@ -211,6 +243,8 @@
io.do_read = 1;
offset = 0;
data = ntfs_find_attr(attrdef, attrdef->vol->at_data, 0);
+ ntfs_debug(DEBUG_BSD, "In ntfs_init_attrdef() after call to "
+ "ntfs_find_attr.\n");
if (!data) {
ntfs_free(buf);
return -EINVAL;
@@ -218,13 +252,23 @@
do {
io.param = buf;
io.size = 4050;
+ ntfs_debug(DEBUG_BSD, "In ntfs_init_attrdef() going to call "
+ "ntfs_readwrite_attr.\n");
error = ntfs_readwrite_attr(attrdef, data, offset, &io);
- for (i = 0; !error && i < io.size - 0xA0; i += 0xA0)
+ ntfs_debug(DEBUG_BSD, "In ntfs_init_attrdef() after call to "
+ "ntfs_readwrite_attr.\n");
+ for (i = 0; !error && i <= io.size - 0xA0; i += 0xA0) {
+ ntfs_debug(DEBUG_BSD, "In ntfs_init_attrdef() going "
+ "to call process_attrdef.\n");
error = process_attrdef(attrdef, buf + i);
+ ntfs_debug(DEBUG_BSD, "In ntfs_init_attrdef() after "
+ "call to process_attrdef.\n");
+ }
offset += 4096;
} while (!error && io.size);
+ ntfs_debug(DEBUG_BSD, "Exiting ntfs_init_attrdef()\n");
ntfs_free(buf);
- return error;
+ return error == 1 ? 0 : error;
}
/* ntfs_get_version will determine the NTFS version of the volume and will
@@ -253,7 +297,10 @@
int error;
ntfs_inode upcase, attrdef, volume;
- vol->mft_ino = (ntfs_inode*)ntfs_calloc(3 * sizeof(ntfs_inode));
+ vol->mft_ino = (ntfs_inode*)ntfs_calloc(sizeof(ntfs_inode));
+ vol->mftmirr = (ntfs_inode*)ntfs_calloc(sizeof(ntfs_inode));
+ vol->bitmap = (ntfs_inode*)ntfs_calloc(sizeof(ntfs_inode));
+ vol->ino_flags = 4 | 2 | 1;
error = -ENOMEM;
ntfs_debug(DEBUG_BSD, "Going to load MFT\n");
if (!vol->mft_ino || (error = ntfs_init_inode(vol->mft_ino, vol,
@@ -263,13 +310,11 @@
return error;
}
ntfs_debug(DEBUG_BSD, "Going to load MIRR\n");
- vol->mftmirr = vol->mft_ino + 1;
if ((error = ntfs_init_inode(vol->mftmirr, vol, FILE_$MftMirr))) {
ntfs_error("Problem %d loading MFTMirr\n", error);
return error;
}
ntfs_debug(DEBUG_BSD, "Going to load BITMAP\n");
- vol->bitmap = vol->mft_ino + 2;
if ((error = ntfs_init_inode(vol->bitmap, vol, FILE_$BitMap))) {
ntfs_error("Problem loading Bitmap\n");
return error;
@@ -311,36 +356,48 @@
int ntfs_release_volume(ntfs_volume *vol)
{
- if (vol->mft_ino) {
+ if (((vol->ino_flags & 1) == 1) && vol->mft_ino) {
ntfs_clear_inode(vol->mft_ino);
- ntfs_clear_inode(vol->mftmirr);
- ntfs_clear_inode(vol->bitmap);
ntfs_free(vol->mft_ino);
vol->mft_ino = 0;
}
+ if (((vol->ino_flags & 2) == 2) && vol->mftmirr) {
+ ntfs_clear_inode(vol->mftmirr);
+ ntfs_free(vol->mftmirr);
+ vol->mftmirr = 0;
+ }
+ if (((vol->ino_flags & 4) == 4) && vol->bitmap) {
+ ntfs_clear_inode(vol->bitmap);
+ ntfs_free(vol->bitmap);
+ vol->bitmap = 0;
+ }
ntfs_free(vol->mft);
ntfs_free(vol->upcase);
return 0;
}
-/* Writes the volume size into vol_size. Returns 0 if successful or error. */
-int ntfs_get_volumesize(ntfs_volume *vol, ntfs_u64 *vol_size)
+/*
+ * Writes the volume size (units of clusters) into vol_size.
+ * Returns 0 if successful or error.
+ */
+int ntfs_get_volumesize(ntfs_volume *vol, ntfs_s64 *vol_size)
{
ntfs_io io;
char *cluster0;
if (!vol_size)
return -EFAULT;
- cluster0 = ntfs_malloc(vol->clustersize);
+ cluster0 = ntfs_malloc(vol->cluster_size);
if (!cluster0)
return -ENOMEM;
io.fn_put = ntfs_put;
io.fn_get = ntfs_get;
io.param = cluster0;
io.do_read = 1;
- io.size = vol->clustersize;
+ io.size = vol->cluster_size;
ntfs_getput_clusters(vol, 0, 0, &io);
- *vol_size = NTFS_GETU64(cluster0 + 0x28) >> vol->clusterfactorbits;
+ *vol_size = NTFS_GETU64(cluster0 + 0x28) >>
+ (ffs(NTFS_GETU8(cluster0 + 0xD)) - 1);
ntfs_free(cluster0);
return 0;
}
@@ -349,12 +406,12 @@
int ntfs_get_free_cluster_count(ntfs_inode *bitmap)
{
- unsigned char bits[2048];
- int offset, error;
- int clusters = 0;
ntfs_io io;
-
- offset = 0;
+ int offset, error, clusters;
+ unsigned char *bits = ntfs_malloc(2048);
+ if (!bits)
+ return -ENOMEM;
+ offset = clusters = 0;
io.fn_put = ntfs_put;
io.fn_get = ntfs_get;
while (1) {
@@ -382,6 +439,7 @@
}
offset += io.size;
}
+ ntfs_free(bits);
return clusters;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)