patch-2.4.4 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: 1005
- Date:
Wed Apr 18 11:49:13 2001
- Orig file:
v2.4.3/linux/fs/ntfs/super.c
- Orig date:
Tue Nov 7 11:22:35 2000
diff -u --recursive --new-file v2.4.3/linux/fs/ntfs/super.c linux/fs/ntfs/super.c
@@ -1,10 +1,9 @@
-/*
- * 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 Anton Altparmakov
+ * Copyright (C) 2000-2001 Anton Altparmakov (AIA)
*/
#include "ntfstypes.h"
@@ -12,13 +11,13 @@
#include "super.h"
#include <linux/errno.h>
+#include <linux/bitops.h>
#include "macros.h"
#include "inode.h"
#include "support.h"
#include "util.h"
-/*
- * All important structures in NTFS use 2 consistency checks :
+/* All important structures in NTFS use 2 consistency checks:
* . a magic structure identifier (FILE, INDX, RSTR, RCRD...)
* . a fixup technique : the last word of each sector (called a fixup) of a
* structure's record should end with the word at offset <n> of the first
@@ -36,188 +35,204 @@
int start, count, offset;
ntfs_u16 fixup;
- if(!IS_MAGIC(record,magic))
+ if (!IS_MAGIC(record, magic))
return 0;
- start=NTFS_GETU16(record+4);
- count=NTFS_GETU16(record+6);
+ start = NTFS_GETU16(record + 4);
+ count = NTFS_GETU16(record + 6);
count--;
- if(size && vol->blocksize*count != size)
+ if(size && vol->blocksize * count != size)
return 0;
- fixup = NTFS_GETU16(record+start);
- start+=2;
- offset=vol->blocksize-2;
- while(count--){
- if(NTFS_GETU16(record+offset)!=fixup)
+ fixup = NTFS_GETU16(record + start);
+ start += 2;
+ offset = vol->blocksize - 2;
+ while (count--){
+ if (NTFS_GETU16(record + offset) != fixup)
return 0;
- NTFS_PUTU16(record+offset, NTFS_GETU16(record+start));
- start+=2;
- offset+=vol->blocksize;
+ NTFS_PUTU16(record + offset, NTFS_GETU16(record + start));
+ start += 2;
+ offset += vol->blocksize;
}
return 1;
}
-/* Get vital informations about the ntfs partition from the boot sector */
-int ntfs_init_volume(ntfs_volume *vol,char *boot)
+/*
+ * Get vital informations about the ntfs partition from the boot sector.
+ * Return 0 on success or -1 on error.
+ */
+int ntfs_init_volume(ntfs_volume *vol, char *boot)
{
- /* Historical default values, in case we don't load $AttrDef */
- vol->at_standard_information=0x10;
- vol->at_attribute_list=0x20;
- vol->at_file_name=0x30;
- vol->at_volume_version=0x40;
- vol->at_security_descriptor=0x50;
- vol->at_volume_name=0x60;
- vol->at_volume_information=0x70;
- vol->at_data=0x80;
- vol->at_index_root=0x90;
- vol->at_index_allocation=0xA0;
- vol->at_bitmap=0xB0;
- vol->at_symlink=0xC0;
-
+ /* Historical default values, in case we don't load $AttrDef. */
+ vol->at_standard_information = 0x10;
+ vol->at_attribute_list = 0x20;
+ vol->at_file_name = 0x30;
+ vol->at_volume_version = 0x40;
+ vol->at_security_descriptor = 0x50;
+ vol->at_volume_name = 0x60;
+ vol->at_volume_information = 0x70;
+ vol->at_data = 0x80;
+ vol->at_index_root = 0x90;
+ vol->at_index_allocation = 0xA0;
+ vol->at_bitmap = 0xB0;
+ vol->at_symlink = 0xC0;
/* Sector size */
- vol->blocksize=NTFS_GETU16(boot+0xB);
- vol->clusterfactor=NTFS_GETU8(boot+0xD);
- vol->mft_clusters_per_record=NTFS_GETS8(boot+0x40);
- vol->index_clusters_per_record=NTFS_GETS8(boot+0x44);
-
- /* Just some consistency checks */
- if(NTFS_GETU32(boot+0x40)>256)
+ vol->blocksize = NTFS_GETU16(boot + 0xB);
+ vol->clusterfactorbits = ffs(NTFS_GETU8(boot + 0xD)) - 1;
+ vol->mft_clusters_per_record = NTFS_GETS8(boot + 0x40);
+ 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)
+ if (NTFS_GETU32(boot+ 0x44) > 256)
ntfs_error("Unexpected data #2 in boot block\n");
- if(vol->index_clusters_per_record<0){
- ntfs_error("Unexpected data #3 in boot block\n");
- /* If this really means a fraction, setting it to 1
- should be safe. */
- vol->index_clusters_per_record=1;
- }
- /* in some cases, 0xF6 meant 1024 bytes. Other strange values have not
- been observed */
- if(vol->mft_clusters_per_record<0 && vol->mft_clusters_per_record!=-10)
- ntfs_error("Unexpected data #4 in boot block\n");
-
- vol->clustersize=vol->blocksize*vol->clusterfactor;
- if(vol->mft_clusters_per_record>0)
- vol->mft_recordsize=
- vol->clustersize*vol->mft_clusters_per_record;
- else
- vol->mft_recordsize=1<<(-vol->mft_clusters_per_record);
- vol->index_recordsize=vol->clustersize*vol->index_clusters_per_record;
+ vol->clustersize = vol->blocksize << vol->clusterfactorbits;
+ 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);
+ }
+ 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.");
+ 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;
- vol->mft_ino=0;
+ vol->mft_cluster = NTFS_GETU64(boot + 0x30);
+ /* This will be initialized later. */
+ vol->upcase = 0;
+ vol->upcase_length = 0;
+ vol->mft_ino = 0;
return 0;
}
-static void
-ntfs_init_upcase(ntfs_inode *upcase)
+static void ntfs_init_upcase(ntfs_inode *upcase)
{
ntfs_io io;
#define UPCASE_LENGTH 256
- upcase->vol->upcase = ntfs_malloc(2*UPCASE_LENGTH);
- if( !upcase->vol->upcase )
+ upcase->vol->upcase = ntfs_malloc(UPCASE_LENGTH << 1);
+ if (!upcase->vol->upcase)
return;
- io.fn_put=ntfs_put;
- io.fn_get=0;
- io.param=(char*)upcase->vol->upcase;
- io.size=2*UPCASE_LENGTH;
- ntfs_read_attr(upcase,upcase->vol->at_data,0,0,&io);
- upcase->vol->upcase_length = io.size / 2;
+ io.fn_put = ntfs_put;
+ io.fn_get = 0;
+ io.param = (char*)upcase->vol->upcase;
+ io.size = UPCASE_LENGTH << 1;
+ ntfs_read_attr(upcase, upcase->vol->at_data, 0, 0, &io);
+ upcase->vol->upcase_length = io.size >> 1;
}
-static int
-process_attrdef(ntfs_inode* attrdef,ntfs_u8* def)
+static int process_attrdef(ntfs_inode* attrdef, ntfs_u8* def)
{
int type = NTFS_GETU32(def+0x80);
int check_type = 0;
- ntfs_volume *vol=attrdef->vol;
+ ntfs_volume *vol = attrdef->vol;
ntfs_u16* name = (ntfs_u16*)def;
- if(ntfs_ua_strncmp(name,"$STANDARD_INFORMATION",64)==0){
- vol->at_standard_information=type;
- check_type=0x10;
- }else if(ntfs_ua_strncmp(name,"$ATTRIBUTE_LIST",64)==0){
- vol->at_attribute_list=type;
- check_type=0x20;
- }else if(ntfs_ua_strncmp(name,"$FILE_NAME",64)==0){
- vol->at_file_name=type;
- check_type=0x30;
- }else if(ntfs_ua_strncmp(name,"$VOLUME_VERSION",64)==0){
- vol->at_volume_version=type;
- check_type=0x40;
- }else if(ntfs_ua_strncmp(name,"$SECURITY_DESCRIPTOR",64)==0){
- vol->at_security_descriptor=type;
- check_type=0x50;
- }else if(ntfs_ua_strncmp(name,"$VOLUME_NAME",64)==0){
- vol->at_volume_name=type;
- check_type=0x60;
- }else if(ntfs_ua_strncmp(name,"$VOLUME_INFORMATION",64)==0){
- vol->at_volume_information=type;
- check_type=0x70;
- }else if(ntfs_ua_strncmp(name,"$DATA",64)==0){
- vol->at_data=type;
- check_type=0x80;
- }else if(ntfs_ua_strncmp(name,"$INDEX_ROOT",64)==0){
- vol->at_index_root=type;
- check_type=0x90;
- }else if(ntfs_ua_strncmp(name,"$INDEX_ALLOCATION",64)==0){
- vol->at_index_allocation=type;
- check_type=0xA0;
- }else if(ntfs_ua_strncmp(name,"$BITMAP",64)==0){
- vol->at_bitmap=type;
- check_type=0xB0;
- }else if(ntfs_ua_strncmp(name,"$SYMBOLIC_LINK",64)==0 ||
- ntfs_ua_strncmp(name,"$REPARSE_POINT",64)==0){
- vol->at_symlink=type;
- check_type=0xC0;
- }
- if(check_type && check_type!=type){
- ntfs_error("Unexpected type %x for %x\n",type,check_type);
- return EINVAL;
+ if (ntfs_ua_strncmp(name, "$STANDARD_INFORMATION", 64) == 0) {
+ vol->at_standard_information = type;
+ check_type = 0x10;
+ } else if (ntfs_ua_strncmp(name, "$ATTRIBUTE_LIST", 64) == 0) {
+ vol->at_attribute_list = type;
+ check_type = 0x20;
+ } else if (ntfs_ua_strncmp(name, "$FILE_NAME", 64) == 0) {
+ vol->at_file_name = type;
+ check_type = 0x30;
+ } else if (ntfs_ua_strncmp(name, "$VOLUME_VERSION", 64) == 0) {
+ vol->at_volume_version = type;
+ check_type = 0x40;
+ } else if (ntfs_ua_strncmp(name, "$SECURITY_DESCRIPTOR", 64) == 0) {
+ vol->at_security_descriptor = type;
+ check_type = 0x50;
+ } else if (ntfs_ua_strncmp(name, "$VOLUME_NAME", 64) == 0) {
+ vol->at_volume_name = type;
+ check_type = 0x60;
+ } else if (ntfs_ua_strncmp(name, "$VOLUME_INFORMATION", 64) == 0) {
+ vol->at_volume_information = type;
+ check_type = 0x70;
+ } else if (ntfs_ua_strncmp(name, "$DATA", 64) == 0) {
+ vol->at_data = type;
+ check_type = 0x80;
+ } else if (ntfs_ua_strncmp(name, "$INDEX_ROOT", 64) == 0) {
+ vol->at_index_root = type;
+ check_type = 0x90;
+ } else if (ntfs_ua_strncmp(name, "$INDEX_ALLOCATION", 64) == 0) {
+ vol->at_index_allocation = type;
+ check_type = 0xA0;
+ } else if (ntfs_ua_strncmp(name, "$BITMAP", 64) == 0) {
+ vol->at_bitmap = type;
+ check_type = 0xB0;
+ } else if (ntfs_ua_strncmp(name, "$SYMBOLIC_LINK", 64) == 0 ||
+ ntfs_ua_strncmp(name, "$REPARSE_POINT", 64) == 0) {
+ vol->at_symlink = type;
+ check_type = 0xC0;
+ }
+ if (check_type && check_type != type) {
+ ntfs_error("Unexpected type %x for %x\n", type, check_type);
+ return -EINVAL;
}
return 0;
}
-int
-ntfs_init_attrdef(ntfs_inode* attrdef)
+int ntfs_init_attrdef(ntfs_inode* attrdef)
{
ntfs_u8 *buf;
ntfs_io io;
- int offset,error,i;
+ int offset, error,i;
ntfs_attribute *data;
- buf=ntfs_malloc(4050); /* 90*45 */
- if(!buf)return ENOMEM;
- io.fn_put=ntfs_put;
- io.fn_get=ntfs_get;
- io.do_read=1;
- offset=0;
- data=ntfs_find_attr(attrdef,attrdef->vol->at_data,0);
- if(!data){
+
+ buf = ntfs_malloc(4050); /* 90*45 */
+ if (!buf)
+ return -ENOMEM;
+ io.fn_put = ntfs_put;
+ io.fn_get = ntfs_get;
+ io.do_read = 1;
+ offset = 0;
+ data = ntfs_find_attr(attrdef, attrdef->vol->at_data, 0);
+ if (!data) {
ntfs_free(buf);
- return EINVAL;
+ return -EINVAL;
}
- do{
- io.param=buf;
- io.size=4050;
- error=ntfs_readwrite_attr(attrdef,data,offset,&io);
- for(i=0;!error && i<io.size-0xA0;i+=0xA0)
- error=process_attrdef(attrdef,buf+i);
- offset+=4096;
- }while(!error && io.size);
+ do {
+ io.param = buf;
+ io.size = 4050;
+ error = ntfs_readwrite_attr(attrdef, data, offset, &io);
+ for (i = 0; !error && i < io.size - 0xA0; i += 0xA0)
+ error = process_attrdef(attrdef, buf + i);
+ offset += 4096;
+ } while (!error && io.size);
ntfs_free(buf);
return error;
}
-/* ntfs_get_version will determine the NTFS version of the
- volume and will return the version in a BCD format, with
- the MSB being the major version number and the LSB the
- minor one. Otherwise return <0 on error.
- Example: version 3.1 will be returned as 0x0301.
- This has the obvious limitation of not coping with version
- numbers above 0x80 but that shouldn't be a problem... */
+/* ntfs_get_version will determine the NTFS version of the volume and will
+ * return the version in a BCD format, with the MSB being the major version
+ * number and the LSB the minor one. Otherwise return <0 on error.
+ * Example: version 3.1 will be returned as 0x0301. This has the obvious
+ * limitation of not coping with version numbers above 0x80 but that shouldn't
+ * be a problem... */
int ntfs_get_version(ntfs_inode* volume)
{
ntfs_attribute *volinfo;
@@ -229,7 +244,8 @@
ntfs_error("Volume information attribute is not resident!\n");
return -EINVAL;
}
- return ((ntfs_u8*)volinfo->d.data)[8] << 8 | ((ntfs_u8*)volinfo->d.data)[9];
+ return ((ntfs_u8*)volinfo->d.data)[8] << 8 |
+ ((ntfs_u8*)volinfo->d.data)[9];
}
int ntfs_load_special_files(ntfs_volume *vol)
@@ -237,119 +253,120 @@
int error;
ntfs_inode upcase, attrdef, volume;
- vol->mft_ino=(ntfs_inode*)ntfs_calloc(3*sizeof(ntfs_inode));
- error=ENOMEM;
- ntfs_debug(DEBUG_BSD,"Going to load MFT\n");
- if(!vol->mft_ino || (error=ntfs_init_inode(vol->mft_ino,vol,FILE_MFT)))
+ vol->mft_ino = (ntfs_inode*)ntfs_calloc(3 * sizeof(ntfs_inode));
+ error = -ENOMEM;
+ ntfs_debug(DEBUG_BSD, "Going to load MFT\n");
+ if (!vol->mft_ino || (error = ntfs_init_inode(vol->mft_ino, vol,
+ FILE_$Mft)))
{
ntfs_error("Problem loading MFT\n");
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);
+ 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_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;
}
- ntfs_debug(DEBUG_BSD,"Going to load UPCASE\n");
- error=ntfs_init_inode(&upcase,vol,FILE_UPCASE);
- if(error)return error;
+ ntfs_debug(DEBUG_BSD, "Going to load UPCASE\n");
+ error = ntfs_init_inode(&upcase, vol, FILE_$UpCase);
+ if (error)
+ return error;
ntfs_init_upcase(&upcase);
ntfs_clear_inode(&upcase);
- ntfs_debug(DEBUG_BSD,"Going to load ATTRDEF\n");
- error=ntfs_init_inode(&attrdef,vol,FILE_ATTRDEF);
- if(error)return error;
- error=ntfs_init_attrdef(&attrdef);
+ ntfs_debug(DEBUG_BSD, "Going to load ATTRDEF\n");
+ error = ntfs_init_inode(&attrdef, vol, FILE_$AttrDef);
+ if (error)
+ return error;
+ error = ntfs_init_attrdef(&attrdef);
ntfs_clear_inode(&attrdef);
- if(error)return error;
+ if (error)
+ return error;
- /* Check for NTFS version and if Win2k version (ie. 3.0+)
- do not allow write access since the driver write support
- is broken, especially for Win2k. */
- ntfs_debug(DEBUG_BSD,"Going to load VOLUME\n");
- error = ntfs_init_inode(&volume,vol,FILE_VOLUME);
- if (error) return error;
- if ((error = ntfs_get_version(&volume)) >= 0x0300) {
+ /* Check for NTFS version and if Win2k version (ie. 3.0+) do not allow
+ * write access since the driver write support is broken. */
+ ntfs_debug(DEBUG_BSD, "Going to load VOLUME\n");
+ error = ntfs_init_inode(&volume, vol, FILE_$Volume);
+ if (error)
+ return error;
+ if ((error = ntfs_get_version(&volume)) >= 0x0300 &&
+ !(NTFS_SB(vol)->s_flags & MS_RDONLY)) {
NTFS_SB(vol)->s_flags |= MS_RDONLY;
- ntfs_error("Warning! NTFS volume version is Win2k+: Mounting read-only\n");
+ ntfs_error("Warning! NTFS volume version is Win2k+: Mounting "
+ "read-only\n");
}
ntfs_clear_inode(&volume);
- if (error < 0) return error;
- ntfs_debug(DEBUG_BSD, "NTFS volume is version %d.%d\n", error >> 8, error & 0xff);
-
+ if (error < 0)
+ return error;
+ ntfs_debug(DEBUG_BSD, "NTFS volume is version %d.%d\n", error >> 8,
+ error & 0xff);
return 0;
}
int ntfs_release_volume(ntfs_volume *vol)
{
- if(vol->mft_ino){
+ if (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;
+ vol->mft_ino = 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 into vol_size. Returns 0 if successful or error. */
+int ntfs_get_volumesize(ntfs_volume *vol, ntfs_u64 *vol_size)
{
ntfs_io io;
char *cluster0;
- if( !vol_size )
- return EFAULT;
-
- cluster0=ntfs_malloc(vol->clustersize);
- 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;
- ntfs_getput_clusters(vol,0,0,&io);
- *vol_size = NTFS_GETU64(cluster0+0x28);
+ if (!vol_size)
+ return -EFAULT;
+ cluster0 = ntfs_malloc(vol->clustersize);
+ 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;
+ ntfs_getput_clusters(vol, 0, 0, &io);
+ *vol_size = NTFS_GETU64(cluster0 + 0x28) >> vol->clusterfactorbits;
ntfs_free(cluster0);
return 0;
}
static int nc[16]={4,3,3,2,3,2,2,1,3,2,2,1,2,1,1,0};
-int
-ntfs_get_free_cluster_count(ntfs_inode *bitmap)
+int ntfs_get_free_cluster_count(ntfs_inode *bitmap)
{
unsigned char bits[2048];
- int offset,error;
- int clusters=0;
+ int offset, error;
+ int clusters = 0;
ntfs_io io;
- offset=0;
- io.fn_put=ntfs_put;
- io.fn_get=ntfs_get;
- while(1)
- {
+ offset = 0;
+ io.fn_put = ntfs_put;
+ io.fn_get = ntfs_get;
+ while (1) {
register int i;
- io.param=bits;
- io.size=2048;
- error=ntfs_read_attr(bitmap,bitmap->vol->at_data,0,
- offset,&io);
- if(error || io.size==0)break;
+ io.param = bits;
+ io.size = 2048;
+ error = ntfs_read_attr(bitmap, bitmap->vol->at_data, 0, offset,
+ &io);
+ if (error || io.size == 0)
+ break;
/* I never thought I would do loop unrolling some day */
- for(i=0;i<io.size-8;){
+ for (i = 0; i < io.size - 8; ) {
clusters+=nc[bits[i]>>4];clusters+=nc[bits[i++] & 0xF];
clusters+=nc[bits[i]>>4];clusters+=nc[bits[i++] & 0xF];
clusters+=nc[bits[i]>>4];clusters+=nc[bits[i++] & 0xF];
@@ -359,261 +376,263 @@
clusters+=nc[bits[i]>>4];clusters+=nc[bits[i++] & 0xF];
clusters+=nc[bits[i]>>4];clusters+=nc[bits[i++] & 0xF];
}
- for(;i<io.size;){
- clusters+=nc[bits[i]>>4];clusters+=nc[bits[i++] & 0xF];
+ while (i < io.size) {
+ clusters += nc[bits[i] >> 4];
+ clusters += nc[bits[i++] & 0xF];
}
- offset+=io.size;
+ offset += io.size;
}
return clusters;
}
-/* Insert the fixups for the record. The number and location of the fixes
- is obtained from the record header */
+/* Insert the fixups for the record. The number and location of the fixes
+ * is obtained from the record header */
void ntfs_insert_fixups(unsigned char *rec, int secsize)
{
- int first=NTFS_GETU16(rec+4);
- int count=NTFS_GETU16(rec+6);
- int offset=-2;
- ntfs_u16 fix=NTFS_GETU16(rec+first);
- fix=fix+1;
- NTFS_PUTU16(rec+first,fix);
+ int first = NTFS_GETU16(rec + 4);
+ int count = NTFS_GETU16(rec + 6);
+ int offset = -2;
+ ntfs_u16 fix = NTFS_GETU16(rec + first);
+
+ fix++;
+ if (fix == 0xffff || !fix)
+ fix = 1;
+ NTFS_PUTU16(rec + first, fix);
count--;
- while(count--){
- first+=2;
- offset+=secsize;
- NTFS_PUTU16(rec+first,NTFS_GETU16(rec+offset));
- NTFS_PUTU16(rec+offset,fix);
+ while (count--) {
+ first += 2;
+ offset += secsize;
+ NTFS_PUTU16(rec + first, NTFS_GETU16(rec + offset));
+ NTFS_PUTU16(rec + offset, fix);
};
}
-/* search the bitmap bits of l bytes for *cnt zero bits. Return the bit
- number in *loc, which is initially set to the number of the first bit.
- Return the largest block found in *cnt. Return 0 on success, ENOSPC if
- all bits are used */
-static int
-search_bits(unsigned char* bits,ntfs_cluster_t *loc,int *cnt,int l)
-{
- unsigned char c=0;
- int bc=0;
- int bstart=0,bstop=0,found=0;
- int start,stop=0,in=0;
+/* Search the bitmap bits of l bytes for *cnt zero bits. Return the bit number
+ * in *loc, which is initially set to the number of the first bit. Return the
+ * largest block found in *cnt. Return 0 on success, -ENOSPC if all bits are
+ * used. */
+static int search_bits(unsigned char* bits, ntfs_cluster_t *loc, int *cnt,int l)
+{
+ unsigned char c = 0;
+ int bc = 0;
+ int bstart = 0, bstop = 0, found = 0;
+ int start, stop = 0, in = 0;
/* special case searching for a single block */
- if(*cnt==1){
- while(l && *bits==0xFF){
+ if (*cnt == 1) {
+ while (l && *bits == 0xFF) {
bits++;
- *loc+=8;
+ *loc += 8;
l--;
}
- if(!l)return ENOSPC;
- for(c=*bits;c & 1;c>>=1)
+ if (!l)
+ return -ENOSPC;
+ for (c = *bits; c & 1; c >>= 1)
(*loc)++;
return 0;
}
- start=*loc;
- while(l || bc){
- if(bc==0){
- c=*bits;
- if(l){
- l--;bits++;
+ start = *loc;
+ while (l || bc) {
+ if (bc == 0) {
+ c = *bits;
+ if (l) {
+ l--;
+ bits++;
}
- bc=8;
+ bc = 8;
}
- if(in){
- if((c&1)==0)
+ if (in) {
+ if ((c & 1) == 0)
stop++;
- else{ /* end of sequence of zeroes */
- in=0;
- if(!found || bstop-bstart<stop-start){
- bstop=stop;bstart=start;found=1;
- if(bstop-bstart>*cnt)
+ else { /* end of sequence of zeroes */
+ in = 0;
+ if (!found || bstop-bstart < stop-start) {
+ bstop = stop; bstart = start;
+ found = 1;
+ if (bstop - bstart > *cnt)
break;
}
- start=stop+1;
+ start = stop + 1;
}
- }else{
- if(c&1)
+ } else {
+ if (c & 1)
start++;
- else{ /*start of sequence*/
- in=1;
- stop=start+1;
+ else { /*start of sequence*/
+ in = 1;
+ stop = start + 1;
}
}
bc--;
- c>>=1;
+ c >>= 1;
}
- if(in && (!found || bstop-bstart<stop-start)){
- bstop=stop;bstart=start;found=1;
+ if (in && (!found || bstop - bstart < stop - start)) {
+ bstop = stop; bstart = start; found = 1;
}
- if(!found)return ENOSPC;
- *loc=bstart;
- if(*cnt>bstop-bstart)
- *cnt=bstop-bstart;
+ if (!found)
+ return -ENOSPC;
+ *loc = bstart;
+ if (*cnt > bstop - bstart)
+ *cnt = bstop - bstart;
return 0;
}
-int
-ntfs_set_bitrange(ntfs_inode* bitmap,ntfs_cluster_t loc,int cnt,int bit)
+int ntfs_set_bitrange(ntfs_inode* bitmap, ntfs_cluster_t loc, int cnt, int bit)
{
- int bsize,locit,error;
- unsigned char *bits,*it;
+ int bsize, locit, error;
+ unsigned char *bits, *it;
ntfs_io io;
- io.fn_put=ntfs_put;
- io.fn_get=ntfs_get;
- bsize=(cnt+(loc & 7)+7) >> 3; /* round up to multiple of 8*/
- bits=ntfs_malloc(bsize);
- io.param=bits;
- io.size=bsize;
- if(!bits)
- return ENOMEM;
- error=ntfs_read_attr(bitmap,bitmap->vol->at_data,0,loc>>3,&io);
- if(error || io.size!=bsize){
+ io.fn_put = ntfs_put;
+ io.fn_get = ntfs_get;
+ bsize = (cnt + (loc & 7) + 7) >> 3; /* round up to multiple of 8*/
+ bits = ntfs_malloc(bsize);
+ if (!bits)
+ return -ENOMEM;
+ io.param = bits;
+ io.size = bsize;
+ error = ntfs_read_attr(bitmap, bitmap->vol->at_data, 0, loc >> 3, &io);
+ if (error || io.size != bsize){
ntfs_free(bits);
- return error?error:EIO;
+ return error ? error : -EIO;
}
- /* now set the bits */
- it=bits;
- locit=loc;
- while(locit%8 && cnt){ /* process first byte */
- if(bit)
- *it |= 1<<(locit%8);
+ /* Now set the bits. */
+ it = bits;
+ locit = loc;
+ while (locit % 8 && cnt) { /* process first byte */
+ if (bit)
+ *it |= 1 << (locit % 8);
else
- *it &= ~(1<<(locit%8));
- cnt--;locit++;
- if(locit%8==0)
+ *it &= ~(1 << (locit % 8));
+ cnt--;
+ locit++;
+ if (locit % 8 == 0)
it++;
}
- while(cnt>8){ /*process full bytes */
- *it= bit ? 0xFF : 0;
- cnt-=8;
- locit+=8;
+ while (cnt > 8) { /*process full bytes */
+ *it = bit ? 0xFF : 0;
+ cnt -= 8;
+ locit += 8;
it++;
}
- while(cnt){ /*process last byte */
- if(bit)
- *it |= 1<<(locit%8);
+ while (cnt) { /*process last byte */
+ if (bit)
+ *it |= 1 << (locit % 8);
else
- *it &= ~(1<<(locit%8));
- cnt--;locit++;
+ *it &= ~(1 << (locit % 8));
+ cnt--;
+ locit++;
}
/* reset to start */
- io.param=bits;
- io.size=bsize;
- error=ntfs_write_attr(bitmap,bitmap->vol->at_data,0,loc>>3,&io);
+ io.param = bits;
+ io.size = bsize;
+ error = ntfs_write_attr(bitmap, bitmap->vol->at_data, 0, loc >> 3, &io);
ntfs_free(bits);
- if(error)return error;
- if(io.size!=bsize)
- return EIO;
+ if (error)
+ return error;
+ if (io.size != bsize)
+ return -EIO;
return 0;
}
-
-
-/* allocate count clusters around location. If location is -1,
- it does not matter where the clusters are. Result is 0 if
- success, in which case location and count says what they really got */
-int
-ntfs_search_bits(ntfs_inode* bitmap, ntfs_cluster_t *location, int *count, int flags)
+/* Allocate count clusters around location. If location is -1, it does not
+ * matter where the clusters are. Result is 0 if success, in which case
+ * location and count says what they really got. */
+int ntfs_search_bits(ntfs_inode* bitmap, ntfs_cluster_t *location, int *count,
+ int flags)
{
unsigned char *bits;
ntfs_io io;
- int error=0,found=0;
- int cnt,bloc=-1,bcnt=0;
+ int error = 0, found = 0;
+ int cnt, bloc = -1, bcnt = 0;
int start;
ntfs_cluster_t loc;
- bits=ntfs_malloc(2048);
- if( !bits )
- return ENOMEM;
- io.fn_put=ntfs_put;
- io.fn_get=ntfs_get;
- io.param=bits;
+ bits = ntfs_malloc(2048);
+ if (!bits)
+ return -ENOMEM;
+ io.fn_put = ntfs_put;
+ io.fn_get = ntfs_get;
+ io.param = bits;
/* first search within +/- 8192 clusters */
- start=*location>>3;
- start= start>1024 ? start-1024 : 0;
- io.size=2048;
- error=ntfs_read_attr(bitmap,bitmap->vol->at_data,0,start,&io);
- if(error)goto fail;
- loc=start*8;
- cnt=*count;
- error=search_bits(bits,&loc,&cnt,io.size);
- if(error)
+ start = *location >> 3;
+ start = start > 1024 ? start - 1024 : 0;
+ io.size = 2048;
+ error = ntfs_read_attr(bitmap, bitmap->vol->at_data, 0, start, &io);
+ if (error)
goto fail;
- if(*count==cnt){
- bloc=loc;
- bcnt=cnt;
+ loc = start * 8;
+ cnt = *count;
+ error = search_bits(bits, &loc, &cnt, io.size);
+ if (error)
+ goto fail;
+ if (*count == cnt){
+ bloc = loc;
+ bcnt = cnt;
goto success;
}
-
- /* now search from the beginning */
- for(start=0;1;start+=2048)
- {
- io.param=bits;
- io.size=2048;
- error=ntfs_read_attr(bitmap,bitmap->vol->at_data,
- 0,start,&io);
- if(error)goto fail;
- if(io.size==0){
+ /* Now search from the beginning. */
+ for (start = 0; 1; start += 2048) {
+ io.param = bits;
+ io.size = 2048;
+ error = ntfs_read_attr(bitmap, bitmap->vol->at_data, 0, start,
+ &io);
+ if (error)
+ goto fail;
+ if (io.size == 0) {
if(found)
goto success;
- else{
- error=ENOSPC;
+ else {
+ error = -ENOSPC;
goto fail;
}
}
- loc=start*8;
- cnt=*count;
- error=search_bits(bits,&loc,&cnt,io.size);
- if(error)
+ loc = start * 8;
+ cnt = *count;
+ error = search_bits(bits, &loc, &cnt, io.size);
+ if (error)
goto fail;
- if(*count==cnt)
+ if (*count == cnt)
goto success;
- if(bcnt<cnt){
- bcnt=cnt;
- bloc=loc;
- found=1;
+ if (bcnt < cnt) {
+ bcnt = cnt;
+ bloc = loc;
+ found = 1;
}
}
success:
ntfs_free(bits);
/* check flags */
- if((flags & ALLOC_REQUIRE_LOCATION) && *location!=bloc)
- error=ENOSPC;
- else if((flags & ALLOC_REQUIRE_SIZE) && *count!=bcnt)
- error=ENOSPC;
- else ntfs_set_bitrange(bitmap,bloc,bcnt,1);
- /* If allocation failed due to the flags, tell the caller what he
- could have gotten */
- *location=bloc;
- *count=bcnt;
+ if ((flags & ALLOC_REQUIRE_LOCATION) && *location != bloc)
+ error = -ENOSPC;
+ else if ((flags & ALLOC_REQUIRE_SIZE) && *count != bcnt)
+ error = -ENOSPC;
+ else
+ ntfs_set_bitrange(bitmap, bloc, bcnt, 1);
+ /* If allocation failed due to the flags, tell the caller what he could
+ * have gotten */
+ *location = bloc;
+ *count = bcnt;
return 0;
fail:
- *location=-1;
- *count=0;
+ *location = -1;
+ *count = 0;
ntfs_free(bits);
return error;
}
-int ntfs_allocate_clusters(ntfs_volume *vol, ntfs_cluster_t *location, int *count,
- int flags)
+int ntfs_allocate_clusters(ntfs_volume *vol, ntfs_cluster_t *location,
+ int *count, int flags)
{
int error;
- error=ntfs_search_bits(vol->bitmap,location,count,flags);
+ error = ntfs_search_bits(vol->bitmap, location, count, flags);
return error;
}
-int ntfs_deallocate_clusters(ntfs_volume *vol, ntfs_cluster_t location, int count)
+int ntfs_deallocate_clusters(ntfs_volume *vol, ntfs_cluster_t location,
+ int count)
{
int error;
- error=ntfs_set_bitrange(vol->bitmap,location,count,0);
+ error = ntfs_set_bitrange(vol->bitmap, location, count, 0);
return error;
}
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
-
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)