4 * Copyright (C) 1995-1997, 1999 Martin von Löwis
5 * Copyright (C) 1996-1997 Régis Duchesne
6 * Copyright (C) 1999 Steve Dodd
13 #include <linux/errno.h>
20 * All important structures in NTFS use 2 consistency checks :
21 * . a magic structure identifier (FILE, INDX, RSTR, RCRD...)
22 * . a fixup technique : the last word of each sector (called a fixup) of a
23 * structure's record should end with the word at offset <n> of the first
24 * sector, and if it is the case, must be replaced with the words following
25 * <n>. The value of <n> and the number of fixups is taken from the fields
26 * at the offsets 4 and 6.
28 * This function perform these 2 checks, and _fails_ if :
29 * . the magic identifier is wrong
30 * . the size is given and does not match the number of sectors
31 * . a fixup is invalid
33 int ntfs_fixup_record(ntfs_volume
*vol
, char *record
, char *magic
, int size
)
35 int start
, count
, offset
;
38 if(!IS_MAGIC(record
,magic
))
40 start
=NTFS_GETU16(record
+4);
41 count
=NTFS_GETU16(record
+6);
43 if(size
&& vol
->blocksize
*count
!= size
)
45 fixup
= NTFS_GETU16(record
+start
);
47 offset
=vol
->blocksize
-2;
49 if(NTFS_GETU16(record
+offset
)!=fixup
)
51 NTFS_PUTU16(record
+offset
, NTFS_GETU16(record
+start
));
53 offset
+=vol
->blocksize
;
58 /* Get vital informations about the ntfs partition from the boot sector */
59 int ntfs_init_volume(ntfs_volume
*vol
,char *boot
)
61 /* Historical default values, in case we don't load $AttrDef */
62 vol
->at_standard_information
=0x10;
63 vol
->at_attribute_list
=0x20;
64 vol
->at_file_name
=0x30;
65 vol
->at_security_descriptor
=0x50;
67 vol
->at_index_root
=0x90;
68 vol
->at_index_allocation
=0xA0;
73 vol
->blocksize
=NTFS_GETU16(boot
+0xB);
74 vol
->clusterfactor
=NTFS_GETU8(boot
+0xD);
75 vol
->mft_clusters_per_record
=NTFS_GETS8(boot
+0x40);
76 vol
->index_clusters_per_record
=NTFS_GETS8(boot
+0x44);
78 /* Just some consistency checks */
79 if(NTFS_GETU32(boot
+0x40)>256)
80 ntfs_error("Unexpected data #1 in boot block\n");
81 if(NTFS_GETU32(boot
+0x44)>256)
82 ntfs_error("Unexpected data #2 in boot block\n");
83 if(vol
->index_clusters_per_record
<0){
84 ntfs_error("Unexpected data #3 in boot block\n");
85 /* If this really means a fraction, setting it to 1
87 vol
->index_clusters_per_record
=1;
89 /* in some cases, 0xF6 meant 1024 bytes. Other strange values have not
91 if(vol
->mft_clusters_per_record
<0 && vol
->mft_clusters_per_record
!=-10)
92 ntfs_error("Unexpected data #4 in boot block\n");
94 vol
->clustersize
=vol
->blocksize
*vol
->clusterfactor
;
95 if(vol
->mft_clusters_per_record
>0)
97 vol
->clustersize
*vol
->mft_clusters_per_record
;
99 vol
->mft_recordsize
=1<<(-vol
->mft_clusters_per_record
);
100 vol
->index_recordsize
=vol
->clustersize
*vol
->index_clusters_per_record
;
101 /* FIXME: long long value */
102 vol
->mft_cluster
=NTFS_GETU64(boot
+0x30);
104 /* This will be initialized later */
106 vol
->upcase_length
=0;
112 ntfs_init_upcase(ntfs_inode
*upcase
)
115 #define UPCASE_LENGTH 256
116 upcase
->vol
->upcase
= ntfs_malloc(2*UPCASE_LENGTH
);
117 if( !upcase
->vol
->upcase
)
121 io
.param
=(char*)upcase
->vol
->upcase
;
122 io
.size
=2*UPCASE_LENGTH
;
123 ntfs_read_attr(upcase
,upcase
->vol
->at_data
,0,0,&io
);
124 upcase
->vol
->upcase_length
= io
.size
;
128 process_attrdef(ntfs_inode
* attrdef
,ntfs_u8
* def
)
130 int type
= NTFS_GETU32(def
+0x80);
132 ntfs_volume
*vol
=attrdef
->vol
;
133 ntfs_u16
* name
= (ntfs_u16
*)def
;
135 if(ntfs_ua_strncmp(name
,"$STANDARD_INFORMATION",64)==0){
136 vol
->at_standard_information
=type
;
138 }else if(ntfs_ua_strncmp(name
,"$ATTRIBUTE_LIST",64)==0){
139 vol
->at_attribute_list
=type
;
141 }else if(ntfs_ua_strncmp(name
,"$FILE_NAME",64)==0){
142 vol
->at_file_name
=type
;
144 }else if(ntfs_ua_strncmp(name
,"$SECURITY_DESCRIPTOR",64)==0){
145 vol
->at_file_name
=type
;
146 }else if(ntfs_ua_strncmp(name
,"$DATA",64)==0){
149 }else if(ntfs_ua_strncmp(name
,"$INDEX_ROOT",64)==0){
150 vol
->at_index_root
=type
;
152 }else if(ntfs_ua_strncmp(name
,"$INDEX_ALLOCATION",64)==0){
153 vol
->at_index_allocation
=type
;
155 }else if(ntfs_ua_strncmp(name
,"$BITMAP",64)==0){
158 }else if(ntfs_ua_strncmp(name
,"$SYMBOLIC_LINK",64)==0 ||
159 ntfs_ua_strncmp(name
,"$REPARSE_POINT",64)==0){
160 vol
->at_symlink
=type
;
162 if(check_type
&& check_type
!=type
){
163 ntfs_error("Unexpected type %x for %x\n",type
,check_type
);
170 ntfs_init_attrdef(ntfs_inode
* attrdef
)
175 ntfs_attribute
*data
;
176 buf
=ntfs_malloc(4050); /* 90*45 */
177 if(!buf
)return ENOMEM
;
182 data
=ntfs_find_attr(attrdef
,attrdef
->vol
->at_data
,0);
190 error
=ntfs_readwrite_attr(attrdef
,data
,offset
,&io
);
191 for(i
=0;!error
&& i
<io
.size
-0xA0;i
+=0xA0)
192 error
=process_attrdef(attrdef
,buf
+i
);
194 }while(!error
&& io
.size
);
199 int ntfs_load_special_files(ntfs_volume
*vol
)
202 ntfs_inode upcase
,attrdef
;
204 vol
->mft_ino
=(ntfs_inode
*)ntfs_calloc(3*sizeof(ntfs_inode
));
206 ntfs_debug(DEBUG_BSD
,"Going to load MFT\n");
207 if(!vol
->mft_ino
|| (error
=ntfs_init_inode(vol
->mft_ino
,vol
,FILE_MFT
)))
209 ntfs_error("Problem loading MFT\n");
212 ntfs_debug(DEBUG_BSD
,"Going to load MIRR\n");
213 vol
->mftmirr
=vol
->mft_ino
+1;
214 if((error
=ntfs_init_inode(vol
->mftmirr
,vol
,FILE_MFTMIRR
))){
215 ntfs_error("Problem %d loading MFTMirr\n",error
);
218 ntfs_debug(DEBUG_BSD
,"Going to load BITMAP\n");
219 vol
->bitmap
=vol
->mft_ino
+2;
220 if((error
=ntfs_init_inode(vol
->bitmap
,vol
,FILE_BITMAP
))){
221 ntfs_error("Problem loading Bitmap\n");
224 ntfs_debug(DEBUG_BSD
,"Going to load UPCASE\n");
225 error
=ntfs_init_inode(&upcase
,vol
,FILE_UPCASE
);
226 if(error
)return error
;
227 ntfs_init_upcase(&upcase
);
228 ntfs_clear_inode(&upcase
);
229 ntfs_debug(DEBUG_BSD
,"Going to load ATTRDEF\n");
230 error
=ntfs_init_inode(&attrdef
,vol
,FILE_ATTRDEF
);
231 if(error
)return error
;
232 error
=ntfs_init_attrdef(&attrdef
);
233 ntfs_clear_inode(&attrdef
);
234 if(error
)return error
;
238 int ntfs_release_volume(ntfs_volume
*vol
)
241 ntfs_clear_inode(vol
->mft_ino
);
242 ntfs_clear_inode(vol
->mftmirr
);
243 ntfs_clear_inode(vol
->bitmap
);
244 ntfs_free(vol
->mft_ino
);
248 ntfs_free(vol
->upcase
);
253 * Writes the volume size into vol_size. Returns 0 if successful
256 int ntfs_get_volumesize(ntfs_volume
*vol
, long *vol_size
)
265 cluster0
=ntfs_malloc(vol
->clustersize
);
273 io
.size
=vol
->clustersize
;
274 ntfs_getput_clusters(vol
,0,0,&io
);
275 size
=NTFS_GETU64(cluster0
+0x28);
277 /* FIXME: more than 2**32 cluster */
278 /* FIXME: gcc will emit udivdi3 if we don't truncate it */
279 *vol_size
= ((unsigned long)size
)/vol
->clusterfactor
;
283 static int nc
[16]={4,3,3,2,3,2,2,1,3,2,2,1,2,1,1,0};
286 ntfs_get_free_cluster_count(ntfs_inode
*bitmap
)
288 unsigned char bits
[2048];
301 error
=ntfs_read_attr(bitmap
,bitmap
->vol
->at_data
,0,
303 if(error
|| io
.size
==0)break;
304 /* I never thought I would do loop unrolling some day */
305 for(i
=0;i
<io
.size
-8;){
306 clusters
+=nc
[bits
[i
]>>4];clusters
+=nc
[bits
[i
++] & 0xF];
307 clusters
+=nc
[bits
[i
]>>4];clusters
+=nc
[bits
[i
++] & 0xF];
308 clusters
+=nc
[bits
[i
]>>4];clusters
+=nc
[bits
[i
++] & 0xF];
309 clusters
+=nc
[bits
[i
]>>4];clusters
+=nc
[bits
[i
++] & 0xF];
310 clusters
+=nc
[bits
[i
]>>4];clusters
+=nc
[bits
[i
++] & 0xF];
311 clusters
+=nc
[bits
[i
]>>4];clusters
+=nc
[bits
[i
++] & 0xF];
312 clusters
+=nc
[bits
[i
]>>4];clusters
+=nc
[bits
[i
++] & 0xF];
313 clusters
+=nc
[bits
[i
]>>4];clusters
+=nc
[bits
[i
++] & 0xF];
316 clusters
+=nc
[bits
[i
]>>4];clusters
+=nc
[bits
[i
++] & 0xF];
323 /* Insert the fixups for the record. The number and location of the fixes
324 is obtained from the record header */
325 void ntfs_insert_fixups(unsigned char *rec
, int secsize
)
327 int first
=NTFS_GETU16(rec
+4);
328 int count
=NTFS_GETU16(rec
+6);
330 ntfs_u16 fix
=NTFS_GETU16(rec
+first
);
332 NTFS_PUTU16(rec
+first
,fix
);
337 NTFS_PUTU16(rec
+first
,NTFS_GETU16(rec
+offset
));
338 NTFS_PUTU16(rec
+offset
,fix
);
342 /* search the bitmap bits of l bytes for *cnt zero bits. Return the bit
343 number in *loc, which is initially set to the number of the first bit.
344 Return the largest block found in *cnt. Return 0 on success, ENOSPC if
347 search_bits(unsigned char* bits
,ntfs_cluster_t
*loc
,int *cnt
,int l
)
351 int bstart
=0,bstop
=0,found
=0;
352 int start
,stop
=0,in
=0;
353 /* special case searching for a single block */
355 while(l
&& *bits
==0xFF){
361 for(c
=*bits
;c
& 1;c
>>=1)
377 else{ /* end of sequence of zeroes */
379 if(!found
|| bstop
-bstart
<stop
-start
){
380 bstop
=stop
;bstart
=start
;found
=1;
381 if(bstop
-bstart
>*cnt
)
389 else{ /*start of sequence*/
397 if(in
&& (!found
|| bstop
-bstart
<stop
-start
)){
398 bstop
=stop
;bstart
=start
;found
=1;
400 if(!found
)return ENOSPC
;
402 if(*cnt
>bstop
-bstart
)
408 ntfs_set_bitrange(ntfs_inode
* bitmap
,ntfs_cluster_t loc
,int cnt
,int bit
)
410 int bsize
,locit
,error
;
411 unsigned char *bits
,*it
;
416 bsize
=(cnt
+(loc
& 7)+7) >> 3; /* round up to multiple of 8*/
417 bits
=ntfs_malloc(bsize
);
422 error
=ntfs_read_attr(bitmap
,bitmap
->vol
->at_data
,0,loc
>>3,&io
);
423 if(error
|| io
.size
!=bsize
){
425 return error
?error
:EIO
;
427 /* now set the bits */
430 while(locit
%8 && cnt
){ /* process first byte */
434 *it
&= ~(1<<(locit
%8));
439 while(cnt
>8){ /*process full bytes */
445 while(cnt
){ /*process last byte */
449 *it
&= ~(1<<(locit
%8));
455 error
=ntfs_write_attr(bitmap
,bitmap
->vol
->at_data
,0,loc
>>3,&io
);
457 if(error
)return error
;
465 /* allocate count clusters around location. If location is -1,
466 it does not matter where the clusters are. Result is 0 if
467 success, in which case location and count says what they really got */
469 ntfs_search_bits(ntfs_inode
* bitmap
, ntfs_cluster_t
*location
, int *count
, int flags
)
474 int cnt
,bloc
=-1,bcnt
=0;
478 bits
=ntfs_malloc(2048);
485 /* first search within +/- 8192 clusters */
487 start
= start
>1024 ? start
-1024 : 0;
489 error
=ntfs_read_attr(bitmap
,bitmap
->vol
->at_data
,0,start
,&io
);
493 error
=search_bits(bits
,&loc
,&cnt
,io
.size
);
502 /* now search from the beginning */
503 for(start
=0;1;start
+=2048)
507 error
=ntfs_read_attr(bitmap
,bitmap
->vol
->at_data
,
520 error
=search_bits(bits
,&loc
,&cnt
,io
.size
);
534 if((flags
& ALLOC_REQUIRE_LOCATION
) && *location
!=bloc
)
536 else if((flags
& ALLOC_REQUIRE_SIZE
) && *count
!=bcnt
)
538 else ntfs_set_bitrange(bitmap
,bloc
,bcnt
,1);
539 /* If allocation failed due to the flags, tell the caller what he
551 int ntfs_allocate_clusters(ntfs_volume
*vol
, ntfs_cluster_t
*location
, int *count
,
555 error
=ntfs_search_bits(vol
->bitmap
,location
,count
,flags
);
559 int ntfs_deallocate_clusters(ntfs_volume
*vol
, ntfs_cluster_t location
, int count
)
562 error
=ntfs_set_bitrange(vol
->bitmap
,location
,count
,0);
568 * c-file-style: "linux"