Import 2.1.81
[davej-history.git] / fs / ntfs / fs.c
blobac4f5892b1671beaa68fd32b9c9a04ed825d5bb2
1 /*
2 * fs.c
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
8 */
10 #ifdef HAVE_CONFIG_H
11 #include "config.h"
12 #endif
13 #ifdef NTFS_IN_LINUX_KERNEL
14 #include <linux/config.h>
15 #endif
17 #include "types.h"
18 #include "struct.h"
19 #include "util.h"
20 #include "inode.h"
21 #include "super.h"
22 #include "dir.h"
23 #include "support.h"
24 #include "macros.h"
25 #include "sysctl.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);
38 dest->param+=len;
41 #ifdef CONFIG_NTFS_RW
42 static void ntfs_getuser(void *dest,ntfs_io *src,ntfs_size_t len)
44 copy_from_user(dest,src->param,len);
45 src->param+=len;
47 #endif
49 static ssize_t
50 ntfs_read(struct file * filp, char *buf, size_t count, loff_t *off)
52 int error;
53 ntfs_io io;
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))
62 return -EINVAL;
64 /* read the data */
65 io.fn_put=ntfs_putuser;
66 io.fn_get=0;
67 io.param=buf;
68 io.size=count;
69 error=ntfs_read_attr(ino,ino->vol->at_data,NULL,*off,&io);
70 if(error)return -error;
72 *off+=io.size;
73 return io.size;
76 #ifdef CONFIG_NTFS_RW
77 static ssize_t
78 ntfs_write(struct file *filp,const char* buf,size_t count,loff_t *pos)
80 struct super_block* sb;
81 int ret;
82 ntfs_io io;
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)
91 return -ENOSPC;
92 if(!ntfs_find_attr(ino,ino->vol->at_data,NULL))
93 return -EINVAL;
95 io.fn_put=0;
96 io.fn_get=ntfs_getuser;
97 io.param=(void*)buf; /* to get rid of the const */
98 io.size=count;
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;
103 *pos+=ret;
104 return ret;
106 #endif
108 struct ntfs_filldir{
109 struct inode *dir;
110 filldir_t filldir;
111 unsigned int type;
112 ntfs_u32 ph,pl;
113 void *dirent;
114 char *name;
115 int namelen;
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);
125 int i,error;
126 switch(nf->type){
127 case ngt_dos:
128 /* Don't display long names */
129 if((flags & 2)==0)
130 return 0;
131 break;
132 case ngt_nt:
133 /* Don't display short-only names */
134 switch(flags&3){
135 case 2: return 0;
136 case 3: to_lower=1;
138 break;
139 case ngt_posix:
140 break;
141 case ngt_full:
142 show_hidden=1;
143 break;
145 if(!show_hidden && ((NTFS_GETU8(entry+0x48) & 2)==2)){
146 ntfs_debug(DEBUG_OTHER,"Skipping hidden file\n");
147 return 0;
149 nf->name=0;
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);
154 return 0;
156 /* Do not return ".", as this is faked */
157 if(length==1 && *nf->name=='.')
158 return 0;
159 if(to_lower)
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);
172 ntfs_free(nf->name);
173 /* Linux filldir errors are negative, other errors positive */
174 return error;
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;
183 int error;
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 */
195 if(cb.ph==0xFFFF){
196 /* FIXME: Maybe we can return those with the previous call */
197 switch(cb.pl){
198 case 0: filldir(dirent,".",1,filp->f_pos,dir->i_ino);
199 filp->f_pos=0xFFFF0001;
200 return 0;
201 /* FIXME: parent directory */
202 case 1: filldir(dirent,"..",2,filp->f_pos,0);
203 filp->f_pos=0xFFFF0002;
204 return 0;
206 ntfs_debug(DEBUG_OTHER, "readdir: EOD\n");
207 return 0;
209 cb.dir=dir;
210 cb.filldir=filldir;
211 cb.dirent=dirent;
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,
216 ntfs_printcb,&cb);
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 */
222 if(error<0)
223 error=0;
224 /* Otherwise (device error, inconsistent data), switch the sign */
225 return -error;
228 /* Copied from vfat driver */
229 static int simple_getbool(char *s, int *setval)
231 if (s) {
232 if (!strcmp(s,"1") || !strcmp(s,"yes") || !strcmp(s,"true")) {
233 *setval = 1;
234 } else if (!strcmp(s,"0") || !strcmp(s,"no") || !strcmp(s,"false")) {
235 *setval = 0;
236 } else {
237 return 0;
239 } else {
240 *setval = 1;
242 return 1;
245 /* Parse the (re)mount options */
246 static int parse_options(ntfs_volume* vol,char *opt)
248 char *value;
250 vol->uid=vol->gid=0;
251 vol->umask=0077;
252 vol->ngt=ngt_nt;
253 vol->nls_map=0;
254 vol->nct=0;
255 if(!opt)goto done;
257 for(opt = strtok(opt,",");opt;opt=strtok(NULL,","))
259 if ((value = strchr(opt, '=')) != NULL)
260 *value++='\0';
261 if(strcmp(opt,"uid")==0)
263 if(!value || !*value)goto needs_arg;
264 vol->uid=simple_strtoul(value,&value,0);
265 if(*value){
266 printk(KERN_ERR "NTFS: uid invalid argument\n");
267 return 0;
269 }else if(strcmp(opt, "gid") == 0)
271 if(!value || !*value)goto needs_arg;
272 vol->gid=simple_strtoul(value,&value,0);
273 if(*value){
274 printk(KERN_ERR "gid invalid argument\n");
275 return 0;
277 }else if(strcmp(opt, "umask") == 0)
279 if(!value || !*value)goto needs_arg;
280 vol->umask=simple_strtoul(value,&value,0);
281 if(*value){
282 printk(KERN_ERR "umask invalid argument\n");
283 return 0;
285 }else if(strcmp(opt, "iocharset") == 0){
286 if(!value || !*value)goto needs_arg;
287 vol->nls_map=load_nls(value);
288 vol->nct |= nct_map;
289 if(!vol->nls_map){
290 printk(KERN_ERR "NTFS: charset not found");
291 return 0;
293 }else if(strcmp(opt, "posix") == 0){
294 int val;
295 if(!value || !*value)goto needs_arg;
296 if(!simple_getbool(value,&val))
297 goto needs_bool;
298 vol->ngt=val?ngt_posix:ngt_nt;
299 }else if(strcmp(opt,"utf8") == 0){
300 int val=0;
301 if(!value || !*value)
302 val=1;
303 else if(!simple_getbool(value,&val))
304 goto needs_bool;
305 if(val)
306 vol->nct|=nct_utf8;
307 }else if(strcmp(opt,"uni_xlate") == 0){
308 int val=0;
309 /* no argument: uni_vfat.
310 boolean argument: uni_vfat.
311 "2": uni.
313 if(!value || !*value)
314 val=1;
315 else if(strcmp(value,"2")==0)
316 vol->nct |= nct_uni_xlate;
317 else if(!simple_getbool(value,&val))
318 goto needs_bool;
319 if(val)
320 vol->nct |= nct_uni_xlate_vfat | nct_uni_xlate;
321 }else{
322 printk(KERN_ERR "NTFS: unkown option '%s'\n", opt);
323 return 0;
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");
328 return 0;
330 done:
331 if((vol->nct & (nct_uni_xlate | nct_map | nct_utf8))==0)
332 /* default to UTF-8 */
333 vol->nct=nct_utf8;
334 if(!vol->nls_map)
335 vol->nls_map=load_nls_default();
336 return 1;
338 needs_arg:
339 printk(KERN_ERR "NTFS: %s needs an argument",opt);
340 return 0;
341 needs_bool:
342 printk(KERN_ERR "NTFS: %s needs boolean argument",opt);
343 return 0;
346 static int ntfs_lookup(struct inode *dir, struct dentry *d)
348 struct inode *res=0;
349 char *item=0;
350 ntfs_iterate_s walk;
351 int error;
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);
357 if(error)
358 return error;
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 */
362 walk.type=BY_NAME;
363 walk.dir=NTFS_LINO2NINO(dir);
364 walk.result=item;
365 if(ntfs_getdir_byname(&walk))
367 res=iget(dir->i_sb,NTFS_GETU32(item));
369 d_add(d,res);
370 ntfs_free(item);
371 ntfs_free(walk.name);
372 return res?0:-ENOENT;
375 struct file_operations ntfs_file_operations_nommap = {
376 NULL, /* lseek */
377 ntfs_read,
378 #ifdef CONFIG_NTFS_RW
379 ntfs_write,
380 #else
381 NULL,
382 #endif
383 NULL, /* readdir */
384 NULL, /* select */
385 NULL, /* ioctl */
386 NULL, /* mmap */
387 NULL, /* open */
388 NULL, /* release */
389 NULL, /* fsync */
390 NULL, /* fasync */
391 NULL, /* check_media_change */
392 NULL, /* revalidate */
393 NULL, /* lock */
396 struct inode_operations ntfs_inode_operations_nobmap = {
397 &ntfs_file_operations_nommap,
398 NULL, /* create */
399 NULL, /* lookup */
400 NULL, /* link */
401 NULL, /* unlink */
402 NULL, /* symlink */
403 NULL, /* mkdir */
404 NULL, /* rmdir */
405 NULL, /* mknod */
406 NULL, /* rename */
407 NULL, /* readlink */
408 NULL, /* follow_link */
409 NULL, /* readpage */
410 NULL, /* writepage */
411 NULL, /* bmap */
412 NULL, /* truncate */
413 NULL, /* permission */
414 NULL, /* smap */
415 NULL, /* updatepage */
416 NULL, /* revalidate */
419 #ifdef CONFIG_NTFS_RW
420 static int
421 ntfs_create(struct inode* dir,struct dentry *d,int mode)
423 struct inode *r=0;
424 ntfs_inode *ino=0;
425 ntfs_volume *vol;
426 int error=0;
427 ntfs_attribute *si;
429 r=get_empty_inode();
430 if(!r){
431 error=ENOMEM;
432 goto fail;
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);
439 #else
440 ino=ntfs_malloc(sizeof(ntfs_inode));
441 if(!ino){
442 error=ENOMEM;
443 goto fail;
445 r->u.generic_ip=ino;
446 #endif
447 error=ntfs_alloc_inode(NTFS_LINO2NINO(dir),ino,(char*)d->d_name.name,
448 d->d_name.len);
449 if(error)goto fail;
450 error=ntfs_update_inode(ino);
451 if(error)goto fail;
452 error=ntfs_update_inode(NTFS_LINO2NINO(dir));
453 if(error)goto fail;
455 r->i_uid=vol->uid;
456 r->i_gid=vol->gid;
457 r->i_nlink=1;
458 r->i_sb=dir->i_sb;
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);
462 if(si){
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
472 r->i_mode|=S_IWUGO;
473 #endif
474 r->i_mode &= ~vol->umask;
476 d_instantiate(d,r);
477 return 0;
478 fail:
479 #ifndef NTFS_IN_LINUX_KERNEL
480 if(ino)ntfs_free(ino);
481 #endif
482 if(r)iput(r);
483 return -error;
485 #endif
487 static int
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 = {
497 NULL, /* lseek */
498 ntfs_read,
499 #ifdef CONFIG_NTFS_RW
500 ntfs_write,
501 #else
502 NULL,
503 #endif
504 NULL, /* readdir */
505 NULL, /* select */
506 NULL, /* ioctl */
507 generic_file_mmap,
508 NULL, /* open */
509 NULL, /* release */
510 NULL, /* fsync */
511 NULL, /* fasync */
512 NULL, /* check_media_change */
513 NULL, /* revalidate */
514 NULL, /* lock */
517 struct inode_operations ntfs_inode_operations = {
518 &ntfs_file_operations,
519 NULL, /* create */
520 NULL, /* lookup */
521 NULL, /* link */
522 NULL, /* unlink */
523 NULL, /* symlink */
524 NULL, /* mkdir */
525 NULL, /* rmdir */
526 NULL, /* mknod */
527 NULL, /* rename */
528 NULL, /* readlink */
529 NULL, /* follow_link */
530 generic_readpage,
531 NULL, /* writepage */
532 ntfs_bmap,
533 NULL, /* truncate */
534 NULL, /* permission */
535 NULL, /* smap */
536 NULL, /* updatepage */
537 NULL, /* revalidate */
540 struct file_operations ntfs_dir_operations = {
541 NULL, /* lseek */
542 NULL, /* read */
543 NULL, /* write */
544 ntfs_readdir, /* readdir */
545 NULL, /* poll */
546 NULL, /* ioctl */
547 NULL, /* mmap */
548 NULL, /* open */
549 NULL, /* release */
550 NULL, /* fsync */
551 NULL, /* fasync */
552 NULL, /* check_media_change */
553 NULL, /* revalidate */
554 NULL, /* lock */
557 struct inode_operations ntfs_dir_inode_operations = {
558 &ntfs_dir_operations,
559 #ifdef CONFIG_NTFS_RW
560 ntfs_create, /* create */
561 #else
562 NULL,
563 #endif
564 ntfs_lookup, /* lookup */
565 NULL, /* link */
566 NULL, /* unlink */
567 NULL, /* symlink */
568 NULL, /* mkdir */
569 NULL, /* rmdir */
570 NULL, /* mknod */
571 NULL, /* rename */
572 NULL, /* readlink */
573 NULL, /* follow_link */
574 NULL, /* readpage */
575 NULL, /* writepage */
576 NULL, /* bmap */
577 NULL, /* truncate */
578 NULL, /* permission */
579 NULL, /* smap */
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)
591 ntfs_volume *vol;
592 int can_mmap=0;
593 ntfs_inode *ino;
594 ntfs_attribute *data;
595 ntfs_attribute *si;
597 vol=NTFS_INO2VOL(inode);
598 inode->i_op=NULL;
599 inode->i_mode=0;
600 ntfs_debug(DEBUG_OTHER, "ntfs_read_inode %x\n",(unsigned)inode->i_ino);
602 switch(inode->i_ino)
604 /* those are loaded special files */
605 case FILE_MFT:
606 ntfs_error("Trying to open MFT\n");return;
607 default:
608 #ifdef NTFS_IN_LINUX_KERNEL
609 ino=&inode->u.ntfs_i;
610 #else
611 ino=(ntfs_inode*)ntfs_malloc(sizeof(ntfs_inode));
612 inode->u.generic_ip=ino;
613 #endif
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);
619 return;
622 /* Set uid/gid from mount options */
623 inode->i_uid=vol->uid;
624 inode->i_gid=vol->gid;
625 inode->i_nlink=1;
626 /* Use the size of the data attribute as file size */
627 data = ntfs_find_attr(ino,vol->at_data,NULL);
628 if(!data)
630 inode->i_size=0;
631 can_mmap=0;
633 else
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);
640 if(si){
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"))
649 ntfs_attribute *at;
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;
656 else
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;
665 #endif
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);
675 #else
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);
680 ino->u.generic_ip=0;
682 #endif
683 clear_inode(ino);
686 /* Called when umounting a filesystem by do_umount() in fs/super.c */
687 static void ntfs_put_super(struct super_block *sb)
689 ntfs_volume *vol;
691 ntfs_debug(DEBUG_OTHER, "ntfs_put_super\n");
692 /* Ensure that nobody uses the super block anymore */
693 lock_super(sb);
694 vol=NTFS_SB2VOL(sb);
695 /* Tell the kernel that the super block is no more used */
696 sb->s_dev = 0;
697 unlock_super(sb);
698 ntfs_release_volume(vol);
699 if(vol->nls_map)
700 unload_nls(vol->nls_map);
701 #ifndef NTFS_IN_LINUX_KERNEL
702 ntfs_free(vol);
703 #endif
704 ntfs_debug(DEBUG_OTHER, "ntfs_put_super: done\n");
705 MOD_DEC_USE_COUNT;
708 /* Called by the kernel when asking for stats */
709 static int ntfs_statfs(struct super_block *sb, struct statfs *sf, int bufsize)
711 struct statfs fs;
712 struct inode *mft;
713 ntfs_volume *vol;
715 ntfs_debug(DEBUG_OTHER, "ntfs_statfs\n");
716 vol=NTFS_SB2VOL(sb);
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 */
726 fs.f_ffree=0;
727 mft=iget(sb,FILE_MFT);
728 fs.f_files=mft->i_size/vol->mft_recordsize;
729 iput(mft);
731 /* should be read from volume */
732 fs.f_namelen=255;
733 copy_to_user(sf,&fs,bufsize);
734 return 0;
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))
741 return -EINVAL;
742 return 0;
745 /* Define the super block operation that are implemented */
746 struct super_operations ntfs_super_operations = {
747 ntfs_read_inode,
748 NULL, /* write_inode */
749 ntfs_put_inode,
750 NULL, /* delete_inode */
751 NULL, /* notify_change */
752 ntfs_put_super,
753 NULL, /* write_super */
754 ntfs_statfs,
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)
770 ntfs_volume *vol;
771 struct buffer_head *bh;
772 int i;
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
776 * reference counter.
778 MOD_INC_USE_COUNT;
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);
786 #else
787 if(!(vol = ntfs_malloc(sizeof(ntfs_volume))))
788 goto ntfs_read_super_dec;
789 NTFS_SB2VOL(sb)=vol;
790 #endif
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 */
796 lock_super(sb);
797 ntfs_debug(DEBUG_OTHER, "lock_super\n");
798 #if 0
799 /* Set to read only, user option might reset it */
800 sb->s_flags |= MS_RDONLY;
801 #endif
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");
815 brelse(bh);
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);
822 brelse(bh);
823 NTFS_SB(vol)=sb;
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);
844 brelse(bh);
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;
870 unlock_super(sb);
871 ntfs_debug(DEBUG_OTHER, "unlock_super\n");
872 ntfs_debug(DEBUG_OTHER, "read_super: done\n");
873 return sb;
875 ntfs_read_super_mft:
876 ntfs_free(vol->mft);
877 ntfs_read_super_unl:
878 sb->s_dev = 0;
879 unlock_super(sb);
880 ntfs_debug(DEBUG_OTHER, "unlock_super\n");
881 ntfs_read_super_vol:
882 #ifndef NTFS_IN_LINUX_KERNEL
883 ntfs_free(vol);
884 ntfs_read_super_dec:
885 #endif
886 ntfs_debug(DEBUG_OTHER, "read_super: done\n");
887 MOD_DEC_USE_COUNT;
888 return NULL;
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 */
898 #ifndef SECOND
899 "ntfs",
900 #else
901 "ntfs2",
902 #endif
903 /* This filesystem requires a device (a hard disk)
904 * May want to add FS_IBASKET when it works
906 FS_REQUIRES_DEV,
907 /* Entry point of the filesystem */
908 ntfs_read_super,
909 /* Will point to the next filesystem in the kernel table */
910 NULL
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;
925 console_loglevel=15;
926 #endif
927 printk(KERN_NOTICE "NTFS version " NTFS_VERSION "\n");
928 SYSCTL(1);
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);
934 #ifdef MODULE
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
937 * kerneld
940 /* No function of this module is needed by another module */
941 EXPORT_NO_SYMBOLS;
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)
966 SYSCTL(0);
967 ntfs_debug(DEBUG_OTHER, "unregistering %s\n",ntfs_fs_type.name);
968 unregister_filesystem(&ntfs_fs_type);
970 #endif
973 * Local variables:
974 * c-file-style: "linux"
975 * End: