3 * NTFS driver for Linux 2.3.x
5 * Copyright (C) 1995-1997, 1999 Martin von Löwis
6 * Copyright (C) 1996 Richard Russon
7 * Copyright (C) 1996-1997 Régis Duchesne
8 * Copyright (C) 2000, Anton Altaparmakov
14 #ifdef NTFS_IN_LINUX_KERNEL
15 #include <linux/config.h>
18 #include "ntfstypes.h"
27 #include <linux/module.h>
28 #include <asm/uaccess.h>
29 #include <linux/nls.h>
30 #include <linux/locks.h>
31 #include <linux/init.h>
32 #include <linux/smp_lock.h>
34 /* Forward declarations */
35 static struct inode_operations ntfs_dir_inode_operations
;
36 static struct file_operations ntfs_dir_operations
;
38 #define ITEM_SIZE 2040
40 /* io functions to user space */
41 static void ntfs_putuser(ntfs_io
* dest
,void *src
,ntfs_size_t len
)
43 copy_to_user(dest
->param
,src
,len
);
48 struct ntfs_getuser_update_vm_s
{
54 static void ntfs_getuser_update_vm (void *dest
, ntfs_io
*src
, ntfs_size_t len
)
56 struct ntfs_getuser_update_vm_s
*p
= src
->param
;
57 copy_from_user (dest
, p
->user
, len
);
64 ntfs_read(struct file
* filp
, char *buf
, size_t count
, loff_t
*off
)
68 ntfs_inode
*ino
=NTFS_LINO2NINO(filp
->f_dentry
->d_inode
);
70 /* inode is not properly initialized */
71 if(!ino
)return -EINVAL
;
72 ntfs_debug(DEBUG_OTHER
, "ntfs_read %x,%x,%x ->",
73 (unsigned)ino
->i_number
,(unsigned)*off
,(unsigned)count
);
74 /* inode has no unnamed data attribute */
75 if(!ntfs_find_attr(ino
,ino
->vol
->at_data
,NULL
))
79 io
.fn_put
=ntfs_putuser
;
83 error
=ntfs_read_attr(ino
,ino
->vol
->at_data
,NULL
,*off
,&io
);
84 if(error
&& !io
.size
)return -error
;
92 ntfs_write(struct file
*filp
,const char* buf
,size_t count
,loff_t
*pos
)
96 struct inode
*inode
= filp
->f_dentry
->d_inode
;
97 ntfs_inode
*ino
= NTFS_LINO2NINO(inode
);
98 struct ntfs_getuser_update_vm_s param
;
102 ntfs_debug (DEBUG_LINUX
, "ntfs_write %x,%x,%x ->\n",
103 (unsigned)ino
->i_number
, (unsigned)*pos
, (unsigned)count
);
104 /* Allows to lock fs ro at any time */
105 if (inode
->i_sb
->s_flags
& MS_RDONLY
)
107 if (!ntfs_find_attr(ino
,ino
->vol
->at_data
,NULL
))
110 /* Evaluating O_APPEND is the file system's job... */
111 if (filp
->f_flags
& O_APPEND
)
112 *pos
= inode
->i_size
;
117 io
.fn_get
= ntfs_getuser_update_vm
;
120 ret
= ntfs_write_attr (ino
, ino
->vol
->at_data
, NULL
, *pos
, &io
);
121 ntfs_debug (DEBUG_LINUX
, "write -> %x\n", ret
);
126 if (*pos
> inode
->i_size
)
127 inode
->i_size
= *pos
;
128 mark_inode_dirty (filp
->f_dentry
->d_inode
);
143 static int ntfs_printcb(ntfs_u8
*entry
,void *param
)
145 struct ntfs_filldir
* nf
=param
;
146 int flags
=NTFS_GETU8(entry
+0x51);
148 int length
=NTFS_GETU8(entry
+0x50);
149 int inum
=NTFS_GETU32(entry
);
151 #ifdef NTFS_NGT_NT_DOES_LOWER
156 /* Don't display long names */
161 /* Don't display short-only names */
164 #ifdef NTFS_NGT_NT_DOES_LOWER
175 if(!show_hidden
&& ((NTFS_GETU8(entry
+0x48) & 2)==2)){
176 ntfs_debug(DEBUG_OTHER
,"Skipping hidden file\n");
180 if(ntfs_encodeuni(NTFS_INO2VOL(nf
->dir
),(ntfs_u16
*)(entry
+0x52),
181 length
,&nf
->name
,&nf
->namelen
)){
182 ntfs_debug(DEBUG_OTHER
,"Skipping unrepresentable file\n");
183 if(nf
->name
)ntfs_free(nf
->name
);
186 /* Do not return ".", as this is faked */
187 if(length
==1 && *nf
->name
=='.')
189 #ifdef NTFS_NGT_NT_DOES_LOWER
191 for(i
=0;i
<nf
->namelen
;i
++)
192 /* This supports ASCII only. Since only DOS-only
193 names get converted, and since those are restricted
194 to ASCII, this should be correct */
195 if(nf
->name
[i
]>='A' && nf
->name
[i
]<='Z')
196 nf
->name
[i
]+='a'-'A';
198 nf
->name
[nf
->namelen
]=0;
199 ntfs_debug(DEBUG_OTHER
, "readdir got %s,len %d\n",nf
->name
,nf
->namelen
);
200 /* filldir expects an off_t rather than an loff_t.
201 Hope we don't have more than 65535 index records */
202 error
=nf
->filldir(nf
->dirent
,nf
->name
,nf
->namelen
,
203 (nf
->ph
<<16)|nf
->pl
,inum
,DT_UNKNOWN
);
205 /* Linux filldir errors are negative, other errors positive */
209 /* readdir returns '..', then '.', then the directory entries in sequence
210 As the root directory contains a entry for itself, '.' is not emulated
211 for the root directory */
212 static int ntfs_readdir(struct file
* filp
, void *dirent
, filldir_t filldir
)
214 struct ntfs_filldir cb
;
216 struct inode
*dir
=filp
->f_dentry
->d_inode
;
218 ntfs_debug(DEBUG_OTHER
, "ntfs_readdir ino %x mode %x\n",
219 (unsigned)dir
->i_ino
,(unsigned int)dir
->i_mode
);
221 ntfs_debug(DEBUG_OTHER
, "readdir: Looking for file %x dircount %d\n",
222 (unsigned)filp
->f_pos
,atomic_read(&dir
->i_count
));
223 cb
.pl
=filp
->f_pos
& 0xFFFF;
224 cb
.ph
=filp
->f_pos
>> 16;
225 /* end of directory */
227 /* FIXME: Maybe we can return those with the previous call */
229 case 0: filldir(dirent
,".",1,filp
->f_pos
,dir
->i_ino
,DT_DIR
);
230 filp
->f_pos
=0xFFFF0001;
232 /* FIXME: parent directory */
233 case 1: filldir(dirent
,"..",2,filp
->f_pos
,0,DT_DIR
);
234 filp
->f_pos
=0xFFFF0002;
237 ntfs_debug(DEBUG_OTHER
, "readdir: EOD\n");
243 cb
.type
=NTFS_INO2VOL(dir
)->ngt
;
245 ntfs_debug(DEBUG_OTHER
,"looking for next file\n");
246 error
=ntfs_getdir_unsorted(NTFS_LINO2NINO(dir
),&cb
.ph
,&cb
.pl
,
248 }while(!error
&& cb
.ph
!=0xFFFFFFFF);
249 filp
->f_pos
=(cb
.ph
<<16)|cb
.pl
;
250 ntfs_debug(DEBUG_OTHER
, "new position %x\n",(unsigned)filp
->f_pos
);
251 /* -EINVAL is on user buffer full. This is not considered
252 as an error by sys_getdents */
255 /* Otherwise (device error, inconsistent data), switch the sign */
259 /* Copied from vfat driver */
260 static int simple_getbool(char *s
, int *setval
)
263 if (!strcmp(s
,"1") || !strcmp(s
,"yes") || !strcmp(s
,"true")) {
265 } else if (!strcmp(s
,"0") || !strcmp(s
,"no") || !strcmp(s
,"false")) {
276 /* Parse the (re)mount options */
277 static int parse_options(ntfs_volume
* vol
,char *opt
)
288 for(opt
= strtok(opt
,",");opt
;opt
=strtok(NULL
,","))
290 if ((value
= strchr(opt
, '=')) != NULL
)
292 if(strcmp(opt
,"uid")==0)
294 if(!value
|| !*value
)goto needs_arg
;
295 vol
->uid
=simple_strtoul(value
,&value
,0);
297 printk(KERN_ERR
"NTFS: uid invalid argument\n");
300 }else if(strcmp(opt
, "gid") == 0)
302 if(!value
|| !*value
)goto needs_arg
;
303 vol
->gid
=simple_strtoul(value
,&value
,0);
305 printk(KERN_ERR
"gid invalid argument\n");
308 }else if(strcmp(opt
, "umask") == 0)
310 if(!value
|| !*value
)goto needs_arg
;
311 vol
->umask
=simple_strtoul(value
,&value
,0);
313 printk(KERN_ERR
"umask invalid argument\n");
316 }else if(strcmp(opt
, "iocharset") == 0){
317 if(!value
|| !*value
)goto needs_arg
;
318 vol
->nls_map
=load_nls(value
);
321 printk(KERN_ERR
"NTFS: charset not found");
324 }else if(strcmp(opt
, "posix") == 0){
326 if(!value
|| !*value
)goto needs_arg
;
327 if(!simple_getbool(value
,&val
))
329 vol
->ngt
=val
?ngt_posix
:ngt_nt
;
330 }else if(strcmp(opt
,"utf8") == 0){
332 if(!value
|| !*value
)
334 else if(!simple_getbool(value
,&val
))
338 }else if(strcmp(opt
,"uni_xlate") == 0){
340 /* no argument: uni_vfat.
341 boolean argument: uni_vfat.
344 if(!value
|| !*value
)
346 else if(strcmp(value
,"2")==0)
347 vol
->nct
|= nct_uni_xlate
;
348 else if(!simple_getbool(value
,&val
))
351 vol
->nct
|= nct_uni_xlate_vfat
| nct_uni_xlate
;
353 printk(KERN_ERR
"NTFS: unkown option '%s'\n", opt
);
357 if(vol
->nct
& nct_utf8
& (nct_map
| nct_uni_xlate
)){
358 printk(KERN_ERR
"utf8 cannot be combined with iocharset or uni_xlate\n");
362 if((vol
->nct
& (nct_uni_xlate
| nct_map
| nct_utf8
))==0)
363 /* default to UTF-8 */
366 vol
->nls_map
=load_nls_default();
368 vol
->nct
=nct_map
| (vol
->nct
&nct_uni_xlate
);
373 printk(KERN_ERR
"NTFS: %s needs an argument",opt
);
376 printk(KERN_ERR
"NTFS: %s needs boolean argument",opt
);
380 static struct dentry
*ntfs_lookup(struct inode
*dir
, struct dentry
*d
)
386 ntfs_debug(DEBUG_NAME1
, "Looking up %s in %x\n",d
->d_name
.name
,
387 (unsigned)dir
->i_ino
);
388 /* convert to wide string */
389 error
=ntfs_decodeuni(NTFS_INO2VOL(dir
),(char*)d
->d_name
.name
,
390 d
->d_name
.len
,&walk
.name
,&walk
.namelen
);
392 return ERR_PTR(-error
);
393 item
=ntfs_malloc(ITEM_SIZE
);
395 return ERR_PTR(-ENOMEM
);
396 /* ntfs_getdir will place the directory entry into item,
397 and the first long long is the MFT record number */
399 walk
.dir
=NTFS_LINO2NINO(dir
);
401 if(ntfs_getdir_byname(&walk
))
403 res
=iget(dir
->i_sb
,NTFS_GETU32(item
));
407 ntfs_free(walk
.name
);
408 /* Always return success, the dcache will handle negative entries. */
412 static struct file_operations ntfs_file_operations_nommap
= {
414 #ifdef CONFIG_NTFS_RW
419 static struct inode_operations ntfs_inode_operations_nobmap
;
421 #ifdef CONFIG_NTFS_RW
423 ntfs_create(struct inode
* dir
,struct dentry
*d
,int mode
)
431 r
=new_inode(dir
->i_sb
);
437 ntfs_debug(DEBUG_OTHER
, "ntfs_create %s\n",d
->d_name
.name
);
438 vol
=NTFS_INO2VOL(dir
);
439 #ifdef NTFS_IN_LINUX_KERNEL
440 ino
=NTFS_LINO2NINO(r
);
442 ino
=ntfs_malloc(sizeof(ntfs_inode
));
449 error
=ntfs_alloc_file(NTFS_LINO2NINO(dir
),ino
,(char*)d
->d_name
.name
,
452 error
=ntfs_update_inode(ino
);
454 error
=ntfs_update_inode(NTFS_LINO2NINO(dir
));
459 /* FIXME: dirty? dev? */
460 /* get the file modification times from the standard information */
461 si
=ntfs_find_attr(ino
,vol
->at_standard_information
,NULL
);
463 char *attr
=si
->d
.data
;
464 r
->i_atime
=ntfs_ntutc2unixutc(NTFS_GETU64(attr
+0x18));
465 r
->i_ctime
=ntfs_ntutc2unixutc(NTFS_GETU64(attr
));
466 r
->i_mtime
=ntfs_ntutc2unixutc(NTFS_GETU64(attr
+8));
468 /* It's not a directory */
469 r
->i_op
=&ntfs_inode_operations_nobmap
;
470 r
->i_fop
=&ntfs_file_operations_nommap
,
471 r
->i_mode
=S_IFREG
|S_IRUGO
;
472 #ifdef CONFIG_NTFS_RW
475 r
->i_mode
&= ~vol
->umask
;
477 insert_inode_hash(r
);
481 #ifndef NTFS_IN_LINUX_KERNEL
482 if(ino
)ntfs_free(ino
);
489 _linux_ntfs_mkdir(struct inode
*dir
, struct dentry
* d
, int mode
)
497 ntfs_debug (DEBUG_DIR1
, "mkdir %s in %x\n",d
->d_name
.name
, dir
->i_ino
);
498 error
= ENAMETOOLONG
;
499 if (d
->d_name
.len
> /* FIXME */255)
503 r
= new_inode(dir
->i_sb
);
507 vol
= NTFS_INO2VOL(dir
);
508 #ifdef NTFS_IN_LINUX_KERNEL
509 ino
= NTFS_LINO2NINO(r
);
511 ino
= ntfs_malloc(sizeof(ntfs_inode
));
515 r
->u
.generic_ip
= ino
;
517 error
= ntfs_mkdir(NTFS_LINO2NINO(dir
),
518 d
->d_name
.name
, d
->d_name
.len
, ino
);
523 si
= ntfs_find_attr(ino
,vol
->at_standard_information
,NULL
);
525 char *attr
= si
->d
.data
;
526 r
->i_atime
= ntfs_ntutc2unixutc(NTFS_GETU64(attr
+0x18));
527 r
->i_ctime
= ntfs_ntutc2unixutc(NTFS_GETU64(attr
));
528 r
->i_mtime
= ntfs_ntutc2unixutc(NTFS_GETU64(attr
+8));
530 /* It's a directory */
531 r
->i_op
= &ntfs_dir_inode_operations
;
532 r
->i_fop
= &ntfs_dir_operations
;
533 r
->i_mode
= S_IFDIR
|S_IRUGO
|S_IXUGO
;
534 #ifdef CONFIG_NTFS_RW
537 r
->i_mode
&= ~vol
->umask
;
539 insert_inode_hash(r
);
543 ntfs_debug (DEBUG_DIR1
, "mkdir returns %d\n", -error
);
550 ntfs_bmap(struct inode
*ino
,int block
)
552 int ret
=ntfs_vcn_to_lcn(NTFS_LINO2NINO(ino
),block
);
553 ntfs_debug(DEBUG_OTHER
, "bmap of %lx,block %x is %x\n",
554 ino
->i_ino
,block
,ret
);
555 return (ret
==-1) ? 0:ret
;
559 /* It's fscking broken. */
560 /* FIXME: [bm]map code is disabled until ntfs_get_block gets sorted! */
562 static int ntfs_get_block(struct inode *inode, long block, struct buffer_head *bh, int create)
568 static struct file_operations ntfs_file_operations = {
570 mmap: generic_file_mmap,
571 #ifdef CONFIG_NTFS_RW
576 static struct inode_operations ntfs_inode_operations;
579 static struct file_operations ntfs_dir_operations
= {
580 read
: generic_read_dir
,
581 readdir
: ntfs_readdir
,
584 static struct inode_operations ntfs_dir_inode_operations
= {
586 #ifdef CONFIG_NTFS_RW
588 mkdir
: _linux_ntfs_mkdir
,
593 static int ntfs_writepage(struct page *page)
595 return block_write_full_page(page,ntfs_get_block);
597 static int ntfs_readpage(struct file *file, struct page *page)
599 return block_read_full_page(page,ntfs_get_block);
601 static int ntfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
603 return cont_prepare_write(page,from,to,ntfs_get_block,
604 &((struct inode*)page->mapping->host)->u.ntfs_i.mmu_private);
606 static int _ntfs_bmap(struct address_space *mapping, long block)
608 return generic_block_bmap(mapping,block,ntfs_get_block);
610 struct address_space_operations ntfs_aops = {
611 readpage: ntfs_readpage,
612 writepage: ntfs_writepage,
613 sync_page: block_sync_page,
614 prepare_write: ntfs_prepare_write,
615 commit_write: generic_commit_write,
620 /* ntfs_read_inode is called by the Virtual File System (the kernel layer that
621 * deals with filesystems) when iget is called requesting an inode not already
622 * present in the inode table. Typically filesystems have separate
623 * inode_operations for directories, files and symlinks.
625 static void ntfs_read_inode(struct inode
* inode
)
630 ntfs_attribute
*data
;
633 vol
=NTFS_INO2VOL(inode
);
635 ntfs_debug(DEBUG_OTHER
, "ntfs_read_inode %x\n",(unsigned)inode
->i_ino
);
639 /* those are loaded special files */
641 ntfs_error("Trying to open MFT\n");return;
643 #ifdef NTFS_IN_LINUX_KERNEL
644 ino
=&inode
->u
.ntfs_i
;
646 /* FIXME: check for ntfs_malloc failure */
647 ino
=(ntfs_inode
*)ntfs_malloc(sizeof(ntfs_inode
));
648 inode
->u
.generic_ip
=ino
;
650 if(!ino
|| ntfs_init_inode(ino
,
651 NTFS_INO2VOL(inode
),inode
->i_ino
))
653 ntfs_debug(DEBUG_OTHER
, "NTFS:Error loading inode %x\n",
654 (unsigned int)inode
->i_ino
);
658 /* Set uid/gid from mount options */
659 inode
->i_uid
=vol
->uid
;
660 inode
->i_gid
=vol
->gid
;
662 /* Use the size of the data attribute as file size */
663 data
= ntfs_find_attr(ino
,vol
->at_data
,NULL
);
671 inode
->i_size
=data
->size
;
672 /* FIXME: once ntfs_get_block is implemented, uncomment the
673 * next line and remove the can_mmap = 0; */
674 /* can_mmap=!data->resident && !data->compressed;*/
677 /* get the file modification times from the standard information */
678 si
=ntfs_find_attr(ino
,vol
->at_standard_information
,NULL
);
680 char *attr
=si
->d
.data
;
681 inode
->i_atime
=ntfs_ntutc2unixutc(NTFS_GETU64(attr
+0x18));
682 inode
->i_ctime
=ntfs_ntutc2unixutc(NTFS_GETU64(attr
));
683 inode
->i_mtime
=ntfs_ntutc2unixutc(NTFS_GETU64(attr
+8));
685 /* if it has an index root, it's a directory */
686 if(ntfs_find_attr(ino
,vol
->at_index_root
,"$I30"))
689 at
= ntfs_find_attr (ino
, vol
->at_index_allocation
, "$I30");
690 inode
->i_size
= at
? at
->size
: 0;
692 inode
->i_op
=&ntfs_dir_inode_operations
;
693 inode
->i_fop
=&ntfs_dir_operations
;
694 inode
->i_mode
=S_IFDIR
|S_IRUGO
|S_IXUGO
;
698 /* As long as ntfs_get_block() is just a call to BUG() do not
699 * define any [bm]map ops or we get the BUG() whenever someone
700 * runs mc or mpg123 on an ntfs partition!
701 * FIXME: Uncomment the below code when ntfs_get_block is
704 inode->i_op = &ntfs_inode_operations;
705 inode->i_fop = &ntfs_file_operations;
706 inode->i_mapping->a_ops = &ntfs_aops;
707 inode->u.ntfs_i.mmu_private = inode->i_size;
709 inode
->i_op
=&ntfs_inode_operations_nobmap
;
710 inode
->i_fop
=&ntfs_file_operations_nommap
;
712 inode
->i_mode
=S_IFREG
|S_IRUGO
;
714 #ifdef CONFIG_NTFS_RW
715 if(!data
|| !data
->compressed
)
716 inode
->i_mode
|=S_IWUGO
;
718 inode
->i_mode
&= ~vol
->umask
;
721 #ifdef CONFIG_NTFS_RW
723 ntfs_write_inode (struct inode
*ino
, int unused
)
726 ntfs_debug (DEBUG_LINUX
, "ntfs:write inode %x\n", ino
->i_ino
);
727 ntfs_update_inode (NTFS_LINO2NINO (ino
));
732 static void _ntfs_clear_inode(struct inode
*ino
)
735 ntfs_debug(DEBUG_OTHER
, "ntfs_clear_inode %lx\n",ino
->i_ino
);
736 #ifdef NTFS_IN_LINUX_KERNEL
737 if(ino
->i_ino
!=FILE_MFT
)
738 ntfs_clear_inode(&ino
->u
.ntfs_i
);
740 if(ino
->i_ino
!=FILE_MFT
&& ino
->u
.generic_ip
)
742 ntfs_clear_inode(ino
->u
.generic_ip
);
743 ntfs_free(ino
->u
.generic_ip
);
751 /* Called when umounting a filesystem by do_umount() in fs/super.c */
752 static void ntfs_put_super(struct super_block
*sb
)
756 ntfs_debug(DEBUG_OTHER
, "ntfs_put_super\n");
760 ntfs_release_volume(vol
);
762 unload_nls(vol
->nls_map
);
763 #ifndef NTFS_IN_LINUX_KERNEL
766 ntfs_debug(DEBUG_OTHER
, "ntfs_put_super: done\n");
769 /* Called by the kernel when asking for stats */
770 static int ntfs_statfs(struct super_block
*sb
, struct statfs
*sf
)
777 ntfs_debug(DEBUG_OTHER
, "ntfs_statfs\n");
779 sf
->f_type
=NTFS_SUPER_MAGIC
;
780 sf
->f_bsize
=vol
->clustersize
;
782 error
= ntfs_get_volumesize( NTFS_SB2VOL( sb
), &size
);
785 sf
->f_blocks
= size
; /* volumesize is in clusters */
786 sf
->f_bfree
=ntfs_get_free_cluster_count(vol
->bitmap
);
787 sf
->f_bavail
=sf
->f_bfree
;
789 mft
=iget(sb
,FILE_MFT
);
792 /* So ... we lie... thus this following cast of loff_t value
794 sf
->f_files
= (unsigned long)mft
->i_size
/ vol
->mft_recordsize
;
797 /* should be read from volume */
802 /* Called when remounting a filesystem by do_remount_sb() in fs/super.c */
803 static int ntfs_remount_fs(struct super_block
*sb
, int *flags
, char *options
)
805 if(!parse_options(NTFS_SB2VOL(sb
), options
))
810 /* Define the super block operation that are implemented */
811 static struct super_operations ntfs_super_operations
= {
812 read_inode
: ntfs_read_inode
,
813 #ifdef CONFIG_NTFS_RW
814 write_inode
: ntfs_write_inode
,
816 put_super
: ntfs_put_super
,
818 remount_fs
: ntfs_remount_fs
,
819 clear_inode
: _ntfs_clear_inode
,
822 /* Called to mount a filesystem by read_super() in fs/super.c
823 * Return a super block, the main structure of a filesystem
825 * NOTE : Don't store a pointer to an option, as the page containing the
826 * options is freed after ntfs_read_super() returns.
828 * NOTE : A context switch can happen in kernel code only if the code blocks
829 * (= calls schedule() in kernel/sched.c).
831 struct super_block
* ntfs_read_super(struct super_block
*sb
,
832 void *options
, int silent
)
835 struct buffer_head
*bh
;
838 ntfs_debug(DEBUG_OTHER
, "ntfs_read_super\n");
840 #ifdef NTFS_IN_LINUX_KERNEL
841 vol
= NTFS_SB2VOL(sb
);
843 if(!(vol
= ntfs_malloc(sizeof(ntfs_volume
))))
844 goto ntfs_read_super_dec
;
848 if(!parse_options(vol
,(char*)options
))
849 goto ntfs_read_super_vol
;
852 /* Set to read only, user option might reset it */
853 sb
->s_flags
|= MS_RDONLY
;
856 /* Assume a 512 bytes block device for now */
857 set_blocksize(sb
->s_dev
, 512);
858 /* Read the super block (boot block) */
859 if(!(bh
=bread(sb
->s_dev
,0,512))) {
860 ntfs_error("Reading super block failed\n");
861 goto ntfs_read_super_unl
;
863 ntfs_debug(DEBUG_OTHER
, "Done reading boot block\n");
865 /* Check for 'NTFS' magic number */
866 if(!IS_NTFS_VOLUME(bh
->b_data
)){
867 ntfs_debug(DEBUG_OTHER
, "Not a NTFS volume\n");
869 goto ntfs_read_super_unl
;
872 ntfs_debug(DEBUG_OTHER
, "Going to init volume\n");
873 ntfs_init_volume(vol
,bh
->b_data
);
874 ntfs_debug(DEBUG_OTHER
, "MFT record at cluster 0x%X\n",vol
->mft_cluster
);
877 ntfs_debug(DEBUG_OTHER
, "Done to init volume\n");
879 /* Inform the kernel that a device block is a NTFS cluster */
880 sb
->s_blocksize
=vol
->clustersize
;
881 for(i
=sb
->s_blocksize
,sb
->s_blocksize_bits
=0;i
!= 1;i
>>=1)
882 sb
->s_blocksize_bits
++;
883 set_blocksize(sb
->s_dev
,sb
->s_blocksize
);
884 ntfs_debug(DEBUG_OTHER
, "set_blocksize\n");
886 /* Allocate a MFT record (MFT record can be smaller than a cluster) */
887 if(!(vol
->mft
=ntfs_malloc(max(vol
->mft_recordsize
,vol
->clustersize
))))
888 goto ntfs_read_super_unl
;
890 /* Read at least the MFT record for $MFT */
891 for(i
=0;i
<max(vol
->mft_clusters_per_record
,1);i
++){
892 if(!(bh
=bread(sb
->s_dev
,vol
->mft_cluster
+i
,vol
->clustersize
))) {
893 ntfs_error("Could not read MFT record 0\n");
894 goto ntfs_read_super_mft
;
896 ntfs_memcpy(vol
->mft
+i
*vol
->clustersize
,bh
->b_data
,vol
->clustersize
);
898 ntfs_debug(DEBUG_OTHER
, "Read cluster %x\n",vol
->mft_cluster
+i
);
901 /* Check and fixup this MFT record */
902 if(!ntfs_check_mft_record(vol
,vol
->mft
)){
903 ntfs_error("Invalid MFT record 0\n");
904 goto ntfs_read_super_mft
;
907 /* Inform the kernel about which super operations are available */
908 sb
->s_op
= &ntfs_super_operations
;
909 sb
->s_magic
= NTFS_SUPER_MAGIC
;
911 ntfs_debug(DEBUG_OTHER
, "Reading special files\n");
912 if(ntfs_load_special_files(vol
)){
913 ntfs_error("Error loading special files\n");
914 goto ntfs_read_super_mft
;
917 ntfs_debug(DEBUG_OTHER
, "Getting RootDir\n");
918 /* Get the root directory */
919 if(!(sb
->s_root
=d_alloc_root(iget(sb
,FILE_ROOT
)))){
920 ntfs_error("Could not get root dir inode\n");
921 goto ntfs_read_super_mft
;
923 ntfs_debug(DEBUG_OTHER
, "read_super: done\n");
930 #ifndef NTFS_IN_LINUX_KERNEL
934 ntfs_debug(DEBUG_OTHER
, "read_super: done\n");
938 /* Define the filesystem
940 static DECLARE_FSTYPE_DEV(ntfs_fs_type
, "ntfs", ntfs_read_super
);
942 static int __init
init_ntfs_fs(void)
944 /* Comment this if you trust klogd. There are reasons not to trust it
946 #if defined(DEBUG) && !defined(MODULE)
949 printk(KERN_NOTICE
"NTFS version " NTFS_VERSION
"\n");
951 ntfs_debug(DEBUG_OTHER
, "registering %s\n",ntfs_fs_type
.name
);
952 /* add this filesystem to the kernel table of filesystems */
953 return register_filesystem(&ntfs_fs_type
);
956 static void __exit
exit_ntfs_fs(void)
959 ntfs_debug(DEBUG_OTHER
, "unregistering %s\n",ntfs_fs_type
.name
);
960 unregister_filesystem(&ntfs_fs_type
);
964 MODULE_AUTHOR("Martin von Löwis");
965 MODULE_DESCRIPTION("NTFS driver");
966 MODULE_PARM(ntdebug
, "i");
967 MODULE_PARM_DESC(ntdebug
, "Debug level");
969 module_init(init_ntfs_fs
)
970 module_exit(exit_ntfs_fs
)
973 * c-file-style: "linux"