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
391 NULL
, /* check_media_change */
392 NULL
, /* revalidate */
396 struct inode_operations ntfs_inode_operations_nobmap
= {
397 &ntfs_file_operations_nommap
,
408 NULL
, /* follow_link */
410 NULL
, /* writepage */
413 NULL
, /* permission */
415 NULL
, /* updatepage */
416 NULL
, /* revalidate */
419 #ifdef CONFIG_NTFS_RW
421 ntfs_create(struct inode
* dir
,struct dentry
*d
,int mode
)
435 ntfs_debug(DEBUG_OTHER
, "ntfs_create %s\n",d
->d_name
.name
);
436 vol
=NTFS_INO2VOL(dir
);
437 #ifdef NTFS_IN_LINUX_KERNEL
438 ino
=NTFS_LINO2NINO(r
);
440 ino
=ntfs_malloc(sizeof(ntfs_inode
));
447 error
=ntfs_alloc_inode(NTFS_LINO2NINO(dir
),ino
,(char*)d
->d_name
.name
,
450 error
=ntfs_update_inode(ino
);
452 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_mode
=S_IFREG
|S_IRUGO
;
471 #ifdef CONFIG_NTFS_RW
474 r
->i_mode
&= ~vol
->umask
;
479 #ifndef NTFS_IN_LINUX_KERNEL
480 if(ino
)ntfs_free(ino
);
488 ntfs_bmap(struct inode
*ino
,int block
)
490 int ret
=ntfs_vcn_to_lcn(NTFS_LINO2NINO(ino
),block
);
491 ntfs_debug(DEBUG_OTHER
, "bmap of %lx,block %x is %x\n",
492 ino
->i_ino
,block
,ret
);
493 return (ret
==-1) ? 0:ret
;
496 struct file_operations ntfs_file_operations
= {
499 #ifdef CONFIG_NTFS_RW
512 NULL
, /* check_media_change */
513 NULL
, /* revalidate */
517 struct inode_operations ntfs_inode_operations
= {
518 &ntfs_file_operations
,
529 NULL
, /* follow_link */
531 NULL
, /* writepage */
534 NULL
, /* permission */
536 NULL
, /* updatepage */
537 NULL
, /* revalidate */
540 struct file_operations ntfs_dir_operations
= {
544 ntfs_readdir
, /* readdir */
552 NULL
, /* check_media_change */
553 NULL
, /* revalidate */
557 struct inode_operations ntfs_dir_inode_operations
= {
558 &ntfs_dir_operations
,
559 #ifdef CONFIG_NTFS_RW
560 ntfs_create
, /* create */
564 ntfs_lookup
, /* lookup */
573 NULL
, /* follow_link */
575 NULL
, /* writepage */
578 NULL
, /* permission */
580 NULL
, /* updatepage */
581 NULL
, /* revalidate */
584 /* ntfs_read_inode is called by the Virtual File System (the kernel layer that
585 * deals with filesystems) when iget is called requesting an inode not already
586 * present in the inode table. Typically filesystems have separate
587 * inode_operations for directories, files and symlinks.
589 static void ntfs_read_inode(struct inode
* inode
)
594 ntfs_attribute
*data
;
597 vol
=NTFS_INO2VOL(inode
);
600 ntfs_debug(DEBUG_OTHER
, "ntfs_read_inode %x\n",(unsigned)inode
->i_ino
);
604 /* those are loaded special files */
606 ntfs_error("Trying to open MFT\n");return;
608 #ifdef NTFS_IN_LINUX_KERNEL
609 ino
=&inode
->u
.ntfs_i
;
611 ino
=(ntfs_inode
*)ntfs_malloc(sizeof(ntfs_inode
));
612 inode
->u
.generic_ip
=ino
;
614 if(!ino
|| ntfs_init_inode(ino
,
615 NTFS_INO2VOL(inode
),inode
->i_ino
))
617 ntfs_debug(DEBUG_OTHER
, "NTFS:Error loading inode %x\n",
618 (unsigned int)inode
->i_ino
);
622 /* Set uid/gid from mount options */
623 inode
->i_uid
=vol
->uid
;
624 inode
->i_gid
=vol
->gid
;
626 /* Use the size of the data attribute as file size */
627 data
= ntfs_find_attr(ino
,vol
->at_data
,NULL
);
635 inode
->i_size
=data
->size
;
636 can_mmap
=!data
->resident
&& !data
->compressed
;
638 /* get the file modification times from the standard information */
639 si
=ntfs_find_attr(ino
,vol
->at_standard_information
,NULL
);
641 char *attr
=si
->d
.data
;
642 inode
->i_atime
=ntfs_ntutc2unixutc(NTFS_GETU64(attr
+0x18));
643 inode
->i_ctime
=ntfs_ntutc2unixutc(NTFS_GETU64(attr
));
644 inode
->i_mtime
=ntfs_ntutc2unixutc(NTFS_GETU64(attr
+8));
646 /* if it has an index root, it's a directory */
647 if(ntfs_find_attr(ino
,vol
->at_index_root
,"$I30"))
650 at
= ntfs_find_attr (ino
, vol
->at_index_allocation
, "$I30");
651 inode
->i_size
= at
? at
->size
: 0;
653 inode
->i_op
=&ntfs_dir_inode_operations
;
654 inode
->i_mode
=S_IFDIR
|S_IRUGO
|S_IXUGO
;
658 inode
->i_op
=can_mmap
? &ntfs_inode_operations
:
659 &ntfs_inode_operations_nobmap
;
660 inode
->i_mode
=S_IFREG
|S_IRUGO
;
662 #ifdef CONFIG_NTFS_RW
663 if(!data
|| !data
->compressed
)
664 inode
->i_mode
|=S_IWUGO
;
666 inode
->i_mode
&= ~vol
->umask
;
669 static void ntfs_put_inode(struct inode
*ino
)
671 ntfs_debug(DEBUG_OTHER
, "ntfs_put_inode %lx\n",ino
->i_ino
);
672 #ifdef NTFS_IN_LINUX_KERNEL
673 if(ino
->i_ino
!=FILE_MFT
)
674 ntfs_clear_inode(&ino
->u
.ntfs_i
);
676 if(ino
->i_ino
!=FILE_MFT
&& ino
->u
.generic_ip
)
678 ntfs_clear_inode(ino
->u
.generic_ip
);
679 ntfs_free(ino
->u
.generic_ip
);
686 /* Called when umounting a filesystem by do_umount() in fs/super.c */
687 static void ntfs_put_super(struct super_block
*sb
)
691 ntfs_debug(DEBUG_OTHER
, "ntfs_put_super\n");
692 /* Ensure that nobody uses the super block anymore */
695 /* Tell the kernel that the super block is no more used */
698 ntfs_release_volume(vol
);
700 unload_nls(vol
->nls_map
);
701 #ifndef NTFS_IN_LINUX_KERNEL
704 ntfs_debug(DEBUG_OTHER
, "ntfs_put_super: done\n");
708 /* Called by the kernel when asking for stats */
709 static int ntfs_statfs(struct super_block
*sb
, struct statfs
*sf
, int bufsize
)
715 ntfs_debug(DEBUG_OTHER
, "ntfs_statfs\n");
717 memset(&fs
,0,sizeof(fs
));
718 fs
.f_type
=NTFS_SUPER_MAGIC
;
719 fs
.f_bsize
=vol
->clustersize
;
721 fs
.f_blocks
=ntfs_get_volumesize(NTFS_SB2VOL(sb
));
722 fs
.f_bfree
=ntfs_get_free_cluster_count(vol
->bitmap
);
723 fs
.f_bavail
=fs
.f_bfree
;
725 /* Number of files is limited by free space only, so we lie here */
727 mft
=iget(sb
,FILE_MFT
);
728 fs
.f_files
=mft
->i_size
/vol
->mft_recordsize
;
731 /* should be read from volume */
733 copy_to_user(sf
,&fs
,bufsize
);
737 /* Called when remounting a filesystem by do_remount_sb() in fs/super.c */
738 static int ntfs_remount_fs(struct super_block
*sb
, int *flags
, char *options
)
740 if(!parse_options(NTFS_SB2VOL(sb
), options
))
745 /* Define the super block operation that are implemented */
746 struct super_operations ntfs_super_operations
= {
748 NULL
, /* write_inode */
750 NULL
, /* delete_inode */
751 NULL
, /* notify_change */
753 NULL
, /* write_super */
755 ntfs_remount_fs
, /* remount */
758 /* Called to mount a filesystem by read_super() in fs/super.c
759 * Return a super block, the main structure of a filesystem
761 * NOTE : Don't store a pointer to an option, as the page containing the
762 * options is freed after ntfs_read_super() returns.
764 * NOTE : A context switch can happen in kernel code only if the code blocks
765 * (= calls schedule() in kernel/sched.c).
767 struct super_block
* ntfs_read_super(struct super_block
*sb
,
768 void *options
, int silent
)
771 struct buffer_head
*bh
;
774 /* When the driver is compiled as a module, kerneld must know when it
775 * can safely remove it from memory. To do this, each module owns a
779 /* Don't put ntfs_debug() before MOD_INC_USE_COUNT, printk() can block
780 * so this could lead to a race condition with kerneld.
782 ntfs_debug(DEBUG_OTHER
, "ntfs_read_super\n");
784 #ifdef NTFS_IN_LINUX_KERNEL
785 vol
= NTFS_SB2VOL(sb
);
787 if(!(vol
= ntfs_malloc(sizeof(ntfs_volume
))))
788 goto ntfs_read_super_dec
;
792 if(!parse_options(vol
,(char*)options
))
793 goto ntfs_read_super_vol
;
795 /* Ensure that the super block won't be used until it is completed */
797 ntfs_debug(DEBUG_OTHER
, "lock_super\n");
799 /* Set to read only, user option might reset it */
800 sb
->s_flags
|= MS_RDONLY
;
803 /* Assume a 512 bytes block device for now */
804 set_blocksize(sb
->s_dev
, 512);
805 /* Read the super block (boot block) */
806 if(!(bh
=bread(sb
->s_dev
,0,512))) {
807 ntfs_error("Reading super block failed\n");
808 goto ntfs_read_super_unl
;
810 ntfs_debug(DEBUG_OTHER
, "Done reading boot block\n");
812 /* Check for 'NTFS' magic number */
813 if(!IS_NTFS_VOLUME(bh
->b_data
)){
814 ntfs_debug(DEBUG_OTHER
, "Not a NTFS volume\n");
816 goto ntfs_read_super_unl
;
819 ntfs_debug(DEBUG_OTHER
, "Going to init volume\n");
820 ntfs_init_volume(vol
,bh
->b_data
);
821 ntfs_debug(DEBUG_OTHER
, "MFT record at cluster 0x%X\n",vol
->mft_cluster
);
824 ntfs_debug(DEBUG_OTHER
, "Done to init volume\n");
826 /* Inform the kernel that a device block is a NTFS cluster */
827 sb
->s_blocksize
=vol
->clustersize
;
828 for(i
=sb
->s_blocksize
,sb
->s_blocksize_bits
=0;i
;i
>>=1)
829 sb
->s_blocksize_bits
++;
830 set_blocksize(sb
->s_dev
,sb
->s_blocksize
);
831 ntfs_debug(DEBUG_OTHER
, "set_blocksize\n");
833 /* Allocate a MFT record (MFT record can be smaller than a cluster) */
834 if(!(vol
->mft
=ntfs_malloc(max(vol
->mft_recordsize
,vol
->clustersize
))))
835 goto ntfs_read_super_unl
;
837 /* Read at least the MFT record for $MFT */
838 for(i
=0;i
<max(vol
->mft_clusters_per_record
,1);i
++){
839 if(!(bh
=bread(sb
->s_dev
,vol
->mft_cluster
+i
,vol
->clustersize
))) {
840 ntfs_error("Could not read MFT record 0\n");
841 goto ntfs_read_super_mft
;
843 ntfs_memcpy(vol
->mft
+i
*vol
->clustersize
,bh
->b_data
,vol
->clustersize
);
845 ntfs_debug(DEBUG_OTHER
, "Read cluster %x\n",vol
->mft_cluster
+i
);
848 /* Check and fixup this MFT record */
849 if(!ntfs_check_mft_record(vol
,vol
->mft
)){
850 ntfs_error("Invalid MFT record 0\n");
851 goto ntfs_read_super_mft
;
854 /* Inform the kernel about which super operations are available */
855 sb
->s_op
= &ntfs_super_operations
;
856 sb
->s_magic
= NTFS_SUPER_MAGIC
;
858 ntfs_debug(DEBUG_OTHER
, "Reading special files\n");
859 if(ntfs_load_special_files(vol
)){
860 ntfs_error("Error loading special files\n");
861 goto ntfs_read_super_mft
;
864 ntfs_debug(DEBUG_OTHER
, "Getting RootDir\n");
865 /* Get the root directory */
866 if(!(sb
->s_root
=d_alloc_root(iget(sb
,FILE_ROOT
),NULL
))){
867 ntfs_error("Could not get root dir inode\n");
868 goto ntfs_read_super_mft
;
871 ntfs_debug(DEBUG_OTHER
, "unlock_super\n");
872 ntfs_debug(DEBUG_OTHER
, "read_super: done\n");
880 ntfs_debug(DEBUG_OTHER
, "unlock_super\n");
882 #ifndef NTFS_IN_LINUX_KERNEL
886 ntfs_debug(DEBUG_OTHER
, "read_super: done\n");
891 /* Define the filesystem
893 * Define SECOND if you cannot unload ntfs, and want to avoid rebooting
894 * for just one more test
896 struct file_system_type ntfs_fs_type
= {
897 /* Filesystem name, as used after mount -t */
903 /* This filesystem requires a device (a hard disk)
904 * May want to add FS_IBASKET when it works
907 /* Entry point of the filesystem */
909 /* Will point to the next filesystem in the kernel table */
913 /* When this code is not compiled as a module, this is the main entry point,
914 * called by do_sys_setup() in fs/filesystems.c
916 * NOTE : __initfunc() is a macro used to remove this function from memory
917 * once initialization is done
919 __initfunc(int init_ntfs_fs(void))
921 /* Comment this if you trust klogd. There are reasons not to trust it
923 #if defined(DEBUG) && !defined(MODULE)
924 extern int console_loglevel
;
927 printk(KERN_NOTICE
"NTFS version " NTFS_VERSION
"\n");
929 ntfs_debug(DEBUG_OTHER
, "registering %s\n",ntfs_fs_type
.name
);
930 /* add this filesystem to the kernel table of filesystems */
931 return register_filesystem(&ntfs_fs_type
);
935 /* A module is a piece of code which can be inserted in and removed
936 * from the running kernel whenever you want using lsmod, or on demand using
940 /* No function of this module is needed by another module */
942 /* Only used for documentation purposes at the moment,
943 * see include/linux/module.h
945 MODULE_AUTHOR("Martin von Löwis");
946 MODULE_DESCRIPTION("NTFS driver");
947 /* no MODULE_SUPPORTED_DEVICE() */
948 /* Load-time parameter */
949 MODULE_PARM(ntdebug
, "i");
950 MODULE_PARM_DESC(ntdebug
, "Debug level");
952 /* When this code is compiled as a module, if you use mount -t ntfs when no
953 * ntfs filesystem is registered (see /proc/filesystems), get_fs_type() in
954 * fs/super.c asks kerneld to load the module named ntfs in memory.
956 * Therefore, this function is the main entry point in this case
958 int init_module(void)
960 return init_ntfs_fs();
963 /* Called by kerneld just before the kernel removes the module from memory */
964 void cleanup_module(void)
967 ntfs_debug(DEBUG_OTHER
, "unregistering %s\n",ntfs_fs_type
.name
);
968 unregister_filesystem(&ntfs_fs_type
);
974 * c-file-style: "linux"