4 * Copyright (C) 1995-1997 Martin von Löwis
5 * Copyright (C) 1996-1997 Régis Duchesne
12 #include <linux/errno.h>
19 * All important structures in NTFS use 2 consistency checks :
20 * . a magic structure identifier (FILE, INDX, RSTR, RCRD...)
21 * . a fixup technique : the last word of each sector (called a fixup) of a
22 * structure's record should end with the word at offset <n> of the first
23 * sector, and if it is the case, must be replaced with the words following
24 * <n>. The value of <n> and the number of fixups is taken from the fields
25 * at the offsets 4 and 6.
27 * This function perform these 2 checks, and _fails_ if :
28 * . the magic identifier is wrong
29 * . the size is given and does not match the number of sectors
30 * . a fixup is invalid
32 int ntfs_fixup_record(ntfs_volume
*vol
, char *record
, char *magic
, int size
)
34 int start
, count
, offset
;
37 if(!IS_MAGIC(record
,magic
))
39 start
=NTFS_GETU16(record
+4);
40 count
=NTFS_GETU16(record
+6);
42 if(size
&& vol
->blocksize
*count
!= size
)
44 fixup
= NTFS_GETU16(record
+start
);
46 offset
=vol
->blocksize
-2;
48 if(NTFS_GETU16(record
+offset
)!=fixup
)
50 NTFS_PUTU16(record
+offset
, NTFS_GETU16(record
+start
));
52 offset
+=vol
->blocksize
;
57 /* Get vital informations about the ntfs partition from the boot sector */
58 int ntfs_init_volume(ntfs_volume
*vol
,char *boot
)
60 /* Historical default values, in case we don't load $AttrDef */
61 vol
->at_standard_information
=0x10;
62 vol
->at_attribute_list
=0x20;
63 vol
->at_file_name
=0x30;
64 vol
->at_security_descriptor
=0x50;
66 vol
->at_index_root
=0x90;
67 vol
->at_index_allocation
=0xA0;
72 vol
->blocksize
=NTFS_GETU16(boot
+0xB);
73 vol
->clusterfactor
=NTFS_GETU8(boot
+0xD);
74 vol
->mft_clusters_per_record
=NTFS_GETS8(boot
+0x40);
75 vol
->index_clusters_per_record
=NTFS_GETS8(boot
+0x44);
77 /* Just some consistency checks */
78 if(NTFS_GETU32(boot
+0x40)>256)
79 ntfs_error("Unexpected data #1 in boot block\n");
80 if(NTFS_GETU32(boot
+0x44)>256)
81 ntfs_error("Unexpected data #2 in boot block\n");
82 if(vol
->index_clusters_per_record
<0){
83 ntfs_error("Unexpected data #3 in boot block\n");
84 /* If this really means a fraction, setting it to 1
86 vol
->index_clusters_per_record
=1;
88 /* in some cases, 0xF6 meant 1024 bytes. Other strange values have not
90 if(vol
->mft_clusters_per_record
<0 && vol
->mft_clusters_per_record
!=-10)
91 ntfs_error("Unexpected data #4 in boot block\n");
93 vol
->clustersize
=vol
->blocksize
*vol
->clusterfactor
;
94 if(vol
->mft_clusters_per_record
>0)
96 vol
->clustersize
*vol
->mft_clusters_per_record
;
98 vol
->mft_recordsize
=1<<(-vol
->mft_clusters_per_record
);
99 vol
->index_recordsize
=vol
->clustersize
*vol
->index_clusters_per_record
;
100 /* FIXME: long long value */
101 vol
->mft_cluster
=NTFS_GETU64(boot
+0x30);
103 /* This will be initialized later */
105 vol
->upcase_length
=0;
111 ntfs_init_upcase(ntfs_inode
*upcase
)
114 #define UPCASE_LENGTH 256
115 upcase
->vol
->upcase
= ntfs_malloc(2*UPCASE_LENGTH
);
116 upcase
->vol
->upcase_length
= UPCASE_LENGTH
;
119 io
.param
=(char*)upcase
->vol
->upcase
;
120 io
.size
=2*UPCASE_LENGTH
;
121 ntfs_read_attr(upcase
,upcase
->vol
->at_data
,0,0,&io
);
125 process_attrdef(ntfs_inode
* attrdef
,ntfs_u8
* def
)
127 int type
= NTFS_GETU32(def
+0x80);
129 ntfs_volume
*vol
=attrdef
->vol
;
130 ntfs_u16
* name
= (ntfs_u16
*)def
;
132 if(ntfs_ua_strncmp(name
,"$STANDARD_INFORMATION",64)==0){
133 vol
->at_standard_information
=type
;
135 }else if(ntfs_ua_strncmp(name
,"$ATTRIBUTE_LIST",64)==0){
136 vol
->at_attribute_list
=type
;
138 }else if(ntfs_ua_strncmp(name
,"$FILE_NAME",64)==0){
139 vol
->at_file_name
=type
;
141 }else if(ntfs_ua_strncmp(name
,"$SECURITY_DESCRIPTOR",64)==0){
142 vol
->at_file_name
=type
;
143 }else if(ntfs_ua_strncmp(name
,"$DATA",64)==0){
146 }else if(ntfs_ua_strncmp(name
,"$INDEX_ROOT",64)==0){
147 vol
->at_index_root
=type
;
149 }else if(ntfs_ua_strncmp(name
,"$INDEX_ALLOCATION",64)==0){
150 vol
->at_index_allocation
=type
;
152 }else if(ntfs_ua_strncmp(name
,"$BITMAP",64)==0){
155 }else if(ntfs_ua_strncmp(name
,"$SYMBOLIC_LINK",64)==0 ||
156 ntfs_ua_strncmp(name
,"$REPARSE_POINT",64)==0){
157 vol
->at_symlink
=type
;
159 if(check_type
&& check_type
!=type
){
160 ntfs_error("Unexpected type %x for %x\n",type
,check_type
);
167 ntfs_init_attrdef(ntfs_inode
* attrdef
)
172 ntfs_attribute
*data
;
173 buf
=ntfs_malloc(4050); /* 90*45 */
174 if(!buf
)return ENOMEM
;
179 data
=ntfs_find_attr(attrdef
,attrdef
->vol
->at_data
,0);
187 error
=ntfs_readwrite_attr(attrdef
,data
,offset
,&io
);
188 for(i
=0;!error
&& i
<io
.size
-0xA0;i
+=0xA0)
189 error
=process_attrdef(attrdef
,buf
+i
);
191 }while(!error
&& io
.size
);
196 int ntfs_load_special_files(ntfs_volume
*vol
)
199 ntfs_inode upcase
,attrdef
;
201 vol
->mft_ino
=(ntfs_inode
*)ntfs_calloc(3*sizeof(ntfs_inode
));
203 ntfs_debug(DEBUG_BSD
,"Going to load MFT\n");
204 if(!vol
->mft_ino
|| (error
=ntfs_init_inode(vol
->mft_ino
,vol
,FILE_MFT
)))
206 ntfs_error("Problem loading MFT\n");
209 ntfs_debug(DEBUG_BSD
,"Going to load MIRR\n");
210 vol
->mftmirr
=vol
->mft_ino
+1;
211 if((error
=ntfs_init_inode(vol
->mftmirr
,vol
,FILE_MFTMIRR
))){
212 ntfs_error("Problem %d loading MFTMirr\n",error
);
215 ntfs_debug(DEBUG_BSD
,"Going to load BITMAP\n");
216 vol
->bitmap
=vol
->mft_ino
+2;
217 if((error
=ntfs_init_inode(vol
->bitmap
,vol
,FILE_BITMAP
))){
218 ntfs_error("Problem loading Bitmap\n");
221 ntfs_debug(DEBUG_BSD
,"Going to load UPCASE\n");
222 error
=ntfs_init_inode(&upcase
,vol
,FILE_UPCASE
);
223 if(error
)return error
;
224 ntfs_init_upcase(&upcase
);
225 ntfs_clear_inode(&upcase
);
226 ntfs_debug(DEBUG_BSD
,"Going to load ATTRDEF\n");
227 error
=ntfs_init_inode(&attrdef
,vol
,FILE_ATTRDEF
);
228 if(error
)return error
;
229 error
=ntfs_init_attrdef(&attrdef
);
230 ntfs_clear_inode(&attrdef
);
231 if(error
)return error
;
235 int ntfs_release_volume(ntfs_volume
*vol
)
238 ntfs_clear_inode(vol
->mft_ino
);
239 ntfs_clear_inode(vol
->mftmirr
);
240 ntfs_clear_inode(vol
->bitmap
);
241 ntfs_free(vol
->mft_ino
);
245 ntfs_free(vol
->upcase
);
249 int ntfs_get_volumesize(ntfs_volume
*vol
)
252 char *cluster0
=ntfs_malloc(vol
->clustersize
);
259 io
.size
=vol
->clustersize
;
260 ntfs_getput_clusters(vol
,0,0,&io
);
261 size
=NTFS_GETU64(cluster0
+0x28);
263 /* FIXME: more than 2**32 cluster */
264 /* FIXME: gcc will emit udivdi3 if we don't truncate it */
265 return ((unsigned int)size
)/vol
->clusterfactor
;
268 static int nc
[16]={4,3,3,2,3,2,2,1,3,2,2,1,2,1,1,0};
271 ntfs_get_free_cluster_count(ntfs_inode
*bitmap
)
273 unsigned char bits
[2048];
286 error
=ntfs_read_attr(bitmap
,bitmap
->vol
->at_data
,0,
288 if(error
|| io
.size
==0)break;
289 /* I never thought I would do loop unrolling some day */
290 for(i
=0;i
<io
.size
-8;){
291 clusters
+=nc
[bits
[i
]>>4];clusters
+=nc
[bits
[i
++] & 0xF];
292 clusters
+=nc
[bits
[i
]>>4];clusters
+=nc
[bits
[i
++] & 0xF];
293 clusters
+=nc
[bits
[i
]>>4];clusters
+=nc
[bits
[i
++] & 0xF];
294 clusters
+=nc
[bits
[i
]>>4];clusters
+=nc
[bits
[i
++] & 0xF];
295 clusters
+=nc
[bits
[i
]>>4];clusters
+=nc
[bits
[i
++] & 0xF];
296 clusters
+=nc
[bits
[i
]>>4];clusters
+=nc
[bits
[i
++] & 0xF];
297 clusters
+=nc
[bits
[i
]>>4];clusters
+=nc
[bits
[i
++] & 0xF];
298 clusters
+=nc
[bits
[i
]>>4];clusters
+=nc
[bits
[i
++] & 0xF];
301 clusters
+=nc
[bits
[i
]>>4];clusters
+=nc
[bits
[i
++] & 0xF];
308 /* Insert the fixups for the record. The number and location of the fixes
309 is obtained from the record header */
310 void ntfs_insert_fixups(unsigned char *rec
, int secsize
)
312 int first
=NTFS_GETU16(rec
+4);
313 int count
=NTFS_GETU16(rec
+6);
315 ntfs_u16 fix
=NTFS_GETU16(rec
+first
);
317 NTFS_PUTU16(rec
+first
,fix
);
322 NTFS_PUTU16(rec
+first
,NTFS_GETU16(rec
+offset
));
323 NTFS_PUTU16(rec
+offset
,fix
);
327 /* search the bitmap bits of l bytes for *cnt zero bits. Return the bit
328 number in *loc, which is initially set to the number of the first bit.
329 Return the largest block found in *cnt. Return 0 on success, ENOSPC if
332 search_bits(unsigned char* bits
,ntfs_cluster_t
*loc
,int *cnt
,int l
)
336 int bstart
=0,bstop
=0,found
=0;
337 int start
,stop
=0,in
=0;
338 /* special case searching for a single block */
340 while(l
&& *cnt
==0xFF){
346 for(c
=*bits
;c
& 1;c
>>=1)
362 else{ /* end of sequence of zeroes */
364 if(!found
|| bstop
-bstart
<stop
-start
){
365 bstop
=stop
;bstart
=start
;found
=1;
366 if(bstop
-bstart
>*cnt
)
374 else{ /*start of sequence*/
382 if(in
&& (!found
|| bstop
-bstart
<stop
-start
)){
383 bstop
=stop
;bstart
=start
;found
=1;
385 if(!found
)return ENOSPC
;
387 if(*cnt
>bstop
-bstart
)
393 ntfs_set_bitrange(ntfs_inode
* bitmap
,ntfs_cluster_t loc
,int cnt
,int bit
)
395 int bsize
,locit
,error
;
396 unsigned char *bits
,*it
;
401 bsize
=(cnt
+(loc
& 7)+7) & ~7; /* round up to multiple of 8*/
402 bits
=ntfs_malloc(bsize
);
407 error
=ntfs_read_attr(bitmap
,bitmap
->vol
->at_data
,0,loc
>>3,&io
);
408 if(error
|| io
.size
!=bsize
){
410 return error
?error
:EIO
;
412 /* now set the bits */
415 while(locit
%8 && cnt
){ /* process first byte */
419 *it
&= ~(1<<(locit
%8));
424 while(cnt
>8){ /*process full bytes */
430 while(cnt
){ /*process last byte */
434 *it
&= ~(1<<(locit
%8));
440 error
=ntfs_write_attr(bitmap
,bitmap
->vol
->at_data
,0,loc
>>3,&io
);
442 if(error
)return error
;
450 /* allocate count clusters around location. If location is -1,
451 it does not matter where the clusters are. Result is 0 if
452 success, in which case location and count says what they really got */
454 ntfs_search_bits(ntfs_inode
* bitmap
, ntfs_cluster_t
*location
, int *count
, int flags
)
459 int loc
,cnt
,bloc
=-1,bcnt
=0;
462 bits
=ntfs_malloc(2048);
467 /* first search within +/- 8192 clusters */
469 start
= start
>1024 ? start
-1024 : 0;
471 error
=ntfs_read_attr(bitmap
,bitmap
->vol
->at_data
,0,start
,&io
);
475 error
=search_bits(bits
,&loc
,&cnt
,io
.size
);
484 /* now search from the beginning */
485 for(start
=0;1;start
+=2048)
489 error
=ntfs_read_attr(bitmap
,bitmap
->vol
->at_data
,
502 error
=search_bits(bits
,&loc
,&cnt
,io
.size
);
516 if((flags
& ALLOC_REQUIRE_LOCATION
) && *location
!=bloc
)
518 else if((flags
& ALLOC_REQUIRE_SIZE
) && *count
!=bcnt
)
520 else ntfs_set_bitrange(bitmap
,bloc
,bcnt
,1);
521 /* If allocation failed due to the flags, tell the caller what he
533 int ntfs_allocate_clusters(ntfs_volume
*vol
, ntfs_cluster_t
*location
, int *count
,
537 error
=ntfs_search_bits(vol
->bitmap
,location
,count
,flags
);
541 int ntfs_deallocate_clusters(ntfs_volume
*vol
, ntfs_cluster_t location
, int count
)
544 error
=ntfs_set_bitrange(vol
->bitmap
,location
,count
,0);
550 * c-file-style: "linux"