3 * NTFS driver for Linux 2.1
5 * Copyright (C) 1995-1997 Martin von Löwis
6 * Copyright (C) 1996 Richard Russon
7 * Copyright (C) 1996-1997 Régis Duchesne
13 #ifdef NTFS_IN_LINUX_KERNEL
14 #include <linux/config.h>
26 #include <linux/module.h>
27 #include <asm/uaccess.h>
28 #include <linux/nls.h>
29 #include <linux/locks.h>
30 #include <linux/init.h>
32 #define ITEM_SIZE 2040
34 /* io functions to user space */
35 static void ntfs_putuser(ntfs_io
* dest
,void *src
,ntfs_size_t len
)
37 copy_to_user(dest
->param
,src
,len
);
42 static void ntfs_getuser(void *dest
,ntfs_io
*src
,ntfs_size_t len
)
44 copy_from_user(dest
,src
->param
,len
);
50 ntfs_read(struct file
* filp
, char *buf
, size_t count
, loff_t
*off
)
54 ntfs_inode
*ino
=NTFS_LINO2NINO(filp
->f_dentry
->d_inode
);
56 /* inode is not properly initialized */
57 if(!ino
)return -EINVAL
;
58 ntfs_debug(DEBUG_OTHER
, "ntfs_read %x,%x,%x ->",
59 (unsigned)ino
->i_number
,(unsigned)*off
,(unsigned)count
);
60 /* inode has no unnamed data attribute */
61 if(!ntfs_find_attr(ino
,ino
->vol
->at_data
,NULL
))
65 io
.fn_put
=ntfs_putuser
;
69 error
=ntfs_read_attr(ino
,ino
->vol
->at_data
,NULL
,*off
,&io
);
70 if(error
)return -error
;
78 ntfs_write(struct file
*filp
,const char* buf
,size_t count
,loff_t
*pos
)
80 struct super_block
* sb
;
83 ntfs_inode
*ino
=NTFS_LINO2NINO(filp
->f_dentry
->d_inode
);
85 if(!ino
)return -EINVAL
;
86 ntfs_debug(DEBUG_OTHER
, "ntfs_write %x,%x,%x ->",
87 (unsigned)ino
->i_number
,(unsigned)*pos
,(unsigned)count
);
88 sb
= filp
->f_dentry
->d_inode
->i_sb
;
89 /* Allows to lock fs ro at any time */
90 if(sb
->s_flags
& MS_RDONLY
)
92 if(!ntfs_find_attr(ino
,ino
->vol
->at_data
,NULL
))
96 io
.fn_get
=ntfs_getuser
;
97 io
.param
=(void*)buf
; /* to get rid of the const */
99 ret
= ntfs_write_attr(ino
,ino
->vol
->at_data
,NULL
,*pos
,&io
);
100 ntfs_debug(DEBUG_OTHER
, "%x\n",ret
);
101 if(ret
<0)return -EINVAL
;
118 static int ntfs_printcb(ntfs_u8
*entry
,void *param
)
120 struct ntfs_filldir
* nf
=param
;
121 int flags
=NTFS_GETU8(entry
+0x51);
122 int show_hidden
=0,to_lower
=0;
123 int length
=NTFS_GETU8(entry
+0x50);
124 int inum
=NTFS_GETU32(entry
);
128 /* Don't display long names */
133 /* Don't display short-only names */
145 if(!show_hidden
&& ((NTFS_GETU8(entry
+0x48) & 2)==2)){
146 ntfs_debug(DEBUG_OTHER
,"Skipping hidden file\n");
150 if(ntfs_encodeuni(NTFS_INO2VOL(nf
->dir
),(ntfs_u16
*)(entry
+0x52),
151 length
,&nf
->name
,&nf
->namelen
)){
152 ntfs_debug(DEBUG_OTHER
,"Skipping unrepresentable file\n");
153 if(nf
->name
)ntfs_free(nf
->name
);
156 /* Do not return ".", as this is faked */
157 if(length
==1 && *nf
->name
=='.')
160 for(i
=0;i
<nf
->namelen
;i
++)
161 /* This supports ASCII only. Since only DOS-only
162 names get converted, and since those are restricted
163 to ASCII, this should be correct */
164 if(nf
->name
[i
]>='A' && nf
->name
[i
]<='Z')
165 nf
->name
[i
]+='a'-'A';
166 nf
->name
[nf
->namelen
]=0;
167 ntfs_debug(DEBUG_OTHER
, "readdir got %s,len %d\n",nf
->name
,nf
->namelen
);
168 /* filldir expects an off_t rather than an loff_t.
169 Hope we don't have more than 65535 index records */
170 error
=nf
->filldir(nf
->dirent
,nf
->name
,nf
->namelen
,
171 (nf
->ph
<<16)|nf
->pl
,inum
);
173 /* Linux filldir errors are negative, other errors positive */
177 /* readdir returns '..', then '.', then the directory entries in sequence
178 As the root directory contains a entry for itself, '.' is not emulated
179 for the root directory */
180 static int ntfs_readdir(struct file
* filp
, void *dirent
, filldir_t filldir
)
182 struct ntfs_filldir cb
;
184 struct inode
*dir
=filp
->f_dentry
->d_inode
;
186 ntfs_debug(DEBUG_OTHER
, "ntfs_readdir ino %x mode %x\n",
187 (unsigned)dir
->i_ino
,(unsigned int)dir
->i_mode
);
188 if(!dir
|| (dir
->i_ino
==0) || !S_ISDIR(dir
->i_mode
))return -EBADF
;
190 ntfs_debug(DEBUG_OTHER
, "readdir: Looking for file %x dircount %d\n",
191 (unsigned)filp
->f_pos
,dir
->i_count
);
192 cb
.pl
=filp
->f_pos
& 0xFFFF;
193 cb
.ph
=filp
->f_pos
>> 16;
194 /* end of directory */
196 /* FIXME: Maybe we can return those with the previous call */
198 case 0: filldir(dirent
,".",1,filp
->f_pos
,dir
->i_ino
);
199 filp
->f_pos
=0xFFFF0001;
201 /* FIXME: parent directory */
202 case 1: filldir(dirent
,"..",2,filp
->f_pos
,0);
203 filp
->f_pos
=0xFFFF0002;
206 ntfs_debug(DEBUG_OTHER
, "readdir: EOD\n");
212 cb
.type
=NTFS_INO2VOL(dir
)->ngt
;
214 ntfs_debug(DEBUG_OTHER
,"looking for next file\n");
215 error
=ntfs_getdir_unsorted(NTFS_LINO2NINO(dir
),&cb
.ph
,&cb
.pl
,
217 }while(!error
&& cb
.ph
!=0xFFFFFFFF);
218 filp
->f_pos
=(cb
.ph
<<16)|cb
.pl
;
219 ntfs_debug(DEBUG_OTHER
, "new position %x\n",(unsigned)filp
->f_pos
);
220 /* -EINVAL is on user buffer full. This is not considered
221 as an error by sys_getdents */
224 /* Otherwise (device error, inconsistent data), switch the sign */
228 /* Copied from vfat driver */
229 static int simple_getbool(char *s
, int *setval
)
232 if (!strcmp(s
,"1") || !strcmp(s
,"yes") || !strcmp(s
,"true")) {
234 } else if (!strcmp(s
,"0") || !strcmp(s
,"no") || !strcmp(s
,"false")) {
245 /* Parse the (re)mount options */
246 static int parse_options(ntfs_volume
* vol
,char *opt
)
257 for(opt
= strtok(opt
,",");opt
;opt
=strtok(NULL
,","))
259 if ((value
= strchr(opt
, '=')) != NULL
)
261 if(strcmp(opt
,"uid")==0)
263 if(!value
|| !*value
)goto needs_arg
;
264 vol
->uid
=simple_strtoul(value
,&value
,0);
266 printk(KERN_ERR
"NTFS: uid invalid argument\n");
269 }else if(strcmp(opt
, "gid") == 0)
271 if(!value
|| !*value
)goto needs_arg
;
272 vol
->gid
=simple_strtoul(value
,&value
,0);
274 printk(KERN_ERR
"gid invalid argument\n");
277 }else if(strcmp(opt
, "umask") == 0)
279 if(!value
|| !*value
)goto needs_arg
;
280 vol
->umask
=simple_strtoul(value
,&value
,0);
282 printk(KERN_ERR
"umask invalid argument\n");
285 }else if(strcmp(opt
, "iocharset") == 0){
286 if(!value
|| !*value
)goto needs_arg
;
287 vol
->nls_map
=load_nls(value
);
290 printk(KERN_ERR
"NTFS: charset not found");
293 }else if(strcmp(opt
, "posix") == 0){
295 if(!value
|| !*value
)goto needs_arg
;
296 if(!simple_getbool(value
,&val
))
298 vol
->ngt
=val
?ngt_posix
:ngt_nt
;
299 }else if(strcmp(opt
,"utf8") == 0){
301 if(!value
|| !*value
)
303 else if(!simple_getbool(value
,&val
))
307 }else if(strcmp(opt
,"uni_xlate") == 0){
309 /* no argument: uni_vfat.
310 boolean argument: uni_vfat.
313 if(!value
|| !*value
)
315 else if(strcmp(value
,"2")==0)
316 vol
->nct
|= nct_uni_xlate
;
317 else if(!simple_getbool(value
,&val
))
320 vol
->nct
|= nct_uni_xlate_vfat
| nct_uni_xlate
;
322 printk(KERN_ERR
"NTFS: unkown option '%s'\n", opt
);
326 if(vol
->nct
& nct_utf8
& (nct_map
| nct_uni_xlate
)){
327 printk(KERN_ERR
"utf8 cannot be combined with iocharset or uni_xlate\n");
331 if((vol
->nct
& (nct_uni_xlate
| nct_map
| nct_utf8
))==0)
332 /* default to UTF-8 */
335 vol
->nls_map
=load_nls_default();
339 printk(KERN_ERR
"NTFS: %s needs an argument",opt
);
342 printk(KERN_ERR
"NTFS: %s needs boolean argument",opt
);
346 static int ntfs_lookup(struct inode
*dir
, struct dentry
*d
)
352 ntfs_debug(DEBUG_OTHER
, "Looking up %s in %x\n",d
->d_name
.name
,
353 (unsigned)dir
->i_ino
);
354 /* convert to wide string */
355 error
=ntfs_decodeuni(NTFS_INO2VOL(dir
),(char*)d
->d_name
.name
,
356 d
->d_name
.len
,&walk
.name
,&walk
.namelen
);
359 item
=ntfs_malloc(ITEM_SIZE
);
360 /* ntfs_getdir will place the directory entry into item,
361 and the first long long is the MFT record number */
363 walk
.dir
=NTFS_LINO2NINO(dir
);
365 if(ntfs_getdir_byname(&walk
))
367 res
=iget(dir
->i_sb
,NTFS_GETU32(item
));
371 ntfs_free(walk
.name
);
372 return res
?0:-ENOENT
;
375 struct file_operations ntfs_file_operations_nommap
= {
378 #ifdef CONFIG_NTFS_RW
392 NULL
, /* check_media_change */
393 NULL
, /* revalidate */
397 struct inode_operations ntfs_inode_operations_nobmap
= {
398 &ntfs_file_operations_nommap
,
409 NULL
, /* follow_link */
411 NULL
, /* writepage */
414 NULL
, /* permission */
416 NULL
, /* updatepage */
417 NULL
, /* revalidate */
420 #ifdef CONFIG_NTFS_RW
422 ntfs_create(struct inode
* dir
,struct dentry
*d
,int mode
)
436 ntfs_debug(DEBUG_OTHER
, "ntfs_create %s\n",d
->d_name
.name
);
437 vol
=NTFS_INO2VOL(dir
);
438 #ifdef NTFS_IN_LINUX_KERNEL
439 ino
=NTFS_LINO2NINO(r
);
441 ino
=ntfs_malloc(sizeof(ntfs_inode
));
448 error
=ntfs_alloc_inode(NTFS_LINO2NINO(dir
),ino
,(char*)d
->d_name
.name
,
451 error
=ntfs_update_inode(ino
);
453 error
=ntfs_update_inode(NTFS_LINO2NINO(dir
));
460 /* FIXME: dirty? dev? */
461 /* get the file modification times from the standard information */
462 si
=ntfs_find_attr(ino
,vol
->at_standard_information
,NULL
);
464 char *attr
=si
->d
.data
;
465 r
->i_atime
=ntfs_ntutc2unixutc(NTFS_GETU64(attr
+0x18));
466 r
->i_ctime
=ntfs_ntutc2unixutc(NTFS_GETU64(attr
));
467 r
->i_mtime
=ntfs_ntutc2unixutc(NTFS_GETU64(attr
+8));
469 /* It's not a directory */
470 r
->i_op
=&ntfs_inode_operations_nobmap
;
471 r
->i_mode
=S_IFREG
|S_IRUGO
;
472 #ifdef CONFIG_NTFS_RW
475 r
->i_mode
&= ~vol
->umask
;
480 #ifndef NTFS_IN_LINUX_KERNEL
481 if(ino
)ntfs_free(ino
);
489 ntfs_bmap(struct inode
*ino
,int block
)
491 int ret
=ntfs_vcn_to_lcn(NTFS_LINO2NINO(ino
),block
);
492 ntfs_debug(DEBUG_OTHER
, "bmap of %lx,block %x is %x\n",
493 ino
->i_ino
,block
,ret
);
494 return (ret
==-1) ? 0:ret
;
497 struct file_operations ntfs_file_operations
= {
500 #ifdef CONFIG_NTFS_RW
514 NULL
, /* check_media_change */
515 NULL
, /* revalidate */
519 struct inode_operations ntfs_inode_operations
= {
520 &ntfs_file_operations
,
531 NULL
, /* follow_link */
533 NULL
, /* writepage */
536 NULL
, /* permission */
538 NULL
, /* updatepage */
539 NULL
, /* revalidate */
542 struct file_operations ntfs_dir_operations
= {
546 ntfs_readdir
, /* readdir */
555 NULL
, /* check_media_change */
556 NULL
, /* revalidate */
560 struct inode_operations ntfs_dir_inode_operations
= {
561 &ntfs_dir_operations
,
562 #ifdef CONFIG_NTFS_RW
563 ntfs_create
, /* create */
567 ntfs_lookup
, /* lookup */
576 NULL
, /* follow_link */
578 NULL
, /* writepage */
581 NULL
, /* permission */
583 NULL
, /* updatepage */
584 NULL
, /* revalidate */
587 /* ntfs_read_inode is called by the Virtual File System (the kernel layer that
588 * deals with filesystems) when iget is called requesting an inode not already
589 * present in the inode table. Typically filesystems have separate
590 * inode_operations for directories, files and symlinks.
592 static void ntfs_read_inode(struct inode
* inode
)
597 ntfs_attribute
*data
;
600 vol
=NTFS_INO2VOL(inode
);
603 ntfs_debug(DEBUG_OTHER
, "ntfs_read_inode %x\n",(unsigned)inode
->i_ino
);
607 /* those are loaded special files */
609 ntfs_error("Trying to open MFT\n");return;
611 #ifdef NTFS_IN_LINUX_KERNEL
612 ino
=&inode
->u
.ntfs_i
;
614 ino
=(ntfs_inode
*)ntfs_malloc(sizeof(ntfs_inode
));
615 inode
->u
.generic_ip
=ino
;
617 if(!ino
|| ntfs_init_inode(ino
,
618 NTFS_INO2VOL(inode
),inode
->i_ino
))
620 ntfs_debug(DEBUG_OTHER
, "NTFS:Error loading inode %x\n",
621 (unsigned int)inode
->i_ino
);
625 /* Set uid/gid from mount options */
626 inode
->i_uid
=vol
->uid
;
627 inode
->i_gid
=vol
->gid
;
629 /* Use the size of the data attribute as file size */
630 data
= ntfs_find_attr(ino
,vol
->at_data
,NULL
);
638 inode
->i_size
=data
->size
;
639 can_mmap
=!data
->resident
&& !data
->compressed
;
641 /* get the file modification times from the standard information */
642 si
=ntfs_find_attr(ino
,vol
->at_standard_information
,NULL
);
644 char *attr
=si
->d
.data
;
645 inode
->i_atime
=ntfs_ntutc2unixutc(NTFS_GETU64(attr
+0x18));
646 inode
->i_ctime
=ntfs_ntutc2unixutc(NTFS_GETU64(attr
));
647 inode
->i_mtime
=ntfs_ntutc2unixutc(NTFS_GETU64(attr
+8));
649 /* if it has an index root, it's a directory */
650 if(ntfs_find_attr(ino
,vol
->at_index_root
,"$I30"))
653 at
= ntfs_find_attr (ino
, vol
->at_index_allocation
, "$I30");
654 inode
->i_size
= at
? at
->size
: 0;
656 inode
->i_op
=&ntfs_dir_inode_operations
;
657 inode
->i_mode
=S_IFDIR
|S_IRUGO
|S_IXUGO
;
661 inode
->i_op
=can_mmap
? &ntfs_inode_operations
:
662 &ntfs_inode_operations_nobmap
;
663 inode
->i_mode
=S_IFREG
|S_IRUGO
;
665 #ifdef CONFIG_NTFS_RW
666 if(!data
|| !data
->compressed
)
667 inode
->i_mode
|=S_IWUGO
;
669 inode
->i_mode
&= ~vol
->umask
;
672 static void ntfs_put_inode(struct inode
*ino
)
676 static void _ntfs_clear_inode(struct inode
*ino
)
678 ntfs_debug(DEBUG_OTHER
, "ntfs_clear_inode %lx\n",ino
->i_ino
);
679 #ifdef NTFS_IN_LINUX_KERNEL
680 if(ino
->i_ino
!=FILE_MFT
)
681 ntfs_clear_inode(&ino
->u
.ntfs_i
);
683 if(ino
->i_ino
!=FILE_MFT
&& ino
->u
.generic_ip
)
685 ntfs_clear_inode(ino
->u
.generic_ip
);
686 ntfs_free(ino
->u
.generic_ip
);
693 /* Called when umounting a filesystem by do_umount() in fs/super.c */
694 static void ntfs_put_super(struct super_block
*sb
)
698 ntfs_debug(DEBUG_OTHER
, "ntfs_put_super\n");
702 ntfs_release_volume(vol
);
704 unload_nls(vol
->nls_map
);
705 #ifndef NTFS_IN_LINUX_KERNEL
708 ntfs_debug(DEBUG_OTHER
, "ntfs_put_super: done\n");
712 /* Called by the kernel when asking for stats */
713 static int ntfs_statfs(struct super_block
*sb
, struct statfs
*sf
, int bufsize
)
719 ntfs_debug(DEBUG_OTHER
, "ntfs_statfs\n");
721 memset(&fs
,0,sizeof(fs
));
722 fs
.f_type
=NTFS_SUPER_MAGIC
;
723 fs
.f_bsize
=vol
->clustersize
;
725 fs
.f_blocks
=ntfs_get_volumesize(NTFS_SB2VOL(sb
));
726 fs
.f_bfree
=ntfs_get_free_cluster_count(vol
->bitmap
);
727 fs
.f_bavail
=fs
.f_bfree
;
729 /* Number of files is limited by free space only, so we lie here */
731 mft
=iget(sb
,FILE_MFT
);
732 fs
.f_files
=mft
->i_size
/vol
->mft_recordsize
;
735 /* should be read from volume */
737 copy_to_user(sf
,&fs
,bufsize
);
741 /* Called when remounting a filesystem by do_remount_sb() in fs/super.c */
742 static int ntfs_remount_fs(struct super_block
*sb
, int *flags
, char *options
)
744 if(!parse_options(NTFS_SB2VOL(sb
), options
))
749 /* Define the super block operation that are implemented */
750 struct super_operations ntfs_super_operations
= {
752 NULL
, /* write_inode */
754 NULL
, /* delete_inode */
755 NULL
, /* notify_change */
757 NULL
, /* write_super */
759 ntfs_remount_fs
, /* remount */
760 _ntfs_clear_inode
, /* clear_inode */
763 /* Called to mount a filesystem by read_super() in fs/super.c
764 * Return a super block, the main structure of a filesystem
766 * NOTE : Don't store a pointer to an option, as the page containing the
767 * options is freed after ntfs_read_super() returns.
769 * NOTE : A context switch can happen in kernel code only if the code blocks
770 * (= calls schedule() in kernel/sched.c).
772 struct super_block
* ntfs_read_super(struct super_block
*sb
,
773 void *options
, int silent
)
776 struct buffer_head
*bh
;
779 /* When the driver is compiled as a module, kmod must know when it
780 * can safely remove it from memory. To do this, each module owns a
784 /* Don't put ntfs_debug() before MOD_INC_USE_COUNT, printk() can block
785 * so this could lead to a race condition with kmod.
787 ntfs_debug(DEBUG_OTHER
, "ntfs_read_super\n");
789 #ifdef NTFS_IN_LINUX_KERNEL
790 vol
= NTFS_SB2VOL(sb
);
792 if(!(vol
= ntfs_malloc(sizeof(ntfs_volume
))))
793 goto ntfs_read_super_dec
;
797 if(!parse_options(vol
,(char*)options
))
798 goto ntfs_read_super_vol
;
800 /* Ensure that the super block won't be used until it is completed */
802 ntfs_debug(DEBUG_OTHER
, "lock_super\n");
804 /* Set to read only, user option might reset it */
805 sb
->s_flags
|= MS_RDONLY
;
808 /* Assume a 512 bytes block device for now */
809 set_blocksize(sb
->s_dev
, 512);
810 /* Read the super block (boot block) */
811 if(!(bh
=bread(sb
->s_dev
,0,512))) {
812 ntfs_error("Reading super block failed\n");
813 goto ntfs_read_super_unl
;
815 ntfs_debug(DEBUG_OTHER
, "Done reading boot block\n");
817 /* Check for 'NTFS' magic number */
818 if(!IS_NTFS_VOLUME(bh
->b_data
)){
819 ntfs_debug(DEBUG_OTHER
, "Not a NTFS volume\n");
821 goto ntfs_read_super_unl
;
824 ntfs_debug(DEBUG_OTHER
, "Going to init volume\n");
825 ntfs_init_volume(vol
,bh
->b_data
);
826 ntfs_debug(DEBUG_OTHER
, "MFT record at cluster 0x%X\n",vol
->mft_cluster
);
829 ntfs_debug(DEBUG_OTHER
, "Done to init volume\n");
831 /* Inform the kernel that a device block is a NTFS cluster */
832 sb
->s_blocksize
=vol
->clustersize
;
833 for(i
=sb
->s_blocksize
,sb
->s_blocksize_bits
=0;i
!= 1;i
>>=1)
834 sb
->s_blocksize_bits
++;
835 set_blocksize(sb
->s_dev
,sb
->s_blocksize
);
836 ntfs_debug(DEBUG_OTHER
, "set_blocksize\n");
838 /* Allocate a MFT record (MFT record can be smaller than a cluster) */
839 if(!(vol
->mft
=ntfs_malloc(max(vol
->mft_recordsize
,vol
->clustersize
))))
840 goto ntfs_read_super_unl
;
842 /* Read at least the MFT record for $MFT */
843 for(i
=0;i
<max(vol
->mft_clusters_per_record
,1);i
++){
844 if(!(bh
=bread(sb
->s_dev
,vol
->mft_cluster
+i
,vol
->clustersize
))) {
845 ntfs_error("Could not read MFT record 0\n");
846 goto ntfs_read_super_mft
;
848 ntfs_memcpy(vol
->mft
+i
*vol
->clustersize
,bh
->b_data
,vol
->clustersize
);
850 ntfs_debug(DEBUG_OTHER
, "Read cluster %x\n",vol
->mft_cluster
+i
);
853 /* Check and fixup this MFT record */
854 if(!ntfs_check_mft_record(vol
,vol
->mft
)){
855 ntfs_error("Invalid MFT record 0\n");
856 goto ntfs_read_super_mft
;
859 /* Inform the kernel about which super operations are available */
860 sb
->s_op
= &ntfs_super_operations
;
861 sb
->s_magic
= NTFS_SUPER_MAGIC
;
863 ntfs_debug(DEBUG_OTHER
, "Reading special files\n");
864 if(ntfs_load_special_files(vol
)){
865 ntfs_error("Error loading special files\n");
866 goto ntfs_read_super_mft
;
869 ntfs_debug(DEBUG_OTHER
, "Getting RootDir\n");
870 /* Get the root directory */
871 if(!(sb
->s_root
=d_alloc_root(iget(sb
,FILE_ROOT
),NULL
))){
872 ntfs_error("Could not get root dir inode\n");
873 goto ntfs_read_super_mft
;
876 ntfs_debug(DEBUG_OTHER
, "unlock_super\n");
877 ntfs_debug(DEBUG_OTHER
, "read_super: done\n");
885 ntfs_debug(DEBUG_OTHER
, "unlock_super\n");
887 #ifndef NTFS_IN_LINUX_KERNEL
891 ntfs_debug(DEBUG_OTHER
, "read_super: done\n");
896 /* Define the filesystem
898 * Define SECOND if you cannot unload ntfs, and want to avoid rebooting
899 * for just one more test
901 struct file_system_type ntfs_fs_type
= {
902 /* Filesystem name, as used after mount -t */
908 /* This filesystem requires a device (a hard disk)
909 * May want to add FS_IBASKET when it works
912 /* Entry point of the filesystem */
914 /* Will point to the next filesystem in the kernel table */
918 /* When this code is not compiled as a module, this is the main entry point,
919 * called by do_sys_setup() in fs/filesystems.c
921 * NOTE : __initfunc() is a macro used to remove this function from memory
922 * once initialization is done
924 __initfunc(int init_ntfs_fs(void))
926 /* Comment this if you trust klogd. There are reasons not to trust it
928 #if defined(DEBUG) && !defined(MODULE)
929 extern int console_loglevel
;
932 printk(KERN_NOTICE
"NTFS version " NTFS_VERSION
"\n");
934 ntfs_debug(DEBUG_OTHER
, "registering %s\n",ntfs_fs_type
.name
);
935 /* add this filesystem to the kernel table of filesystems */
936 return register_filesystem(&ntfs_fs_type
);
940 /* A module is a piece of code which can be inserted in and removed
941 * from the running kernel whenever you want using lsmod, or on demand using
945 /* No function of this module is needed by another module */
947 /* Only used for documentation purposes at the moment,
948 * see include/linux/module.h
950 MODULE_AUTHOR("Martin von Löwis");
951 MODULE_DESCRIPTION("NTFS driver");
952 /* no MODULE_SUPPORTED_DEVICE() */
953 /* Load-time parameter */
954 MODULE_PARM(ntdebug
, "i");
955 MODULE_PARM_DESC(ntdebug
, "Debug level");
957 /* When this code is compiled as a module, if you use mount -t ntfs when no
958 * ntfs filesystem is registered (see /proc/filesystems), get_fs_type() in
959 * fs/super.c asks kmod to load the module named ntfs in memory.
961 * Therefore, this function is the main entry point in this case
963 int init_module(void)
965 return init_ntfs_fs();
968 /* Called by kmod just before the kernel removes the module from memory */
969 void cleanup_module(void)
972 ntfs_debug(DEBUG_OTHER
, "unregistering %s\n",ntfs_fs_type
.name
);
973 unregister_filesystem(&ntfs_fs_type
);
979 * c-file-style: "linux"