Import 2.3.9pre7
[davej-history.git] / fs / ntfs / fs.c
blobcc6bfe2e3a9781712f735ce95d6e39e1c4a805ff
1 /*
2 * fs.c
3 * NTFS driver for Linux 2.1
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 */
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 "ntfstypes.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 /* Forward declarations */
33 static struct inode_operations ntfs_dir_inode_operations;
35 #define ITEM_SIZE 2040
37 /* io functions to user space */
38 static void ntfs_putuser(ntfs_io* dest,void *src,ntfs_size_t len)
40 copy_to_user(dest->param,src,len);
41 dest->param+=len;
44 #ifdef CONFIG_NTFS_RW
45 struct ntfs_getuser_update_vm_s{
46 const char *user;
47 struct inode *ino;
48 loff_t off;
51 static void ntfs_getuser_update_vm (void *dest, ntfs_io *src, ntfs_size_t len)
53 struct ntfs_getuser_update_vm_s *p = src->param;
54 copy_from_user (dest, p->user, len);
55 update_vm_cache (p->ino, p->off, dest, len);
56 p->user += len;
57 p->off += len;
59 #endif
61 static ssize_t
62 ntfs_read(struct file * filp, char *buf, size_t count, loff_t *off)
64 int error;
65 ntfs_io io;
66 ntfs_inode *ino=NTFS_LINO2NINO(filp->f_dentry->d_inode);
68 /* inode is not properly initialized */
69 if(!ino)return -EINVAL;
70 ntfs_debug(DEBUG_OTHER, "ntfs_read %x,%x,%x ->",
71 (unsigned)ino->i_number,(unsigned)*off,(unsigned)count);
72 /* inode has no unnamed data attribute */
73 if(!ntfs_find_attr(ino,ino->vol->at_data,NULL))
74 return -EINVAL;
76 /* read the data */
77 io.fn_put=ntfs_putuser;
78 io.fn_get=0;
79 io.param=buf;
80 io.size=count;
81 error=ntfs_read_attr(ino,ino->vol->at_data,NULL,*off,&io);
82 if(error)return -error;
84 *off+=io.size;
85 return io.size;
88 #ifdef CONFIG_NTFS_RW
89 static ssize_t
90 ntfs_write(struct file *filp,const char* buf,size_t count,loff_t *pos)
92 int ret;
93 ntfs_io io;
94 struct inode *inode = filp->f_dentry->d_inode;
95 ntfs_inode *ino = NTFS_LINO2NINO(inode);
96 struct ntfs_getuser_update_vm_s param;
98 if (!ino)
99 return -EINVAL;
100 ntfs_debug (DEBUG_LINUX, "ntfs_write %x,%x,%x ->\n",
101 (unsigned)ino->i_number, (unsigned)*pos, (unsigned)count);
102 /* Allows to lock fs ro at any time */
103 if (inode->i_sb->s_flags & MS_RDONLY)
104 return -ENOSPC;
105 if (!ntfs_find_attr(ino,ino->vol->at_data,NULL))
106 return -EINVAL;
108 /* Evaluating O_APPEND is the file system's job... */
109 if (filp->f_flags & O_APPEND)
110 *pos = inode->i_size;
111 param.user = buf;
112 param.ino = inode;
113 param.off = *pos;
114 io.fn_put = 0;
115 io.fn_get = ntfs_getuser_update_vm;
116 io.param = &param;
117 io.size = count;
118 ret = ntfs_write_attr (ino, ino->vol->at_data, NULL, *pos, &io);
119 ntfs_debug (DEBUG_LINUX, "write -> %x\n", ret);
120 if(ret<0)
121 return -EINVAL;
123 *pos += io.size;
124 if (*pos > inode->i_size)
125 inode->i_size = *pos;
126 mark_inode_dirty (filp->f_dentry->d_inode);
127 return io.size;
129 #endif
131 struct ntfs_filldir{
132 struct inode *dir;
133 filldir_t filldir;
134 unsigned int type;
135 ntfs_u32 ph,pl;
136 void *dirent;
137 char *name;
138 int namelen;
141 static int ntfs_printcb(ntfs_u8 *entry,void *param)
143 struct ntfs_filldir* nf=param;
144 int flags=NTFS_GETU8(entry+0x51);
145 int show_hidden=0;
146 int length=NTFS_GETU8(entry+0x50);
147 int inum=NTFS_GETU32(entry);
148 int error;
149 #ifdef NTFS_NGT_NT_DOES_LOWER
150 int i,to_lower=0;
151 #endif
152 switch(nf->type){
153 case ngt_dos:
154 /* Don't display long names */
155 if((flags & 2)==0)
156 return 0;
157 break;
158 case ngt_nt:
159 /* Don't display short-only names */
160 switch(flags&3){
161 case 2: return 0;
162 #ifdef NTFS_NGT_NT_DOES_LOWER
163 case 3: to_lower=1;
164 #endif
166 break;
167 case ngt_posix:
168 break;
169 case ngt_full:
170 show_hidden=1;
171 break;
173 if(!show_hidden && ((NTFS_GETU8(entry+0x48) & 2)==2)){
174 ntfs_debug(DEBUG_OTHER,"Skipping hidden file\n");
175 return 0;
177 nf->name=0;
178 if(ntfs_encodeuni(NTFS_INO2VOL(nf->dir),(ntfs_u16*)(entry+0x52),
179 length,&nf->name,&nf->namelen)){
180 ntfs_debug(DEBUG_OTHER,"Skipping unrepresentable file\n");
181 if(nf->name)ntfs_free(nf->name);
182 return 0;
184 /* Do not return ".", as this is faked */
185 if(length==1 && *nf->name=='.')
186 return 0;
187 #ifdef NTFS_NGT_NT_DOES_LOWER
188 if(to_lower)
189 for(i=0;i<nf->namelen;i++)
190 /* This supports ASCII only. Since only DOS-only
191 names get converted, and since those are restricted
192 to ASCII, this should be correct */
193 if(nf->name[i]>='A' && nf->name[i]<='Z')
194 nf->name[i]+='a'-'A';
195 #endif
196 nf->name[nf->namelen]=0;
197 ntfs_debug(DEBUG_OTHER, "readdir got %s,len %d\n",nf->name,nf->namelen);
198 /* filldir expects an off_t rather than an loff_t.
199 Hope we don't have more than 65535 index records */
200 error=nf->filldir(nf->dirent,nf->name,nf->namelen,
201 (nf->ph<<16)|nf->pl,inum);
202 ntfs_free(nf->name);
203 /* Linux filldir errors are negative, other errors positive */
204 return error;
207 /* readdir returns '..', then '.', then the directory entries in sequence
208 As the root directory contains a entry for itself, '.' is not emulated
209 for the root directory */
210 static int ntfs_readdir(struct file* filp, void *dirent, filldir_t filldir)
212 struct ntfs_filldir cb;
213 int error;
214 struct inode *dir=filp->f_dentry->d_inode;
216 ntfs_debug(DEBUG_OTHER, "ntfs_readdir ino %x mode %x\n",
217 (unsigned)dir->i_ino,(unsigned int)dir->i_mode);
219 ntfs_debug(DEBUG_OTHER, "readdir: Looking for file %x dircount %d\n",
220 (unsigned)filp->f_pos,dir->i_count);
221 cb.pl=filp->f_pos & 0xFFFF;
222 cb.ph=filp->f_pos >> 16;
223 /* end of directory */
224 if(cb.ph==0xFFFF){
225 /* FIXME: Maybe we can return those with the previous call */
226 switch(cb.pl){
227 case 0: filldir(dirent,".",1,filp->f_pos,dir->i_ino);
228 filp->f_pos=0xFFFF0001;
229 return 0;
230 /* FIXME: parent directory */
231 case 1: filldir(dirent,"..",2,filp->f_pos,0);
232 filp->f_pos=0xFFFF0002;
233 return 0;
235 ntfs_debug(DEBUG_OTHER, "readdir: EOD\n");
236 return 0;
238 cb.dir=dir;
239 cb.filldir=filldir;
240 cb.dirent=dirent;
241 cb.type=NTFS_INO2VOL(dir)->ngt;
243 ntfs_debug(DEBUG_OTHER,"looking for next file\n");
244 error=ntfs_getdir_unsorted(NTFS_LINO2NINO(dir),&cb.ph,&cb.pl,
245 ntfs_printcb,&cb);
246 }while(!error && cb.ph!=0xFFFFFFFF);
247 filp->f_pos=(cb.ph<<16)|cb.pl;
248 ntfs_debug(DEBUG_OTHER, "new position %x\n",(unsigned)filp->f_pos);
249 /* -EINVAL is on user buffer full. This is not considered
250 as an error by sys_getdents */
251 if(error<0)
252 error=0;
253 /* Otherwise (device error, inconsistent data), switch the sign */
254 return -error;
257 /* Copied from vfat driver */
258 static int simple_getbool(char *s, int *setval)
260 if (s) {
261 if (!strcmp(s,"1") || !strcmp(s,"yes") || !strcmp(s,"true")) {
262 *setval = 1;
263 } else if (!strcmp(s,"0") || !strcmp(s,"no") || !strcmp(s,"false")) {
264 *setval = 0;
265 } else {
266 return 0;
268 } else {
269 *setval = 1;
271 return 1;
274 /* Parse the (re)mount options */
275 static int parse_options(ntfs_volume* vol,char *opt)
277 char *value;
279 vol->uid=vol->gid=0;
280 vol->umask=0077;
281 vol->ngt=ngt_nt;
282 vol->nls_map=0;
283 vol->nct=0;
284 if(!opt)goto done;
286 for(opt = strtok(opt,",");opt;opt=strtok(NULL,","))
288 if ((value = strchr(opt, '=')) != NULL)
289 *value++='\0';
290 if(strcmp(opt,"uid")==0)
292 if(!value || !*value)goto needs_arg;
293 vol->uid=simple_strtoul(value,&value,0);
294 if(*value){
295 printk(KERN_ERR "NTFS: uid invalid argument\n");
296 return 0;
298 }else if(strcmp(opt, "gid") == 0)
300 if(!value || !*value)goto needs_arg;
301 vol->gid=simple_strtoul(value,&value,0);
302 if(*value){
303 printk(KERN_ERR "gid invalid argument\n");
304 return 0;
306 }else if(strcmp(opt, "umask") == 0)
308 if(!value || !*value)goto needs_arg;
309 vol->umask=simple_strtoul(value,&value,0);
310 if(*value){
311 printk(KERN_ERR "umask invalid argument\n");
312 return 0;
314 }else if(strcmp(opt, "iocharset") == 0){
315 if(!value || !*value)goto needs_arg;
316 vol->nls_map=load_nls(value);
317 vol->nct |= nct_map;
318 if(!vol->nls_map){
319 printk(KERN_ERR "NTFS: charset not found");
320 return 0;
322 }else if(strcmp(opt, "posix") == 0){
323 int val;
324 if(!value || !*value)goto needs_arg;
325 if(!simple_getbool(value,&val))
326 goto needs_bool;
327 vol->ngt=val?ngt_posix:ngt_nt;
328 }else if(strcmp(opt,"utf8") == 0){
329 int val=0;
330 if(!value || !*value)
331 val=1;
332 else if(!simple_getbool(value,&val))
333 goto needs_bool;
334 if(val)
335 vol->nct|=nct_utf8;
336 }else if(strcmp(opt,"uni_xlate") == 0){
337 int val=0;
338 /* no argument: uni_vfat.
339 boolean argument: uni_vfat.
340 "2": uni.
342 if(!value || !*value)
343 val=1;
344 else if(strcmp(value,"2")==0)
345 vol->nct |= nct_uni_xlate;
346 else if(!simple_getbool(value,&val))
347 goto needs_bool;
348 if(val)
349 vol->nct |= nct_uni_xlate_vfat | nct_uni_xlate;
350 }else{
351 printk(KERN_ERR "NTFS: unkown option '%s'\n", opt);
352 return 0;
355 if(vol->nct & nct_utf8 & (nct_map | nct_uni_xlate)){
356 printk(KERN_ERR "utf8 cannot be combined with iocharset or uni_xlate\n");
357 return 0;
359 done:
360 if((vol->nct & (nct_uni_xlate | nct_map | nct_utf8))==0)
361 /* default to UTF-8 */
362 vol->nct=nct_utf8;
363 if(!vol->nls_map)
364 vol->nls_map=load_nls_default();
365 return 1;
367 needs_arg:
368 printk(KERN_ERR "NTFS: %s needs an argument",opt);
369 return 0;
370 needs_bool:
371 printk(KERN_ERR "NTFS: %s needs boolean argument",opt);
372 return 0;
375 static struct dentry *ntfs_lookup(struct inode *dir, struct dentry *d)
377 struct inode *res=0;
378 char *item=0;
379 ntfs_iterate_s walk;
380 int error;
381 ntfs_debug(DEBUG_NAME1, "Looking up %s in %x\n",d->d_name.name,
382 (unsigned)dir->i_ino);
383 /* convert to wide string */
384 error=ntfs_decodeuni(NTFS_INO2VOL(dir),(char*)d->d_name.name,
385 d->d_name.len,&walk.name,&walk.namelen);
386 if(error)
387 return ERR_PTR(-error);
388 item=ntfs_malloc(ITEM_SIZE);
389 if( !item )
390 return ERR_PTR(-ENOMEM);
391 /* ntfs_getdir will place the directory entry into item,
392 and the first long long is the MFT record number */
393 walk.type=BY_NAME;
394 walk.dir=NTFS_LINO2NINO(dir);
395 walk.result=item;
396 if(ntfs_getdir_byname(&walk))
398 res=iget(dir->i_sb,NTFS_GETU32(item));
400 d_add(d,res);
401 ntfs_free(item);
402 ntfs_free(walk.name);
403 /* Always return success, the dcache will handle negative entries. */
404 return NULL;
407 static struct file_operations ntfs_file_operations_nommap = {
408 NULL, /* lseek */
409 ntfs_read,
410 #ifdef CONFIG_NTFS_RW
411 ntfs_write,
412 #else
413 NULL,
414 #endif
415 NULL, /* readdir */
416 NULL, /* select */
417 NULL, /* ioctl */
418 NULL, /* mmap */
419 NULL, /* open */
420 NULL, /* flush */
421 NULL, /* release */
422 NULL, /* fsync */
423 NULL, /* fasync */
424 NULL, /* check_media_change */
425 NULL, /* revalidate */
426 NULL, /* lock */
429 static struct inode_operations ntfs_inode_operations_nobmap = {
430 &ntfs_file_operations_nommap,
431 NULL, /* create */
432 NULL, /* lookup */
433 NULL, /* link */
434 NULL, /* unlink */
435 NULL, /* symlink */
436 NULL, /* mkdir */
437 NULL, /* rmdir */
438 NULL, /* mknod */
439 NULL, /* rename */
440 NULL, /* readlink */
441 NULL, /* follow_link */
442 NULL, /* get_block */
443 NULL, /* readpage */
444 NULL, /* writepage */
445 NULL, /* flushpage */
446 NULL, /* truncate */
447 NULL, /* permission */
448 NULL, /* smap */
449 NULL, /* revalidate */
452 #ifdef CONFIG_NTFS_RW
453 static int
454 ntfs_create(struct inode* dir,struct dentry *d,int mode)
456 struct inode *r=0;
457 ntfs_inode *ino=0;
458 ntfs_volume *vol;
459 int error=0;
460 ntfs_attribute *si;
462 r=get_empty_inode();
463 if(!r){
464 error=ENOMEM;
465 goto fail;
468 ntfs_debug(DEBUG_OTHER, "ntfs_create %s\n",d->d_name.name);
469 vol=NTFS_INO2VOL(dir);
470 #ifdef NTFS_IN_LINUX_KERNEL
471 ino=NTFS_LINO2NINO(r);
472 #else
473 ino=ntfs_malloc(sizeof(ntfs_inode));
474 if(!ino){
475 error=ENOMEM;
476 goto fail;
478 r->u.generic_ip=ino;
479 #endif
480 error=ntfs_alloc_file(NTFS_LINO2NINO(dir),ino,(char*)d->d_name.name,
481 d->d_name.len);
482 if(error)goto fail;
483 error=ntfs_update_inode(ino);
484 if(error)goto fail;
485 error=ntfs_update_inode(NTFS_LINO2NINO(dir));
486 if(error)goto fail;
488 r->i_uid=vol->uid;
489 r->i_gid=vol->gid;
490 r->i_nlink=1;
491 r->i_sb=dir->i_sb;
492 /* FIXME: dirty? dev? */
493 /* get the file modification times from the standard information */
494 si=ntfs_find_attr(ino,vol->at_standard_information,NULL);
495 if(si){
496 char *attr=si->d.data;
497 r->i_atime=ntfs_ntutc2unixutc(NTFS_GETU64(attr+0x18));
498 r->i_ctime=ntfs_ntutc2unixutc(NTFS_GETU64(attr));
499 r->i_mtime=ntfs_ntutc2unixutc(NTFS_GETU64(attr+8));
501 /* It's not a directory */
502 r->i_op=&ntfs_inode_operations_nobmap;
503 r->i_mode=S_IFREG|S_IRUGO;
504 #ifdef CONFIG_NTFS_RW
505 r->i_mode|=S_IWUGO;
506 #endif
507 r->i_mode &= ~vol->umask;
509 insert_inode_hash(r);
510 d_instantiate(d,r);
511 return 0;
512 fail:
513 #ifndef NTFS_IN_LINUX_KERNEL
514 if(ino)ntfs_free(ino);
515 #endif
516 if(r)iput(r);
517 return -error;
520 static int
521 _linux_ntfs_mkdir(struct inode *dir, struct dentry* d, int mode)
523 int error;
524 struct inode *r = 0;
525 ntfs_volume *vol;
526 ntfs_inode *ino;
527 ntfs_attribute *si;
529 ntfs_debug (DEBUG_DIR1, "mkdir %s in %x\n",d->d_name.name, dir->i_ino);
530 error = ENAMETOOLONG;
531 if (d->d_name.len > /* FIXME */255)
532 goto out;
534 error = EIO;
535 r = get_empty_inode();
536 if (!r)
537 goto out;
539 vol = NTFS_INO2VOL(dir);
540 #ifdef NTFS_IN_LINUX_KERNEL
541 ino = NTFS_LINO2NINO(r);
542 #else
543 ino = ntfs_malloc(sizeof(ntfs_inode));
544 error = ENOMEM;
545 if(!ino)
546 goto out;
547 r->u.generic_ip = ino;
548 #endif
549 error = ntfs_mkdir(NTFS_LINO2NINO(dir),
550 d->d_name.name, d->d_name.len, ino);
551 if(error)
552 goto out;
553 r->i_uid = vol->uid;
554 r->i_gid = vol->gid;
555 r->i_nlink = 1;
556 r->i_sb = dir->i_sb;
557 si = ntfs_find_attr(ino,vol->at_standard_information,NULL);
558 if(si){
559 char *attr = si->d.data;
560 r->i_atime = ntfs_ntutc2unixutc(NTFS_GETU64(attr+0x18));
561 r->i_ctime = ntfs_ntutc2unixutc(NTFS_GETU64(attr));
562 r->i_mtime = ntfs_ntutc2unixutc(NTFS_GETU64(attr+8));
564 /* It's a directory */
565 r->i_op = &ntfs_dir_inode_operations;
566 r->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
567 #ifdef CONFIG_NTFS_RW
568 r->i_mode|=S_IWUGO;
569 #endif
570 r->i_mode &= ~vol->umask;
572 insert_inode_hash(r);
573 d_instantiate(d, r);
574 error = 0;
575 out:
576 ntfs_debug (DEBUG_DIR1, "mkdir returns %d\n", -error);
577 return -error;
579 #endif
581 static int
582 ntfs_bmap(struct inode *ino,int block)
584 int ret=ntfs_vcn_to_lcn(NTFS_LINO2NINO(ino),block);
585 ntfs_debug(DEBUG_OTHER, "bmap of %lx,block %x is %x\n",
586 ino->i_ino,block,ret);
587 return (ret==-1) ? 0:ret;
590 static struct file_operations ntfs_file_operations = {
591 NULL, /* lseek */
592 ntfs_read,
593 #ifdef CONFIG_NTFS_RW
594 ntfs_write,
595 #else
596 NULL,
597 #endif
598 NULL, /* readdir */
599 NULL, /* select */
600 NULL, /* ioctl */
601 generic_file_mmap,
602 NULL, /* open */
603 NULL, /* flush */
604 NULL, /* release */
605 NULL, /* fsync */
606 NULL, /* fasync */
607 NULL, /* check_media_change */
608 NULL, /* revalidate */
609 NULL, /* lock */
612 static struct inode_operations ntfs_inode_operations = {
613 &ntfs_file_operations,
614 NULL, /* create */
615 NULL, /* lookup */
616 NULL, /* link */
617 NULL, /* unlink */
618 NULL, /* symlink */
619 NULL, /* mkdir */
620 NULL, /* rmdir */
621 NULL, /* mknod */
622 NULL, /* rename */
623 NULL, /* readlink */
624 NULL, /* follow_link */
625 ntfs_bmap, /* get_block */
626 block_read_full_page, /* readpage */
627 NULL, /* writepage */
628 NULL, /* flushpage */
629 NULL, /* truncate */
630 NULL, /* permission */
631 NULL, /* smap */
632 NULL, /* revalidate */
635 static struct file_operations ntfs_dir_operations = {
636 NULL, /* lseek */
637 NULL, /* read */
638 NULL, /* write */
639 ntfs_readdir, /* readdir */
640 NULL, /* poll */
641 NULL, /* ioctl */
642 NULL, /* mmap */
643 NULL, /* open */
644 NULL, /* flush */
645 NULL, /* release */
646 NULL, /* fsync */
647 NULL, /* fasync */
648 NULL, /* check_media_change */
649 NULL, /* revalidate */
650 NULL, /* lock */
653 static struct inode_operations ntfs_dir_inode_operations = {
654 &ntfs_dir_operations,
655 #ifdef CONFIG_NTFS_RW
656 ntfs_create, /* create */
657 #else
658 NULL,
659 #endif
660 ntfs_lookup, /* lookup */
661 NULL, /* link */
662 NULL, /* unlink */
663 NULL, /* symlink */
664 #ifdef CONFIG_NTFS_RW
665 _linux_ntfs_mkdir, /* mkdir */
666 #else
667 NULL,
668 #endif
669 NULL, /* rmdir */
670 NULL, /* mknod */
671 NULL, /* rename */
672 NULL, /* readlink */
673 NULL, /* follow_link */
674 NULL, /* get_block */
675 NULL, /* readpage */
676 NULL, /* writepage */
677 NULL, /* flushpage */
678 NULL, /* truncate */
679 NULL, /* permission */
680 NULL, /* smap */
681 NULL, /* revalidate */
684 /* ntfs_read_inode is called by the Virtual File System (the kernel layer that
685 * deals with filesystems) when iget is called requesting an inode not already
686 * present in the inode table. Typically filesystems have separate
687 * inode_operations for directories, files and symlinks.
689 static void ntfs_read_inode(struct inode* inode)
691 ntfs_volume *vol;
692 int can_mmap=0;
693 ntfs_inode *ino;
694 ntfs_attribute *data;
695 ntfs_attribute *si;
697 vol=NTFS_INO2VOL(inode);
698 inode->i_op=NULL;
699 inode->i_mode=0;
700 ntfs_debug(DEBUG_OTHER, "ntfs_read_inode %x\n",(unsigned)inode->i_ino);
702 switch(inode->i_ino)
704 /* those are loaded special files */
705 case FILE_MFT:
706 ntfs_error("Trying to open MFT\n");return;
707 default:
708 #ifdef NTFS_IN_LINUX_KERNEL
709 ino=&inode->u.ntfs_i;
710 #else
711 /* FIXME: check for ntfs_malloc failure */
712 ino=(ntfs_inode*)ntfs_malloc(sizeof(ntfs_inode));
713 inode->u.generic_ip=ino;
714 #endif
715 if(!ino || ntfs_init_inode(ino,
716 NTFS_INO2VOL(inode),inode->i_ino))
718 ntfs_debug(DEBUG_OTHER, "NTFS:Error loading inode %x\n",
719 (unsigned int)inode->i_ino);
720 return;
723 /* Set uid/gid from mount options */
724 inode->i_uid=vol->uid;
725 inode->i_gid=vol->gid;
726 inode->i_nlink=1;
727 /* Use the size of the data attribute as file size */
728 data = ntfs_find_attr(ino,vol->at_data,NULL);
729 if(!data)
731 inode->i_size=0;
732 can_mmap=0;
734 else
736 inode->i_size=data->size;
737 can_mmap=!data->resident && !data->compressed;
739 /* get the file modification times from the standard information */
740 si=ntfs_find_attr(ino,vol->at_standard_information,NULL);
741 if(si){
742 char *attr=si->d.data;
743 inode->i_atime=ntfs_ntutc2unixutc(NTFS_GETU64(attr+0x18));
744 inode->i_ctime=ntfs_ntutc2unixutc(NTFS_GETU64(attr));
745 inode->i_mtime=ntfs_ntutc2unixutc(NTFS_GETU64(attr+8));
747 /* if it has an index root, it's a directory */
748 if(ntfs_find_attr(ino,vol->at_index_root,"$I30"))
750 ntfs_attribute *at;
751 at = ntfs_find_attr (ino, vol->at_index_allocation, "$I30");
752 inode->i_size = at ? at->size : 0;
754 inode->i_op=&ntfs_dir_inode_operations;
755 inode->i_mode=S_IFDIR|S_IRUGO|S_IXUGO;
757 else
759 inode->i_op=can_mmap ? &ntfs_inode_operations :
760 &ntfs_inode_operations_nobmap;
761 inode->i_mode=S_IFREG|S_IRUGO;
763 #ifdef CONFIG_NTFS_RW
764 if(!data || !data->compressed)
765 inode->i_mode|=S_IWUGO;
766 #endif
767 inode->i_mode &= ~vol->umask;
770 #ifdef CONFIG_NTFS_RW
771 static void
772 ntfs_write_inode (struct inode *ino)
774 ntfs_debug (DEBUG_LINUX, "ntfs:write inode %x\n", ino->i_ino);
775 ntfs_update_inode (NTFS_LINO2NINO (ino));
777 #endif
779 static void _ntfs_clear_inode(struct inode *ino)
781 ntfs_debug(DEBUG_OTHER, "ntfs_clear_inode %lx\n",ino->i_ino);
782 #ifdef NTFS_IN_LINUX_KERNEL
783 if(ino->i_ino!=FILE_MFT)
784 ntfs_clear_inode(&ino->u.ntfs_i);
785 #else
786 if(ino->i_ino!=FILE_MFT && ino->u.generic_ip)
788 ntfs_clear_inode(ino->u.generic_ip);
789 ntfs_free(ino->u.generic_ip);
790 ino->u.generic_ip=0;
792 #endif
793 return;
796 /* Called when umounting a filesystem by do_umount() in fs/super.c */
797 static void ntfs_put_super(struct super_block *sb)
799 ntfs_volume *vol;
801 ntfs_debug(DEBUG_OTHER, "ntfs_put_super\n");
803 vol=NTFS_SB2VOL(sb);
805 ntfs_release_volume(vol);
806 if(vol->nls_map)
807 unload_nls(vol->nls_map);
808 #ifndef NTFS_IN_LINUX_KERNEL
809 ntfs_free(vol);
810 #endif
811 ntfs_debug(DEBUG_OTHER, "ntfs_put_super: done\n");
812 MOD_DEC_USE_COUNT;
815 /* Called by the kernel when asking for stats */
816 static int ntfs_statfs(struct super_block *sb, struct statfs *sf, int bufsize)
818 struct statfs fs;
819 struct inode *mft;
820 ntfs_volume *vol;
821 int error;
823 ntfs_debug(DEBUG_OTHER, "ntfs_statfs\n");
824 vol=NTFS_SB2VOL(sb);
825 memset(&fs,0,sizeof(fs));
826 fs.f_type=NTFS_SUPER_MAGIC;
827 fs.f_bsize=vol->clustersize;
829 error = ntfs_get_volumesize( NTFS_SB2VOL( sb ), &fs.f_blocks );
830 if( error )
831 return -error;
832 fs.f_bfree=ntfs_get_free_cluster_count(vol->bitmap);
833 fs.f_bavail=fs.f_bfree;
835 /* Number of files is limited by free space only, so we lie here */
836 fs.f_ffree=0;
837 mft=iget(sb,FILE_MFT);
838 fs.f_files=mft->i_size/vol->mft_recordsize;
839 iput(mft);
841 /* should be read from volume */
842 fs.f_namelen=255;
843 copy_to_user(sf,&fs,bufsize);
844 return 0;
847 /* Called when remounting a filesystem by do_remount_sb() in fs/super.c */
848 static int ntfs_remount_fs(struct super_block *sb, int *flags, char *options)
850 if(!parse_options(NTFS_SB2VOL(sb), options))
851 return -EINVAL;
852 return 0;
855 /* Define the super block operation that are implemented */
856 static struct super_operations ntfs_super_operations = {
857 ntfs_read_inode,
858 #ifdef CONFIG_NTFS_RW
859 ntfs_write_inode,
860 #else
861 NULL,
862 #endif
863 NULL, /* put_inode */
864 NULL, /* delete_inode */
865 NULL, /* notify_change */
866 ntfs_put_super,
867 NULL, /* write_super */
868 ntfs_statfs,
869 ntfs_remount_fs, /* remount */
870 _ntfs_clear_inode, /* clear_inode */
873 /* Called to mount a filesystem by read_super() in fs/super.c
874 * Return a super block, the main structure of a filesystem
876 * NOTE : Don't store a pointer to an option, as the page containing the
877 * options is freed after ntfs_read_super() returns.
879 * NOTE : A context switch can happen in kernel code only if the code blocks
880 * (= calls schedule() in kernel/sched.c).
882 struct super_block * ntfs_read_super(struct super_block *sb,
883 void *options, int silent)
885 ntfs_volume *vol;
886 struct buffer_head *bh;
887 int i;
889 /* When the driver is compiled as a module, kmod must know when it
890 * can safely remove it from memory. To do this, each module owns a
891 * reference counter.
893 MOD_INC_USE_COUNT;
894 /* Don't put ntfs_debug() before MOD_INC_USE_COUNT, printk() can block
895 * so this could lead to a race condition with kmod.
897 ntfs_debug(DEBUG_OTHER, "ntfs_read_super\n");
899 #ifdef NTFS_IN_LINUX_KERNEL
900 vol = NTFS_SB2VOL(sb);
901 #else
902 if(!(vol = ntfs_malloc(sizeof(ntfs_volume))))
903 goto ntfs_read_super_dec;
904 NTFS_SB2VOL(sb)=vol;
905 #endif
907 if(!parse_options(vol,(char*)options))
908 goto ntfs_read_super_vol;
910 /* Ensure that the super block won't be used until it is completed */
911 lock_super(sb);
912 ntfs_debug(DEBUG_OTHER, "lock_super\n");
913 #if 0
914 /* Set to read only, user option might reset it */
915 sb->s_flags |= MS_RDONLY;
916 #endif
918 /* Assume a 512 bytes block device for now */
919 set_blocksize(sb->s_dev, 512);
920 /* Read the super block (boot block) */
921 if(!(bh=bread(sb->s_dev,0,512))) {
922 ntfs_error("Reading super block failed\n");
923 goto ntfs_read_super_unl;
925 ntfs_debug(DEBUG_OTHER, "Done reading boot block\n");
927 /* Check for 'NTFS' magic number */
928 if(!IS_NTFS_VOLUME(bh->b_data)){
929 ntfs_debug(DEBUG_OTHER, "Not a NTFS volume\n");
930 brelse(bh);
931 goto ntfs_read_super_unl;
934 ntfs_debug(DEBUG_OTHER, "Going to init volume\n");
935 ntfs_init_volume(vol,bh->b_data);
936 ntfs_debug(DEBUG_OTHER, "MFT record at cluster 0x%X\n",vol->mft_cluster);
937 brelse(bh);
938 NTFS_SB(vol)=sb;
939 ntfs_debug(DEBUG_OTHER, "Done to init volume\n");
941 /* Inform the kernel that a device block is a NTFS cluster */
942 sb->s_blocksize=vol->clustersize;
943 for(i=sb->s_blocksize,sb->s_blocksize_bits=0;i != 1;i>>=1)
944 sb->s_blocksize_bits++;
945 set_blocksize(sb->s_dev,sb->s_blocksize);
946 ntfs_debug(DEBUG_OTHER, "set_blocksize\n");
948 /* Allocate a MFT record (MFT record can be smaller than a cluster) */
949 if(!(vol->mft=ntfs_malloc(max(vol->mft_recordsize,vol->clustersize))))
950 goto ntfs_read_super_unl;
952 /* Read at least the MFT record for $MFT */
953 for(i=0;i<max(vol->mft_clusters_per_record,1);i++){
954 if(!(bh=bread(sb->s_dev,vol->mft_cluster+i,vol->clustersize))) {
955 ntfs_error("Could not read MFT record 0\n");
956 goto ntfs_read_super_mft;
958 ntfs_memcpy(vol->mft+i*vol->clustersize,bh->b_data,vol->clustersize);
959 brelse(bh);
960 ntfs_debug(DEBUG_OTHER, "Read cluster %x\n",vol->mft_cluster+i);
963 /* Check and fixup this MFT record */
964 if(!ntfs_check_mft_record(vol,vol->mft)){
965 ntfs_error("Invalid MFT record 0\n");
966 goto ntfs_read_super_mft;
969 /* Inform the kernel about which super operations are available */
970 sb->s_op = &ntfs_super_operations;
971 sb->s_magic = NTFS_SUPER_MAGIC;
973 ntfs_debug(DEBUG_OTHER, "Reading special files\n");
974 if(ntfs_load_special_files(vol)){
975 ntfs_error("Error loading special files\n");
976 goto ntfs_read_super_mft;
979 ntfs_debug(DEBUG_OTHER, "Getting RootDir\n");
980 /* Get the root directory */
981 if(!(sb->s_root=d_alloc_root(iget(sb,FILE_ROOT)))){
982 ntfs_error("Could not get root dir inode\n");
983 goto ntfs_read_super_mft;
985 unlock_super(sb);
986 ntfs_debug(DEBUG_OTHER, "unlock_super\n");
987 ntfs_debug(DEBUG_OTHER, "read_super: done\n");
988 return sb;
990 ntfs_read_super_mft:
991 ntfs_free(vol->mft);
992 ntfs_read_super_unl:
993 sb->s_dev = 0;
994 unlock_super(sb);
995 ntfs_debug(DEBUG_OTHER, "unlock_super\n");
996 ntfs_read_super_vol:
997 #ifndef NTFS_IN_LINUX_KERNEL
998 ntfs_free(vol);
999 ntfs_read_super_dec:
1000 #endif
1001 ntfs_debug(DEBUG_OTHER, "read_super: done\n");
1002 MOD_DEC_USE_COUNT;
1003 return NULL;
1006 /* Define the filesystem
1008 * Define SECOND if you cannot unload ntfs, and want to avoid rebooting
1009 * for just one more test
1011 static struct file_system_type ntfs_fs_type = {
1012 /* Filesystem name, as used after mount -t */
1013 #ifndef SECOND
1014 "ntfs",
1015 #else
1016 "ntfs2",
1017 #endif
1018 /* This filesystem requires a device (a hard disk)
1019 * May want to add FS_IBASKET when it works
1021 FS_REQUIRES_DEV,
1022 /* Entry point of the filesystem */
1023 ntfs_read_super,
1024 /* Will point to the next filesystem in the kernel table */
1025 NULL
1028 /* When this code is not compiled as a module, this is the main entry point,
1029 * called by do_sys_setup() in fs/filesystems.c
1031 * NOTE : __initfunc() is a macro used to remove this function from memory
1032 * once initialization is done
1034 __initfunc(int init_ntfs_fs(void))
1036 /* Comment this if you trust klogd. There are reasons not to trust it
1038 #if defined(DEBUG) && !defined(MODULE)
1039 extern int console_loglevel;
1040 console_loglevel=15;
1041 #endif
1042 printk(KERN_NOTICE "NTFS version " NTFS_VERSION "\n");
1043 SYSCTL(1);
1044 ntfs_debug(DEBUG_OTHER, "registering %s\n",ntfs_fs_type.name);
1045 /* add this filesystem to the kernel table of filesystems */
1046 return register_filesystem(&ntfs_fs_type);
1049 #ifdef MODULE
1050 /* A module is a piece of code which can be inserted in and removed
1051 * from the running kernel whenever you want using lsmod, or on demand using
1052 * kmod
1055 /* No function of this module is needed by another module */
1056 EXPORT_NO_SYMBOLS;
1057 /* Only used for documentation purposes at the moment,
1058 * see include/linux/module.h
1060 MODULE_AUTHOR("Martin von Löwis");
1061 MODULE_DESCRIPTION("NTFS driver");
1062 /* no MODULE_SUPPORTED_DEVICE() */
1063 /* Load-time parameter */
1064 MODULE_PARM(ntdebug, "i");
1065 MODULE_PARM_DESC(ntdebug, "Debug level");
1067 /* When this code is compiled as a module, if you use mount -t ntfs when no
1068 * ntfs filesystem is registered (see /proc/filesystems), get_fs_type() in
1069 * fs/super.c asks kmod to load the module named ntfs in memory.
1071 * Therefore, this function is the main entry point in this case
1073 int init_module(void)
1075 return init_ntfs_fs();
1078 /* Called by kmod just before the kernel removes the module from memory */
1079 void cleanup_module(void)
1081 SYSCTL(0);
1082 ntfs_debug(DEBUG_OTHER, "unregistering %s\n",ntfs_fs_type.name);
1083 unregister_filesystem(&ntfs_fs_type);
1085 #endif
1088 * Local variables:
1089 * c-file-style: "linux"
1090 * End: